servlib/bundling/BPQBlock.cc
changeset 64 1296a0283271
parent 55 1938118cd06c
child 65 333724f2f7cf
equal deleted inserted replaced
63:9a8be24c5037 64:1296a0283271
     1 /*
     1 /*
     2  *    Copyright 2006 Intel Corporation
     2  *    Copyright 2010-2011 Trinity College Dublin
     3  * 
     3  * 
     4  *    Licensed under the Apache License, Version 2.0 (the "License");
     4  *    Licensed under the Apache License, Version 2.0 (the "License");
     5  *    you may not use this file except in compliance with the License.
     5  *    you may not use this file except in compliance with the License.
     6  *    You may obtain a copy of the License at
     6  *    You may obtain a copy of the License at
     7  * 
     7  * 
    23 #include "BundleProtocol.h"
    23 #include "BundleProtocol.h"
    24 #include "SDNV.h"
    24 #include "SDNV.h"
    25 
    25 
    26 namespace dtn {
    26 namespace dtn {
    27 
    27 
    28 // Setup our logging information
    28 BPQBlock::BPQBlock(const Bundle* bundle)
    29 static const char* LOG = "/dtn/bundle/extblock/bpq";
    29 		: Logger("BPQBlock", "/dtn/bundle/bpq")
    30 
    30 {
    31 BPQBlock::BPQBlock(Bundle* bundle)
    31     log_info("constructor()");
    32 {
       
    33     log_info_p(LOG, "BPQBlock::constructor()");
       
    34 
    32 
    35     if( bundle->recv_blocks().
    33     if( bundle->recv_blocks().
    36         has_block(BundleProtocol::QUERY_EXTENSION_BLOCK) ) {
    34         has_block(BundleProtocol::QUERY_EXTENSION_BLOCK) ) {
    37 
    35 
    38         log_debug_p(LOG, "BPQBlock found in Recv Block Vec => created remotly");
    36         log_debug("BPQBlock found in Recv Block Vec => created remotely");
    39         initialise( const_cast<BlockInfo*> (bundle->recv_blocks().
    37         initialise( const_cast<BlockInfo*> (bundle->recv_blocks().
    40                     find_block(BundleProtocol::QUERY_EXTENSION_BLOCK)) );
    38                     find_block(BundleProtocol::QUERY_EXTENSION_BLOCK)),
    41 
    39         			true, bundle);
    42     } else if( bundle->api_blocks()->
    40 
       
    41     } else if( const_cast<Bundle*>(bundle)->api_blocks()->
    43                has_block(BundleProtocol::QUERY_EXTENSION_BLOCK) ) {
    42                has_block(BundleProtocol::QUERY_EXTENSION_BLOCK) ) {
    44 
    43 
    45         log_debug_p(LOG, "BPQBlock found in API Block Vec => created locally");
    44         log_debug("BPQBlock found in API Block Vec => created locally");
    46         initialise( const_cast<BlockInfo*> (bundle->api_blocks()->
    45         initialise( const_cast<BlockInfo*> (const_cast<Bundle*>(bundle)->api_blocks()->
    47                     find_block(BundleProtocol::QUERY_EXTENSION_BLOCK)) );
    46                     find_block(BundleProtocol::QUERY_EXTENSION_BLOCK)),
    48 
    47                     true, bundle);
    49     } else {
    48 
    50         log_err_p(LOG, "BPQ Block not found in bundle");
    49     } else {
    51     }
    50         log_err("BPQ Block not found in bundle");
    52 
    51     }
    53     log_info_p(LOG, "leaving constructor");
    52 
    54 }
    53     log_info("leaving constructor");
    55 
       
    56 //----------------------------------------------------------------------
       
    57 BPQBlock::BPQBlock(BlockInfo* block)
       
    58 {
       
    59     log_info_p(LOG, "BPQBlock::constructor()");
       
    60 
       
    61     ASSERT( block->type() == BundleProtocol::QUERY_EXTENSION_BLOCK);
       
    62 
       
    63     initialise(block);
       
    64 
       
    65     log_info_p(LOG, "leaving constructor");
       
    66 }
    54 }
    67 
    55 
    68 //----------------------------------------------------------------------
    56 //----------------------------------------------------------------------
    69 BPQBlock::~BPQBlock()
    57 BPQBlock::~BPQBlock()
    70 {
    58 {
    71     log_info_p(LOG, "BPQBlock: destructor");
    59     log_info("BPQBlock: destructor");
    72     if ( query_val_ != NULL ){
    60     if ( query_val_ != NULL ){
    73         free(query_val_);
    61         free(query_val_);
    74         query_val_ = NULL;
    62         query_val_ = NULL;
    75     }
    63     }
    76 }
    64 }
    92     if ( i < len )
    80     if ( i < len )
    93         buf[i++] = (u_char) matching_rule_;
    81         buf[i++] = (u_char) matching_rule_;
    94     else
    82     else
    95         return -1;
    83         return -1;
    96 
    84 
       
    85     // timestamp secs		SDNV
       
    86     if ( i < len &&
       
    87         (encoding_len = SDNV::encode (creation_ts_.seconds_, &(buf[i]), len -i)) >= 0 ) {
       
    88         i += encoding_len;
       
    89     } else {
       
    90         log_err("Error encoding BPQ creation timestamp secs");
       
    91         return -1;
       
    92     }
       
    93 
       
    94     // timestamp seqno		SDNV
       
    95     if ( i < len &&
       
    96         (encoding_len = SDNV::encode (creation_ts_.seqno_, &(buf[i]), len -i)) >= 0 ) {
       
    97         i += encoding_len;
       
    98     } else {
       
    99         log_err("Error encoding BPQ creation timestamp seqno");
       
   100         return -1;
       
   101     }
       
   102 
       
   103     // source eid length	SDNV
       
   104     if ( i < len &&
       
   105         (encoding_len = SDNV::encode (source_.length(), &(buf[i]), len -i)) >= 0 ) {
       
   106         i += encoding_len;
       
   107     } else {
       
   108         log_err("Error encoding BPQ source EID length");
       
   109         return -1;
       
   110     }
       
   111 
       
   112     // source eid           n-bytes
       
   113     const char* src_eid = source_.c_str();
       
   114     for (j=0; src_eid != NULL && i < len && j < source_.length(); i++, j++)
       
   115         buf[i] = src_eid[j];
       
   116 
    97     // query-length         SDNV
   117     // query-length         SDNV
    98     if ( i < len &&
   118     if ( i < len &&
    99         (encoding_len = SDNV::encode (query_len_, &(buf[i]), len -i)) >= 0 ) {
   119         (encoding_len = SDNV::encode (query_len_, &(buf[i]), len -i)) >= 0 ) {
   100         i += encoding_len;
   120         i += encoding_len;
   101     } else {
   121     } else {
   102         log_err_p(LOG, "Error encoding _BPQ query length");
   122         log_err("Error encoding BPQ query length");
   103         return -1;
   123         return -1;
   104     }
   124     }
   105 
   125 
   106     // query-value           n-bytes
   126     // query-value           n-bytes
   107     for (j=0; query_val_ != NULL && i < len && j < query_len_; i++, j++)
   127     for (j=0; query_val_ != NULL && i < len && j < query_len_; i++, j++)
   110     // fragment-length		SDNV
   130     // fragment-length		SDNV
   111     if ( i < len &&
   131     if ( i < len &&
   112         (encoding_len = SDNV::encode (frag_len(), &(buf[i]), len -i)) >= 0 ) {
   132         (encoding_len = SDNV::encode (frag_len(), &(buf[i]), len -i)) >= 0 ) {
   113         i += encoding_len;
   133         i += encoding_len;
   114     } else {
   134     } else {
   115         log_err_p(LOG, "Error encoding _BPQ fragment length");
   135         log_err("Error encoding BPQ fragment length");
   116         return -1;
   136         return -1;
   117     }
   137     }
   118 
   138 
   119     // fragment-values		SDNV
   139     // fragment-values		SDNV
   120     BPQFragmentVec::const_iterator iter;
   140     BPQFragmentVec::const_iterator iter;
   124 
   144 
   125         if ( i < len &&
   145         if ( i < len &&
   126             (encoding_len = SDNV::encode (iter->offset(), &(buf[i]), len -i)) >= 0 ) {
   146             (encoding_len = SDNV::encode (iter->offset(), &(buf[i]), len -i)) >= 0 ) {
   127             i += encoding_len;
   147             i += encoding_len;
   128         } else {
   148         } else {
   129             log_err_p(LOG, "Error encoding _BPQ individual fragment offset");
   149             log_err("Error encoding BPQ individual fragment offset");
   130             return -1;
   150             return -1;
   131         }
   151         }
   132 
   152 
   133         if ( i < len &&
   153         if ( i < len &&
   134             (encoding_len = SDNV::encode (iter->length(), &(buf[i]), len -i)) >= 0 ) {
   154             (encoding_len = SDNV::encode (iter->length(), &(buf[i]), len -i)) >= 0 ) {
   135             i += encoding_len;
   155             i += encoding_len;
   136         } else {
   156         } else {
   137             log_err_p(LOG, "Error encoding _BPQ individual fragment length");
   157             log_err("Error encoding BPQ individual fragment length");
   138             return -1;
   158             return -1;
   139         }
   159         }
   140     }
   160     }
   141 
   161 
   142     ASSERT ( i == this->length())
   162     ASSERT ( i == this->length())
   149 BPQBlock::length() const
   169 BPQBlock::length() const
   150 {
   170 {
   151     // initial size {kind, matching rule}
   171     // initial size {kind, matching rule}
   152     u_int len = 2; 
   172     u_int len = 2; 
   153         
   173         
       
   174     len += SDNV::encoding_len(creation_ts_.seconds_);
       
   175     len += SDNV::encoding_len(creation_ts_.seqno_);
       
   176     len += SDNV::encoding_len(source_.length());
       
   177     len += source_.length();
       
   178 
   154     len += SDNV::encoding_len(query_len_);
   179     len += SDNV::encoding_len(query_len_);
   155     len += query_len_;
   180     len += query_len_;
       
   181 
   156     len += SDNV::encoding_len(frag_len());
   182     len += SDNV::encoding_len(frag_len());
   157 
       
   158     BPQFragmentVec::const_iterator iter;
   183     BPQFragmentVec::const_iterator iter;
   159 	for (iter  = fragments_.begin();
   184 	for (iter  = fragments_.begin();
   160 		 iter != fragments_.end();
   185 		 iter != fragments_.end();
   161 		 ++iter) {
   186 		 ++iter) {
   162 
   187 
   169 
   194 
   170 //----------------------------------------------------------------------
   195 //----------------------------------------------------------------------
   171 bool
   196 bool
   172 BPQBlock::match(const BPQBlock* other) const
   197 BPQBlock::match(const BPQBlock* other) const
   173 {
   198 {
   174     return query_len_ == other->query_len() &&
   199     return matching_rule_ == other->matching_rule() &&
       
   200     	   query_len_ == other->query_len() 		&&
   175            strncmp( (char*)query_val_, (char*)other->query_val(),
   201            strncmp( (char*)query_val_, (char*)other->query_val(),
   176                      query_len_ ) == 0;
   202                      query_len_ ) == 0;
   177 }
   203 }
   178 
   204 
   179 //----------------------------------------------------------------------
   205 //----------------------------------------------------------------------
   180 int
   206 int
   181 BPQBlock::initialise(BlockInfo* b)
   207 BPQBlock::initialise(BlockInfo* block, bool created_locally, const Bundle* bundle)
   182 {
   208 {
   183     ASSERT ( b != NULL);
   209 #define TRY(fn) 		\
   184 
   210     if(!fn) { 			\
   185     int decoding_len=0;
   211         return BP_FAIL; \
   186 	u_int i=0, j=0, offset=0, length=0, full_len=0;
   212     }
   187 	u_int frag_count=0, frag_off=0, frag_len=0;
   213 
   188 	u_char* buf = 0;
   214 	ASSERT ( block != NULL);
   189     BlockInfo* block = b;
   215 
   190 
   216 	u_int buf_index = 0;
   191     /**************************************************************************
   217 	u_int buf_length = block->data_length();
   192      * Begin extracting block length with lots of logging
   218 	const u_char* buf = block->data();
   193      *************************************************************************/
   219 
   194     log_debug_p(LOG, "block: data_length() = %d", block->data_length());
   220 	log_block_info(block);
   195     log_debug_p(LOG, "block: data_offset() = %d", block->data_offset());
   221 	TRY (extract_kind(buf, &buf_index, buf_length));
   196     log_debug_p(LOG, "block: full_length() = %d", block->full_length());
   222 	TRY (extract_matching_rule(buf, &buf_index, buf_length));
   197     log_debug_p(LOG, "block: complete() = %s",
   223 
       
   224 	if (created_locally) {
       
   225 		creation_ts_.seconds_ 	= bundle->creation_ts().seconds_;
       
   226 		creation_ts_.seqno_		= bundle->creation_ts().seqno_;
       
   227 		source_.assign(bundle->source());
       
   228 	} else {
       
   229 		TRY (extract_creation_ts(buf, &buf_index, buf_length));
       
   230 		TRY (extract_source(buf, &buf_index, buf_length));
       
   231 	}
       
   232 
       
   233 	TRY (extract_query(buf, &buf_index, buf_length));
       
   234 	TRY (extract_fragments(buf, &buf_index, buf_length));
       
   235 
       
   236 	return BP_SUCCESS;
       
   237 
       
   238 #undef TRY
       
   239 }
       
   240 
       
   241 //----------------------------------------------------------------------
       
   242 void
       
   243 BPQBlock::log_block_info(BlockInfo* block)
       
   244 {
       
   245     ASSERT ( block != NULL);
       
   246 
       
   247     log_debug("block: data_length() = %d", block->data_length());
       
   248     log_debug("block: data_offset() = %d", block->data_offset());
       
   249     log_debug("block: full_length() = %d", block->full_length());
       
   250     log_debug("block: complete() = %s",
   198         (block->complete()) ? "true" : "false" );
   251         (block->complete()) ? "true" : "false" );
   199 
   252 
   200     log_debug_p(LOG, "block: reloaded() = %s",
   253     log_debug("block: reloaded() = %s",
   201         (block->reloaded()) ? "true" : "false" );
   254         (block->reloaded()) ? "true" : "false" );
   202 
   255 
   203     if ( b->source() != NULL ) {
   256     if ( block->source() != NULL ) {
   204         BlockInfo* block_src = const_cast<BlockInfo*>(b->source());;
   257         BlockInfo* block_src = const_cast<BlockInfo*>(block->source());
   205 
   258 
   206         log_debug_p(LOG, "block_src: data_length() = %d", block_src->data_length());
   259         log_debug("block_src: data_length() = %d", block_src->data_length());
   207         log_debug_p(LOG, "block_src: data_offset() = %d", block_src->data_offset());
   260         log_debug("block_src: data_offset() = %d", block_src->data_offset());
   208         log_debug_p(LOG, "block_src: full_length() = %d", block_src->full_length());
   261         log_debug("block_src: full_length() = %d", block_src->full_length());
   209         log_debug_p(LOG, "block_src: complete() = %s",
   262         log_debug("block_src: complete() = %s",
   210             (block_src->complete()) ? "true" : "false" );
   263             (block_src->complete()) ? "true" : "false" );
   211     
   264 
   212         log_debug_p(LOG, "block_src: reloaded() = %s",
   265         log_debug("block_src: reloaded() = %s",
   213             (block_src->reloaded()) ? "true" : "false" );
   266             (block_src->reloaded()) ? "true" : "false" );
   214     }
   267     }
   215 
   268 
   216 
   269     if ( block->full_length() != block->data_offset() + block->data_length() ) {
   217     offset = block->data_offset();
   270         log_err("BPQBlock: full_len != offset + length");
   218     length = block->data_length();
   271     }
   219     full_len = block->full_length();
   272 
   220 
   273     if ( block->writable_contents()->buf_len() < block->full_length() ){
   221     if ( full_len != offset + length ) {
   274         log_err("BPQBlock:  buf_len() < full_len");
   222         log_err_p(LOG, "BPQBlock::initialise: full_len != offset + length");
   275         log_err("BPQBlock:  buf_len() = %zu",
   223     }
       
   224 
       
   225     if ( block->writable_contents()->buf_len() < full_len ){
       
   226         log_err_p(LOG, "BPQBlock::initialise:  buf_len() < full_len");
       
   227         log_err_p(LOG, "BPQBlock::initialise:  buf_len() = %zu",
       
   228             block->writable_contents()->buf_len());
   276             block->writable_contents()->buf_len());
   229 
   277     }
   230         log_debug_p(LOG, "BPQBlock::initialise: reserving space in buffer %zu",
   278 
   231             full_len);
   279     if ( *(block->data()) != KIND_QUERY 		||
   232 
   280          *(block->data()) != KIND_RESPONSE 		||
   233         block->writable_contents()->reserve(full_len);
   281          *(block->data()) != KIND_RESPONSE_DO_NOT_CACHE_FRAG ) {
   234         log_debug_p(LOG, "BPQBlock::initialise: new buf_len() = %zu",
   282         log_err("BPQBlock: block->data() = %c (should be 0|1|2)",
   235             block->writable_contents()->buf_len());
       
   236     }
       
   237 
       
   238     buf = block->data();
       
   239 
       
   240 
       
   241     // BPQ Kind must be 0 or 1
       
   242     if ( *(block->data()) != 0 &&
       
   243          *(block->data()) != 1 ) {
       
   244         log_err_p(LOG, "BPQBlock::initialise: block->data() = %c (should be 0|1)",
       
   245             *(block->data()));
   283             *(block->data()));
       
   284     }
       
   285 }
       
   286 
       
   287 //----------------------------------------------------------------------
       
   288 int
       
   289 BPQBlock::extract_kind (const u_char* buf, u_int* buf_index, u_int buf_length)
       
   290 {
       
   291 	if ( *buf_index < buf_length ) {
       
   292 	    kind_ = (kind_t) buf[*buf_index++];
       
   293 	    log_debug("BPQBlock::extract_kind: kind = %d", kind_);
       
   294 	    return BP_SUCCESS;
       
   295 
       
   296 	} else {
       
   297 	    log_err("Error decoding kind");
       
   298 	    return BP_FAIL;
       
   299 	}
       
   300 }
       
   301 
       
   302 //----------------------------------------------------------------------
       
   303 int
       
   304 BPQBlock::extract_matching_rule (const u_char* buf, u_int* buf_index, u_int buf_length)
       
   305 {
       
   306 	if ( *buf_index < buf_length ) {
       
   307 	    matching_rule_ = (kind_t) buf[*buf_index++];
       
   308 	    log_debug("BPQBlock::extract_matching_rule: matching rule = %d", matching_rule_);
       
   309 	    return BP_SUCCESS;
       
   310 
       
   311 	} else {
       
   312 	    log_err("Error decoding matching rule");
       
   313 	    return BP_FAIL;
       
   314 	}
       
   315 }
       
   316 
       
   317 //----------------------------------------------------------------------
       
   318 int
       
   319 BPQBlock::extract_creation_ts (const u_char* buf, u_int* buf_index, u_int buf_length)
       
   320 {
       
   321 	int decoding_len = 0;
       
   322 	if (*buf_index < buf_length &&
       
   323 		(decoding_len = SDNV::decode(	&(buf[*buf_index]),
       
   324 				 	 	 	 	 	 	buf_length - *buf_index,
       
   325 				 	 	 	 	 	 	&(creation_ts_.seconds_)) ) >= 0 ) {
       
   326 		*buf_index += decoding_len;
       
   327 		log_debug("BPQBlock::extract_creation_ts: timestamp seconds = %llu",
       
   328 				creation_ts_.seconds_);
       
   329 	} else {
       
   330 		log_err("Error decoding timestamp seconds");
       
   331 		return BP_FAIL;
       
   332 	}
       
   333 
       
   334 
       
   335 	if (*buf_index < buf_length &&
       
   336 		(decoding_len = SDNV::decode(	&(buf[*buf_index]),
       
   337 										buf_length - *buf_index,
       
   338 										&(creation_ts_.seqno_)) ) >= 0 ) {
       
   339 		*buf_index += decoding_len;
       
   340 		log_debug("BPQBlock::extract_creation_ts: timestamp sequence number = %llu",
       
   341 				creation_ts_.seqno_);
       
   342 	} else {
       
   343 		log_err("Error decoding timestamp sequence number");
       
   344 		return BP_FAIL;
       
   345 	}
       
   346 
       
   347 	return BP_SUCCESS;
       
   348 }
       
   349 
       
   350 //----------------------------------------------------------------------
       
   351 int
       
   352 BPQBlock::extract_source (const u_char* buf, u_int* buf_index, u_int buf_length)
       
   353 {
       
   354 	int decoding_len = 0;
       
   355 	u_int src_eid_len = 0;
       
   356 
       
   357 	if (*buf_index < buf_length &&
       
   358 		(decoding_len = SDNV::decode(	&(buf[*buf_index]),
       
   359 										buf_length - *buf_index,
       
   360 										&src_eid_len)) >= 0 ) {
       
   361 		*buf_index += decoding_len;
       
   362 		log_debug("BPQBlock::extract_source: Source EID length = %u", src_eid_len);
       
   363 	} else {
       
   364 		log_err("Error decoding Source EID length");
       
   365 		return BP_FAIL;
       
   366 	}
       
   367 
       
   368     if ((*buf_index + src_eid_len) < buf_length  &&
       
   369         source_.assign((const char*) &(buf[*buf_index]), src_eid_len) ) {
       
   370 
       
   371     	*buf_index += src_eid_len;
       
   372     	log_debug("BPQBlock::extract_source: Source EID = %s", source_.c_str());
       
   373 
       
   374     } else {
       
   375         log_err("Error extracting Source EID");
   246         return BP_FAIL;
   376         return BP_FAIL;
   247     }
   377     }
   248 
   378 
   249     /**************************************************************************
   379     return BP_SUCCESS;
   250      * Begin extracting block info
   380 }
   251      *************************************************************************/
   381 
   252 
   382 //----------------------------------------------------------------------
   253     // BPQ-kind             1-byte
   383 int
   254     if ( i < length ) {
   384 BPQBlock::extract_query (const u_char* buf, u_int* buf_index, u_int buf_length)
   255         log_debug_p(LOG, "BPQBlock::initialise: extracting kind");
   385 {
   256         kind_ = (kind_t) buf[i++];
   386 	int decoding_len = 0;
   257         log_debug_p(LOG, "BPQBlock::initialise: kind = %d", kind_);
   387 
   258     } else {
   388 	if (*buf_index < buf_length &&
   259     	log_err_p(LOG, "Error decoding BPQ kind");
   389 		(decoding_len = SDNV::decode(	&(buf[*buf_index]),
   260     	return BP_FAIL;
   390 										buf_length - *buf_index,
   261     }
   391 										&query_len_)) >= 0 ) {
   262 
   392 		*buf_index += decoding_len;
   263     // matching rule type   1-byte
   393 		log_debug("BPQBlock::extract_query: query length = %u", query_len_);
   264     if ( i < length ) {
   394     } else {
   265         matching_rule_ = (u_int) buf[i++];
   395         log_err("Error decoding BPQ query length");
   266         log_debug_p(LOG, "BPQBlock::initialise: matching rule = %u", matching_rule_);
       
   267     } else {
       
   268     	log_err_p(LOG, "Error decoding BPQ matching rule");
       
   269     	return BP_FAIL;
       
   270     }
       
   271 
       
   272     // query-len			SDNV
       
   273     if ( i < length &&
       
   274         (decoding_len = SDNV::decode(&(buf[i]), length - i, &query_len_)) >= 0 ) {
       
   275         i += decoding_len;
       
   276         log_debug_p(LOG, "BPQBlock::initialise: query len = %u", query_len_);
       
   277     } else {
       
   278         log_err_p(LOG, "Error decoding BPQ query length");
       
   279         return BP_FAIL;
   396         return BP_FAIL;
   280     }
   397 	}
   281 
   398 
   282     // query-value           n-bytes
   399     if ((*buf_index + query_len_) < buf_length) {
   283     if ( (i+query_len_) < length ) {
   400     	query_val_ = (u_char*) malloc ( sizeof(u_char) * query_len_ );
   284         query_val_ = (u_char*) malloc ( sizeof(u_char) * query_len_ );
   401 
   285 
   402     	memcpy(query_val_, &(buf[*buf_index]), query_len_);
   286         for (j=0; query_val_ != NULL && i < length && j < query_len_; i++, j++)
   403 
   287             query_val_[j] = buf[i];
   404     	*buf_index += query_len_;
   288 
   405     	log_debug("BPQBlock::extract_query: query value = %s", query_val_);
   289         log_debug_p(LOG, "BPQBlock::initialise: query val = %s", query_val_);
   406 
   290 
   407     } else {
   291     } else {
   408         log_err("Error extracting query value");
   292         query_val_ = NULL;
       
   293         log_err_p(LOG, "Error extracting BPQ query value");
       
   294         return BP_FAIL;
   409         return BP_FAIL;
   295     }
   410     }
   296 
   411 
   297     if ( i < length &&
   412     return BP_SUCCESS;
   298         (decoding_len = SDNV::decode(&(buf[i]), length - i, &frag_count)) >= 0 ) {
   413 }
   299         i += decoding_len;
   414 
   300         log_debug_p(LOG, "BPQBlock::initialise: frag count = %u", frag_count);
   415 //----------------------------------------------------------------------
   301     } else {
   416 int
   302         log_err_p(LOG, "Error decoding BPQ fragment count");
   417 BPQBlock::extract_fragments (const u_char* buf, u_int* buf_index, u_int buf_length)
       
   418 {
       
   419 	int decoding_len = 0;
       
   420 	u_int i;
       
   421 	u_int frag_count = 0;
       
   422 	u_int frag_off = 0;
       
   423 	u_int frag_len = 0;
       
   424 
       
   425 	if (*buf_index < buf_length &&
       
   426 		(decoding_len = SDNV::decode(	&(buf[*buf_index]),
       
   427 										buf_length - *buf_index,
       
   428 										&frag_count)) >= 0 ) {
       
   429 		*buf_index += decoding_len;
       
   430 		log_debug("BPQBlock::extract_fragments: number of fragments = %u", frag_count);
       
   431     } else {
       
   432         log_err("Error decoding number of fragments");
   303         return BP_FAIL;
   433         return BP_FAIL;
   304     }
   434 	}
   305 
   435 
   306 
   436 	for (i=0; i < frag_count; i++) {
   307 	for (j=0;  i < length && j < frag_count; j++) {
   437 
   308 
   438 		if (*buf_index < buf_length &&
   309 		if ( (decoding_len = SDNV::decode(&(buf[i]), length - i, &frag_off)) >= 0 ) {
   439 			(decoding_len = SDNV::decode(	&(buf[*buf_index]),
   310 			i += decoding_len;
   440 											buf_length - *buf_index,
   311 			log_debug_p(LOG, "BPQBlock::initialise: frag offset = %u", frag_off);
   441 											&frag_off)) >= 0 ) {
   312 		} else {
   442 			*buf_index += decoding_len;
   313 			log_err_p(LOG, "Error decoding BPQ fragment offset");
   443 			log_debug("BPQBlock::extract_fragments: fragment [%u] offset = %u", i, frag_off);
   314 			return BP_FAIL;
   444 	    } else {
       
   445 	        log_err("Error decoding fragment [%u] offset", i);
       
   446 	        return BP_FAIL;
   315 		}
   447 		}
   316 
   448 
   317 		if ( (decoding_len = SDNV::decode(&(buf[i]), length - i, &frag_len)) >= 0 ) {
   449 		if (*buf_index < buf_length &&
   318 			i += decoding_len;
   450 			(decoding_len = SDNV::decode(	&(buf[*buf_index]),
   319 			log_debug_p(LOG, "BPQBlock::initialise: frag length = %u", frag_len);
   451 											buf_length - *buf_index,
   320 		} else {
   452 											&frag_len)) >= 0 ) {
   321 			log_err_p(LOG, "Error decoding BPQ fragment length");
   453 			*buf_index += decoding_len;
   322 			return BP_FAIL;
   454 			log_debug("BPQBlock::extract_fragments: fragment [%u] length = %u", i, frag_len);
       
   455 	    } else {
       
   456 	        log_err("Error decoding fragment [%u] length", i);
       
   457 	        return BP_FAIL;
   323 		}
   458 		}
   324 
   459 
   325 
       
   326 		BPQFragment frag(frag_off, frag_len);
   460 		BPQFragment frag(frag_off, frag_len);
   327 		add_fragment(frag);
   461 		this->add_fragment(frag);
   328 	}
   462 	}
   329 
   463 
   330 
   464 	return BP_SUCCESS;
   331 
       
   332     return BP_SUCCESS;
       
   333 }
   465 }
   334 
   466 
   335 } // namespace dtn
   467 } // namespace dtn
   336