17 #ifdef HAVE_CONFIG_H |
17 #ifdef HAVE_CONFIG_H |
18 # include <dtn-config.h> |
18 # include <dtn-config.h> |
19 #endif |
19 #endif |
20 |
20 |
21 #include "BPQBlock.h" |
21 #include "BPQBlock.h" |
|
22 #include "Bundle.h" |
|
23 #include "BundleProtocol.h" |
|
24 #include "SDNV.h" |
22 |
25 |
23 namespace dtn { |
26 namespace dtn { |
24 |
27 |
|
28 // Setup our logging information |
|
29 static const char* LOG = "/dtn/bundle/extblock/bpq"; |
|
30 |
|
31 BPQBlock::BPQBlock(Bundle* bundle) |
|
32 { |
|
33 log_info_p(LOG, "BPQBlock::constructor()"); |
|
34 |
|
35 if( bundle->recv_blocks(). |
|
36 has_block(BundleProtocol::QUERY_EXTENSION_BLOCK) ) { |
|
37 |
|
38 log_debug_p(LOG, "BPQBlock found in Recv Block Vec => created remotly"); |
|
39 initialise( const_cast<BlockInfo*> (bundle->recv_blocks(). |
|
40 find_block(BundleProtocol::QUERY_EXTENSION_BLOCK)) ); |
|
41 |
|
42 } else if( bundle->api_blocks()-> |
|
43 has_block(BundleProtocol::QUERY_EXTENSION_BLOCK) ) { |
|
44 |
|
45 log_debug_p(LOG, "BPQBlock found in API Block Vec => created locally"); |
|
46 initialise( const_cast<BlockInfo*> (bundle->api_blocks()-> |
|
47 find_block(BundleProtocol::QUERY_EXTENSION_BLOCK)) ); |
|
48 |
|
49 } else { |
|
50 log_err_p(LOG, "BPQ Block not found in bundle"); |
|
51 } |
|
52 |
|
53 log_info_p(LOG, "leaving constructor"); |
|
54 } |
|
55 |
25 BPQBlock::BPQBlock(BlockInfo* block) |
56 BPQBlock::BPQBlock(BlockInfo* block) |
26 { |
57 { |
27 static const char* log = "/dtn/bundle/protocol"; |
58 log_info_p(LOG, "BPQBlock::constructor()"); |
28 log_err_p(log, "BPQBlock: constructor"); |
59 |
29 |
60 initialise(block); |
30 log_err_p(log, "block->data_length(): %d",block->data_length()); |
61 |
31 log_err_p(log, "block->data_offset(): %d",block->data_offset()); |
62 log_info_p(LOG, "leaving constructor"); |
32 log_err_p(log, "block->full_length(): %d",block->full_length()); |
63 } |
33 |
64 |
34 |
65 BPQBlock::~BPQBlock() |
35 size_t len = block->writable_contents()->buf_len(); |
66 { |
36 u_char* buf = block->writable_contents()->buf(len); |
67 log_info_p(LOG, "BPQBlock: destructor"); |
37 |
68 //TODO |
38 size_t i=0; |
69 /* |
39 //, j=0, decoding_len=0; |
70 if ( query_val_ != NULL ){ |
|
71 free(query_val_); |
|
72 query_val_ = NULL; |
|
73 } |
|
74 */ |
|
75 } |
|
76 |
|
77 int |
|
78 BPQBlock::write_to_buffer(u_char* buf, size_t len) |
|
79 { |
|
80 int encoding_len=0; |
|
81 u_int i=0, j=0; |
40 |
82 |
41 // BPQ-kind 1-byte |
83 // BPQ-kind 1-byte |
42 if (i<len) { |
84 if ( i < len ) |
43 kind_ = (u_int) buf[i++]; |
85 buf[i++] = (u_char) kind_; |
44 log_err_p(log, "kind: %d",kind_); |
86 else |
45 } |
87 return -1; |
46 |
88 |
47 // matching rule type 1-byte |
89 // matching rule type 1-byte |
48 if (i<len) { |
90 if ( i < len ) |
|
91 buf[i++] = (u_char) matching_rule_; |
|
92 else |
|
93 return -1; |
|
94 |
|
95 // query-length SDNV |
|
96 // todo: check this len -i is correct |
|
97 if ( i < len && |
|
98 (encoding_len = SDNV::encode (query_len_, &(buf[i]), len -i)) >= 0 ) { |
|
99 i += encoding_len; |
|
100 } else { |
|
101 log_err_p(LOG, "Error encoding _BPQ query length"); |
|
102 return -1; |
|
103 } |
|
104 |
|
105 // query-value n-bytes |
|
106 for (j=0; query_val_ != NULL && i < len && j < query_len_; i++, j++) |
|
107 buf[i] = query_val_[j]; |
|
108 |
|
109 // todo: Still need to handle fragments |
|
110 if ( i < len && |
|
111 (encoding_len = SDNV::encode (0, &(buf[i]), len -i)) >= 0 ) { |
|
112 i += encoding_len; |
|
113 } else { |
|
114 log_err_p(LOG, "Error encoding _BPQ fragment length"); |
|
115 return -1; |
|
116 } |
|
117 |
|
118 return i; |
|
119 } |
|
120 |
|
121 u_int |
|
122 BPQBlock::length() const |
|
123 { |
|
124 // initial size {kind, matching rule} |
|
125 u_int len = 2; |
|
126 |
|
127 len += SDNV::encoding_len(query_len_); |
|
128 len += query_len_; |
|
129 len += SDNV::encoding_len(0); // todo: frag len |
|
130 return len; |
|
131 } |
|
132 |
|
133 bool |
|
134 BPQBlock::match(BPQBlock* other) const |
|
135 { |
|
136 log_debug_p(LOG, "_BPQ_ Match: this(%s) other(%s)", |
|
137 (char*)query_val_, |
|
138 (char*)other->query_val()); |
|
139 |
|
140 return query_len_ == other->query_len() && |
|
141 strncmp( (char*)query_val_, (char*)other->query_val(), |
|
142 query_len_ ) == 0; |
|
143 } |
|
144 |
|
145 int |
|
146 BPQBlock::initialise(BlockInfo* block) |
|
147 { |
|
148 int decoding_len=0; |
|
149 u_int i=0, j=0; |
|
150 u_int len = block->data_length(); |
|
151 u_int num_frags; |
|
152 u_char* buf = block->data(); |
|
153 |
|
154 // BPQ-kind 1-byte |
|
155 if ( i < len ) |
|
156 kind_ = (kind_t) buf[i++]; |
|
157 |
|
158 // matching rule type 1-byte |
|
159 if ( i < len ) |
49 matching_rule_ = (u_int) buf[i++]; |
160 matching_rule_ = (u_int) buf[i++]; |
50 log_err_p(log, "marching rule: %d",matching_rule_); |
161 |
51 } |
162 // Decode the SDNV-encoded query length. Note that we need to know the length of the |
52 log_err_p(log, "leaving constructor"); |
163 // of the encoded value and provide some pointers to the encoded value along with |
53 } |
164 // where we want the decoded value (in this case, query_len_). |
54 |
165 if ( i < len && |
55 BPQBlock::~BPQBlock() |
166 (decoding_len = SDNV::decode(&(buf[i]), len - i, &query_len_)) >= 0 ) |
56 { |
167 i += decoding_len; |
57 static const char* log = "/dtn/bundle/protocol"; |
168 else |
58 log_err_p(log, "BPQBlock: destructor"); |
169 log_err_p(LOG, "Error decoding BPQ query length"); |
59 } |
170 |
60 |
171 // query-value n-bytes |
|
172 if ( (i+query_len_) < len ) { |
|
173 query_val_ = (u_char*) malloc ( sizeof(u_char) * query_len_ ); |
|
174 |
|
175 for (j=0; query_val_ != NULL && i < len && j < query_len_; i++, j++) |
|
176 query_val_[j] = buf[i]; |
|
177 |
|
178 } else { |
|
179 query_val_ = NULL; |
|
180 } |
|
181 |
|
182 if ( i < len && |
|
183 (decoding_len = SDNV::decode(&(buf[i]), len - i, &num_frags)) >= 0 ) |
|
184 i += decoding_len; |
|
185 else |
|
186 log_err_p(LOG, "Error decoding BPQ fragment length"); |
|
187 |
|
188 // todo: Still need to handle fragments |
|
189 // test assert - to be removed once we start handling fragments |
|
190 //ASSERT ( num_frags == 0 ); |
|
191 if ( num_frags != 0 ) |
|
192 log_err_p(LOG, "Error BPQ fragment length = %d", num_frags); |
|
193 |
|
194 return BP_SUCCESS; |
|
195 } |
61 |
196 |
62 } // namespace dtn |
197 } // namespace dtn |
|
198 |
|
199 |
|
200 |
|
201 |
|
202 |
|
203 |
|
204 |
|
205 |
|
206 |
|
207 |
|
208 |
|
209 |
|
210 |
|
211 |
|
212 |
|
213 |