00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifndef _BUNDLE_PROTOCOL_H_
00039 #define _BUNDLE_PROTOCOL_H_
00040
00041 #include <sys/types.h>
00042
00043 namespace dtn {
00044
00045 class Bundle;
00046 class BundleTimestamp;
00047 class DictionaryVector;
00048 class EndpointID;
00049
00054 class BundleProtocol {
00055 public:
00065 static int format_header_blocks(const Bundle* bundle,
00066 u_char* buf, size_t len);
00067
00080 static int parse_header_blocks(Bundle* bundle,
00081 u_char* buf, size_t len);
00082
00090 static int format_tail_blocks(const Bundle* bundle,
00091 u_char* buf, size_t len)
00092 {
00093 (void)bundle;
00094 (void)buf;
00095 (void)len;
00096
00097 return 0;
00098 }
00099
00107 static int parse_tail_blocks(Bundle* bundle,
00108 u_char* buf, size_t len)
00109 {
00110 (void)bundle;
00111 (void)buf;
00112 (void)len;
00113 return 0;
00114 }
00115
00119 static size_t header_block_length(const Bundle* bundle);
00120
00124 static size_t tail_block_length(const Bundle* bundle)
00125 {
00126 (void)bundle;
00127 return 0;
00128 }
00129
00134 static size_t formatted_length(const Bundle* bundle);
00135
00142 static int format_bundle(const Bundle* bundle, u_char* buf, size_t len);
00143
00150 static int parse_bundle(Bundle* bundle, u_char* buf, size_t len);
00151
00156 static void set_timestamp(u_char* bp, const BundleTimestamp* tv);
00157
00164 static void set_timestamp(u_int64_t* bp, const BundleTimestamp* tv) {
00165 set_timestamp((u_char *) bp, tv);
00166 }
00167
00173 static void get_timestamp(BundleTimestamp* tv, const u_char* bp);
00174
00180 static void get_timestamp(BundleTimestamp* tv, const u_int64_t* bp) {
00181 get_timestamp(tv, (u_char *) bp);
00182 }
00183
00187 static const int CURRENT_VERSION = 0x04;
00188
00193 typedef enum {
00194 BUNDLE_IS_FRAGMENT = 1 << 0,
00195 BUNDLE_IS_ADMIN = 1 << 1,
00196 BUNDLE_DO_NOT_FRAGMENT = 1 << 2,
00197 BUNDLE_CUSTODY_XFER_REQUESTED = 1 << 3,
00198 BUNDLE_SINGLETON_DESTINATION = 1 << 4
00199 } bundle_processing_flag_t;
00200
00205 struct PrimaryBlock1 {
00206 u_int8_t version;
00207 u_int8_t bundle_processing_flags;
00208 u_int8_t class_of_service_flags;
00209 u_int8_t status_report_request_flags;
00210 u_char block_length[0];
00211 } __attribute__((packed));
00212
00217 struct PrimaryBlock2 {
00218 u_int16_t dest_scheme_offset;
00219 u_int16_t dest_ssp_offset;
00220 u_int16_t source_scheme_offset;
00221 u_int16_t source_ssp_offset;
00222 u_int16_t replyto_scheme_offset;
00223 u_int16_t replyto_ssp_offset;
00224 u_int16_t custodian_scheme_offset;
00225 u_int16_t custodian_ssp_offset;
00226 u_int64_t creation_ts;
00227 u_int32_t lifetime;
00228
00229 } __attribute__((packed));
00230
00235 typedef enum {
00236 PAYLOAD_BLOCK = 0x01
00237 } bundle_block_type_t;
00238
00243 typedef enum {
00244 BLOCK_FLAG_REPLICATE = 1 << 0,
00245 BLOCK_FLAG_REPORT_ONERROR = 1 << 1,
00246 BLOCK_FLAG_DISCARD_ONERROR = 1 << 2,
00247 BLOCK_FLAG_LAST_BLOCK = 1 << 3,
00248 } block_flag_t;
00249
00254 struct BlockPreamble {
00255 u_int8_t type;
00256 u_int8_t flags;
00257 u_char length[0];
00258 } __attribute__((packed));
00259
00263 typedef enum {
00264 ADMIN_STATUS_REPORT = 0x01,
00265 ADMIN_CUSTODY_SIGNAL = 0x02,
00266 ADMIN_ECHO = 0x03,
00267 ADMIN_NULL = 0x04,
00268 ADMIN_ANNOUNCE = 0x05,
00269 } admin_record_type_t;
00270
00274 typedef enum {
00275 ADMIN_IS_FRAGMENT = 0x01,
00276 } admin_record_flags_t;
00277
00281 typedef enum {
00282 STATUS_RECEIVED = 0x01,
00283 STATUS_CUSTODY_ACCEPTED = 0x02,
00284 STATUS_FORWARDED = 0x04,
00285 STATUS_DELIVERED = 0x08,
00286 STATUS_DELETED = 0x10,
00287 STATUS_ACKED_BY_APP = 0x20,
00288 STATUS_UNUSED = 0x40,
00289 STATUS_UNUSED2 = 0x80,
00290 } status_report_flag_t;
00291
00295 typedef enum {
00296 REASON_NO_ADDTL_INFO = 0x00,
00297 REASON_LIFETIME_EXPIRED = 0x01,
00298 REASON_FORWARDED_UNIDIR_LINK = 0x02,
00299 REASON_TRANSMISSION_CANCELLED = 0x03,
00300 REASON_DEPLETED_STORAGE = 0x04,
00301 REASON_ENDPOINT_ID_UNINTELLIGIBLE = 0x05,
00302 REASON_NO_ROUTE_TO_DEST = 0x06,
00303 REASON_NO_TIMELY_CONTACT = 0x07,
00304 REASON_BLOCK_UNINTELLIGIBLE = 0x08,
00305 } status_report_reason_t;
00306
00310 typedef enum {
00311 CUSTODY_NO_ADDTL_INFO = 0x00,
00312 CUSTODY_REDUNDANT_RECEPTION = 0x03,
00313 CUSTODY_DEPLETED_STORAGE = 0x04,
00314 CUSTODY_ENDPOINT_ID_UNINTELLIGIBLE = 0x05,
00315 CUSTODY_NO_ROUTE_TO_DEST = 0x06,
00316 CUSTODY_NO_TIMELY_CONTACT = 0x07,
00317 CUSTODY_BLOCK_UNINTELLIGIBLE = 0x08
00318 } custody_signal_reason_t;
00319
00326 static bool get_admin_type(const Bundle* bundle,
00327 admin_record_type_t* type);
00328
00329 protected:
00330 static size_t get_primary_len(const Bundle* bundle,
00331 DictionaryVector* dict,
00332 size_t* dictionary_len,
00333 size_t* primary_var_len);
00334
00335 static size_t get_payload_block_len(const Bundle* bundle);
00336
00337 static void add_to_dictionary(const EndpointID& eid,
00338 DictionaryVector* dict,
00339 size_t* dictlen);
00340
00341 static void get_dictionary_offsets(DictionaryVector *dict,
00342 EndpointID eid,
00343 u_int16_t* scheme_offset,
00344 u_int16_t* ssp_offset);
00345
00346 static u_int8_t format_bundle_flags(const Bundle* bundle);
00347 static void parse_bundle_flags(Bundle* bundle, u_int8_t flags);
00348
00349 static u_int8_t format_cos_flags(const Bundle* bundle);
00350 static void parse_cos_flags(Bundle* bundle, u_int8_t cos_flags);
00351
00352 static u_int8_t format_srr_flags(const Bundle* bundle);
00353 static void parse_srr_flags(Bundle* bundle, u_int8_t srr_flags);
00354 };
00355
00356 }
00357
00358 #endif