00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef PACKET_METADATA_H
00021 #define PACKET_METADATA_H
00022
00023 #include <stdint.h>
00024 #include <vector>
00025 #include "ns3/callback.h"
00026 #include "ns3/assert.h"
00027 #include "ns3/type-id.h"
00028 #include "buffer.h"
00029
00030 namespace ns3 {
00031
00032 class Chunk;
00033 class Buffer;
00034 class Header;
00035 class Trailer;
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078 class PacketMetadata
00079 {
00080 public:
00081 struct Item
00082 {
00083 enum {
00084 PAYLOAD,
00085 HEADER,
00086 TRAILER
00087 } type;
00088
00089
00090
00091 bool isFragment;
00092
00093
00094
00095 TypeId tid;
00096
00097
00098
00099 uint32_t currentSize;
00100
00101
00102
00103 uint32_t currentTrimedFromStart;
00104
00105
00106
00107 uint32_t currentTrimedFromEnd;
00108
00109
00110
00111 Buffer::Iterator current;
00112 };
00113 class ItemIterator
00114 {
00115 public:
00116 ItemIterator (const PacketMetadata *metadata, Buffer buffer);
00117 bool HasNext (void) const;
00118 Item Next (void);
00119 private:
00120 const PacketMetadata *m_metadata;
00121 Buffer m_buffer;
00122 uint16_t m_current;
00123 uint32_t m_offset;
00124 bool m_hasReadTail;
00125 };
00126
00127 static void Enable (void);
00128 static void EnableChecking (void);
00129
00130 inline PacketMetadata (uint32_t uid, uint32_t size);
00131 inline PacketMetadata (PacketMetadata const &o);
00132 inline PacketMetadata &operator = (PacketMetadata const& o);
00133 inline ~PacketMetadata ();
00134
00135 void AddHeader (Header const &header, uint32_t size);
00136 void RemoveHeader (Header const &header, uint32_t size);
00137
00138 void AddTrailer (Trailer const &trailer, uint32_t size);
00139 void RemoveTrailer (Trailer const &trailer, uint32_t size);
00140
00141
00142
00143
00144
00145
00146
00147
00148 PacketMetadata CreateFragment (uint32_t start, uint32_t end) const;
00149 void AddAtEnd (PacketMetadata const&o);
00150 void AddPaddingAtEnd (uint32_t end);
00151 void RemoveAtStart (uint32_t start);
00152 void RemoveAtEnd (uint32_t end);
00153
00154 uint32_t GetUid (void) const;
00155
00156 uint32_t GetSerializedSize (void) const;
00157 void Serialize (Buffer::Iterator i, uint32_t size) const;
00158 uint32_t Deserialize (Buffer::Iterator i);
00159
00160 ItemIterator BeginItem (Buffer buffer) const;
00161
00162 private:
00163 struct Data {
00164
00165 uint16_t m_count;
00166
00167 uint16_t m_size;
00168
00169
00170 uint16_t m_dirtyEnd;
00171
00172 uint8_t m_data[10];
00173 };
00174
00175
00176
00177
00178
00179
00180 struct SmallItem {
00181
00182
00183
00184
00185
00186 uint16_t next;
00187
00188
00189
00190
00191
00192 uint16_t prev;
00193
00194
00195
00196
00197
00198
00199
00200 uint32_t typeUid;
00201
00202
00203
00204
00205 uint32_t size;
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218 uint16_t chunkUid;
00219 };
00220 struct ExtraItem {
00221
00222
00223
00224
00225 uint32_t fragmentStart;
00226
00227
00228
00229
00230 uint32_t fragmentEnd;
00231
00232
00233
00234
00235
00236 uint32_t packetUid;
00237 };
00238
00239 class DataFreeList : public std::vector<struct Data *>
00240 {
00241 public:
00242 ~DataFreeList ();
00243 };
00244
00245 friend DataFreeList::~DataFreeList ();
00246 friend class ItemIterator;
00247
00248 PacketMetadata ();
00249
00250 inline uint16_t AddSmall (const PacketMetadata::SmallItem *item);
00251 uint16_t AddBig (uint32_t head, uint32_t tail,
00252 const PacketMetadata::SmallItem *item,
00253 const PacketMetadata::ExtraItem *extraItem);
00254 void ReplaceTail (PacketMetadata::SmallItem *item,
00255 PacketMetadata::ExtraItem *extraItem,
00256 uint32_t available);
00257 inline void UpdateHead (uint16_t written);
00258 inline void UpdateTail (uint16_t written);
00259 inline uint32_t GetUleb128Size (uint32_t value) const;
00260 uint32_t ReadUleb128 (const uint8_t **pBuffer) const;
00261 inline void Append16 (uint16_t value, uint8_t *buffer);
00262 inline void Append32 (uint32_t value, uint8_t *buffer);
00263 inline void AppendValue (uint32_t value, uint8_t *buffer);
00264 void AppendValueExtra (uint32_t value, uint8_t *buffer);
00265 inline void Reserve (uint32_t n);
00266 void ReserveCopy (uint32_t n);
00267 uint32_t GetTotalSize (void) const;
00268 uint32_t ReadItems (uint16_t current,
00269 struct PacketMetadata::SmallItem *item,
00270 struct PacketMetadata::ExtraItem *extraItem) const;
00271 void DoAddHeader (uint32_t uid, uint32_t size);
00272
00273
00274 static struct PacketMetadata::Data *Create (uint32_t size);
00275 static void Recycle (struct PacketMetadata::Data *data);
00276 static struct PacketMetadata::Data *Allocate (uint32_t n);
00277 static void Deallocate (struct PacketMetadata::Data *data);
00278
00279 static DataFreeList m_freeList;
00280 static bool m_enable;
00281 static bool m_enableChecking;
00282
00283
00284
00285
00286 static bool m_metadataSkipped;
00287
00288 static uint32_t m_maxSize;
00289 static uint16_t m_chunkUid;
00290
00291 struct Data *m_data;
00292
00293
00294
00295
00296
00297 uint16_t m_head;
00298 uint16_t m_tail;
00299 uint16_t m_used;
00300 uint32_t m_packetUid;
00301 };
00302
00303 };
00304
00305 namespace ns3 {
00306
00307 PacketMetadata::PacketMetadata (uint32_t uid, uint32_t size)
00308 : m_data (m_data = PacketMetadata::Create (10)),
00309 m_head (0xffff),
00310 m_tail (0xffff),
00311 m_used (0),
00312 m_packetUid (uid)
00313 {
00314 memset (m_data->m_data, 0xff, 4);
00315 if (size > 0)
00316 {
00317 DoAddHeader (0, size);
00318 }
00319 }
00320 PacketMetadata::PacketMetadata (PacketMetadata const &o)
00321 : m_data (o.m_data),
00322 m_head (o.m_head),
00323 m_tail (o.m_tail),
00324 m_used (o.m_used),
00325 m_packetUid (o.m_packetUid)
00326 {
00327 NS_ASSERT (m_data != 0);
00328 m_data->m_count++;
00329 }
00330 PacketMetadata &
00331 PacketMetadata::operator = (PacketMetadata const& o)
00332 {
00333 if (m_data != o.m_data)
00334 {
00335
00336 NS_ASSERT (m_data != 0);
00337 m_data->m_count--;
00338 if (m_data->m_count == 0)
00339 {
00340 PacketMetadata::Recycle (m_data);
00341 }
00342 m_data = o.m_data;
00343 NS_ASSERT (m_data != 0);
00344 m_data->m_count++;
00345 }
00346 m_head = o.m_head;
00347 m_tail = o.m_tail;
00348 m_used = o.m_used;
00349 m_packetUid = o.m_packetUid;
00350 return *this;
00351 }
00352 PacketMetadata::~PacketMetadata ()
00353 {
00354 NS_ASSERT (m_data != 0);
00355 m_data->m_count--;
00356 if (m_data->m_count == 0)
00357 {
00358 PacketMetadata::Recycle (m_data);
00359 }
00360 }
00361
00362 }
00363
00364
00365 #endif