NamTracer.cc

00001 // Copyright 2008 Michael Marsh, University of Maryland.
00002 //
00003 // This file is part of pydtn.
00004 //
00005 // pydtn is free software: you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License as published by
00007 // the Free Software Foundation, either version 3 of the License, or
00008 // (at your option) any later version.
00009 //
00010 // pydtn is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with pydtn.  If not, see <http://www.gnu.org/licenses/>.
00017 //
00018 // The views and conclusions contained in the software and documentation
00019 // are those of the authors and should not be interpreted as representing
00020 // official policies, either expressed or implied, of the University
00021 // of Maryland.
00022 //
00023 // pydtn extends and embeds the Python interpreter, which is
00024 // Copyright 2001-2006 Python Software Foundation, All Rights Reserved,
00025 // and is released under the PSF License Agreement.
00026 //
00027 // RANLUX random number generation uses the Boost library,
00028 // Copyright 1994-2006 by various authors (details in individual files),
00029 // which is released under the Boost Software License, Version 1.0.
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 }

Generated on Mon Mar 24 11:15:46 2008 for Pydtn Simulator by  doxygen 1.5.4