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 "EpidemicApp.h"
00032 #include "EpidemicStore.h"
00033
00034 #include "simlpy/interpreter_hooks.h"
00035 #include "pydtn/parsers.h"
00036 #include <iostream>
00037
00038 using namespace Epidemic;
00039
00040 DTN::ByteString EpidemicApp::kIdentifier((unsigned char*)"epidemic");
00041 unsigned char EpidemicApp::kSummaryVector = 0;
00042 unsigned char EpidemicApp::kDataRequest = 1;
00043
00044 EpidemicApp::EpidemicApp( EpidemicStore* es,
00045 DTN::Link* l,
00046 const struct timeval& t ) :
00047 m_store( es ),
00048 m_link( l )
00049 {
00050 m_lifetime.tv_sec = t.tv_sec;
00051 m_lifetime.tv_usec = t.tv_usec;
00052 }
00053
00054 EpidemicApp::~EpidemicApp()
00055 {
00056 LinkMap::iterator itr = m_linkMap.begin();
00057 LinkMap::iterator end = m_linkMap.end();
00058 for ( ; itr != end ; ++itr )
00059 {
00060 if ( 0 != itr->second )
00061 {
00062 delete itr->second;
00063 }
00064 }
00065 }
00066
00067 void
00068 EpidemicApp::newNeighbor( const DTN::ByteString& addr )
00069 {
00070 if ( 0 == m_store ) return;
00071 if ( 0 == m_owner ) return;
00072
00073
00074 if ( m_linkMap.end() == m_linkMap.find(addr) )
00075 {
00076 m_linkMap[addr] = new Mobility::MockLink(m_link,addr);
00077 }
00078
00079
00080
00081 m_store->forwardLastHop( addr, *m_owner );
00082
00083
00084 DTN::ByteString* sv = m_store->summaryVector();
00085 if ( 0 == sv ) return;
00086 if ( 0 == sv->length() )
00087 {
00088 delete sv;
00089 return;
00090 }
00091 DTN::ByteString data;
00092 data.push_back( kSummaryVector );
00093 data.append( *sv );
00094 if ( verbosity() > 1 )
00095 {
00096 std::cout << "sending summary vector from "
00097 << stringify(m_owner->addr())
00098 << " to "
00099 << stringify(addr)
00100 << " ["
00101 << stringify(*sv)
00102 << "]"
00103 << std::endl;
00104 }
00105 delete sv;
00106 struct timeval now = DTN::dtn_time();
00107 struct timeval exp = DTN::dtn_time();
00108 exp.tv_sec += m_lifetime.tv_sec;
00109 exp.tv_usec += m_lifetime.tv_usec;
00110 while ( exp.tv_usec > 1000000 )
00111 {
00112 exp.tv_usec -= 1000000;
00113 exp.tv_sec += 1;
00114 }
00115 DTN::Bundle* b = new DTN::Bundle( m_owner->nextSeq(),
00116 m_owner->addr(),
00117 addr,
00118 data,
00119 now,
00120 exp,
00121 DTN::Bundle::kData,
00122 appID() );
00123
00124 b->recv() = addr;
00125 m_owner->forward(b);
00126 }
00127
00128 void
00129 EpidemicApp::process( const DTN::Bundle& b )
00130 {
00131 if ( 0 == m_store ) return;
00132
00133 if ( b.payload().length() < 2 ) return;
00134
00135
00136
00137 if ( kSummaryVector == b.payload()[0] )
00138 {
00139 if ( verbosity() > 1 )
00140 {
00141 std::cout << "processing a summary vector at "
00142 << stringify( m_owner->addr())
00143 << " from "
00144 << stringify( b.source() )
00145 << std::endl;
00146 }
00147 EpidemicStore::DigestList* dl =
00148 EpidemicStore::parseSummaryVector( b.payload().substr(1) );
00149 if ( 0 == dl ) return;
00150 DTN::ByteString data;
00151 data.push_back( kDataRequest );
00152 EpidemicStore::DigestList::iterator itr = dl->begin();
00153 EpidemicStore::DigestList::iterator end = dl->end();
00154 bool haveReq = false;
00155 for ( ; itr != end ; ++itr )
00156 {
00157 if ( ! m_store->seen(*itr) )
00158 {
00159 haveReq = true;
00160 data.append( *itr );
00161 }
00162 }
00163 delete dl;
00164 if ( ! haveReq ) return;
00165 if ( verbosity() > 1 )
00166 {
00167 std::cout << "sending data request from "
00168 << stringify(m_owner->addr())
00169 << " to "
00170 << stringify(b.source())
00171 << " ["
00172 << stringify(data)
00173 << "]"
00174 << std::endl;
00175 }
00176
00177 struct timeval now = DTN::dtn_time();
00178 struct timeval exp = DTN::dtn_time();
00179 exp.tv_sec += m_lifetime.tv_sec;
00180 exp.tv_usec += m_lifetime.tv_usec;
00181 while ( exp.tv_usec > 1000000 )
00182 {
00183 exp.tv_usec -= 1000000;
00184 exp.tv_sec += 1;
00185 }
00186
00187 DTN::Bundle* pB = new DTN::Bundle( m_owner->nextSeq(),
00188 m_owner->addr(),
00189 b.source(),
00190 data,
00191 now,
00192 exp,
00193 DTN::Bundle::kData,
00194 appID() );
00195
00196 pB->recv() = b.source();
00197 m_owner->forward(pB);
00198 return;
00199 }
00200
00201
00202 if ( kDataRequest == b.payload()[0] )
00203 {
00204 EpidemicStore::DigestList* dl =
00205 EpidemicStore::parseSummaryVector( b.payload().substr(1) );
00206 if ( 0 == dl ) return;
00207
00208 EpidemicStore::DigestList::iterator itr = dl->begin();
00209 EpidemicStore::DigestList::iterator end = dl->end();
00210 for ( ; itr != end ; ++itr )
00211 {
00212 DTN::BundlePointer bp = m_store->getPointer(*itr);
00213 if ( ! bp.isNull() )
00214 {
00215
00216 DTN::Bundle* pB = bp.repr()->bundle()->clone();
00217
00218 pB->recv() = b.source();
00219
00220 m_owner->forward(pB);
00221 }
00222 }
00223 delete dl;
00224
00225 return;
00226 }
00227
00228
00229 }
00230
00231 DTN::Link*
00232 EpidemicApp::getLink( const DTN::ByteString& addr )
00233 {
00234 LinkMap::iterator itr = m_linkMap.find(addr);
00235 if ( m_linkMap.end() == itr ) return 0;
00236 return itr->second;
00237 }