IBR-DTNSuite 0.6

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>" << endl;
00031         cout << "               set the lifetime of outgoing bundles; default: 3600" << endl;
00032         cout << " -U <socket>   use UNIX domain sockets" << endl;
00033         cout << " -n <copies>   create <copies> bundle copies" << endl;
00034         cout << " --encrypt     request encryption on the bundle layer" << endl;
00035         cout << " --sign        request signature on the bundle layer" << endl;
00036         cout << " --custody     request custody transfer of the bundle" << endl;
00037         cout << " --compression request compression of the payload" << endl;
00038 
00039 }
00040 
00041 int main(int argc, char *argv[])
00042 {
00043         bool error = false;
00044         string file_destination = "dtn://local/filetransfer";
00045         string file_source = "filetransfer";
00046         unsigned int lifetime = 3600;
00047         bool use_stdin = false;
00048         std::string filename;
00049         ibrcommon::File unixdomain;
00050         int priority = 1;
00051         int copies = 1;
00052         bool bundle_encryption = false;
00053         bool bundle_signed = false;
00054         bool bundle_custody = false;
00055         bool bundle_compression = false;
00056 
00057 //      ibrcommon::Logger::setVerbosity(99);
00058 //      ibrcommon::Logger::addStream(std::cout, ibrcommon::Logger::LOGGER_ALL, ibrcommon::Logger::LOG_DATETIME | ibrcommon::Logger::LOG_LEVEL);
00059 
00060         std::list<std::string> arglist;
00061 
00062         for (int i = 0; i < argc; i++)
00063         {
00064                 if (argv[i][0] == '-')
00065                 {
00066                         std::string arg = argv[i];
00067 
00068                         // print help if requested
00069                         if (arg == "-h" || arg == "--help")
00070                         {
00071                                 print_help();
00072                                 return 0;
00073                         }
00074                         else if (arg == "--encrypt")
00075                         {
00076                                 bundle_encryption = true;
00077                         }
00078                         else if (arg == "--sign")
00079                         {
00080                                 bundle_signed = true;
00081                         }
00082                         else if (arg == "--custody")
00083                         {
00084                                 bundle_custody = true;
00085                         }
00086                         else if (arg == "--compression")
00087                         {
00088                                 bundle_compression = true;
00089                         }
00090                         else if (arg == "--src" && argc > i)
00091                         {
00092                                 if (++i > argc)
00093                                 {
00094                                         std::cout << "argument missing!" << std::endl;
00095                                         return -1;
00096                                 }
00097 
00098                                 file_source = argv[i];
00099                         }
00100                         else if (arg == "--lifetime" && argc > i)
00101                         {
00102                                 if (++i > argc)
00103                                 {
00104                                         std::cout << "argument missing!" << std::endl;
00105                                         return -1;
00106                                 }
00107 
00108                                 stringstream data; data << argv[i];
00109                                 data >> lifetime;
00110                         }
00111                         else if (arg == "-p" && argc > i)
00112                         {
00113                                 if (++i > argc)
00114                                 {
00115                                         std::cout << "argument missing!" << std::endl;
00116                                         return -1;
00117                                 }
00118                                 stringstream data; data << argv[i];
00119                                 data >> priority;
00120                         }
00121                         else if (arg == "-U" && argc > i)
00122                         {
00123                                 if (++i > argc)
00124                                 {
00125                                         std::cout << "argument missing!" << std::endl;
00126                                         return -1;
00127                                 }
00128 
00129                                 unixdomain = ibrcommon::File(argv[i]);
00130                         }
00131                         else if (arg == "-n" && argc > i)
00132                         {
00133                                 if (++i > argc)
00134                                 {
00135                                         std::cout << "argument missing!" << std::endl;
00136                                         return -1;
00137                                 }
00138 
00139                                 stringstream data; data << argv[i];
00140                                 data >> copies;
00141 
00142                                 if( copies < 1 ) {
00143                                         std::cout << "invalid number of bundle copies!" << std::endl;
00144                                         return -1;
00145                                 }
00146                         } 
00147                         else
00148                         {
00149                                 std::cout << "invalid argument " << arg << std::endl;
00150                                 return -1;
00151                         }
00152                 }
00153                 else
00154                 {
00155                         arglist.push_back(argv[i]);
00156                 }
00157         }
00158 
00159         if (arglist.size() <= 1)
00160         {
00161                 print_help();
00162                 return -1;
00163         } else if (arglist.size() == 2)
00164         {
00165                 std::list<std::string>::iterator iter = arglist.begin(); iter++;
00166 
00167                 // the first parameter is the destination
00168                 file_destination = (*iter);
00169 
00170                 use_stdin = true;
00171         }
00172         else if (arglist.size() > 2)
00173         {
00174                 std::list<std::string>::iterator iter = arglist.begin(); iter++;
00175 
00176                 // the first parameter is the destination
00177                 file_destination = (*iter); iter++;
00178 
00179                 // the second parameter is the filename
00180                 filename = (*iter);
00181         }
00182 
00183         try {
00184                 // Create a stream to the server using TCP.
00185                 ibrcommon::tcpclient conn;
00186 
00187                 // check if the unixdomain socket exists
00188                 if (unixdomain.exists())
00189                 {
00190                         // connect to the unix domain socket
00191                         conn.open(unixdomain);
00192                 }
00193                 else
00194                 {
00195                         // connect to the standard local api port
00196                         conn.open("127.0.0.1", 4550);
00197 
00198                         // enable nodelay option
00199                         conn.enableNoDelay();
00200                 }
00201 
00202                 try {
00203                         // Initiate a client for synchronous receiving
00204                         dtn::api::Client client(file_source, conn, dtn::api::Client::MODE_SENDONLY);
00205 
00206                         // Connect to the server. Actually, this function initiate the
00207                         // stream protocol by starting the thread and sending the contact header.
00208                         client.connect();
00209 
00210                         // target address
00211                         EID addr = EID(file_destination);
00212 
00213                         try {
00214                                 if (use_stdin)
00215                                 {
00216                                         cout << "Transfer stdin to " << addr.getString() << endl;
00217 
00218                                         // create an empty BLOB
00219                                         ibrcommon::BLOB::Reference ref = ibrcommon::TmpFileBLOB::create();
00220 
00221                                         // copy cin to a BLOB
00222                                         (*ref.iostream()) << cin.rdbuf();
00223 
00224                                         for(int u=0; u<copies; u++){
00225                                                 dtn::api::BLOBBundle b(file_destination, ref);
00226 
00227                                                 // enable encryption if requested
00228                                                 if (bundle_encryption) b.requestEncryption();
00229 
00230                                                 // enable signature if requested
00231                                                 if (bundle_signed) b.requestSigned();
00232 
00233                                                 // enable custody transfer if requested
00234                                                 if (bundle_custody) b.requestCustodyTransfer();
00235 
00236                                                 // enable compression
00237                                                 if (bundle_compression) b.requestCompression();
00238 
00239                                                 // set the lifetime
00240                                                 b.setLifetime(lifetime);
00241 
00242                                                 // set the bundles priority
00243                                                 b.setPriority(dtn::api::Bundle::BUNDLE_PRIORITY(priority));
00244 
00245                                                 // send the bundle
00246                                                 client << b;
00247 
00248                                                 if (copies > 1)
00249                                                 {
00250                                                         std::cout << "sent copy #" << (u+1) << std::endl;
00251                                                 }
00252                                         }
00253                                 }
00254                                 else
00255                                 {
00256                                         cout << "Transfer file \"" << filename << "\" to " << addr.getString() << endl;
00257                                         
00258                                         for(int u=0; u<copies; u++){
00259                                                 // create a bundle from the file
00260                                                 dtn::api::FileBundle b(file_destination, filename);
00261 
00262                                                 // enable encryption if requested
00263                                                 if (bundle_encryption) b.requestEncryption();
00264 
00265                                                 // enable signature if requested
00266                                                 if (bundle_signed) b.requestSigned();
00267 
00268                                                 // enable custody transfer if requested
00269                                                 if (bundle_custody) b.requestCustodyTransfer();
00270 
00271                                                 // enable compression
00272                                                 if (bundle_compression) b.requestCompression();
00273 
00274                                                 // set the lifetime
00275                                                 b.setLifetime(lifetime);
00276 
00277                                                 // set the bundles priority
00278                                                 b.setPriority(dtn::api::Bundle::BUNDLE_PRIORITY(priority));
00279 
00280                                                 // send the bundle
00281                                                 client << b;
00282 
00283                                                 if (copies > 1)
00284                                                 {
00285                                                         std::cout << "sent copy #" << (u+1) << std::endl;
00286                                                 }
00287                                         }
00288                                 }
00289 
00290                                 // flush the buffers
00291                                 client.flush();
00292                         } catch (const ibrcommon::IOException &ex) {
00293                                 std::cerr << "Error while sending bundle." << std::endl;
00294                                 std::cerr << "\t" << ex.what() << std::endl;
00295                                 error = true;
00296                         }
00297 
00298                         // Shutdown the client connection.
00299                         client.close();
00300 
00301                         // print out the transmitted bytes
00302                         std::cout << client.lastack << " bytes sent" << std::endl;
00303 
00304                 } catch (const ibrcommon::IOException &ex) {
00305                         cout << "Error: " << ex.what() << endl;
00306                         error = true;
00307                 } catch (const dtn::api::ConnectionException&) {
00308                         // connection already closed, the daemon was faster
00309                 }
00310 
00311                 // close the tcpstream
00312                 conn.close();
00313         } catch (const std::exception &ex) {
00314                 cout << "Error: " << ex.what() << endl;
00315                 error = true;
00316         }
00317 
00318         if (error) return -1;
00319 
00320         return 0;
00321 }