servlib/bundling/BPQCacheEntry.cc
changeset 66 e1101c5d54a1
parent 64 1296a0283271
child 72 e978673d3bc2
equal deleted inserted replaced
65:333724f2f7cf 66:e1101c5d54a1
    17 #include "BPQCacheEntry.h"
    17 #include "BPQCacheEntry.h"
    18 #include "BPQBlock.h"
    18 #include "BPQBlock.h"
    19 
    19 
    20 namespace dtn {
    20 namespace dtn {
    21 
    21 
    22 int
    22 bool
    23 BPQCacheEntry::add_response(Bundle* bundle)
    23 BPQCacheEntry::add_response(Bundle* bundle)
    24 {
    24 {
    25 	if ( ! bundle->is_fragment() ) {
    25 	if ( ! bundle->is_fragment() ) {
    26 		log_debug("add complete response to cache entry");
    26 		log_debug("add complete response to cache entry");
    27 
    27 	} else {
    28 		fragments_.insert_sorted(bundle, BundleList::SORT_FRAG_OFFSET);
       
    29 		is_complete_ = true;
       
    30 
       
    31 	} else if ( bundle->is_fragment() && ! is_complete_ ) {
       
    32 		log_debug("add response fragment to cache entry");
    28 		log_debug("add response fragment to cache entry");
    33 
       
    34 		fragments_.insert_sorted(bundle, BundleList::SORT_FRAG_OFFSET);
       
    35 		is_complete_ = check_complete();
       
    36 
       
    37 	} else if ( bundle->is_fragment() && is_complete_ ) {
       
    38 		log_debug("ignoring response fragment as cache entry is complete");
       
    39 
       
    40 	} else {
       
    41 		NOTREACHED;
       
    42 	}
    29 	}
    43 
    30 
       
    31 	fragments_.insert_sorted(bundle, BundleList::SORT_FRAG_OFFSET);
       
    32 
       
    33 	return is_complete();
       
    34 }
       
    35 
       
    36 //----------------------------------------------------------------------
       
    37 int
       
    38 BPQCacheEntry::reassemble_fragments(Bundle* new_bundle, Bundle* meta_bundle){
       
    39 
       
    40 	log_debug("reassembling fragments for bundle id=%u", meta_bundle->bundleid());
       
    41 
       
    42 	// copy metadata
       
    43 	new_bundle->copy_metadata(meta_bundle);
       
    44 	new_bundle->set_orig_length(meta_bundle->orig_length());
       
    45 	new_bundle->set_frag_offset(0);
       
    46 
       
    47 	// copy payload
       
    48 	BundleList::iterator frag_iter;
       
    49 	Bundle* current_fragment;
       
    50 
       
    51     for (frag_iter = fragments_.begin();
       
    52 		 frag_iter != fragments_.end();
       
    53          ++frag_iter) {
       
    54 
       
    55     	current_fragment = *frag_iter;
       
    56     	size_t fraglen = current_fragment->payload().length();
       
    57 
       
    58     	new_bundle->mutable_payload()->write_data(	current_fragment->payload(),
       
    59     												0,
       
    60 													fraglen,
       
    61 													current_fragment->frag_offset());
       
    62     }
       
    63 
       
    64     // copy extension blocks
       
    65 	BlockInfoVec::const_iterator block_iter;
       
    66 
       
    67     for (block_iter =  meta_bundle->recv_blocks().begin();
       
    68     	 block_iter != meta_bundle->recv_blocks().end();
       
    69          ++block_iter) {
       
    70 
       
    71     	if (! new_bundle->recv_blocks().has_block( block_iter->type() ) &&
       
    72     		block_iter->type() != BundleProtocol::PRIMARY_BLOCK         &&
       
    73 			block_iter->type() != BundleProtocol::PAYLOAD_BLOCK) {
       
    74 
       
    75     		log_debug("Adding block(%d) to fragment bundle", block_iter->type());
       
    76 
       
    77     		new_bundle->mutable_recv_blocks()->push_back(BlockInfo(*block_iter));
       
    78 		}
       
    79     }
    44 	return BP_SUCCESS;
    80 	return BP_SUCCESS;
    45 }
    81 }
    46 
    82 
    47 //----------------------------------------------------------------------
    83 //----------------------------------------------------------------------
    48 int
       
    49 BPQCacheEntry::reassemble_fragments(Bundle* new_bundle, const Bundle* meta_bundle){
       
    50 	//TODO: implement this
       
    51 	NOTIMPLEMENTED;
       
    52 	return BP_FAIL;
       
    53 }
       
    54 
       
    55 //----------------------------------------------------------------------
       
    56 bool
    84 bool
    57 BPQCacheEntry::check_complete() const
    85 BPQCacheEntry::is_complete() const
    58 {
    86 {
    59     Bundle* fragment;
    87     Bundle* fragment;
    60     BundleList::iterator iter;
    88     BundleList::iterator iter;
    61     oasys::ScopeLock l(fragments_.lock(),
    89     oasys::ScopeLock l(fragments_.lock(),
    62                        "BPQCacheEntry::check_complete");
    90                        "BPQCacheEntry::is_complete");
    63 
    91 
    64     size_t done_up_to = 0;  // running total of completed reassembly
    92     size_t done_up_to = 0;  // running total of completed reassembly
    65     size_t f_len;
    93     size_t f_len;
    66     size_t f_offset;
    94     size_t f_offset;
    67     size_t f_origlen;
    95     size_t f_origlen;
    68 
       
    69 //    size_t total_len = bundle_->payload().length();
       
    70 
    96 
    71     int fragi = 0;
    97     int fragi = 0;
    72     int fragn = fragments_.size();
    98     int fragn = fragments_.size();
    73     (void)fragn; // in case NDEBUG is defined
    99     (void)fragn; // in case NDEBUG is defined
    74 
   100 
   147         else {
   173         else {
   148             // all cases should be covered above
   174             // all cases should be covered above
   149             NOTREACHED;
   175             NOTREACHED;
   150         }
   176         }
   151     }
   177     }
       
   178     l.unlock();
   152 
   179 
   153     if (done_up_to == total_len_) {
   180     if (done_up_to == total_len_) {
   154         log_debug("check_completed reassembly complete!");
   181         log_debug("check_completed reassembly complete!");
   155         return true;
   182         return true;
   156     } else {
   183     } else {
   158                   done_up_to, total_len_);
   185                   done_up_to, total_len_);
   159         return false;
   186         return false;
   160     }
   187     }
   161 }
   188 }
   162 
   189 
       
   190 //----------------------------------------------------------------------
       
   191 
       
   192 bool
       
   193 BPQCacheEntry::is_fragmented() const
       
   194 {
       
   195     Bundle* bundle;
       
   196     BundleList::iterator iter;
       
   197     oasys::ScopeLock l(fragments_.lock(),
       
   198                        "BPQCacheEntry::is_fragmented");
       
   199 
       
   200     for (iter = fragments_.begin();
       
   201          iter != fragments_.end();
       
   202          ++iter)
       
   203     {
       
   204         bundle = *iter;
       
   205 
       
   206         if (bundle->is_fragment()){
       
   207         	l.unlock();
       
   208         	return true;
       
   209         }
       
   210     }
       
   211 
       
   212     return false;
       
   213 }
       
   214 
       
   215 //----------------------------------------------------------------------
       
   216 size_t
       
   217 BPQCacheEntry::entry_size() const
       
   218 {
       
   219 	size_t size = 0;
       
   220     BundleList::iterator iter;
       
   221     oasys::ScopeLock l(fragments_.lock(),
       
   222                        "BPQCacheEntry::is_fragmented");
       
   223 
       
   224     for (iter = fragments_.begin();
       
   225          iter != fragments_.end();
       
   226          ++iter) {
       
   227         size += (*iter)->payload().length();
       
   228     }
       
   229 
       
   230     return size;
       
   231 }
   163 
   232 
   164 } // namespace dtn
   233 } // namespace dtn