00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "simlpy/interpreter_defs.h"
00032
00033 #include "NamTracer.h"
00034 #include "pydtn/WrapNode.h"
00035 #include "pydtn/WrapLink.h"
00036 #include "simlpy/Clock.h"
00037 #include <iostream>
00038 #include <ctype.h>
00039 #include <netinet/in.h>
00040
00041 bool
00042 NamTraceEvent::handle()
00043 {
00044 return m_destination->handler( *this );
00045 }
00046
00047 NamTracer::NamTracer( std::ostream& s ) :
00048 m_stream( s ),
00049 m_lastNode( 0 ),
00050 m_queueState( false ),
00051 m_tracing( false ),
00052 m_notified( false )
00053 {
00054 m_stream << std::fixed;
00055 }
00056
00057 NamTracer::~NamTracer()
00058 {
00059 }
00060
00061 void
00062 NamTracer::node( const WrapNode& wn )
00063 {
00064 if ( m_tracing )
00065 {
00066 traceNode(wn);
00067 }
00068 else
00069 {
00070 if ( ! m_notified )
00071 {
00072 Clock::schedule( new NamTraceEvent(this,this,Clock::time()) );
00073 m_notified = true;
00074 }
00075 m_nodeSet.insert( &wn );
00076 }
00077 }
00078
00079 void
00080 NamTracer::link( const WrapLink& wl )
00081 {
00082 if ( m_tracing )
00083 {
00084 traceLink(wl);
00085 }
00086 else
00087 {
00088 if ( ! m_notified )
00089 {
00090 Clock::schedule( new NamTraceEvent(this,this,Clock::time()) );
00091 m_notified = true;
00092 }
00093 m_linkSet.insert( &wl );
00094 }
00095 }
00096
00097 void
00098 NamTracer::enqueue( const DTN::Bundle& b, const DTN::Node* n )
00099 {
00100 if ( ! m_queueState ) return;
00101 if ( 0 == n ) return;
00102 m_stream << "+ ";
00103 traceBundle(b);
00104 m_stream << std::endl;
00105 }
00106
00107 void
00108 NamTracer::dequeue( const DTN::Bundle& b, const DTN::Node* n )
00109 {
00110 if ( ! m_queueState ) return;
00111 if ( 0 == n ) return;
00112 m_stream << "- ";
00113 traceBundle(b);
00114 m_stream << std::endl;
00115 }
00116
00117 void
00118 NamTracer::send( const DTN::Bundle& b, const DTN::Node* n )
00119 {
00120 if ( 0 == n ) return;
00121 m_stream << "h ";
00122 traceBundle(b);
00123 m_stream << std::endl;
00124 }
00125
00126 void
00127 NamTracer::receive( const DTN::Bundle& b, const DTN::Node* n )
00128 {
00129 if ( 0 == n ) return;
00130 m_stream << "r ";
00131 traceBundle(b);
00132 m_stream << std::endl;
00133 }
00134
00135 void
00136 NamTracer::drop( const DTN::Bundle& b,
00137 const DTN::DropCause& c,
00138 const DTN::Node* n )
00139 {
00140 if ( 0 == n ) return;
00141 m_stream << "d ";
00142 traceBundle(b);
00143 m_stream << std::endl;
00144 }
00145
00146 bool
00147 NamTracer::handler( NamTraceEvent& event )
00148 {
00149 m_tracing = true;
00150 m_stream << "V -t * -v 1.11" << std::endl;
00151 NodeSet::const_iterator nItr = m_nodeSet.begin();
00152 NodeSet::const_iterator nEnd = m_nodeSet.end();
00153 for ( ; nItr != nEnd ; ++nItr )
00154 {
00155 if ( 0 != *nItr )
00156 {
00157 traceNode(**nItr,true);
00158 }
00159 }
00160 m_nodeSet.clear();
00161 LinkSet::const_iterator lItr = m_linkSet.begin();
00162 LinkSet::const_iterator lEnd = m_linkSet.end();
00163 for ( ; lItr != lEnd ; ++lItr )
00164 {
00165 if ( 0 != *lItr )
00166 {
00167 traceLink(**lItr,true);
00168 }
00169 }
00170 m_linkSet.clear();
00171 return true;
00172 }
00173
00174 void
00175 NamTracer::traceNode( const WrapNode& wn, bool initial )
00176 {
00177 int n = nodeID(wn);
00178 m_stream << "n ";
00179 if ( initial )
00180 {
00181 m_stream << "-t * ";
00182 }
00183 else
00184 {
00185 m_stream << "-t " << time(Clock::time()) << " ";
00186 }
00187 m_stream << "-s " << n << " "
00188 << "-v circle -z 0.15 "
00189 << "-l " << stringify(wn.addr()) << " "
00190 << "-S UP"
00191 << std::endl;
00192 if ( initial )
00193 {
00194 int nv = nodeID( vQueue(wn) );
00195 m_stream << "n -t * "
00196 << "-s " << nv << " "
00197 << "-v square -z 0.05 "
00198 << "-S UP"
00199 << std::endl;
00200 m_stream << "l -t * "
00201 << "-s " << n << " "
00202 << "-d " << nv << " "
00203 << "-r " << 0 << " "
00204 << "-D " << 0 << " "
00205 << "-S " << "UP"
00206 << std::endl;
00207 m_stream << "q -t * "
00208 << "-s " << n << " "
00209 << "-d " << nv << " "
00210 << "-a 1"
00211 << std::endl;
00212 }
00213 }
00214
00215 void
00216 NamTracer::traceLink( const WrapLink& wl, bool initial )
00217 {
00218 if ( 0 == wl.source() )
00219 {
00220 return;
00221 }
00222 if ( 0 == wl.destination() )
00223 {
00224 return;
00225 }
00226 int s = nodeID(*(wl.source()));
00227 int d = nodeID(*(wl.destination()));
00228 m_stream << "l ";
00229 if ( initial )
00230 {
00231 m_stream << "-t * ";
00232 }
00233 else
00234 {
00235 m_stream << "-t " << time(Clock::time()) << " ";
00236 }
00237 m_stream << "-s " << s << " "
00238 << "-d " << d << " "
00239 << "-r " << wl.link().bandwidth() << " "
00240 << "-D " << time(wl.link().latency()) << " "
00241 << "-S " << ( wl.link().up() ? "UP" : "DOWN" )
00242 << std::endl;
00243 }
00244
00245 void
00246 NamTracer::traceBundle( const DTN::Bundle& b )
00247 {
00248 DTN::ByteString dest = b.recv();
00249 if ( b.send() == b.recv() )
00250 {
00251 dest = vQueue( b.send() );
00252 }
00253 m_stream << "-t " << time(Clock::time()) << " "
00254 << "-s " << nodeID(b.send()) << " "
00255 << "-d " << nodeID(dest) << " "
00256 << "-e " << b.size() << " "
00257 << "-i " << ntohl(b.seqNum()) << " "
00258 << "-c " << stringify(b.source()) << " ";
00259 if ( b.type() & DTN::Bundle::kACK )
00260 {
00261 m_stream << "-p " << "ack" << " ";
00262 }
00263 else
00264 {
00265 m_stream << "-p " << "udp" << " ";
00266 }
00267 }
00268
00269 int
00270 NamTracer::nodeID( const WrapNode& wn )
00271 {
00272 return nodeID(wn.addr());
00273 }
00274
00275 int
00276 NamTracer::nodeID( const DTN::ByteString& addr )
00277 {
00278 int n = m_nodes[addr];
00279 if ( 0 == n )
00280 {
00281 n = m_nodes[addr] = ++m_lastNode;
00282 }
00283 return n;
00284 }
00285
00286 DTN::ByteString
00287 NamTracer::vQueue( const WrapNode& wn )
00288 {
00289 return vQueue( wn.addr() );
00290 }
00291
00292 DTN::ByteString
00293 NamTracer::vQueue( const DTN::ByteString& addr )
00294 {
00295 return DTN::ByteString((const unsigned char*)"volatile_queue:") + addr;
00296 }
00297
00298 double
00299 NamTracer::time( const Time& t )
00300 {
00301 return t.tv.tv_sec + 1.0*t.tv.tv_usec/Time::MILLION;
00302 }
00303
00304 std::string
00305 NamTracer::stringify( const DTN::ByteString& b ) const
00306 {
00307 std::string s;
00308 bool printable = true;
00309 for ( unsigned int i = 0 ; i < b.length() ; ++i )
00310 {
00311 if ( !isprint(b[i]) ) printable = false;
00312 if ( isspace(b[i]) ) printable = false;
00313 }
00314 if ( ! printable )
00315 {
00316 s += "0x";
00317 }
00318 for ( unsigned int i = 0 ; i < b.length() ; ++i )
00319 {
00320 if ( printable )
00321 {
00322 s += b[i];
00323 }
00324 else
00325 {
00326 char tmp[3];
00327 ::sprintf(tmp,"%02X",b[i]);
00328 s += tmp[0];
00329 s += tmp[1];
00330 }
00331 }
00332
00333 return s;
00334 }