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 |
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 |