A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
packet-metadata.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2006,2007 INRIA
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19  */
20 #include <utility>
21 #include <list>
22 #include "ns3/assert.h"
23 #include "ns3/fatal-error.h"
24 #include "ns3/log.h"
25 #include "packet-metadata.h"
26 #include "buffer.h"
27 #include "header.h"
28 #include "trailer.h"
29 
30 NS_LOG_COMPONENT_DEFINE ("PacketMetadata");
31 
32 namespace ns3 {
33 
34 bool PacketMetadata::m_enable = false;
37 uint32_t PacketMetadata::m_maxSize = 0;
38 uint16_t PacketMetadata::m_chunkUid = 0;
39 PacketMetadata::DataFreeList PacketMetadata::m_freeList;
40 
42 {
43  NS_LOG_FUNCTION (this);
44  for (iterator i = begin (); i != end (); i++)
45  {
47  }
49 }
50 
51 void
53 {
56  "Error: attempting to enable the packet metadata "
57  "subsystem too late in the simulation, which is not allowed.\n"
58  "A common cause for this problem is to enable ASCII tracing "
59  "after sending any packets. One way to fix this problem is "
60  "to call ns3::PacketMetadata::Enable () near the beginning of"
61  " the program, before any packets are sent.");
62  m_enable = true;
63 }
64 
65 void
67 {
69  Enable ();
70  m_enableChecking = true;
71 }
72 
73 void
75 {
76  NS_LOG_FUNCTION (this << size);
77  struct PacketMetadata::Data *newData = PacketMetadata::Create (m_used + size);
78  memcpy (newData->m_data, m_data->m_data, m_used);
79  newData->m_dirtyEnd = m_used;
80  m_data->m_count--;
81  if (m_data->m_count == 0)
82  {
84  }
85  m_data = newData;
86  if (m_head != 0xffff)
87  {
88  uint8_t *start;
89  NS_ASSERT (m_tail != 0xffff);
90  // clear the next field of the tail
91  start = &m_data->m_data[m_tail];
92  Append16 (0xffff, start);
93  // clear the prev field of the head
94  start = &m_data->m_data[m_head] + 2;
95  Append16 (0xffff, start);
96  }
97 }
98 void
99 PacketMetadata::Reserve (uint32_t size)
100 {
101  NS_LOG_FUNCTION (this << size);
102  NS_ASSERT (m_data != 0);
103  if (m_data->m_size >= m_used + size &&
104  (m_head == 0xffff ||
105  m_data->m_count == 1 ||
106  m_data->m_dirtyEnd == m_used))
107  {
108  /* enough room, not dirty. */
109  }
110  else
111  {
112  /* (enough room and dirty) or (not enough room) */
113  ReserveCopy (size);
114  }
115 }
116 
117 bool
118 PacketMetadata::IsSharedPointerOk (uint16_t pointer) const
119 {
120  NS_LOG_FUNCTION (this << pointer);
121  bool ok = pointer == 0xffff || pointer <= m_data->m_size;
122  return ok;
123 }
124 bool
125 PacketMetadata::IsPointerOk (uint16_t pointer) const
126 {
127  NS_LOG_FUNCTION (this << pointer);
128  bool ok = pointer == 0xffff || pointer <= m_used;
129  return ok;
130 }
131 
132 bool
134 {
135  NS_LOG_FUNCTION (this);
136  bool ok = m_used <= m_data->m_size;
137  ok &= IsPointerOk (m_head);
138  ok &= IsPointerOk (m_tail);
139  uint16_t current = m_head;
140  while (ok && current != 0xffff)
141  {
142  struct PacketMetadata::SmallItem item;
143  PacketMetadata::ExtraItem extraItem;
144  ReadItems (current, &item, &extraItem);
145  ok &= IsSharedPointerOk (item.next);
146  ok &= IsSharedPointerOk (item.prev);
147  if (current != m_head)
148  {
149  ok &= IsPointerOk (item.prev);
150  }
151  if (current != m_tail)
152  {
153  ok &= IsPointerOk (item.next);
154  }
155  if (current == m_tail)
156  {
157  break;
158  }
159  current = item.next;
160  }
161  return ok;
162 }
163 
164 uint32_t
165 PacketMetadata::GetUleb128Size (uint32_t value) const
166 {
167  NS_LOG_FUNCTION (this << value);
168  if (value < 0x80)
169  {
170  return 1;
171  }
172  if (value < 0x4000)
173  {
174  return 2;
175  }
176  if (value < 0x200000)
177  {
178  return 3;
179  }
180  if (value < 0x10000000)
181  {
182  return 4;
183  }
184  return 5;
185 }
186 uint32_t
187 PacketMetadata::ReadUleb128 (const uint8_t **pBuffer) const
188 {
189  NS_LOG_FUNCTION (this << &pBuffer);
190  const uint8_t *buffer = *pBuffer;
191  uint32_t result = 0;
192  uint8_t byte;
193  result = 0;
194  byte = buffer[0];
195  result = (byte & (~0x80));
196  if (!(byte & 0x80))
197  {
198  *pBuffer = buffer + 1;
199  return result;
200  }
201  byte = buffer[1];
202  result |= (byte & (~0x80)) << 7;
203  if (!(byte & 0x80))
204  {
205  *pBuffer = buffer + 2;
206  return result;
207  }
208  byte = buffer[2];
209  result |= (byte & (~0x80)) << 14;
210  if (!(byte & 0x80))
211  {
212  *pBuffer = buffer + 3;
213  return result;
214  }
215  byte = buffer[3];
216  result |= (byte & (~0x80)) << 21;
217  if (!(byte & 0x80))
218  {
219  *pBuffer = buffer + 4;
220  return result;
221  }
222  byte = buffer[4];
223  result |= (byte & (~0x80)) << 28;
224  if (!(byte & 0x80))
225  {
226  *pBuffer = buffer + 5;
227  return result;
228  }
229  /* This means that the LEB128 number was not valid.
230  * ie: the last (5th) byte did not have the high-order bit zeroed.
231  */
232  NS_ASSERT (false);
233  return 0;
234 }
235 
236 void
237 PacketMetadata::Append16 (uint16_t value, uint8_t *buffer)
238 {
239  NS_LOG_FUNCTION (this << value << &buffer);
240  buffer[0] = value & 0xff;
241  value >>= 8;
242  buffer[1] = value;
243 }
244 void
245 PacketMetadata::Append32 (uint32_t value, uint8_t *buffer)
246 {
247  NS_LOG_FUNCTION (this << value << &buffer);
248  buffer[0] = value & 0xff;
249  buffer[1] = (value >> 8) & 0xff;
250  buffer[2] = (value >> 16) & 0xff;
251  buffer[3] = (value >> 24) & 0xff;
252 }
253 
254 void
255 PacketMetadata::AppendValueExtra (uint32_t value, uint8_t *buffer)
256 {
257  NS_LOG_FUNCTION (this << value << &buffer);
258  if (value < 0x200000)
259  {
260  uint8_t byte = value & (~0x80);
261  buffer[0] = 0x80 | byte;
262  value >>= 7;
263  byte = value & (~0x80);
264  buffer[1] = 0x80 | byte;
265  value >>= 7;
266  byte = value & (~0x80);
267  buffer[2] = value;
268  return;
269  }
270  if (value < 0x10000000)
271  {
272  uint8_t byte = value & (~0x80);
273  buffer[0] = 0x80 | byte;
274  value >>= 7;
275  byte = value & (~0x80);
276  buffer[1] = 0x80 | byte;
277  value >>= 7;
278  byte = value & (~0x80);
279  buffer[2] = 0x80 | byte;
280  value >>= 7;
281  buffer[3] = value;
282  return;
283  }
284  {
285  uint8_t byte = value & (~0x80);
286  buffer[0] = 0x80 | byte;
287  value >>= 7;
288  byte = value & (~0x80);
289  buffer[1] = 0x80 | byte;
290  value >>= 7;
291  byte = value & (~0x80);
292  buffer[2] = 0x80 | byte;
293  value >>= 7;
294  byte = value & (~0x80);
295  buffer[3] = 0x80 | byte;
296  value >>= 7;
297  buffer[4] = value;
298  }
299 }
300 
301 void
302 PacketMetadata::AppendValue (uint32_t value, uint8_t *buffer)
303 {
304  NS_LOG_FUNCTION (this << value << &buffer);
305  if (value < 0x80)
306  {
307  buffer[0] = value;
308  return;
309  }
310  if (value < 0x4000)
311  {
312  uint8_t byte = value & (~0x80);
313  buffer[0] = 0x80 | byte;
314  value >>= 7;
315  buffer[1] = value;
316  return;
317  }
318  AppendValueExtra (value, buffer);
319 }
320 
321 void
322 PacketMetadata::UpdateTail (uint16_t written)
323 {
324  NS_LOG_FUNCTION (this << written);
325  if (m_head == 0xffff)
326  {
327  NS_ASSERT (m_tail == 0xffff);
328  m_head = m_used;
329  m_tail = m_used;
330  }
331  else
332  {
333  NS_ASSERT (m_tail != 0xffff);
334  // overwrite the next field of the previous tail of the list.
335  uint8_t *previousTail = &m_data->m_data[m_tail];
336  Append16 (m_used, previousTail);
337  // update the tail of the list to the new node.
338  m_tail = m_used;
339  }
340  NS_ASSERT (m_tail != 0xffff);
341  NS_ASSERT (m_head != 0xffff);
342  NS_ASSERT (written >= 8);
343  m_used += written;
345 }
346 
347 
348 void
349 PacketMetadata::UpdateHead (uint16_t written)
350 {
351  NS_LOG_FUNCTION (this << written);
352  if (m_head == 0xffff)
353  {
354  NS_ASSERT (m_tail == 0xffff);
355  m_head = m_used;
356  m_tail = m_used;
357  }
358  else
359  {
360  NS_ASSERT (m_head != 0xffff);
361  // overwrite the prev field of the previous head of the list.
362  uint8_t *previousHead = &m_data->m_data[m_head + 2];
363  Append16 (m_used, previousHead);
364  // update the head of list to the new node.
365  m_head = m_used;
366  }
367  NS_ASSERT (m_tail != 0xffff);
368  NS_ASSERT (m_head != 0xffff);
369  NS_ASSERT (written >= 8);
370  m_used += written;
372 }
373 
374 uint16_t
376 {
377  NS_LOG_FUNCTION (this << item->next << item->prev << item->typeUid << item->size << item->chunkUid);
378  NS_ASSERT (m_data != 0);
379  NS_ASSERT (m_used != item->prev && m_used != item->next);
380  uint32_t typeUidSize = GetUleb128Size (item->typeUid);
381  uint32_t sizeSize = GetUleb128Size (item->size);
382  uint32_t n = 2 + 2 + typeUidSize + sizeSize + 2;
383  if (m_used + n > m_data->m_size ||
384  (m_head != 0xffff &&
385  m_data->m_count != 1 &&
386  m_used != m_data->m_dirtyEnd))
387  {
388  ReserveCopy (n);
389  }
390  uint8_t *buffer = &m_data->m_data[m_used];
391  Append16 (item->next, buffer);
392  buffer += 2;
393  Append16 (item->prev, buffer);
394  buffer += 2;
395  AppendValue (item->typeUid, buffer);
396  buffer += typeUidSize;
397  AppendValue (item->size, buffer);
398  buffer += sizeSize;
399  Append16 (item->chunkUid, buffer);
400  return n;
401 }
402 
403 uint16_t
404 PacketMetadata::AddBig (uint32_t next, uint32_t prev,
405  const PacketMetadata::SmallItem *item,
406  const PacketMetadata::ExtraItem *extraItem)
407 {
408  NS_LOG_FUNCTION (this << next << prev <<
409  item->next << item->prev << item->typeUid << item->size << item->chunkUid <<
410  extraItem->fragmentStart << extraItem->fragmentEnd << extraItem->packetUid);
411  NS_ASSERT (m_data != 0);
412  uint32_t typeUid = ((item->typeUid & 0x1) == 0x1) ? item->typeUid : item->typeUid+1;
413  NS_ASSERT (m_used != prev && m_used != next);
414 
415  uint32_t typeUidSize = GetUleb128Size (typeUid);
416  uint32_t sizeSize = GetUleb128Size (item->size);
417  uint32_t fragStartSize = GetUleb128Size (extraItem->fragmentStart);
418  uint32_t fragEndSize = GetUleb128Size (extraItem->fragmentEnd);
419  uint32_t n = 2 + 2 + typeUidSize + sizeSize + 2 + fragStartSize + fragEndSize + 4;
420 
421  if (m_used + n > m_data->m_size ||
422  (m_head != 0xffff &&
423  m_data->m_count != 1 &&
424  m_used != m_data->m_dirtyEnd))
425  {
426  ReserveCopy (n);
427  }
428 
429  uint8_t *buffer = &m_data->m_data[m_used];
430 
431  Append16 (next, buffer);
432  buffer += 2;
433  Append16 (prev, buffer);
434  buffer += 2;
435  AppendValue (typeUid, buffer);
436  buffer += typeUidSize;
437  AppendValue (item->size, buffer);
438  buffer += sizeSize;
439  Append16 (item->chunkUid, buffer);
440  buffer += 2;
441  AppendValue (extraItem->fragmentStart, buffer);
442  buffer += fragStartSize;
443  AppendValue (extraItem->fragmentEnd, buffer);
444  buffer += fragEndSize;
445  Append32 (extraItem->packetUid, buffer);
446 
447  return n;
448 }
449 
456 void
458  PacketMetadata::ExtraItem *extraItem,
459  uint32_t available)
460 {
461  NS_LOG_FUNCTION (this <<
462  item->next << item->prev << item->typeUid << item->size << item->chunkUid <<
463  extraItem->fragmentStart << extraItem->fragmentEnd << extraItem->packetUid <<
464  available);
465 
466  NS_ASSERT (m_data != 0);
467  /* If the tail we want to replace is located at the end of the data array,
468  * and if there is extra room at the end of this array, then,
469  * we can try to use that extra space to avoid falling in the slow
470  * path below.
471  */
472  if (m_tail + available == m_used &&
474  {
475  available = m_data->m_size - m_tail;
476  }
477 
478  uint32_t typeUid = ((item->typeUid & 0x1) == 0x1) ? item->typeUid : item->typeUid+1;
479  uint32_t typeUidSize = GetUleb128Size (typeUid);
480  uint32_t sizeSize = GetUleb128Size (item->size);
481  uint32_t fragStartSize = GetUleb128Size (extraItem->fragmentStart);
482  uint32_t fragEndSize = GetUleb128Size (extraItem->fragmentEnd);
483  uint32_t n = 2 + 2 + typeUidSize + sizeSize + 2 + fragStartSize + fragEndSize + 4;
484 
485  if (available >= n &&
486  m_data->m_count == 1)
487  {
488  uint8_t *buffer = &m_data->m_data[m_tail];
489  Append16 (item->next, buffer);
490  buffer += 2;
491  Append16 (item->prev, buffer);
492  buffer += 2;
493  AppendValue (typeUid, buffer);
494  buffer += typeUidSize;
495  AppendValue (item->size, buffer);
496  buffer += sizeSize;
497  Append16 (item->chunkUid, buffer);
498  buffer += 2;
499  AppendValue (extraItem->fragmentStart, buffer);
500  buffer += fragStartSize;
501  AppendValue (extraItem->fragmentEnd, buffer);
502  buffer += fragEndSize;
503  Append32 (extraItem->packetUid, buffer);
504  m_used = std::max (m_used, (uint16_t)(buffer - &m_data->m_data[0]));
506  return;
507  }
508 
509  /* Below is the slow path which is hit if the new tail we want
510  * to append is bigger than the previous tail.
511  */
512 
513  // create a copy of the packet without its tail.
515  uint16_t current = m_head;
516  while (current != 0xffff && current != m_tail)
517  {
518  struct PacketMetadata::SmallItem tmpItem;
519  PacketMetadata::ExtraItem tmpExtraItem;
520  ReadItems (current, &tmpItem, &tmpExtraItem);
521  uint16_t written = h.AddBig (0xffff, h.m_tail,
522  &tmpItem, &tmpExtraItem);
523  h.UpdateTail (written);
524  current = tmpItem.next;
525  }
526  // append new tail.
527  uint16_t written = h.AddBig (0xffff, h.m_tail, item, extraItem);
528  h.UpdateTail (written);
529 
530  *this = h;
531 }
532 
539 uint32_t
541  struct PacketMetadata::SmallItem *item,
542  struct PacketMetadata::ExtraItem *extraItem) const
543 {
544  NS_LOG_FUNCTION (this << current << item->chunkUid << item->prev << item->next << item->size <<
545  item->typeUid << extraItem->fragmentEnd << extraItem->fragmentStart <<
546  extraItem->packetUid);
547  NS_ASSERT (current <= m_data->m_size);
548  const uint8_t *buffer = &m_data->m_data[current];
549  item->next = buffer[0];
550  item->next |= (buffer[1]) << 8;
551  item->prev = buffer[2];
552  item->prev |= (buffer[3]) << 8;
553  buffer += 4;
554  item->typeUid = ReadUleb128 (&buffer);
555  item->size = ReadUleb128 (&buffer);
556  item->chunkUid = buffer[0];
557  item->chunkUid |= (buffer[1]) << 8;
558  buffer += 2;
559 
560  bool isExtra = (item->typeUid & 0x1) == 0x1;
561  if (isExtra)
562  {
563  extraItem->fragmentStart = ReadUleb128 (&buffer);
564  extraItem->fragmentEnd = ReadUleb128 (&buffer);
565  extraItem->packetUid = buffer[0];
566  extraItem->packetUid |= buffer[1] << 8;
567  extraItem->packetUid |= buffer[2] << 16;
568  extraItem->packetUid |= buffer[3] << 24;
569  buffer += 4;
570  }
571  else
572  {
573  extraItem->fragmentStart = 0;
574  extraItem->fragmentEnd = item->size;
575  extraItem->packetUid = m_packetUid;
576  }
577  NS_ASSERT (buffer <= &m_data->m_data[m_data->m_size]);
578  return buffer - &m_data->m_data[current];
579 }
580 
581 struct PacketMetadata::Data *
582 PacketMetadata::Create (uint32_t size)
583 {
584  NS_LOG_FUNCTION (size);
585  NS_LOG_LOGIC ("create size="<<size<<", max="<<m_maxSize);
586  if (size > m_maxSize)
587  {
588  m_maxSize = size;
589  }
590  while (!m_freeList.empty ())
591  {
592  struct PacketMetadata::Data *data = m_freeList.back ();
593  m_freeList.pop_back ();
594  if (data->m_size >= size)
595  {
596  NS_LOG_LOGIC ("create found size="<<data->m_size);
597  data->m_count = 1;
598  return data;
599  }
601  NS_LOG_LOGIC ("create dealloc size="<<data->m_size);
602  }
603  NS_LOG_LOGIC ("create alloc size="<<m_maxSize);
605 }
606 
607 void
609 {
610  NS_LOG_FUNCTION (data);
611  if (!m_enable)
612  {
614  return;
615  }
616  NS_LOG_LOGIC ("recycle size="<<data->m_size<<", list="<<m_freeList.size ());
617  NS_ASSERT (data->m_count == 0);
618  if (m_freeList.size () > 1000 ||
619  data->m_size < m_maxSize)
620  {
622  }
623  else
624  {
625  m_freeList.push_back (data);
626  }
627 }
628 
629 struct PacketMetadata::Data *
631 {
632  NS_LOG_FUNCTION (n);
633  uint32_t size = sizeof (struct Data);
635  {
637  }
639  uint8_t *buf = new uint8_t [size];
640  struct PacketMetadata::Data *data = (struct PacketMetadata::Data *)buf;
641  data->m_size = n;
642  data->m_count = 1;
643  data->m_dirtyEnd = 0;
644  return data;
645 }
646 void
648 {
649  NS_LOG_FUNCTION (data);
650  uint8_t *buf = (uint8_t *)data;
651  delete [] buf;
652 }
653 
654 
656 PacketMetadata::CreateFragment (uint32_t start, uint32_t end) const
657 {
658  NS_LOG_FUNCTION (this << start << end);
659  PacketMetadata fragment = *this;
660  fragment.RemoveAtStart (start);
661  fragment.RemoveAtEnd (end);
662  return fragment;
663 }
664 
665 void
666 PacketMetadata::AddHeader (const Header &header, uint32_t size)
667 {
668  NS_LOG_FUNCTION (this << &header << size);
669  NS_ASSERT (IsStateOk ());
670  uint32_t uid = header.GetInstanceTypeId ().GetUid () << 1;
671  DoAddHeader (uid, size);
672  NS_ASSERT (IsStateOk ());
673 }
674 void
675 PacketMetadata::DoAddHeader (uint32_t uid, uint32_t size)
676 {
677  NS_LOG_FUNCTION (this << uid << size);
678  if (!m_enable)
679  {
680  m_metadataSkipped = true;
681  return;
682  }
683 
684  struct PacketMetadata::SmallItem item;
685  item.next = m_head;
686  item.prev = 0xffff;
687  item.typeUid = uid;
688  item.size = size;
689  item.chunkUid = m_chunkUid;
690  m_chunkUid++;
691  uint16_t written = AddSmall (&item);
692  UpdateHead (written);
693 }
694 void
695 PacketMetadata::RemoveHeader (const Header &header, uint32_t size)
696 {
697  uint32_t uid = header.GetInstanceTypeId ().GetUid () << 1;
698  NS_LOG_FUNCTION (this << &header << size);
699  NS_ASSERT (IsStateOk ());
700  if (!m_enable)
701  {
702  m_metadataSkipped = true;
703  return;
704  }
705  struct PacketMetadata::SmallItem item;
706  struct PacketMetadata::ExtraItem extraItem;
707  uint32_t read = ReadItems (m_head, &item, &extraItem);
708  if ((item.typeUid & 0xfffffffe) != uid ||
709  item.size != size)
710  {
711  if (m_enableChecking)
712  {
713  NS_FATAL_ERROR ("Removing unexpected header.");
714  }
715  return;
716  }
717  else if (item.typeUid != uid &&
718  (extraItem.fragmentStart != 0 ||
719  extraItem.fragmentEnd != size))
720  {
721  if (m_enableChecking)
722  {
723  NS_FATAL_ERROR ("Removing incomplete header.");
724  }
725  return;
726  }
727  if (m_head + read == m_used)
728  {
729  m_used = m_head;
730  }
731  if (m_head == m_tail)
732  {
733  m_head = 0xffff;
734  m_tail = 0xffff;
735  }
736  else
737  {
738  m_head = item.next;
739  }
740  NS_ASSERT (IsStateOk ());
741 }
742 void
743 PacketMetadata::AddTrailer (const Trailer &trailer, uint32_t size)
744 {
745  uint32_t uid = trailer.GetInstanceTypeId ().GetUid () << 1;
746  NS_LOG_FUNCTION (this << &trailer << size);
747  NS_ASSERT (IsStateOk ());
748  if (!m_enable)
749  {
750  m_metadataSkipped = true;
751  return;
752  }
753  struct PacketMetadata::SmallItem item;
754  item.next = 0xffff;
755  item.prev = m_tail;
756  item.typeUid = uid;
757  item.size = size;
758  item.chunkUid = m_chunkUid;
759  m_chunkUid++;
760  uint16_t written = AddSmall (&item);
761  UpdateTail (written);
762  NS_ASSERT (IsStateOk ());
763 }
764 void
765 PacketMetadata::RemoveTrailer (const Trailer &trailer, uint32_t size)
766 {
767  uint32_t uid = trailer.GetInstanceTypeId ().GetUid () << 1;
768  NS_LOG_FUNCTION (this << &trailer << size);
769  NS_ASSERT (IsStateOk ());
770  if (!m_enable)
771  {
772  m_metadataSkipped = true;
773  return;
774  }
775  struct PacketMetadata::SmallItem item;
776  struct PacketMetadata::ExtraItem extraItem;
777  uint32_t read = ReadItems (m_tail, &item, &extraItem);
778  if ((item.typeUid & 0xfffffffe) != uid ||
779  item.size != size)
780  {
781  if (m_enableChecking)
782  {
783  NS_FATAL_ERROR ("Removing unexpected trailer.");
784  }
785  return;
786  }
787  else if (item.typeUid != uid &&
788  (extraItem.fragmentStart != 0 ||
789  extraItem.fragmentEnd != size))
790  {
791  if (m_enableChecking)
792  {
793  NS_FATAL_ERROR ("Removing incomplete trailer.");
794  }
795  return;
796  }
797  if (m_tail + read == m_used)
798  {
799  m_used = m_tail;
800  }
801  if (m_head == m_tail)
802  {
803  m_head = 0xffff;
804  m_tail = 0xffff;
805  }
806  else
807  {
808  m_tail = item.prev;
809  }
810  NS_ASSERT (IsStateOk ());
811 }
812 void
814 {
815  NS_LOG_FUNCTION (this << &o);
816  NS_ASSERT (IsStateOk ());
817  if (!m_enable)
818  {
819  m_metadataSkipped = true;
820  return;
821  }
822  if (m_tail == 0xffff)
823  {
824  // We have no items so 'AddAtEnd' is
825  // equivalent to self-assignment.
826  *this = o;
827  NS_ASSERT (IsStateOk ());
828  return;
829  }
830  if (o.m_head == 0xffff)
831  {
832  NS_ASSERT (o.m_tail == 0xffff);
833  // we have nothing to append.
834  return;
835  }
836  NS_ASSERT (m_head != 0xffff && m_tail != 0xffff);
837 
838  // We read the current tail because we are going to append
839  // after this item.
840  struct PacketMetadata::SmallItem tailItem;
841  PacketMetadata::ExtraItem tailExtraItem;
842  uint32_t tailSize = ReadItems (m_tail, &tailItem, &tailExtraItem);
843 
844  uint16_t current;
845  struct PacketMetadata::SmallItem item;
846  PacketMetadata::ExtraItem extraItem;
847  o.ReadItems (o.m_head, &item, &extraItem);
848  if (extraItem.packetUid == tailExtraItem.packetUid &&
849  item.typeUid == tailItem.typeUid &&
850  item.chunkUid == tailItem.chunkUid &&
851  item.size == tailItem.size &&
852  extraItem.fragmentStart == tailExtraItem.fragmentEnd)
853  {
854  /* If the previous tail came from the same header as
855  * the next item we want to append to our array, then,
856  * we merge them and attempt to reuse the previous tail's
857  * location.
858  */
859  tailExtraItem.fragmentEnd = extraItem.fragmentEnd;
860  ReplaceTail (&tailItem, &tailExtraItem, tailSize);
861  if (o.m_head == o.m_tail)
862  {
863  // there is only one item to append to self from other.
864  return;
865  }
866  current = item.next;
867  }
868  else
869  {
870  current = o.m_head;
871  }
872 
873  /* Now that we have merged our current tail with the head of the
874  * next packet, we just append all items from the next packet
875  * to the current packet.
876  */
877  while (current != 0xffff)
878  {
879  o.ReadItems (current, &item, &extraItem);
880  uint16_t written = AddBig (0xffff, m_tail, &item, &extraItem);
881  UpdateTail (written);
882  if (current == o.m_tail)
883  {
884  break;
885  }
886  current = item.next;
887  }
888  NS_ASSERT (IsStateOk ());
889 }
890 void
892 {
893  NS_LOG_FUNCTION (this << end);
894  if (!m_enable)
895  {
896  m_metadataSkipped = true;
897  return;
898  }
899 }
900 void
902 {
903  NS_LOG_FUNCTION (this << start);
904  NS_ASSERT (IsStateOk ());
905  if (!m_enable)
906  {
907  m_metadataSkipped = true;
908  return;
909  }
910  NS_ASSERT (m_data != 0);
911  uint32_t leftToRemove = start;
912  uint16_t current = m_head;
913  while (current != 0xffff && leftToRemove > 0)
914  {
915  struct PacketMetadata::SmallItem item;
916  PacketMetadata::ExtraItem extraItem;
917  ReadItems (current, &item, &extraItem);
918  uint32_t itemRealSize = extraItem.fragmentEnd - extraItem.fragmentStart;
919  if (itemRealSize <= leftToRemove)
920  {
921  // remove from list.
922  if (m_head == m_tail)
923  {
924  m_head = 0xffff;
925  m_tail = 0xffff;
926  }
927  else
928  {
929  m_head = item.next;
930  }
931  leftToRemove -= itemRealSize;
932  }
933  else
934  {
935  // fragment the list item.
936  PacketMetadata fragment (m_packetUid, 0);
937  extraItem.fragmentStart += leftToRemove;
938  leftToRemove = 0;
939  uint16_t written = fragment.AddBig (0xffff, fragment.m_tail,
940  &item, &extraItem);
941  fragment.UpdateTail (written);
942  while (current != 0xffff && current != m_tail)
943  {
944  current = item.next;
945  ReadItems (current, &item, &extraItem);
946  written = fragment.AddBig (0xffff, fragment.m_tail,
947  &item, &extraItem);
948  fragment.UpdateTail (written);
949  }
950  *this = fragment;
951  }
952  NS_ASSERT (item.size >= extraItem.fragmentEnd - extraItem.fragmentStart &&
953  extraItem.fragmentStart <= extraItem.fragmentEnd);
954  if (current == m_tail)
955  {
956  break;
957  }
958  current = item.next;
959  }
960  NS_ASSERT (leftToRemove == 0);
961  NS_ASSERT (IsStateOk ());
962 }
963 void
965 {
966  NS_LOG_FUNCTION (this << end);
967  NS_ASSERT (IsStateOk ());
968  if (!m_enable)
969  {
970  m_metadataSkipped = true;
971  return;
972  }
973  NS_ASSERT (m_data != 0);
974 
975  uint32_t leftToRemove = end;
976  uint16_t current = m_tail;
977  while (current != 0xffff && leftToRemove > 0)
978  {
979  struct PacketMetadata::SmallItem item;
980  PacketMetadata::ExtraItem extraItem;
981  ReadItems (current, &item, &extraItem);
982  uint32_t itemRealSize = extraItem.fragmentEnd - extraItem.fragmentStart;
983  if (itemRealSize <= leftToRemove)
984  {
985  // remove from list.
986  if (m_head == m_tail)
987  {
988  m_head = 0xffff;
989  m_tail = 0xffff;
990  }
991  else
992  {
993  m_tail = item.prev;
994  }
995  leftToRemove -= itemRealSize;
996  }
997  else
998  {
999  // fragment the list item.
1000  PacketMetadata fragment (m_packetUid, 0);
1001  NS_ASSERT (extraItem.fragmentEnd > leftToRemove);
1002  extraItem.fragmentEnd -= leftToRemove;
1003  leftToRemove = 0;
1004  uint16_t written = fragment.AddBig (fragment.m_head, 0xffff,
1005  &item, &extraItem);
1006  fragment.UpdateHead (written);
1007  while (current != 0xffff && current != m_head)
1008  {
1009  current = item.prev;
1010  ReadItems (current, &item, &extraItem);
1011  written = fragment.AddBig (fragment.m_head, 0xffff,
1012  &item, &extraItem);
1013  fragment.UpdateHead (written);
1014  }
1015  *this = fragment;
1016  }
1017  NS_ASSERT (item.size >= extraItem.fragmentEnd - extraItem.fragmentStart &&
1018  extraItem.fragmentStart <= extraItem.fragmentEnd);
1019  if (current == m_head)
1020  {
1021  break;
1022  }
1023  current = item.prev;
1024  }
1025  NS_ASSERT (leftToRemove == 0);
1026  NS_ASSERT (IsStateOk ());
1027 }
1028 uint32_t
1030 {
1031  NS_LOG_FUNCTION (this);
1032  uint32_t totalSize = 0;
1033  uint16_t current = m_head;
1034  uint16_t tail = m_tail;
1035  while (current != 0xffff)
1036  {
1037  struct PacketMetadata::SmallItem item;
1038  PacketMetadata::ExtraItem extraItem;
1039  ReadItems (current, &item, &extraItem);
1040  totalSize += extraItem.fragmentEnd - extraItem.fragmentStart;
1041  if (current == tail)
1042  {
1043  break;
1044  }
1045  NS_ASSERT (current != item.next);
1046  current = item.next;
1047  }
1048  return totalSize;
1049 }
1050 
1051 uint64_t
1053 {
1054  NS_LOG_FUNCTION (this);
1055  return m_packetUid;
1056 }
1059 {
1060  NS_LOG_FUNCTION (this << &buffer);
1061  return ItemIterator (this, buffer);
1062 }
1064  : m_metadata (metadata),
1065  m_buffer (buffer),
1066  m_current (metadata->m_head),
1067  m_offset (0),
1068  m_hasReadTail (false)
1069 {
1070  NS_LOG_FUNCTION (this << metadata << &buffer);
1071 }
1072 bool
1074 {
1075  NS_LOG_FUNCTION (this);
1076  if (m_current == 0xffff)
1077  {
1078  return false;
1079  }
1080  if (m_hasReadTail)
1081  {
1082  return false;
1083  }
1084  return true;
1085 }
1088 {
1089  NS_LOG_FUNCTION (this);
1090  struct PacketMetadata::Item item;
1091  struct PacketMetadata::SmallItem smallItem;
1092  struct PacketMetadata::ExtraItem extraItem;
1093  m_metadata->ReadItems (m_current, &smallItem, &extraItem);
1094  if (m_current == m_metadata->m_tail)
1095  {
1096  m_hasReadTail = true;
1097  }
1098  m_current = smallItem.next;
1099  uint32_t uid = (smallItem.typeUid & 0xfffffffe) >> 1;
1100  item.tid.SetUid (uid);
1101  item.currentTrimedFromStart = extraItem.fragmentStart;
1102  item.currentTrimedFromEnd = extraItem.fragmentEnd - smallItem.size;
1103  item.currentSize = extraItem.fragmentEnd - extraItem.fragmentStart;
1104  if (extraItem.fragmentStart != 0 || extraItem.fragmentEnd != smallItem.size)
1105  {
1106  item.isFragment = true;
1107  }
1108  else
1109  {
1110  item.isFragment = false;
1111  }
1112  TypeId tid;
1113  tid.SetUid (uid);
1114  if (uid == 0)
1115  {
1117  }
1118  else if (tid.IsChildOf (Header::GetTypeId ()))
1119  {
1121  if (!item.isFragment)
1122  {
1123  ns3::Buffer tmp = m_buffer;
1124  tmp.RemoveAtStart (m_offset);
1125  tmp.RemoveAtEnd (tmp.GetSize () - item.currentSize);
1126  item.current = tmp.Begin ();
1127  }
1128  }
1129  else if (tid.IsChildOf (Trailer::GetTypeId ()))
1130  {
1132  if (!item.isFragment)
1133  {
1134  ns3::Buffer tmp = m_buffer;
1135  tmp.RemoveAtEnd (tmp.GetSize () - (m_offset + smallItem.size));
1136  tmp.RemoveAtStart (tmp.GetSize () - item.currentSize);
1137  item.current = tmp.End ();
1138  }
1139  }
1140  else
1141  {
1142  NS_ASSERT (false);
1143  }
1144  m_offset += extraItem.fragmentEnd - extraItem.fragmentStart;
1145  return item;
1146 }
1147 
1148 uint32_t
1150 {
1151  NS_LOG_FUNCTION (this);
1152  uint32_t totalSize = 0;
1153 
1154  // add 8 bytes for the packet uid
1155  totalSize += 8;
1156 
1157  // if packet-metadata not enabled, total size
1158  // is simply 4-bytes for itself plus 8-bytes
1159  // for packet uid
1160  if (!m_enable)
1161  {
1162  return totalSize;
1163  }
1164 
1165  struct PacketMetadata::SmallItem item;
1166  struct PacketMetadata::ExtraItem extraItem;
1167  uint32_t current = m_head;
1168  while (current != 0xffff)
1169  {
1170  ReadItems (current, &item, &extraItem);
1171  uint32_t uid = (item.typeUid & 0xfffffffe) >> 1;
1172  if (uid == 0)
1173  {
1174  totalSize += 4;
1175  }
1176  else
1177  {
1178  TypeId tid;
1179  tid.SetUid (uid);
1180  totalSize += 4 + tid.GetName ().size ();
1181  }
1182  totalSize += 1 + 4 + 2 + 4 + 4 + 8;
1183  if (current == m_tail)
1184  {
1185  break;
1186  }
1187  NS_ASSERT (current != item.next);
1188  current = item.next;
1189  }
1190  return totalSize;
1191 }
1192 
1193 uint32_t
1194 PacketMetadata::Serialize (uint8_t* buffer, uint32_t maxSize) const
1195 {
1196  NS_LOG_FUNCTION (this << &buffer << maxSize);
1197  uint8_t* start = buffer;
1198 
1199  buffer = AddToRawU64 (m_packetUid, start, buffer, maxSize);
1200  if (buffer == 0)
1201  {
1202  return 0;
1203  }
1204 
1205  struct PacketMetadata::SmallItem item;
1206  struct PacketMetadata::ExtraItem extraItem;
1207  uint32_t current = m_head;
1208  while (current != 0xffff)
1209  {
1210  ReadItems (current, &item, &extraItem);
1211  NS_LOG_LOGIC ("bytesWritten=" << static_cast<uint32_t> (buffer - start) << ", typeUid="<<
1212  item.typeUid << ", size="<<item.size<<", chunkUid="<<item.chunkUid<<
1213  ", fragmentStart="<<extraItem.fragmentStart<<", fragmentEnd="<<
1214  extraItem.fragmentEnd<< ", packetUid="<<extraItem.packetUid);
1215 
1216  uint32_t uid = (item.typeUid & 0xfffffffe) >> 1;
1217  if (uid != 0)
1218  {
1219  TypeId tid;
1220  tid.SetUid (uid);
1221  std::string uidString = tid.GetName ();
1222  uint32_t uidStringSize = uidString.size ();
1223  buffer = AddToRawU32 (uidStringSize, start, buffer, maxSize);
1224  if (buffer == 0)
1225  {
1226  return 0;
1227  }
1228  buffer = AddToRaw (reinterpret_cast<const uint8_t *> (uidString.c_str ()),
1229  uidStringSize, start, buffer, maxSize);
1230  if (buffer == 0)
1231  {
1232  return 0;
1233  }
1234  }
1235  else
1236  {
1237  buffer = AddToRawU32 (0, start, buffer, maxSize);
1238  if (buffer == 0)
1239  {
1240  return 0;
1241  }
1242  }
1243 
1244  uint8_t isBig = item.typeUid & 0x1;
1245  buffer = AddToRawU8 (isBig, start, buffer, maxSize);
1246  if (buffer == 0)
1247  {
1248  return 0;
1249  }
1250 
1251  buffer = AddToRawU32 (item.size, start, buffer, maxSize);
1252  if (buffer == 0)
1253  {
1254  return 0;
1255  }
1256 
1257  buffer = AddToRawU16 (item.chunkUid, start, buffer, maxSize);
1258  if (buffer == 0)
1259  {
1260  return 0;
1261  }
1262 
1263  buffer = AddToRawU32 (extraItem.fragmentStart, start, buffer, maxSize);
1264  if (buffer == 0)
1265  {
1266  return 0;
1267  }
1268 
1269  buffer = AddToRawU32 (extraItem.fragmentEnd, start, buffer, maxSize);
1270  if (buffer == 0)
1271  {
1272  return 0;
1273  }
1274 
1275  buffer = AddToRawU64 (extraItem.packetUid, start, buffer, maxSize);
1276  if (buffer == 0)
1277  {
1278  return 0;
1279  }
1280 
1281  if (current == m_tail)
1282  {
1283  break;
1284  }
1285 
1286  NS_ASSERT (current != item.next);
1287  current = item.next;
1288  }
1289 
1290  NS_ASSERT (static_cast<uint32_t> (buffer - start) == maxSize);
1291  return 1;
1292 }
1293 
1294 uint32_t
1295 PacketMetadata::Deserialize (const uint8_t* buffer, uint32_t size)
1296 {
1297  NS_LOG_FUNCTION (this << &buffer << size);
1298  const uint8_t* start = buffer;
1299  uint32_t desSize = size - 4;
1300 
1301  buffer = ReadFromRawU64 (m_packetUid, start, buffer, size);
1302  desSize -= 8;
1303 
1304  struct PacketMetadata::SmallItem item = {0};
1305  struct PacketMetadata::ExtraItem extraItem = {0};
1306  while (desSize > 0)
1307  {
1308  uint32_t uidStringSize = 0;
1309  buffer = ReadFromRawU32 (uidStringSize, start, buffer, size);
1310  desSize -= 4;
1311  uint32_t uid;
1312  if (uidStringSize == 0)
1313  {
1314  // uid zero for payload.
1315  uid = 0;
1316  }
1317  else
1318  {
1319  std::string uidString;
1320  for (uint32_t j = 0; j < uidStringSize; j++)
1321  {
1322  uint8_t ch = 0;
1323  buffer = ReadFromRawU8 (ch, start, buffer, size);
1324  uidString.push_back (ch);
1325  desSize--;
1326  }
1327  TypeId tid = TypeId::LookupByName (uidString);
1328  uid = tid.GetUid ();
1329  }
1330  uint8_t isBig = 0;
1331  buffer = ReadFromRawU8 (isBig, start, buffer, size);
1332  desSize--;
1333  item.typeUid = (uid << 1) | isBig;
1334  buffer = ReadFromRawU32 (item.size, start, buffer, size);
1335  desSize -= 4;
1336  buffer = ReadFromRawU16 (item.chunkUid, start, buffer, size);
1337  desSize -= 2;
1338  buffer = ReadFromRawU32 (extraItem.fragmentStart, start, buffer, size);
1339  desSize -= 4;
1340  buffer = ReadFromRawU32 (extraItem.fragmentEnd, start, buffer, size);
1341  desSize -= 4;
1342  buffer = ReadFromRawU64 (extraItem.packetUid, start, buffer, size);
1343  desSize -= 8;
1344  NS_LOG_LOGIC ("size=" << size << ", typeUid="<<item.typeUid <<
1345  ", size="<<item.size<<", chunkUid="<<item.chunkUid<<
1346  ", fragmentStart="<<extraItem.fragmentStart<<", fragmentEnd="<<
1347  extraItem.fragmentEnd<< ", packetUid="<<extraItem.packetUid);
1348  uint32_t tmp = AddBig (0xffff, m_tail, &item, &extraItem);
1349  UpdateTail (tmp);
1350  }
1351  NS_ASSERT (desSize == 0);
1352  return (desSize !=0) ? 0 : 1;
1353 }
1354 
1355 uint8_t*
1357  uint8_t* start,
1358  uint8_t* current,
1359  uint32_t maxSize)
1360 {
1361  NS_LOG_FUNCTION (static_cast<uint32_t> (data) << &start << &current << maxSize);
1362  // First check buffer overflow
1363  if (static_cast<uint32_t> ((current + sizeof (uint8_t) - start)) > maxSize)
1364  {
1365  return 0;
1366  }
1367  memcpy (current, &data, sizeof (uint8_t));
1368  return current + sizeof (uint8_t);
1369 }
1370 
1371 uint8_t*
1373  uint8_t* start,
1374  uint8_t* current,
1375  uint32_t maxSize)
1376 {
1377  NS_LOG_FUNCTION (data << &start << &current << maxSize);
1378  // First check buffer overflow
1379  if (static_cast<uint32_t> ((current + sizeof (uint16_t) - start)) > maxSize)
1380  {
1381  return 0;
1382  }
1383  memcpy (current, &data, sizeof (uint16_t));
1384  return current + sizeof (uint16_t);
1385 }
1386 
1387 uint8_t*
1389  uint8_t* start,
1390  uint8_t* current,
1391  uint32_t maxSize)
1392 {
1393  NS_LOG_FUNCTION (data << &start << &current << maxSize);
1394  // First check buffer overflow
1395  if (static_cast<uint32_t> ((current + sizeof (uint32_t) - start)) > maxSize)
1396  {
1397  return 0;
1398  }
1399  memcpy (current, &data, sizeof (uint32_t));
1400  return current + sizeof (uint32_t);
1401 }
1402 
1403 uint8_t*
1405  uint8_t* start,
1406  uint8_t* current,
1407  uint32_t maxSize)
1408 {
1409  NS_LOG_FUNCTION (data << &start << &current << maxSize);
1410  // First check buffer overflow
1411  if (static_cast<uint32_t> ((current + sizeof (uint64_t) - start)) > maxSize)
1412  {
1413  return 0;
1414  }
1415  memcpy (current, &data, sizeof (uint64_t));
1416  return current + sizeof (uint64_t);
1417 }
1418 
1419 uint8_t*
1421  uint32_t dataSize,
1422  uint8_t* start,
1423  uint8_t* current,
1424  uint32_t maxSize)
1425 {
1426  NS_LOG_FUNCTION (&data << dataSize << &start << &current << maxSize);
1427  // First check buffer overflow
1428  if (static_cast<uint32_t> ((current + dataSize - start)) > maxSize)
1429  {
1430  return 0;
1431  }
1432  memcpy (current, data, dataSize);
1433  return current + dataSize;
1434 }
1435 
1436 uint8_t*
1438  const uint8_t* start,
1439  const uint8_t* current,
1440  uint32_t maxSize)
1441 {
1442  NS_LOG_FUNCTION (static_cast<uint32_t> (data) << &start << &current << maxSize);
1443  // First check buffer underflow
1444  if (static_cast<uint32_t> ((current + sizeof (uint8_t) - start)) > maxSize)
1445  {
1446  return 0;
1447  }
1448  memcpy (&data, current, sizeof (uint8_t));
1449  return const_cast<uint8_t *> (current) + sizeof (uint8_t);
1450 }
1451 
1452 uint8_t*
1454  const uint8_t* start,
1455  const uint8_t* current,
1456  uint32_t maxSize)
1457 {
1458  NS_LOG_FUNCTION (data << &start << &current << maxSize);
1459  // First check buffer underflow
1460  if (static_cast<uint32_t> ((current + sizeof (uint16_t) - start)) > maxSize)
1461  {
1462  return 0;
1463  }
1464  memcpy (&data, current, sizeof (uint16_t));
1465  return const_cast<uint8_t *> (current) + sizeof (uint16_t);
1466 }
1467 
1468 uint8_t*
1470  const uint8_t* start,
1471  const uint8_t* current,
1472  uint32_t maxSize)
1473 {
1474  NS_LOG_FUNCTION (data << &start << &current << maxSize);
1475  // First check buffer underflow
1476  if (static_cast<uint32_t> ((current + sizeof (uint32_t) - start)) > maxSize)
1477  {
1478  return 0;
1479  }
1480  memcpy (&data, current, sizeof (uint32_t));
1481  return const_cast<uint8_t *> (current) + sizeof (uint32_t);
1482 }
1483 
1484 uint8_t*
1486  const uint8_t* start,
1487  const uint8_t* current,
1488  uint32_t maxSize)
1489 {
1490  NS_LOG_FUNCTION (data << &start << &current << maxSize);
1491  // First check buffer underflow
1492  if ((uint32_t)((current + sizeof (uint64_t) - start)) > maxSize)
1493  {
1494  return 0;
1495  }
1496  memcpy (&data, current, sizeof (uint64_t));
1497  return const_cast<uint8_t *> (current) + sizeof (uint64_t);
1498 }
1499 
1500 
1501 } // namespace ns3
1502 
Protocol header serialization and deserialization.
Definition: header.h:42
void RemoveAtEnd(uint32_t end)
static void Recycle(struct PacketMetadata::Data *data)
friend class ItemIterator
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:345
void RemoveAtEnd(uint32_t end)
Definition: buffer.cc:497
static uint8_t * ReadFromRawU8(uint8_t &data, const uint8_t *start, const uint8_t *current, uint32_t maxSize)
static bool m_enableChecking
void RemoveAtStart(uint32_t start)
Definition: buffer.cc:452
uint64_t GetUid(void) const
void ReserveCopy(uint32_t n)
automatically resized byte buffer
Definition: buffer.h:92
static void Deallocate(struct PacketMetadata::Data *data)
static void EnableChecking(void)
static uint8_t * ReadFromRawU16(uint16_t &data, const uint8_t *start, const uint8_t *current, uint32_t maxSize)
#define NS_ASSERT(condition)
Definition: assert.h:64
struct Data * m_data
uint32_t GetSerializedSize(void) const
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
Definition: log.h:309
uint16_t AddSmall(const PacketMetadata::SmallItem *item)
static TypeId GetTypeId(void)
Definition: trailer.cc:17
void UpdateHead(uint16_t written)
bool IsSharedPointerOk(uint16_t pointer) const
void AddHeader(Header const &header, uint32_t size)
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72
void AppendValueExtra(uint32_t value, uint8_t *buffer)
void DoAddHeader(uint32_t uid, uint32_t size)
static uint8_t * AddToRaw(const uint8_t *data, uint32_t dataSize, uint8_t *start, uint8_t *current, uint32_t maxSize)
bool IsPointerOk(uint16_t pointer) const
void AddTrailer(Trailer const &trailer, uint32_t size)
static TypeId GetTypeId(void)
Definition: header.cc:17
void AddPaddingAtEnd(uint32_t end)
PacketMetadata CreateFragment(uint32_t start, uint32_t end) const
uint8_t data[writeSize]
static uint8_t * AddToRawU16(const uint16_t &data, uint8_t *start, uint8_t *current, uint32_t maxSize)
NS_LOG_COMPONENT_DEFINE("PacketMetadata")
Buffer::Iterator End(void) const
Definition: buffer.h:881
static DataFreeList m_freeList
void AppendValue(uint32_t value, uint8_t *buffer)
static struct PacketMetadata::Data * Allocate(uint32_t n)
#define NS_LOG_LOGIC(msg)
Definition: log.h:368
Buffer::Iterator Begin(void) const
Definition: buffer.h:875
void AddAtEnd(PacketMetadata const &o)
Protocol trailer serialization and deserialization.
Definition: trailer.h:40
uint32_t GetUleb128Size(uint32_t value) const
static void Enable(void)
void SetUid(uint16_t tid)
Definition: type-id.cc:819
enum ns3::PacketMetadata::Item::@79 type
static uint8_t * AddToRawU64(const uint64_t &data, uint8_t *start, uint8_t *current, uint32_t maxSize)
void Append32(uint32_t value, uint8_t *buffer)
std::string GetName(void) const
Definition: type-id.cc:658
void Append16(uint16_t value, uint8_t *buffer)
uint32_t Deserialize(const uint8_t *buffer, uint32_t size)
static uint32_t m_maxSize
bool IsStateOk(void) const
uint16_t GetUid(void) const
Definition: type-id.cc:813
uint32_t GetSize(void) const
Definition: buffer.h:869
void RemoveHeader(Header const &header, uint32_t size)
static uint8_t * AddToRawU32(const uint32_t &data, uint8_t *start, uint8_t *current, uint32_t maxSize)
static uint16_t m_chunkUid
#define NS_ASSERT_MSG(condition, message)
Definition: assert.h:86
uint32_t GetTotalSize(void) const
Time current
uint16_t AddBig(uint32_t head, uint32_t tail, const PacketMetadata::SmallItem *item, const PacketMetadata::ExtraItem *extraItem)
static struct PacketMetadata::Data * Create(uint32_t size)
void RemoveTrailer(Trailer const &trailer, uint32_t size)
virtual TypeId GetInstanceTypeId(void) const =0
ItemIterator BeginItem(Buffer buffer) const
static uint8_t * ReadFromRawU64(uint64_t &data, const uint8_t *start, const uint8_t *current, uint32_t maxSize)
static bool m_metadataSkipped
bool IsChildOf(TypeId other) const
Definition: type-id.cc:639
void UpdateTail(uint16_t written)
void RemoveAtStart(uint32_t start)
void Reserve(uint32_t n)
void ReplaceTail(PacketMetadata::SmallItem *item, PacketMetadata::ExtraItem *extraItem, uint32_t available)
static uint8_t * AddToRawU8(const uint8_t &data, uint8_t *start, uint8_t *current, uint32_t maxSize)
uint8_t m_data[PACKET_METADATA_DATA_M_DATA_SIZE]
a unique identifier for an interface.
Definition: type-id.h:49
uint32_t ReadUleb128(const uint8_t **pBuffer) const
ItemIterator(const PacketMetadata *metadata, Buffer buffer)
uint16_t m_head
head -(next)-> tail ^ | ---(prev)—|
uint32_t ReadItems(uint16_t current, struct PacketMetadata::SmallItem *item, struct PacketMetadata::ExtraItem *extraItem) const
#define PACKET_METADATA_DATA_M_DATA_SIZE
the size of PacketMetadata::Data::m_data such that the total size of PacketMetadata::Data is 16 bytes...
static uint8_t * ReadFromRawU32(uint32_t &data, const uint8_t *start, const uint8_t *current, uint32_t maxSize)
uint32_t Serialize(uint8_t *buffer, uint32_t maxSize) const
static TypeId LookupByName(std::string name)
Definition: type-id.cc:536
handle packet metadata about packet headers and trailers