00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef _BUNDLE_TLV_ENTRY_H_
00018 #define _BUNDLE_TLV_ENTRY_H_
00019
00020 #include <sys/types.h>
00021
00022 #include "PointerList.h"
00023
00024 namespace prophet
00025 {
00026
00031 class BundleTLVEntry
00032 {
00033 public:
00038 typedef enum
00039 {
00040 UNDEFINED = 0,
00041 OFFER,
00042 RESPONSE,
00043 } bundle_entry_t;
00044
00048 static const char* type_to_str(bundle_entry_t type)
00049 {
00050 switch(type) {
00051 case OFFER: return "OFFER";
00052 case RESPONSE: return "RESPONSE";
00053 case UNDEFINED:
00054 default: break;
00055 }
00056 return "UNDEFINED";
00057 }
00058
00062 static inline BundleTLVEntry* create_entry(u_int32_t cts, u_int32_t seq,
00063 u_int16_t sid, bool custody,
00064 bool accept, bool ack);
00065
00066 protected:
00070 BundleTLVEntry(bundle_entry_t type = UNDEFINED)
00071 : cts_(0), seq_(0), sid_(0), custody_(false),
00072 accept_(false), ack_(false), type_(type) {}
00073
00077 BundleTLVEntry(u_int32_t cts, u_int32_t seq, u_int16_t sid,
00078 bool custody=false, bool accept=false, bool ack=false,
00079 bundle_entry_t type=UNDEFINED)
00080 : cts_(cts), seq_(seq), sid_(sid), custody_(custody),
00081 accept_(accept), ack_(ack), type_(type)
00082 {
00083 init_type(type);
00084 }
00085
00086 public:
00090 BundleTLVEntry(const BundleTLVEntry& b)
00091 : cts_(b.cts_), seq_(b.seq_), sid_(b.sid_), custody_(b.custody_),
00092 accept_(b.accept_), ack_(b.ack_), type_(b.type_)
00093 {
00094 init_type(b.type_);
00095 }
00096
00100 BundleTLVEntry& operator= (const BundleTLVEntry& b)
00101 {
00102 cts_ = b.cts_;
00103 seq_ = b.seq_;
00104 sid_ = b.sid_;
00105 custody_ = b.custody_;
00106 accept_ = b.accept_;
00107 ack_ = b.ack_;
00108 type_ = b.type_;
00109 init_type(b.type_);
00110 return *this;
00111 }
00112
00116 virtual ~BundleTLVEntry() {}
00117
00121 bool operator< (const BundleTLVEntry& b) const
00122 {
00123
00124 if (sid_ == b.sid_)
00125 {
00126 if (cts_ == b.cts_)
00127 return seq_ < b.seq_;
00128 else
00129 return (cts_ < b.cts_);
00130 }
00131 return (sid_ < b.sid_);
00132 }
00133
00135 u_int32_t creation_ts() const { return cts_; }
00136 u_int32_t seqno() const { return seq_; }
00137 u_int16_t sid() const { return sid_; }
00138 bool custody() const { return custody_; }
00139 bool accept() const { return accept_; }
00140 bool ack() const { return ack_; }
00141 virtual bundle_entry_t type() const { return type_; }
00143
00148 static bundle_entry_t decode_flags(bool custody, bool accept, bool ack)
00149 {
00150
00151 if ( accept && ack )
00152 return UNDEFINED;
00153
00154
00155 if (! accept)
00156 {
00157
00158
00159 if (custody && ack)
00160 return UNDEFINED;
00161
00162
00163 return OFFER;
00164 }
00165
00166
00167 if ( (custody || accept) && (! ack))
00168 {
00169
00170
00171 if (custody && !accept)
00172 return UNDEFINED;
00173
00174 return RESPONSE;
00175 }
00176
00177
00178 return UNDEFINED;
00179 }
00180
00181 protected:
00185 void init_type(bundle_entry_t type)
00186 {
00187 bundle_entry_t df = decode_flags(custody_,accept_,ack_);
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202 if (type_ == UNDEFINED)
00203 {
00204 if (df == type) type_ = type;
00205
00206 return;
00207 }
00208
00209 if ((df == type && df == type_))
00210 return;
00211
00212
00213 type_ = UNDEFINED;
00214 }
00215
00216 u_int32_t cts_;
00217 u_int32_t seq_;
00218 u_int16_t sid_;
00219 bool custody_;
00220 bool accept_;
00221 bool ack_;
00222 bundle_entry_t type_;
00223
00224 };
00225
00230 class BundleOfferEntry : public BundleTLVEntry
00231 {
00232 public:
00236 BundleOfferEntry(u_int32_t cts, u_int32_t seq, u_int16_t sid,
00237 bool custody, bool ack)
00238 : BundleTLVEntry(cts,seq,sid,custody,false,ack,BundleTLVEntry::OFFER)
00239 {}
00240
00244 BundleOfferEntry(const BundleOfferEntry& b)
00245 : BundleTLVEntry(b) {}
00246
00250 virtual ~BundleOfferEntry() {}
00251
00252 protected:
00253 friend class PointerList<BundleOfferEntry>;
00254
00258 BundleOfferEntry()
00259 {
00260 BundleTLVEntry::type_ = BundleTLVEntry::UNDEFINED;
00261 }
00262 };
00263
00268 class BundleResponseEntry : public BundleTLVEntry
00269 {
00270 public:
00274 BundleResponseEntry(u_int32_t cts, u_int32_t seq, u_int16_t sid,
00275 bool custody, bool accept)
00276 : BundleTLVEntry(cts,seq,sid,custody,accept,false,BundleTLVEntry::RESPONSE)
00277 {}
00278
00282 BundleResponseEntry(const BundleResponseEntry& b)
00283 : BundleTLVEntry(b) {}
00284
00288 virtual ~BundleResponseEntry() {}
00289
00290 protected:
00291 friend class PointerList<BundleResponseEntry>;
00292
00296 BundleResponseEntry()
00297 {
00298 BundleTLVEntry::type_ = BundleTLVEntry::UNDEFINED;
00299 }
00300 };
00301
00302 BundleTLVEntry*
00303 BundleTLVEntry::create_entry(u_int32_t cts, u_int32_t seq, u_int16_t sid,
00304 bool custody, bool accept, bool ack)
00305 {
00306 switch (decode_flags(custody,accept,ack))
00307 {
00308 case OFFER:
00309 return new BundleOfferEntry(cts,seq,sid,custody,ack);
00310 case RESPONSE:
00311 return new BundleResponseEntry(cts,seq,sid,custody,accept);
00312 case UNDEFINED:
00313 default:
00314 return NULL;
00315 }
00316 return NULL;
00317 }
00318
00319 };
00320
00321 #endif // _BUNDLE_TLV_ENTRY_H_