/** * Internal function get the total length of primary block to write on the buffer * * @param bundle Bundle to generate * @param dict Dictionary to get the offsets of the endpoint eids * @param primary PrimaryBlock data strucre object * @return Total numbers of Bytes required to write primary block */ protected static int get_primary_len(final Bundle bundle, Dictionary dict, PrimaryBlock primary) { int primary_len = 0; int block_len = 0; primary.set_dictionary_length(0); primary.set_block_length(0); /* * We need to figure out the total length of the primary block, * except for the SDNVs used to encode flags and the length itself and * the one byte version field. * * First, we determine the size of the dictionary by first * figuring out all the unique strings, and in the process, * remembering their offsets and summing up their lengths * (including the null terminator for each). */ dict.get_offsets(bundle.dest(), primary.dest_scheme_offset(), primary.dest_ssp_offset()); block_len += SDNV.encoding_len(primary.dest_scheme_offset()); block_len += SDNV.encoding_len(primary.dest_ssp_offset()); dict.get_offsets(bundle.source(), primary.source_scheme_offset(), primary.source_ssp_offset()); block_len += SDNV.encoding_len(primary.source_scheme_offset()); block_len += SDNV.encoding_len(primary.source_ssp_offset()); dict.get_offsets( bundle.replyto(), primary.replyto_scheme_offset(), primary.replyto_ssp_offset()); block_len += SDNV.encoding_len(primary.replyto_scheme_offset()); block_len += SDNV.encoding_len(primary.replyto_ssp_offset()); dict.get_offsets( bundle.custodian(), primary.custodian_scheme_offset(), primary.custodian_ssp_offset()); block_len += SDNV.encoding_len(primary.custodian_scheme_offset()); block_len += SDNV.encoding_len(primary.custodian_ssp_offset()); primary.set_dictionary_length(dict.dict_length()); block_len += SDNV.encoding_len(bundle.creation_ts().seconds()); block_len += SDNV.encoding_len(bundle.creation_ts().seqno()); block_len += SDNV.encoding_len(bundle.expiration()); block_len += SDNV.encoding_len(primary.dictionary_length_value()); block_len += primary.dictionary_length_value(); /* * If the bundle is a fragment, we need to include space for the * fragment offset and the original payload length. * * Note: Any changes to this protocol must be reflected into the * FragmentManager since it depends on this length when * calculating fragment sizes. */ if (bundle.is_fragment()) { block_len += SDNV.encoding_len(bundle.frag_offset()); block_len += SDNV.encoding_len(bundle.orig_length()); } // Format the processing flags. primary.set_processing_flags(format_bundle_flags(bundle)); primary.set_processing_flags(format_bundle_flags(bundle)); primary.set_processing_flags(primary.processing_flags_value() | format_cos_flags(bundle)); primary.set_processing_flags(primary.processing_flags_value() | format_srr_flags(bundle)); /* * Finally, add up the initial preamble and the variable * length part. */ primary.set_block_length(block_len); primary_len = (int) (1 + SDNV.encoding_len(primary.processing_flags) + SDNV.encoding_len(primary.block_length()) + primary.block_length_value()); Log.d(TAG, "get_primary_len: for bundleid = " + bundle.bundleid() + ": " + primary_len); // Fill in the remaining values of 'primary' just for the sake of returning // a complete data structure. primary.set_version(BundleProtocol.CURRENT_VERSION); primary.set_creation_time(bundle.creation_ts().seconds()); primary.set_creation_sequence(bundle.creation_ts().seqno()); primary.set_lifetime(bundle.expiration()); return primary_len; }
/** * Generate primary block by encoding all the metadata of the primary block and copy to primary * block writeable buffer. * * @param bundle Bundle to generate * @param xmit_blocks xmit_blocks of the bundle * @param block Primary block of the bundle to generate and write to the writeable buffer */ public void generate_primary(final Bundle bundle, BlockInfoVec xmit_blocks, BlockInfo block) { // point at the local dictionary Dictionary dict = xmit_blocks.dict(); int primary_len = 0; // total length of the primary block PrimaryBlock primary = new PrimaryBlock(); primary_len = get_primary_len(bundle, dict, primary); block.set_contents(new SerializableByteBuffer(primary_len)); block.set_data_length((int) primary.block_length_value()); block.set_data_offset((int) (primary_len - primary.block_length_value())); /* * Advance buf and decrement len as we go through the process. */ IByteBuffer buf = block.writable_contents(); int len = primary_len; Log.d(TAG, String.format("generating primary: length %s", primary_len)); // Stick the version number in the first byte. buf.put((byte) BundleProtocol.CURRENT_VERSION); len -= 1; len -= write_sdnv(primary.processing_flags(), buf); len -= write_sdnv(primary.block_length(), buf); len -= write_sdnv(primary.dest_scheme_offset(), buf); len -= write_sdnv(primary.dest_ssp_offset(), buf); len -= write_sdnv(primary.source_scheme_offset(), buf); len -= write_sdnv(primary.source_ssp_offset(), buf); len -= write_sdnv(primary.replyto_scheme_offset(), buf); len -= write_sdnv(primary.replyto_ssp_offset(), buf); len -= write_sdnv(primary.custodian_scheme_offset(), buf); len -= write_sdnv(primary.custodian_ssp_offset(), buf); len -= write_sdnv(bundle.creation_ts().seconds(), buf); len -= write_sdnv(bundle.creation_ts().seqno(), buf); len -= write_sdnv(bundle.expiration(), buf); len -= write_sdnv(primary.dictionary_length(), buf); // Add the dictionary. Log.d(TAG, "Current Buf: " + buf.position()); Log.d(TAG, "Dict length: " + dict.dict_length()); Log.d(TAG, "Dict length: " + dict.dict_length()); buf.put(dict.dict()); // memcpy(buf, dict->dict(), dict->length()); // buf += dict->length(); len -= dict.dict_length(); Log.d(TAG, "Preparing len:" + len); /* * If the bundle is a fragment, stuff in SDNVs for the fragment * offset and original length. */ if (bundle.is_fragment()) { len -= write_sdnv(bundle.frag_offset(), buf); Log.d(TAG, "Preparing len:" + len); len -= write_sdnv(bundle.orig_length(), buf); Log.d(TAG, "Preparing len:" + len); } /* * Asuming that get_primary_len is written correctly, len should * now be zero since we initialized it to primary_len at the * beginning of the function. */ buf.position(0); assert (len == 0) : TAG + ": len not ==0"; Log.e(TAG, "Current Len: " + len); }