00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <arpa/inet.h>
00018 #include "OfferTLV.h"
00019
00020 namespace prophet
00021 {
00022
00023 OfferTLV::OfferTLV(const BundleOfferList& bl)
00024 : BundleTLV(BaseTLV::OFFER_TLV,0,bl.guess_size(BundleEntrySize)),
00025 list_(bl) {}
00026
00027 OfferTLV::OfferTLV()
00028 : BundleTLV(BaseTLV::OFFER_TLV) {}
00029
00030 size_t
00031 OfferTLV::serialize(u_char* bp, size_t len) const
00032 {
00033
00034 if (bp == NULL) return 0;
00035 if (typecode_ != BaseTLV::OFFER_TLV) return 0;
00036
00037
00038 if (BundleTLVHeaderSize +
00039 list_.guess_size(BundleEntrySize) > len)
00040 return 0;
00041
00042
00043 length_ = 0;
00044
00045
00046 BundleTLVHeader* hdr = (BundleTLVHeader*) bp;
00047 memset(hdr, 0, BundleTLVHeaderSize);
00048 hdr->type = BaseTLV::OFFER_TLV;
00049 hdr->flags = 0;
00050 hdr->offer_count = htons(list_.size());
00051
00052 length_ += BundleTLVHeaderSize;
00053 bp += BundleTLVHeaderSize;
00054 len -= BundleTLVHeaderSize;
00055
00056
00057 for (BundleOfferList::const_iterator i = list_.begin();
00058 i != list_.end();
00059 i++)
00060 {
00061 const BundleOfferEntry* b = *i;
00062 size_t bytes_written =
00063 BundleTLV::write_bundle_entry(b->creation_ts(),
00064 b->seqno(), b->sid(), b->custody(),
00065 b->accept(), b->ack(), b->type(),
00066 bp, len);
00067
00068 if (BundleEntrySize > bytes_written) break;
00069
00070 length_ += bytes_written;
00071 len -= bytes_written;
00072 bp += bytes_written;
00073 }
00074
00075 hdr->length = htons(length_);
00076 return length_;
00077 }
00078
00079 bool
00080 OfferTLV::deserialize(const u_char* bp, size_t len)
00081 {
00082
00083 if (bp == NULL) return false;
00084 if (typecode_ != OFFER_TLV) return false;
00085 if (! list_.empty()) return false;
00086
00087
00088 if (BundleTLVHeaderSize > len) return false;
00089
00090
00091 size_t amt_read = 0;
00092 length_ = 0;
00093
00094
00095 BundleTLVHeader* b = (BundleTLVHeader*) bp;
00096 if (b->type != typecode_) return false;
00097 length_ = ntohs(b->length);
00098 if (length_ > len) return false;
00099 flags_ = b->flags;
00100 size_t offer_count = ntohs(b->offer_count);
00101
00102
00103 bp += BundleTLVHeaderSize;
00104 len -= BundleTLVHeaderSize;
00105 amt_read += BundleTLVHeaderSize;
00106
00107 while (len >= BundleTLVHeaderSize &&
00108 amt_read + BundleTLVHeaderSize <= length_ &&
00109 offer_count-- > 0)
00110 {
00111 u_int32_t cts = 0;
00112 u_int32_t seq = 0;
00113 u_int16_t sid = 0;
00114 bool custody = false,
00115 accept = false,
00116 ack = false;
00117 BundleTLVEntry::bundle_entry_t type = BundleTLVEntry::UNDEFINED;
00118
00119 size_t bytes_read =
00120 BundleTLV::read_bundle_entry(&cts,&seq,&sid,&custody,
00121 &accept,&ack,&type,bp,len);
00122
00123 if (BundleEntrySize > bytes_read)
00124 return false;
00125
00126 if (type != BundleTLVEntry::OFFER)
00127 return false;
00128
00129 if (! list_.add_offer(cts,seq,sid,custody,ack))
00130 return false;
00131
00132
00133 amt_read += bytes_read;
00134 len -= bytes_read;
00135 bp += bytes_read;
00136 }
00137
00138 return (amt_read == length_);
00139 }
00140
00141 };