--- a/servlib/bundling/BPQBlock.cc Wed May 04 15:44:40 2011 +0100
+++ b/servlib/bundling/BPQBlock.cc Fri May 27 18:33:25 2011 +0100
@@ -19,44 +19,195 @@
#endif
#include "BPQBlock.h"
+#include "Bundle.h"
+#include "BundleProtocol.h"
+#include "SDNV.h"
namespace dtn {
+// Setup our logging information
+static const char* LOG = "/dtn/bundle/extblock/bpq";
+
+BPQBlock::BPQBlock(Bundle* bundle)
+{
+ log_info_p(LOG, "BPQBlock::constructor()");
+
+ if( bundle->recv_blocks().
+ has_block(BundleProtocol::QUERY_EXTENSION_BLOCK) ) {
+
+ log_debug_p(LOG, "BPQBlock found in Recv Block Vec => created remotly");
+ initialise( const_cast<BlockInfo*> (bundle->recv_blocks().
+ find_block(BundleProtocol::QUERY_EXTENSION_BLOCK)) );
+
+ } else if( bundle->api_blocks()->
+ has_block(BundleProtocol::QUERY_EXTENSION_BLOCK) ) {
+
+ log_debug_p(LOG, "BPQBlock found in API Block Vec => created locally");
+ initialise( const_cast<BlockInfo*> (bundle->api_blocks()->
+ find_block(BundleProtocol::QUERY_EXTENSION_BLOCK)) );
+
+ } else {
+ log_err_p(LOG, "BPQ Block not found in bundle");
+ }
+
+ log_info_p(LOG, "leaving constructor");
+}
+
BPQBlock::BPQBlock(BlockInfo* block)
{
- static const char* log = "/dtn/bundle/protocol";
- log_err_p(log, "BPQBlock: constructor");
-
- log_err_p(log, "block->data_length(): %d",block->data_length());
- log_err_p(log, "block->data_offset(): %d",block->data_offset());
- log_err_p(log, "block->full_length(): %d",block->full_length());
-
-
- size_t len = block->writable_contents()->buf_len();
- u_char* buf = block->writable_contents()->buf(len);
+ log_info_p(LOG, "BPQBlock::constructor()");
- size_t i=0;
-//, j=0, decoding_len=0;
+ initialise(block);
- // BPQ-kind 1-byte
- if (i<len) {
- kind_ = (u_int) buf[i++];
- log_err_p(log, "kind: %d",kind_);
- }
-
- // matching rule type 1-byte
- if (i<len) {
- matching_rule_ = (u_int) buf[i++];
- log_err_p(log, "marching rule: %d",matching_rule_);
- }
- log_err_p(log, "leaving constructor");
+ log_info_p(LOG, "leaving constructor");
}
BPQBlock::~BPQBlock()
{
- static const char* log = "/dtn/bundle/protocol";
- log_err_p(log, "BPQBlock: destructor");
+ log_info_p(LOG, "BPQBlock: destructor");
+//TODO
+/*
+ if ( query_val_ != NULL ){
+ free(query_val_);
+ query_val_ = NULL;
+ }
+*/
+}
+
+int
+BPQBlock::write_to_buffer(u_char* buf, size_t len)
+{
+ int encoding_len=0;
+ u_int i=0, j=0;
+
+ // BPQ-kind 1-byte
+ if ( i < len )
+ buf[i++] = (u_char) kind_;
+ else
+ return -1;
+
+ // matching rule type 1-byte
+ if ( i < len )
+ buf[i++] = (u_char) matching_rule_;
+ else
+ return -1;
+
+ // query-length SDNV
+ // todo: check this len -i is correct
+ if ( i < len &&
+ (encoding_len = SDNV::encode (query_len_, &(buf[i]), len -i)) >= 0 ) {
+ i += encoding_len;
+ } else {
+ log_err_p(LOG, "Error encoding _BPQ query length");
+ return -1;
+ }
+
+ // query-value n-bytes
+ for (j=0; query_val_ != NULL && i < len && j < query_len_; i++, j++)
+ buf[i] = query_val_[j];
+
+ // todo: Still need to handle fragments
+ if ( i < len &&
+ (encoding_len = SDNV::encode (0, &(buf[i]), len -i)) >= 0 ) {
+ i += encoding_len;
+ } else {
+ log_err_p(LOG, "Error encoding _BPQ fragment length");
+ return -1;
+ }
+
+ return i;
+}
+
+u_int
+BPQBlock::length() const
+{
+ // initial size {kind, matching rule}
+ u_int len = 2;
+
+ len += SDNV::encoding_len(query_len_);
+ len += query_len_;
+ len += SDNV::encoding_len(0); // todo: frag len
+ return len;
}
+bool
+BPQBlock::match(BPQBlock* other) const
+{
+ log_debug_p(LOG, "_BPQ_ Match: this(%s) other(%s)",
+ (char*)query_val_,
+ (char*)other->query_val());
+
+ return query_len_ == other->query_len() &&
+ strncmp( (char*)query_val_, (char*)other->query_val(),
+ query_len_ ) == 0;
+}
+
+int
+BPQBlock::initialise(BlockInfo* block)
+{
+ int decoding_len=0;
+ u_int i=0, j=0;
+ u_int len = block->data_length();
+ u_int num_frags;
+ u_char* buf = block->data();
+
+ // BPQ-kind 1-byte
+ if ( i < len )
+ kind_ = (kind_t) buf[i++];
+
+ // matching rule type 1-byte
+ if ( i < len )
+ matching_rule_ = (u_int) buf[i++];
+
+ // Decode the SDNV-encoded query length. Note that we need to know the length of the
+ // of the encoded value and provide some pointers to the encoded value along with
+ // where we want the decoded value (in this case, query_len_).
+ if ( i < len &&
+ (decoding_len = SDNV::decode(&(buf[i]), len - i, &query_len_)) >= 0 )
+ i += decoding_len;
+ else
+ log_err_p(LOG, "Error decoding BPQ query length");
+
+ // query-value n-bytes
+ if ( (i+query_len_) < len ) {
+ query_val_ = (u_char*) malloc ( sizeof(u_char) * query_len_ );
+
+ for (j=0; query_val_ != NULL && i < len && j < query_len_; i++, j++)
+ query_val_[j] = buf[i];
+
+ } else {
+ query_val_ = NULL;
+ }
+
+ if ( i < len &&
+ (decoding_len = SDNV::decode(&(buf[i]), len - i, &num_frags)) >= 0 )
+ i += decoding_len;
+ else
+ log_err_p(LOG, "Error decoding BPQ fragment length");
+
+ // todo: Still need to handle fragments
+ // test assert - to be removed once we start handling fragments
+ //ASSERT ( num_frags == 0 );
+ if ( num_frags != 0 )
+ log_err_p(LOG, "Error BPQ fragment length = %d", num_frags);
+
+ return BP_SUCCESS;
+}
} // namespace dtn
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+