• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

tools/src/dtnsend.cpp

Go to the documentation of this file.
00001 /*
00002  * dtnsend.cpp
00003  *
00004  *  Created on: 15.10.2009
00005  *      Author: morgenro
00006  */
00007 
00008 #include "config.h"
00009 #include <ibrdtn/api/Client.h>
00010 #include <ibrdtn/api/FileBundle.h>
00011 #include <ibrdtn/api/BLOBBundle.h>
00012 #include <ibrcommon/net/tcpclient.h>
00013 #include <ibrcommon/thread/Mutex.h>
00014 #include <ibrcommon/thread/MutexLock.h>
00015 #include <ibrcommon/data/BLOB.h>
00016 #include <ibrcommon/Logger.h>
00017 
00018 #include <iostream>
00019 
00020 void print_help()
00021 {
00022         cout << "-- dtnsend (IBR-DTN) --" << endl;
00023         cout << "Syntax: dtnsend [options] <dst> <filename>"  << endl;
00024         cout << " <dst>         set the destination eid (e.g. dtn://node/filetransfer)" << endl;
00025         cout << " <filename>    the file to transfer" << endl;
00026         cout << "* optional parameters *" << endl;
00027         cout << " -h|--help       display this text" << endl;
00028         cout << " --src <name>    set the source application name (e.g. filetransfer)" << endl;
00029         cout << " -p <0..2>       set the bundle priority (0 = low, 1 = normal, 2 = high)" << endl;
00030         cout << " --lifetime <seconds> set the lifetime of outgoing bundles; default: 3600" << endl;
00031         cout << " -U <socket>     use UNIX domain sockets" << endl;
00032         cout << " -n <copies>                   create <copies> bundle copies" << endl;
00033 
00034 }
00035 
00036 int main(int argc, char *argv[])
00037 {
00038         bool error = false;
00039         string file_destination = "dtn://local/filetransfer";
00040         string file_source = "filetransfer";
00041         unsigned int lifetime = 3600;
00042         bool use_stdin = false;
00043         std::string filename;
00044         ibrcommon::File unixdomain;
00045         int priority = 1;
00046         int copies = 1;
00047 
00048 //      ibrcommon::Logger::setVerbosity(99);
00049 //      ibrcommon::Logger::addStream(std::cout, ibrcommon::Logger::LOGGER_ALL, ibrcommon::Logger::LOG_DATETIME | ibrcommon::Logger::LOG_LEVEL);
00050 
00051         std::list<std::string> arglist;
00052 
00053         for (int i = 0; i < argc; i++)
00054         {
00055                 if (argv[i][0] == '-')
00056                 {
00057                         std::string arg = argv[i];
00058 
00059                         // print help if requested
00060                         if (arg == "-h" || arg == "--help")
00061                         {
00062                                 print_help();
00063                                 return 0;
00064                         }
00065                         else if (arg == "--src" && argc > i)
00066                         {
00067                                 if (++i > argc)
00068                                 {
00069                                         std::cout << "argument missing!" << std::endl;
00070                                         return -1;
00071                                 }
00072 
00073                                 file_source = argv[i];
00074                         }
00075                         else if (arg == "--lifetime" && argc > i)
00076                         {
00077                                 if (++i > argc)
00078                                 {
00079                                         std::cout << "argument missing!" << std::endl;
00080                                         return -1;
00081                                 }
00082 
00083                                 stringstream data; data << argv[i];
00084                                 data >> lifetime;
00085                         }
00086                         else if (arg == "-p" && argc > i)
00087                         {
00088                                 if (++i > argc)
00089                                 {
00090                                         std::cout << "argument missing!" << std::endl;
00091                                         return -1;
00092                                 }
00093                                 stringstream data; data << argv[i];
00094                                 data >> priority;
00095                         }
00096                         else if (arg == "-U" && argc > i)
00097                         {
00098                                 if (++i > argc)
00099                                 {
00100                                         std::cout << "argument missing!" << std::endl;
00101                                         return -1;
00102                                 }
00103 
00104                                 unixdomain = ibrcommon::File(argv[i]);
00105                         }
00106                         else if (arg == "-n" && argc > i)
00107                         {
00108                                 if (++i > argc)
00109                                 {
00110                                         std::cout << "argument missing!" << std::endl;
00111                                         return -1;
00112                                 }
00113 
00114                                 stringstream data; data << argv[i];
00115                                 data >> copies;
00116 
00117                                 if( copies < 1 ) {
00118                                         std::cout << "invalid number of bundle copies!" << std::endl;
00119                                         return -1;
00120                                 }
00121                         } 
00122                         else
00123                         {
00124                                 std::cout << "invalid argument " << arg << std::endl;
00125                                 return -1;
00126                         }
00127                 }
00128                 else
00129                 {
00130                         arglist.push_back(argv[i]);
00131                 }
00132         }
00133 
00134         if (arglist.size() <= 1)
00135         {
00136                 print_help();
00137                 return -1;
00138         } else if (arglist.size() == 2)
00139         {
00140                 std::list<std::string>::iterator iter = arglist.begin(); iter++;
00141 
00142                 // the first parameter is the destination
00143                 file_destination = (*iter);
00144 
00145                 use_stdin = true;
00146         }
00147         else if (arglist.size() > 2)
00148         {
00149                 std::list<std::string>::iterator iter = arglist.begin(); iter++;
00150 
00151                 // the first parameter is the destination
00152                 file_destination = (*iter); iter++;
00153 
00154                 // the second parameter is the filename
00155                 filename = (*iter);
00156         }
00157 
00158         try {
00159                 // Create a stream to the server using TCP.
00160                 ibrcommon::tcpclient conn;
00161 
00162                 // check if the unixdomain socket exists
00163                 if (unixdomain.exists())
00164                 {
00165                         // connect to the unix domain socket
00166                         conn.open(unixdomain);
00167                 }
00168                 else
00169                 {
00170                         // connect to the standard local api port
00171                         conn.open("127.0.0.1", 4550);
00172 
00173                         // enable nodelay option
00174                         conn.enableNoDelay();
00175                 }
00176 
00177                 try {
00178                         // Initiate a client for synchronous receiving
00179                         dtn::api::Client client(dtn::api::Client::MODE_SENDONLY, file_source, conn);
00180 
00181                         // Connect to the server. Actually, this function initiate the
00182                         // stream protocol by starting the thread and sending the contact header.
00183                         client.connect();
00184 
00185                         // target address
00186                         EID addr = EID(file_destination);
00187 
00188                         try {
00189                                 if (use_stdin)
00190                                 {
00191                                         cout << "Transfer stdin to " << addr.getNodeEID() << endl;
00192 
00193                                         // create an empty BLOB
00194                                         ibrcommon::BLOB::Reference ref = ibrcommon::TmpFileBLOB::create();
00195 
00196                                         // copy cin to a BLOB
00197                                         {
00198                                                 ibrcommon::MutexLock l(ref);
00199                                                 (*ref) << cin.rdbuf();
00200                                         }
00201 
00202                                         for(int u=0; u<copies; u++){
00203                                                 dtn::api::BLOBBundle b(file_destination, ref);
00204 
00205                                                 // set the lifetime
00206                                                 b.setLifetime(lifetime);
00207 
00208                                                 // set the bundles priority
00209                                                 b.setPriority(dtn::api::Bundle::BUNDLE_PRIORITY(priority));
00210 
00211                                                 // send the bundle
00212                                                 client << b;
00213 
00214                                                 if (copies > 1)
00215                                                 {
00216                                                         std::cout << "sent copy #" << (u+1) << std::endl;
00217                                                 }
00218                                         }
00219                                 }
00220                                 else
00221                                 {
00222                                         cout << "Transfer file \"" << filename << "\" to " << addr.getNodeEID() << endl;
00223                                         
00224                                         for(int u=0; u<copies; u++){
00225                                                 // create a bundle from the file
00226                                                 dtn::api::FileBundle b(file_destination, filename);
00227 
00228                                                 // set the lifetime
00229                                                 b.setLifetime(lifetime);
00230 
00231                                                 // set the bundles priority
00232                                                 b.setPriority(dtn::api::Bundle::BUNDLE_PRIORITY(priority));
00233 
00234                                                 // send the bundle
00235                                                 client << b;
00236 
00237                                                 if (copies > 1)
00238                                                 {
00239                                                         std::cout << "sent copy #" << (u+1) << std::endl;
00240                                                 }
00241                                         }
00242                                 }
00243 
00244                                 // flush the buffers
00245                                 client.flush();
00246                         } catch (const ibrcommon::IOException &ex) {
00247                                 std::cerr << "Error while sending bundle." << std::endl;
00248                                 std::cerr << "\t" << ex.what() << std::endl;
00249                                 error = true;
00250                         }
00251 
00252                         // Shutdown the client connection.
00253                         client.close();
00254 
00255                         // print out the transmitted bytes
00256                         std::cout << client.lastack << " bytes sent" << std::endl;
00257 
00258                 } catch (const ibrcommon::IOException &ex) {
00259                         cout << "Error: " << ex.what() << endl;
00260                         error = true;
00261                 } catch (const dtn::api::ConnectionException&) {
00262                         // connection already closed, the daemon was faster
00263                 }
00264 
00265                 // close the tcpstream
00266                 conn.close();
00267         } catch (const std::exception &ex) {
00268                 cout << "Error: " << ex.what() << endl;
00269                 error = true;
00270         }
00271 
00272         if (error) return -1;
00273 
00274         return 0;
00275 }

Generated on Thu Nov 11 2010 09:49:47 for IBR-DTNSuite by  doxygen 1.7.1