--- a/servlib/bundling/BPQCacheEntry.cc Wed Oct 26 13:33:11 2011 +0100
+++ b/servlib/bundling/BPQCacheEntry.cc Fri Jan 06 17:28:36 2012 +0000
@@ -19,55 +19,81 @@
namespace dtn {
-int
+bool
BPQCacheEntry::add_response(Bundle* bundle)
{
if ( ! bundle->is_fragment() ) {
log_debug("add complete response to cache entry");
-
- fragments_.insert_sorted(bundle, BundleList::SORT_FRAG_OFFSET);
- is_complete_ = true;
-
- } else if ( bundle->is_fragment() && ! is_complete_ ) {
+ } else {
log_debug("add response fragment to cache entry");
-
- fragments_.insert_sorted(bundle, BundleList::SORT_FRAG_OFFSET);
- is_complete_ = check_complete();
-
- } else if ( bundle->is_fragment() && is_complete_ ) {
- log_debug("ignoring response fragment as cache entry is complete");
-
- } else {
- NOTREACHED;
}
+ fragments_.insert_sorted(bundle, BundleList::SORT_FRAG_OFFSET);
+
+ return is_complete();
+}
+
+//----------------------------------------------------------------------
+int
+BPQCacheEntry::reassemble_fragments(Bundle* new_bundle, Bundle* meta_bundle){
+
+ log_debug("reassembling fragments for bundle id=%u", meta_bundle->bundleid());
+
+ // copy metadata
+ new_bundle->copy_metadata(meta_bundle);
+ new_bundle->set_orig_length(meta_bundle->orig_length());
+ new_bundle->set_frag_offset(0);
+
+ // copy payload
+ BundleList::iterator frag_iter;
+ Bundle* current_fragment;
+
+ for (frag_iter = fragments_.begin();
+ frag_iter != fragments_.end();
+ ++frag_iter) {
+
+ current_fragment = *frag_iter;
+ size_t fraglen = current_fragment->payload().length();
+
+ new_bundle->mutable_payload()->write_data( current_fragment->payload(),
+ 0,
+ fraglen,
+ current_fragment->frag_offset());
+ }
+
+ // copy extension blocks
+ BlockInfoVec::const_iterator block_iter;
+
+ for (block_iter = meta_bundle->recv_blocks().begin();
+ block_iter != meta_bundle->recv_blocks().end();
+ ++block_iter) {
+
+ if (! new_bundle->recv_blocks().has_block( block_iter->type() ) &&
+ block_iter->type() != BundleProtocol::PRIMARY_BLOCK &&
+ block_iter->type() != BundleProtocol::PAYLOAD_BLOCK) {
+
+ log_debug("Adding block(%d) to fragment bundle", block_iter->type());
+
+ new_bundle->mutable_recv_blocks()->push_back(BlockInfo(*block_iter));
+ }
+ }
return BP_SUCCESS;
}
//----------------------------------------------------------------------
-int
-BPQCacheEntry::reassemble_fragments(Bundle* new_bundle, const Bundle* meta_bundle){
- //TODO: implement this
- NOTIMPLEMENTED;
- return BP_FAIL;
-}
-
-//----------------------------------------------------------------------
bool
-BPQCacheEntry::check_complete() const
+BPQCacheEntry::is_complete() const
{
Bundle* fragment;
BundleList::iterator iter;
oasys::ScopeLock l(fragments_.lock(),
- "BPQCacheEntry::check_complete");
+ "BPQCacheEntry::is_complete");
size_t done_up_to = 0; // running total of completed reassembly
size_t f_len;
size_t f_offset;
size_t f_origlen;
-// size_t total_len = bundle_->payload().length();
-
int fragi = 0;
int fragn = fragments_.size();
(void)fragn; // in case NDEBUG is defined
@@ -149,6 +175,7 @@
NOTREACHED;
}
}
+ l.unlock();
if (done_up_to == total_len_) {
log_debug("check_completed reassembly complete!");
@@ -160,5 +187,47 @@
}
}
+//----------------------------------------------------------------------
+
+bool
+BPQCacheEntry::is_fragmented() const
+{
+ Bundle* bundle;
+ BundleList::iterator iter;
+ oasys::ScopeLock l(fragments_.lock(),
+ "BPQCacheEntry::is_fragmented");
+
+ for (iter = fragments_.begin();
+ iter != fragments_.end();
+ ++iter)
+ {
+ bundle = *iter;
+
+ if (bundle->is_fragment()){
+ l.unlock();
+ return true;
+ }
+ }
+
+ return false;
+}
+
+//----------------------------------------------------------------------
+size_t
+BPQCacheEntry::entry_size() const
+{
+ size_t size = 0;
+ BundleList::iterator iter;
+ oasys::ScopeLock l(fragments_.lock(),
+ "BPQCacheEntry::is_fragmented");
+
+ for (iter = fragments_.begin();
+ iter != fragments_.end();
+ ++iter) {
+ size += (*iter)->payload().length();
+ }
+
+ return size;
+}
} // namespace dtn