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 "Header.h"
00032 #include "Exception.h"
00033 #include <netinet/in.h>
00034
00035 using namespace DTN;
00036
00037
00038
00039
00040
00041 SDNV::SDNV( const ByteString& s )
00042 {
00043 m_val.clear();
00044 const unsigned char mask = 0x80;
00045 ByteString::const_iterator itr = s.begin();
00046 ByteString::const_iterator end = s.end();
00047 for ( ; itr != end ; ++itr )
00048 {
00049 m_val += *itr;
00050
00051 if ( !( mask & *itr ) ) break;
00052 }
00053 }
00054
00055 SDNV&
00056 SDNV::operator=( const SDNV& v )
00057 {
00058 if ( this != &v )
00059 {
00060 m_val = v.val();
00061 }
00062 return *this;
00063 }
00064
00065 SDNV::operator uint64_t() const
00066 {
00067 uint64_t l = 0;
00068 const unsigned char mask = 0x7F;
00069 ByteString::const_iterator itr = m_val.begin();
00070 ByteString::const_iterator end = m_val.end();
00071 for ( unsigned char n = 0 ; itr != end ; ++itr, ++n )
00072 {
00073 unsigned char temp = mask & *itr;
00074 unsigned char avail_bits = 8*sizeof(l) - 7*n;
00075 if ( (temp>>1) >= (1U<<(avail_bits-1)) )
00076 {
00077 throw Exception( __FILE__ , __LINE__ );
00078 }
00079 l <<= 7;
00080 l += (mask & *itr);
00081 }
00082 return l;
00083 }
00084
00085 void
00086 SDNV::assign( uint64_t l )
00087 {
00088 const unsigned char mask = 0x7F;
00089 if ( m_val.size() != 0 )
00090 {
00091 m_val.clear();
00092 }
00093 while ( 0 != l )
00094 {
00095 unsigned char temp = l & mask;
00096 if ( ! m_val.empty() )
00097 {
00098 temp |= 0x80;
00099 }
00100 m_val.insert(0,1,temp);
00101 l >>= 7;
00102 }
00103 }
00104
00105
00106
00107
00108
00109
00110 Header::Header()
00111 {
00112 }
00113
00114 Header::Header( const ByteString& hdr ) :
00115 m_data( hdr )
00116 {
00117 }
00118
00119 Header::Header( const Header& hdr ) :
00120 m_data( hdr.m_data )
00121 {
00122 }
00123
00124 Header::~Header()
00125 {
00126 }
00127
00128
00129
00130
00131
00132
00133 PrimaryHeader::PrimaryHeader() :
00134 m_parsed ( false ),
00135 m_destinationSchemeOffset ( 0 ),
00136 m_destinationSSPOffset( 0 ),
00137 m_sourceSchemeOffset( 0 ),
00138 m_sourceSSPOffset( 0 ),
00139 m_reportToSchemeOffset( 0 ),
00140 m_reportToSSPOffset( 0 ),
00141 m_custodianSchemeOffset( 0 ),
00142 m_custodianSSPOffset( 0 ),
00143 m_creationTime( 0 ),
00144 m_creationSeqNum( 0 ),
00145 m_lifetime( 0 )
00146 {
00147 }
00148
00149 PrimaryHeader::PrimaryHeader( const ByteString& hdr ) :
00150 Header( hdr ),
00151 m_parsed ( false ),
00152 m_destinationSchemeOffset ( 0 ),
00153 m_destinationSSPOffset( 0 ),
00154 m_sourceSchemeOffset( 0 ),
00155 m_sourceSSPOffset( 0 ),
00156 m_reportToSchemeOffset( 0 ),
00157 m_reportToSSPOffset( 0 ),
00158 m_custodianSchemeOffset( 0 ),
00159 m_custodianSSPOffset( 0 ),
00160 m_creationTime( 0 ),
00161 m_creationSeqNum( 0 ),
00162 m_lifetime( 0 )
00163 {
00164 }
00165
00166 PrimaryHeader::PrimaryHeader( const PrimaryHeader& hdr ) :
00167 Header( hdr ),
00168 m_parsed ( false ),
00169 m_destinationSchemeOffset ( 0 ),
00170 m_destinationSSPOffset( 0 ),
00171 m_sourceSchemeOffset( 0 ),
00172 m_sourceSSPOffset( 0 ),
00173 m_reportToSchemeOffset( 0 ),
00174 m_reportToSSPOffset( 0 ),
00175 m_custodianSchemeOffset( 0 ),
00176 m_custodianSSPOffset( 0 ),
00177 m_creationTime( 0 ),
00178 m_creationSeqNum( 0 ),
00179 m_lifetime( 0 )
00180 {
00181 }
00182
00183 PrimaryHeader::~PrimaryHeader()
00184 {
00185 }
00186
00187 uint16_t
00188 PrimaryHeader::stringToShort( ByteString::size_type offset ) const
00189 {
00190 if ( m_data.length() < (offset+2) ) throw Exception( __FILE__ , __LINE__ );
00191 union { unsigned char c[2]; uint16_t s; } temp;
00192 temp.c[0] = m_data[offset];
00193 temp.c[1] = m_data[offset+1];
00194 return ntohs(temp.s);
00195 }
00196
00197 uint32_t
00198 PrimaryHeader::stringToInt( ByteString::size_type offset ) const
00199 {
00200 if ( m_data.length() < (offset+4) ) throw Exception( __FILE__ , __LINE__ );
00201 union { unsigned char c[4]; uint32_t l; } temp;
00202 temp.c[0] = m_data[offset];
00203 temp.c[1] = m_data[offset+1];
00204 temp.c[2] = m_data[offset+2];
00205 temp.c[3] = m_data[offset+3];
00206 return ntohl(temp.l);
00207 }
00208
00209 unsigned char
00210 PrimaryHeader::version() const
00211 {
00212 if ( m_data.length() < 1 ) throw Exception( __FILE__ , __LINE__ );
00213 return m_data[0];
00214 }
00215
00216 unsigned char
00217 PrimaryHeader::flags() const
00218 {
00219 if ( m_data.length() < 2 ) throw Exception( __FILE__ , __LINE__ );
00220 return m_data[1];
00221 }
00222
00223 unsigned char
00224 PrimaryHeader::COS() const
00225 {
00226 if ( m_data.length() < 3 ) throw Exception( __FILE__ , __LINE__ );
00227 return m_data[2];
00228 }
00229
00230 unsigned char
00231 PrimaryHeader::SRR() const
00232 {
00233 if ( m_data.length() < 4 ) throw Exception( __FILE__ , __LINE__ );
00234 return m_data[3];
00235 }
00236
00237 void
00238 PrimaryHeader::parse() const
00239 {
00240
00241
00242
00243
00244 ByteString::size_type offset = 4;
00245 ByteString temp;
00246
00247 do
00248 {
00249 temp += m_data[offset++];
00250 } while ( temp[temp.length()-1] & 0x80 );
00251 m_length = temp;
00252
00253 m_destinationSchemeOffset = stringToShort( offset ); offset += 2;
00254 m_destinationSSPOffset = stringToShort( offset ); offset += 2;
00255 m_sourceSchemeOffset = stringToShort( offset ); offset += 2;
00256 m_sourceSSPOffset = stringToShort( offset ); offset += 2;
00257 m_reportToSchemeOffset = stringToShort( offset ); offset += 2;
00258 m_reportToSSPOffset = stringToShort( offset ); offset += 2;
00259 m_custodianSchemeOffset = stringToShort( offset ); offset += 2;
00260 m_custodianSSPOffset = stringToShort( offset ); offset += 2;
00261
00262 m_creationTime = stringToInt( offset ); offset += 4;
00263 m_creationSeqNum = stringToInt( offset ); offset += 4;
00264 m_lifetime = stringToInt( offset ); offset += 4;
00265
00266 temp.clear();
00267 do
00268 {
00269 temp += m_data[offset++];
00270 } while ( temp[temp.length()-1] & 0x80 );
00271 m_dictionaryLength = temp;
00272
00273 ByteString::size_type end = offset + m_dictionaryLength;
00274 for ( ; offset < end ; ++offset )
00275 {
00276 m_dictionary += m_data[offset];
00277 }
00278
00279 temp.clear();
00280 do
00281 {
00282 temp += m_data[offset++];
00283 } while ( temp[temp.length()-1] & 0x80 );
00284 m_fragmentOffset = temp;
00285
00286 temp.clear();
00287 do
00288 {
00289 temp += m_data[offset++];
00290 } while ( temp[temp.length()-1] & 0x80 );
00291 m_applicationDataUnitLength = temp;
00292
00293 m_parsed = true;
00294 }
00295
00296 const SDNV&
00297 PrimaryHeader::length() const
00298 {
00299 if ( ! m_parsed ) parse();
00300 return m_length;
00301 }
00302
00303 uint16_t
00304 PrimaryHeader::destinationSchemeOffset() const
00305 {
00306 if ( ! m_parsed ) parse();
00307 return m_destinationSchemeOffset;
00308 }
00309
00310 uint16_t
00311 PrimaryHeader::destinationSSPOffset() const
00312 {
00313 if ( ! m_parsed ) parse();
00314 return m_destinationSSPOffset;
00315 }
00316
00317 uint16_t
00318 PrimaryHeader::sourceSchemeOffset() const
00319 {
00320 if ( ! m_parsed ) parse();
00321 return m_sourceSchemeOffset;
00322 }
00323
00324 uint16_t
00325 PrimaryHeader::sourceSSPOffset() const
00326 {
00327 if ( ! m_parsed ) parse();
00328 return m_sourceSSPOffset;
00329 }
00330
00331 uint16_t
00332 PrimaryHeader::reportToSchemeOffset() const
00333 {
00334 if ( ! m_parsed ) parse();
00335 return m_reportToSchemeOffset;
00336 }
00337
00338 uint16_t
00339 PrimaryHeader::reportToSSPOffset() const
00340 {
00341 if ( ! m_parsed ) parse();
00342 return m_reportToSSPOffset;
00343 }
00344
00345 uint16_t
00346 PrimaryHeader::custodianSchemeOffset() const
00347 {
00348 if ( ! m_parsed ) parse();
00349 return m_custodianSchemeOffset;
00350 }
00351
00352 uint16_t
00353 PrimaryHeader::custodianSSPOffset() const
00354 {
00355 if ( ! m_parsed ) parse();
00356 return m_custodianSSPOffset;
00357 }
00358
00359 uint32_t
00360 PrimaryHeader::creationTime() const
00361 {
00362 if ( ! m_parsed ) parse();
00363 return m_creationTime;
00364 }
00365
00366 uint32_t
00367 PrimaryHeader::creationSeqNum() const
00368 {
00369 if ( ! m_parsed ) parse();
00370 return m_creationSeqNum;
00371 }
00372
00373 uint32_t
00374 PrimaryHeader::lifetime() const
00375 {
00376 if ( ! m_parsed ) parse();
00377 return m_lifetime;
00378 }
00379
00380 const SDNV&
00381 PrimaryHeader::dictionaryLength() const
00382 {
00383 if ( ! m_parsed ) parse();
00384 return m_dictionaryLength;
00385 }
00386
00387 const ByteString&
00388 PrimaryHeader::dictionary() const
00389 {
00390 if ( ! m_parsed ) parse();
00391 return m_dictionary;
00392 }
00393
00394 const SDNV&
00395 PrimaryHeader::fragmentOffset() const
00396 {
00397 if ( ! m_parsed ) parse();
00398 return m_fragmentOffset;
00399 }
00400
00401 const SDNV&
00402 PrimaryHeader::applicationDataUnitLength() const
00403 {
00404 if ( ! m_parsed ) parse();
00405 return m_applicationDataUnitLength;
00406 }
00407
00408
00409
00410
00411
00412
00413 RegularHeader::RegularHeader()
00414 {
00415 }
00416
00417 RegularHeader::RegularHeader( const ByteString& hdr ) :
00418 Header( hdr )
00419 {
00420 }
00421
00422 RegularHeader::RegularHeader( const RegularHeader& hdr ) :
00423 Header( hdr )
00424 {
00425 }
00426
00427 RegularHeader::~RegularHeader()
00428 {
00429 }
00430
00431 unsigned char
00432 RegularHeader::typeCode() const
00433 {
00434 if ( 0 == m_data.length() )
00435 {
00436 throw Exception( __FILE__ , __LINE__ );
00437 }
00438 return m_data[0];
00439 }
00440
00441 unsigned char
00442 RegularHeader::flags() const
00443 {
00444 if ( m_data.length() < 2 )
00445 {
00446 throw Exception( __FILE__ , __LINE__ );
00447 }
00448 return m_data[1];
00449 }
00450
00451 SDNV
00452 RegularHeader::length() const
00453 {
00454 ByteString s;
00455 for ( unsigned int i = 2; i < m_data.length() ; ++i )
00456 {
00457 s += m_data[i];
00458 if ( !(0x80 & m_data[i]) )
00459 {
00460 return s;
00461 }
00462 }
00463 throw Exception( __FILE__ , __LINE__ );
00464 }
00465
00466
00467
00468
00469
00470
00471 PayloadHeader::PayloadHeader()
00472 {
00473 }
00474
00475 PayloadHeader::PayloadHeader( const ByteString& pld, unsigned char flags )
00476 {
00477 m_data.clear();
00478 m_data += kPayloadHeader;
00479 m_data += flags;
00480 SDNV length = pld.length();
00481 m_data += length.val();
00482 m_data += pld;
00483 }
00484
00485 PayloadHeader::PayloadHeader( const PayloadHeader& hdr ) :
00486 RegularHeader( hdr )
00487 {
00488 }
00489
00490 PayloadHeader::~PayloadHeader()
00491 {
00492 }
00493
00494 ByteString
00495 PayloadHeader::payload() const
00496 {
00497 return m_data.substr(m_offset);
00498 }