IBR-DTNSuite 0.6

tools/src/dtntracepath.cpp

Go to the documentation of this file.
00001 /*
00002  * dtnping.cpp
00003  *
00004  *  Created on: 24.06.2009
00005  *      Author: morgenro
00006  */
00007 
00008 #include "config.h"
00009 #include "ibrdtn/api/Client.h"
00010 #include "ibrdtn/api/StringBundle.h"
00011 #include "ibrcommon/net/tcpclient.h"
00012 #include "ibrcommon/thread/Mutex.h"
00013 #include "ibrcommon/thread/MutexLock.h"
00014 #include "ibrcommon/TimeMeasurement.h"
00015 
00016 #include <algorithm>
00017 #include <iostream>
00018 
00019 class Tracer : public dtn::api::Client
00020 {
00021         public:
00022                 Tracer(dtn::api::Client::COMMUNICATION_MODE mode, string app, ibrcommon::tcpstream &stream)
00023                  : dtn::api::Client(app, stream, mode), _stream(stream)
00024                 {
00025                 }
00026 
00027                 virtual ~Tracer()
00028                 {
00029                 }
00030 
00031                 void tracepath(const dtn::data::EID &destination)
00032                 {
00033                         // create a bundle
00034                         dtn::api::StringBundle b(destination);
00035 
00036                         // set lifetime
00037                         b.setLifetime(30);
00038 
00039                         // set some stupid payload
00040                         b.append("follow the white rabbit");
00041 
00042                         // request forward and delivery reports
00043                         b.requestDeliveredReport();
00044                         b.requestForwardedReport();
00045                         b.requestDeletedReport();
00046 
00047                         b.setReportTo( EID("api:me") );
00048 
00049                         ibrcommon::TimeMeasurement tm;
00050 
00051                         std::list<dtn::api::Bundle> bundles;
00052 
00053                         try {
00054                                 // start the timer
00055                                 tm.start();
00056 
00057                                 // send the bundle
00058                                 (*this) << b << std::flush;
00059 
00060                                 try {
00061                                         // now receive all incoming bundles
00062                                         while (true)
00063                                         {
00064                                                 dtn::api::Bundle recv = getBundle(10);
00065                                                 bundles.push_back(recv);
00066                                                 tm.stop();
00067 
00068                                                 std::cout << "Report received after " << tm << std::endl;
00069                                         }
00070                                 } catch (const std::exception&) {
00071 
00072                                 }
00073 
00074                                 std::cout << "No more reports received." << std::endl;
00075 
00076                                 // sort the list
00077                                 bundles.sort();
00078 
00079                                 // print out each hop
00080                                 for (std::list<dtn::api::Bundle>::iterator iter = bundles.begin(); iter != bundles.end(); iter++)
00081                                 {
00082                                         std::cout << "Hop: " << (*iter).getSource().getString() << std::endl;
00083                                 }
00084 
00085                         } catch (const dtn::api::ConnectionException&) {
00086                                 cout << "Disconnected." << endl;
00087                         } catch (const ibrcommon::IOException&) {
00088                                 cout << "Error while receiving a bundle." << endl;
00089                         }
00090                 }
00091 
00092         private:
00093                 ibrcommon::tcpstream &_stream;
00094 };
00095 
00096 void print_help()
00097 {
00098         cout << "-- dtntracepath (IBR-DTN) --" << endl;
00099         cout << "Syntax: dtntracepath [options] <dst>"  << endl;
00100         cout << " <dst>    set the destination eid (e.g. dtn://node/echo)" << endl;
00101         cout << "* optional parameters *" << endl;
00102         cout << " -h|--help       display this text" << endl;
00103 //      cout << " --src <name>    set the source application name (e.g. echo-client)" << endl;
00104 //      cout << " --nowait        do not wait for a reply" << endl;
00105 //      cout << " --size          the size of the payload" << endl;
00106 //      cout << " --count X       send X echo in a row" << endl;
00107 //      cout << " --lifetime <seconds> set the lifetime of outgoing bundles; default: 30" << endl;
00108 
00109 }
00110 
00111 int main(int argc, char *argv[])
00112 {
00113         std::string trace_destination = "dtn://local";
00114         std::string trace_source = "tracepath";
00115         dtn::api::Client::COMMUNICATION_MODE mode = dtn::api::Client::MODE_BIDIRECTIONAL;
00116 
00117         if (argc == 1)
00118         {
00119                 print_help();
00120                 return 0;
00121         }
00122 
00123         for (int i = 0; i < argc; i++)
00124         {
00125                 string arg = argv[i];
00126 
00127                 // print help if requested
00128                 if (arg == "-h" || arg == "--help")
00129                 {
00130                         print_help();
00131                         return 0;
00132                 }
00133 
00134 //              if (arg == "--nowait")
00135 //              {
00136 //                      mode = dtn::api::Client::MODE_SENDONLY;
00137 //                      wait_for_reply = false;
00138 //              }
00139 //
00140 //              if (arg == "--src" && argc > i)
00141 //              {
00142 //                      ping_source = argv[i + 1];
00143 //              }
00144 //
00145 //              if (arg == "--size" && argc > i)
00146 //              {
00147 //                      stringstream str_size;
00148 //                      str_size.str( argv[i + 1] );
00149 //                      str_size >> ping_size;
00150 //              }
00151 //
00152 //              if (arg == "--count" && argc > i)
00153 //              {
00154 //                      stringstream str_count;
00155 //                      str_count.str( argv[i + 1] );
00156 //                      str_count >> count;
00157 //              }
00158 //
00159 //              if (arg == "--lifetime" && argc > i)
00160 //              {
00161 //                      stringstream data; data << argv[i + 1];
00162 //                      data >> lifetime;
00163 //              }
00164         }
00165 
00166         // the last parameter is always the destination
00167         trace_destination = argv[argc - 1];
00168 
00169         try {
00170                 // Create a stream to the server using TCP.
00171                 ibrcommon::tcpclient conn("127.0.0.1", 4550);
00172 
00173                 // enable nodelay option
00174                 conn.enableNoDelay();
00175 
00176                 // Initiate a derivated client
00177                 Tracer tracer(mode, trace_source, conn);
00178 
00179                 // Connect to the server. Actually, this function initiate the
00180                 // stream protocol by starting the thread and sending the contact header.
00181                 tracer.connect();
00182 
00183                 // target address
00184                 tracer.tracepath(trace_destination);
00185 
00186                 // Shutdown the client connection.
00187                 tracer.close();
00188                 conn.close();
00189 
00190         } catch (const ibrcommon::tcpclient::SocketException&) {
00191                 cerr << "Can not connect to the daemon. Does it run?" << endl;
00192                 return -1;
00193         } catch (...) {
00194 
00195         }
00196 
00197         return 0;
00198 }