A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
packet.cc
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2005,2006 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 "packet.h"
21 #include "ns3/assert.h"
22 #include "ns3/log.h"
23 #include "ns3/simulator.h"
24 #include <string>
25 #include <cstdarg>
26 
27 NS_LOG_COMPONENT_DEFINE ("Packet");
28 
29 namespace ns3 {
30 
31 uint32_t Packet::m_globalUid = 0;
32 
33 TypeId
35 {
36  return m_tid;
37 }
38 uint32_t
40 {
41  NS_LOG_FUNCTION (this);
42  return m_start;
43 }
44 uint32_t
46 {
47  NS_LOG_FUNCTION (this);
48  return m_end;
49 }
50 void
52 {
53  NS_LOG_FUNCTION (this << &tag);
54  if (tag.GetInstanceTypeId () != GetTypeId ())
55  {
56  NS_FATAL_ERROR ("The tag you provided is not of the right type.");
57  }
58  tag.Deserialize (m_buffer);
59 }
60 ByteTagIterator::Item::Item (TypeId tid, uint32_t start, uint32_t end, TagBuffer buffer)
61  : m_tid (tid),
62  m_start (start),
63  m_end (end),
64  m_buffer (buffer)
65 {
66  NS_LOG_FUNCTION (this << tid << start << end << &buffer);
67 }
68 bool
70 {
71  return m_current.HasNext ();
72 }
75 {
76  NS_LOG_FUNCTION (this);
77  ByteTagList::Iterator::Item i = m_current.Next ();
78  return ByteTagIterator::Item (i.tid,
79  i.start-m_current.GetOffsetStart (),
80  i.end-m_current.GetOffsetStart (),
81  i.buf);
82 }
83 ByteTagIterator::ByteTagIterator (ByteTagList::Iterator i)
84  : m_current (i)
85 {
86  NS_LOG_FUNCTION (this);
87 }
88 
89 
90 PacketTagIterator::PacketTagIterator (const struct PacketTagList::TagData *head)
91  : m_current (head)
92 {
93  NS_LOG_FUNCTION (this << head);
94 }
95 bool
97 {
98  NS_LOG_FUNCTION (this);
99  return m_current != 0;
100 }
103 {
104  NS_LOG_FUNCTION (this);
105  NS_ASSERT (HasNext ());
106  const struct PacketTagList::TagData *prev = m_current;
107  m_current = m_current->next;
108  return PacketTagIterator::Item (prev);
109 }
110 
111 PacketTagIterator::Item::Item (const struct PacketTagList::TagData *data)
112  : m_data (data)
113 {
114  NS_LOG_FUNCTION (this << data);
115 }
116 TypeId
118 {
119  return m_data->tid;
120 }
121 void
123 {
124  NS_LOG_FUNCTION (this << &tag);
125  NS_ASSERT (tag.GetInstanceTypeId () == m_data->tid);
126  tag.Deserialize (TagBuffer ((uint8_t*)m_data->data, (uint8_t*)m_data->data+PACKET_TAG_MAX_SIZE));
127 }
128 
129 
131 Packet::Copy (void) const
132 {
133  // we need to invoke the copy constructor directly
134  // rather than calling Create because the copy constructor
135  // is private.
136  NS_LOG_FUNCTION (this);
137  return Ptr<Packet> (new Packet (*this), false);
138 }
139 
141  : m_buffer (),
142  m_byteTagList (),
143  m_packetTagList (),
144  /* The upper 32 bits of the packet id in
145  * metadata is for the system id. For non-
146  * distributed simulations, this is simply
147  * zero. The lower 32 bits are for the
148  * global UID
149  */
150  m_metadata (static_cast<uint64_t> (Simulator::GetSystemId ()) << 32 | m_globalUid, 0),
151  m_nixVector (0)
152 {
153  NS_LOG_FUNCTION (this);
154  m_globalUid++;
155 }
156 
157 Packet::Packet (const Packet &o)
158  : m_buffer (o.m_buffer),
159  m_byteTagList (o.m_byteTagList),
160  m_packetTagList (o.m_packetTagList),
161  m_metadata (o.m_metadata)
162 {
163  o.m_nixVector ? m_nixVector = o.m_nixVector->Copy ()
164  : m_nixVector = 0;
165 }
166 
167 Packet &
168 Packet::operator = (const Packet &o)
169 {
170  if (this == &o)
171  {
172  return *this;
173  }
174  m_buffer = o.m_buffer;
175  m_byteTagList = o.m_byteTagList;
176  m_packetTagList = o.m_packetTagList;
177  m_metadata = o.m_metadata;
178  o.m_nixVector ? m_nixVector = o.m_nixVector->Copy ()
179  : m_nixVector = 0;
180  return *this;
181 }
182 
183 Packet::Packet (uint32_t size)
184  : m_buffer (size),
185  m_byteTagList (),
186  m_packetTagList (),
187  /* The upper 32 bits of the packet id in
188  * metadata is for the system id. For non-
189  * distributed simulations, this is simply
190  * zero. The lower 32 bits are for the
191  * global UID
192  */
193  m_metadata (static_cast<uint64_t> (Simulator::GetSystemId ()) << 32 | m_globalUid, size),
194  m_nixVector (0)
195 {
196  NS_LOG_FUNCTION (this << size);
197  m_globalUid++;
198 }
199 Packet::Packet (uint8_t const *buffer, uint32_t size, bool magic)
200  : m_buffer (0, false),
201  m_byteTagList (),
202  m_packetTagList (),
203  m_metadata (0,0),
204  m_nixVector (0)
205 {
206  NS_LOG_FUNCTION (this << &buffer << size << magic);
207  NS_ASSERT (magic);
208  Deserialize (buffer, size);
209 }
210 
211 Packet::Packet (uint8_t const*buffer, uint32_t size)
212  : m_buffer (),
213  m_byteTagList (),
214  m_packetTagList (),
215  /* The upper 32 bits of the packet id in
216  * metadata is for the system id. For non-
217  * distributed simulations, this is simply
218  * zero. The lower 32 bits are for the
219  * global UID
220  */
221  m_metadata (static_cast<uint64_t> (Simulator::GetSystemId ()) << 32 | m_globalUid, size),
222  m_nixVector (0)
223 {
224  NS_LOG_FUNCTION (this << &buffer << size);
225  m_globalUid++;
226  m_buffer.AddAtStart (size);
227  Buffer::Iterator i = m_buffer.Begin ();
228  i.Write (buffer, size);
229 }
230 
231 Packet::Packet (const Buffer &buffer, const ByteTagList &byteTagList,
232  const PacketTagList &packetTagList, const PacketMetadata &metadata)
233  : m_buffer (buffer),
234  m_byteTagList (byteTagList),
235  m_packetTagList (packetTagList),
236  m_metadata (metadata),
237  m_nixVector (0)
238 {
239  NS_LOG_FUNCTION (this << &buffer << &byteTagList << &packetTagList << &metadata);
240 }
241 
242 Ptr<Packet>
243 Packet::CreateFragment (uint32_t start, uint32_t length) const
244 {
245  NS_LOG_FUNCTION (this << start << length);
246  Buffer buffer = m_buffer.CreateFragment (start, length);
247  NS_ASSERT (m_buffer.GetSize () >= start + length);
248  uint32_t end = m_buffer.GetSize () - (start + length);
249  PacketMetadata metadata = m_metadata.CreateFragment (start, end);
250  // again, call the constructor directly rather than
251  // through Create because it is private.
252  return Ptr<Packet> (new Packet (buffer, m_byteTagList, m_packetTagList, metadata), false);
253 }
254 
255 void
256 Packet::SetNixVector (Ptr<NixVector> nixVector)
257 {
258  NS_LOG_FUNCTION (this << nixVector);
259  m_nixVector = nixVector;
260 }
261 
262 Ptr<NixVector>
263 Packet::GetNixVector (void) const
264 {
265  NS_LOG_FUNCTION (this);
266  return m_nixVector;
267 }
268 
269 void
270 Packet::AddHeader (const Header &header)
271 {
272  uint32_t size = header.GetSerializedSize ();
273  NS_LOG_FUNCTION (this << &header);
274  uint32_t orgStart = m_buffer.GetCurrentStartOffset ();
275  bool resized = m_buffer.AddAtStart (size);
276  if (resized)
277  {
278  m_byteTagList.AddAtStart (m_buffer.GetCurrentStartOffset () + size - orgStart,
279  m_buffer.GetCurrentStartOffset () + size);
280  }
281  header.Serialize (m_buffer.Begin ());
282  m_metadata.AddHeader (header, size);
283 }
284 uint32_t
286 {
287  uint32_t deserialized = header.Deserialize (m_buffer.Begin ());
288  NS_LOG_FUNCTION (this << &header);
289  m_buffer.RemoveAtStart (deserialized);
290  m_metadata.RemoveHeader (header, deserialized);
291  return deserialized;
292 }
293 uint32_t
294 Packet::PeekHeader (Header &header) const
295 {
296  uint32_t deserialized = header.Deserialize (m_buffer.Begin ());
297  NS_LOG_FUNCTION (this << &header);
298  return deserialized;
299 }
300 void
301 Packet::AddTrailer (const Trailer &trailer)
302 {
303  uint32_t size = trailer.GetSerializedSize ();
304  NS_LOG_FUNCTION (this << &trailer);
305  uint32_t orgStart = m_buffer.GetCurrentStartOffset ();
306  bool resized = m_buffer.AddAtEnd (size);
307  if (resized)
308  {
309  m_byteTagList.AddAtEnd (m_buffer.GetCurrentStartOffset () - orgStart,
310  m_buffer.GetCurrentEndOffset () - size);
311  }
312  Buffer::Iterator end = m_buffer.End ();
313  trailer.Serialize (end);
314  m_metadata.AddTrailer (trailer, size);
315 }
316 uint32_t
318 {
319  uint32_t deserialized = trailer.Deserialize (m_buffer.End ());
320  NS_LOG_FUNCTION (this << &trailer);
321  m_buffer.RemoveAtEnd (deserialized);
322  m_metadata.RemoveTrailer (trailer, deserialized);
323  return deserialized;
324 }
325 uint32_t
327 {
328  uint32_t deserialized = trailer.Deserialize (m_buffer.End ());
329  NS_LOG_FUNCTION (this << &trailer);
330  return deserialized;
331 }
332 
333 void
335 {
336  NS_LOG_FUNCTION (this << packet);
337  uint32_t aStart = m_buffer.GetCurrentStartOffset ();
338  uint32_t bEnd = packet->m_buffer.GetCurrentEndOffset ();
339  m_buffer.AddAtEnd (packet->m_buffer);
340  uint32_t appendPrependOffset = m_buffer.GetCurrentEndOffset () - packet->m_buffer.GetSize ();
341  m_byteTagList.AddAtEnd (m_buffer.GetCurrentStartOffset () - aStart,
342  appendPrependOffset);
343  ByteTagList copy = packet->m_byteTagList;
344  copy.AddAtStart (m_buffer.GetCurrentEndOffset () - bEnd,
345  appendPrependOffset);
346  m_byteTagList.Add (copy);
347  m_metadata.AddAtEnd (packet->m_metadata);
348 }
349 void
350 Packet::AddPaddingAtEnd (uint32_t size)
351 {
352  NS_LOG_FUNCTION (this << size);
353  uint32_t orgEnd = m_buffer.GetCurrentEndOffset ();
354  bool resized = m_buffer.AddAtEnd (size);
355  if (resized)
356  {
357  m_byteTagList.AddAtEnd (m_buffer.GetCurrentEndOffset () - orgEnd,
358  m_buffer.GetCurrentEndOffset () - size);
359  }
360  m_metadata.AddPaddingAtEnd (size);
361 }
362 void
363 Packet::RemoveAtEnd (uint32_t size)
364 {
365  NS_LOG_FUNCTION (this << size);
366  m_buffer.RemoveAtEnd (size);
367  m_metadata.RemoveAtEnd (size);
368 }
369 void
370 Packet::RemoveAtStart (uint32_t size)
371 {
372  NS_LOG_FUNCTION (this << size);
373  m_buffer.RemoveAtStart (size);
374  m_metadata.RemoveAtStart (size);
375 }
376 
377 void
379 {
380  NS_LOG_FUNCTION (this);
381  m_byteTagList.RemoveAll ();
382 }
383 
384 uint8_t const *
385 Packet::PeekData (void) const
386 {
387  NS_LOG_FUNCTION (this);
388  uint32_t oldStart = m_buffer.GetCurrentStartOffset ();
389  uint8_t const * data = m_buffer.PeekData ();
390  uint32_t newStart = m_buffer.GetCurrentStartOffset ();
391 
392  // Update tag offsets if buffer offsets were changed
393  const_cast<ByteTagList &>(m_byteTagList).AddAtStart (newStart - oldStart, newStart);
394  return data;
395 }
396 
397 uint32_t
398 Packet::CopyData (uint8_t *buffer, uint32_t size) const
399 {
400  NS_LOG_FUNCTION (this << &buffer << size);
401  return m_buffer.CopyData (buffer, size);
402 }
403 
404 void
405 Packet::CopyData (std::ostream *os, uint32_t size) const
406 {
407  NS_LOG_FUNCTION (this << &os << size);
408  return m_buffer.CopyData (os, size);
409 }
410 
411 uint64_t
412 Packet::GetUid (void) const
413 {
414  NS_LOG_FUNCTION (this);
415  return m_metadata.GetUid ();
416 }
417 
418 void
419 Packet::PrintByteTags (std::ostream &os) const
420 {
421  NS_LOG_FUNCTION (this << &os);
423  while (i.HasNext ())
424  {
425  ByteTagIterator::Item item = i.Next ();
426  os << item.GetTypeId ().GetName () << " [" << item.GetStart () << "-" << item.GetEnd () << "]";
427  Callback<ObjectBase *> constructor = item.GetTypeId ().GetConstructor ();
428  if (constructor.IsNull ())
429  {
430  if (i.HasNext ())
431  {
432  os << " ";
433  }
434  continue;
435  }
436  Tag *tag = dynamic_cast<Tag *> (constructor ());
437  NS_ASSERT (tag != 0);
438  os << " ";
439  item.GetTag (*tag);
440  tag->Print (os);
441  if (i.HasNext ())
442  {
443  os << " ";
444  }
445  delete tag;
446  }
447 }
448 
449 void
450 Packet::Print (std::ostream &os) const
451 {
452  NS_LOG_FUNCTION (this << &os);
453  PacketMetadata::ItemIterator i = m_metadata.BeginItem (m_buffer);
454  while (i.HasNext ())
455  {
456  PacketMetadata::Item item = i.Next ();
457  if (item.isFragment)
458  {
459  switch (item.type) {
460  case PacketMetadata::Item::PAYLOAD:
461  os << "Payload";
462  break;
463  case PacketMetadata::Item::HEADER:
464  case PacketMetadata::Item::TRAILER:
465  os << item.tid.GetName ();
466  break;
467  }
468  os << " Fragment [" << item.currentTrimedFromStart<<":"
469  << (item.currentTrimedFromStart + item.currentSize) << "]";
470  }
471  else
472  {
473  switch (item.type) {
474  case PacketMetadata::Item::PAYLOAD:
475  os << "Payload (size=" << item.currentSize << ")";
476  break;
477  case PacketMetadata::Item::HEADER:
478  case PacketMetadata::Item::TRAILER:
479  os << item.tid.GetName () << " (";
480  {
481  NS_ASSERT (item.tid.HasConstructor ());
482  Callback<ObjectBase *> constructor = item.tid.GetConstructor ();
483  NS_ASSERT (!constructor.IsNull ());
484  ObjectBase *instance = constructor ();
485  NS_ASSERT (instance != 0);
486  Chunk *chunk = dynamic_cast<Chunk *> (instance);
487  NS_ASSERT (chunk != 0);
488  chunk->Deserialize (item.current);
489  chunk->Print (os);
490  delete chunk;
491  }
492  os << ")";
493  break;
494  }
495  }
496  if (i.HasNext ())
497  {
498  os << " ";
499  }
500  }
501 #if 0
502  // The code below will work only if headers and trailers
503  // define the right attributes which is not the case for
504  // now. So, as a temporary measure, we use the
505  // headers' and trailers' Print method as shown above.
506  PacketMetadata::ItemIterator i = m_metadata.BeginItem (m_buffer);
507  while (i.HasNext ())
508  {
509  PacketMetadata::Item item = i.Next ();
510  if (item.isFragment)
511  {
512  switch (item.type) {
513  case PacketMetadata::Item::PAYLOAD:
514  os << "Payload";
515  break;
516  case PacketMetadata::Item::HEADER:
517  case PacketMetadata::Item::TRAILER:
518  os << item.tid.GetName ();
519  break;
520  }
521  os << " Fragment [" << item.currentTrimedFromStart<<":"
522  << (item.currentTrimedFromStart + item.currentSize) << "]";
523  }
524  else
525  {
526  switch (item.type) {
527  case PacketMetadata::Item::PAYLOAD:
528  os << "Payload (size=" << item.currentSize << ")";
529  break;
530  case PacketMetadata::Item::HEADER:
531  case PacketMetadata::Item::TRAILER:
532  os << item.tid.GetName () << "(";
533  {
534  NS_ASSERT (item.tid.HasConstructor ());
535  Callback<ObjectBase *> constructor = item.tid.GetConstructor ();
536  NS_ASSERT (constructor.IsNull ());
537  ObjectBase *instance = constructor ();
538  NS_ASSERT (instance != 0);
539  Chunk *chunk = dynamic_cast<Chunk *> (instance);
540  NS_ASSERT (chunk != 0);
541  chunk->Deserialize (item.current);
542  for (uint32_t j = 0; j < item.tid.GetAttributeN (); j++)
543  {
544  std::string attrName = item.tid.GetAttributeName (j);
545  std::string value;
546  bool ok = chunk->GetAttribute (attrName, value);
547  NS_ASSERT (ok);
548  os << attrName << "=" << value;
549  if ((j + 1) < item.tid.GetAttributeN ())
550  {
551  os << ",";
552  }
553  }
554  }
555  os << ")";
556  break;
557  }
558  }
559  if (i.HasNext ())
560  {
561  os << " ";
562  }
563  }
564 #endif
565 }
566 
568 Packet::BeginItem (void) const
569 {
570  NS_LOG_FUNCTION (this);
571  return m_metadata.BeginItem (m_buffer);
572 }
573 
574 void
576 {
578  PacketMetadata::Enable ();
579 }
580 
581 void
583 {
585  PacketMetadata::EnableChecking ();
586 }
587 
588 uint32_t Packet::GetSerializedSize (void) const
589 {
590  NS_LOG_FUNCTION (this);
591  uint32_t size = 0;
592 
593  if (m_nixVector)
594  {
595  // increment total size by the size of the nix-vector
596  // ensuring 4-byte boundary
597  size += ((m_nixVector->GetSerializedSize () + 3) & (~3));
598 
599  // add 4-bytes for entry of total length of nix-vector
600  size += 4;
601  }
602  else
603  {
604  // if no nix-vector, still have to add 4-bytes
605  // to account for the entry of total size for
606  // nix-vector in the buffer
607  size += 4;
608  }
609 
610  //Tag size
611  //XXX
612  //size += m_tags.GetSerializedSize ();
613 
614  // increment total size by size of meta-data
615  // ensuring 4-byte boundary
616  size += ((m_metadata.GetSerializedSize () + 3) & (~3));
617 
618  // add 4-bytes for entry of total length of meta-data
619  size += 4;
620 
621  // increment total size by size of buffer
622  // ensuring 4-byte boundary
623  size += ((m_buffer.GetSerializedSize () + 3) & (~3));
624 
625  // add 4-bytes for entry of total length of buffer
626  size += 4;
627 
628  return size;
629 }
630 
631 uint32_t
632 Packet::Serialize (uint8_t* buffer, uint32_t maxSize) const
633 {
634  NS_LOG_FUNCTION (this << &buffer << maxSize);
635  uint32_t* p = reinterpret_cast<uint32_t *> (buffer);
636  uint32_t size = 0;
637 
638  // if nix-vector exists, serialize it
639  if (m_nixVector)
640  {
641  uint32_t nixSize = m_nixVector->GetSerializedSize ();
642  if (size + nixSize <= maxSize)
643  {
644  // put the total length of nix-vector in the
645  // buffer. this includes 4-bytes for total
646  // length itself
647  *p++ = nixSize + 4;
648  size += nixSize;
649 
650  // serialize the nix-vector
651  uint32_t serialized =
652  m_nixVector->Serialize (p, nixSize);
653  if (serialized)
654  {
655  // increment p by nixSize bytes
656  // ensuring 4-byte boundary
657  p += ((nixSize+3) & (~3)) / 4;
658  }
659  else
660  {
661  return 0;
662  }
663  }
664  else
665  {
666  return 0;
667  }
668  }
669  else
670  {
671  // no nix vector, set zero length,
672  // ie 4-bytes, since it must include
673  // length for itself
674  if (size + 4 <= maxSize)
675  {
676  size += 4;
677  *p++ = 4;
678  }
679  else
680  {
681  return 0;
682  }
683  }
684 
685  // Serialize Tags
686  // XXX
687 
688  // Serialize Metadata
689  uint32_t metaSize = m_metadata.GetSerializedSize ();
690  if (size + metaSize <= maxSize)
691  {
692  // put the total length of metadata in the
693  // buffer. this includes 4-bytes for total
694  // length itself
695  *p++ = metaSize + 4;
696  size += metaSize;
697 
698  // serialize the metadata
699  uint32_t serialized =
700  m_metadata.Serialize (reinterpret_cast<uint8_t *> (p), metaSize);
701  if (serialized)
702  {
703  // increment p by metaSize bytes
704  // ensuring 4-byte boundary
705  p += ((metaSize+3) & (~3)) / 4;
706  }
707  else
708  {
709  return 0;
710  }
711  }
712  else
713  {
714  return 0;
715  }
716 
717  // Serialize the packet contents
718  uint32_t bufSize = m_buffer.GetSerializedSize ();
719  if (size + bufSize <= maxSize)
720  {
721  // put the total length of the buffer in the
722  // buffer. this includes 4-bytes for total
723  // length itself
724  *p++ = bufSize + 4;
725  size += bufSize;
726 
727  // serialize the buffer
728  uint32_t serialized =
729  m_buffer.Serialize (reinterpret_cast<uint8_t *> (p), bufSize);
730  if (serialized)
731  {
732  // increment p by bufSize bytes
733  // ensuring 4-byte boundary
734  p += ((bufSize+3) & (~3)) / 4;
735  }
736  else
737  {
738  return 0;
739  }
740  }
741  else
742  {
743  return 0;
744  }
745 
746  // Serialized successfully
747  return 1;
748 }
749 
750 uint32_t
751 Packet::Deserialize (const uint8_t* buffer, uint32_t size)
752 {
753  NS_LOG_FUNCTION (this << &buffer << size);
754 
755  const uint32_t* p = reinterpret_cast<const uint32_t *> (buffer);
756 
757  // read nix-vector
758  NS_ASSERT (!m_nixVector);
759  uint32_t nixSize = *p++;
760 
761  // if size less than nixSize, the buffer
762  // will be overrun, assert
763  NS_ASSERT (size >= nixSize);
764 
765  size -= nixSize;
766 
767  if (nixSize > 4)
768  {
769  Ptr<NixVector> nix = Create<NixVector> ();
770  uint32_t nixDeserialized = nix->Deserialize (p, nixSize);
771  if (!nixDeserialized)
772  {
773  // nix-vector not deserialized
774  // completely
775  return 0;
776  }
777  m_nixVector = nix;
778  // increment p by nixSize ensuring
779  // 4-byte boundary
780  p += ((((nixSize - 4) + 3) & (~3)) / 4);
781  }
782 
783  // read tags
784  //XXX
785  //uint32_t tagsDeserialized = m_tags.Deserialize (buffer.Begin ());
786  //buffer.RemoveAtStart (tagsDeserialized);
787 
788  // read metadata
789  uint32_t metaSize = *p++;
790 
791  // if size less than metaSize, the buffer
792  // will be overrun, assert
793  NS_ASSERT (size >= metaSize);
794 
795  size -= metaSize;
796 
797  uint32_t metadataDeserialized =
798  m_metadata.Deserialize (reinterpret_cast<const uint8_t *> (p), metaSize);
799  if (!metadataDeserialized)
800  {
801  // meta-data not deserialized
802  // completely
803  return 0;
804  }
805  // increment p by metaSize ensuring
806  // 4-byte boundary
807  p += ((((metaSize - 4) + 3) & (~3)) / 4);
808 
809  // read buffer contents
810  uint32_t bufSize = *p++;
811 
812  // if size less than bufSize, the buffer
813  // will be overrun, assert
814  NS_ASSERT (size >= bufSize);
815 
816  size -= bufSize;
817 
818  uint32_t bufferDeserialized =
819  m_buffer.Deserialize (reinterpret_cast<const uint8_t *> (p), bufSize);
820  if (!bufferDeserialized)
821  {
822  // buffer not deserialized
823  // completely
824  return 0;
825  }
826 
827  // return zero if did not deserialize the
828  // number of expected bytes
829  return (size == 0);
830 }
831 
832 void
833 Packet::AddByteTag (const Tag &tag) const
834 {
835  NS_LOG_FUNCTION (this << &tag);
836  ByteTagList *list = const_cast<ByteTagList *> (&m_byteTagList);
837  TagBuffer buffer = list->Add (tag.GetInstanceTypeId (), tag.GetSerializedSize (),
838  m_buffer.GetCurrentStartOffset (),
839  m_buffer.GetCurrentEndOffset ());
840  tag.Serialize (buffer);
841 }
844 {
845  NS_LOG_FUNCTION (this);
846  return ByteTagIterator (m_byteTagList.Begin (m_buffer.GetCurrentStartOffset (), m_buffer.GetCurrentEndOffset ()));
847 }
848 
849 bool
851 {
852  NS_LOG_FUNCTION (this << &tag);
853  TypeId tid = tag.GetInstanceTypeId ();
855  while (i.HasNext ())
856  {
857  ByteTagIterator::Item item = i.Next ();
858  if (tid == item.GetTypeId ())
859  {
860  item.GetTag (tag);
861  return true;
862  }
863  }
864  return false;
865 }
866 
867 void
868 Packet::AddPacketTag (const Tag &tag) const
869 {
870  NS_LOG_FUNCTION (this << &tag);
871  m_packetTagList.Add (tag);
872 }
873 bool
875 {
876  NS_LOG_FUNCTION (this << &tag);
877  bool found = m_packetTagList.Remove (tag);
878  return found;
879 }
880 bool
882 {
883  NS_LOG_FUNCTION (this << &tag);
884  bool found = m_packetTagList.Peek (tag);
885  return found;
886 }
887 void
889 {
890  NS_LOG_FUNCTION (this);
891  m_packetTagList.RemoveAll ();
892 }
893 
894 void
895 Packet::PrintPacketTags (std::ostream &os) const
896 {
897  NS_LOG_FUNCTION (this << &os);
899  while (i.HasNext ())
900  {
901  PacketTagIterator::Item item = i.Next ();
902  NS_ASSERT (item.GetTypeId ().HasConstructor ());
903  Callback<ObjectBase *> constructor = item.GetTypeId ().GetConstructor ();
904  NS_ASSERT (!constructor.IsNull ());
905  ObjectBase *instance = constructor ();
906  Tag *tag = dynamic_cast<Tag *> (instance);
907  NS_ASSERT (tag != 0);
908  item.GetTag (*tag);
909  tag->Print (os);
910  delete tag;
911  if (i.HasNext ())
912  {
913  os << " ";
914  }
915  }
916 }
917 
920 {
921  NS_LOG_FUNCTION (this);
922  return PacketTagIterator (m_packetTagList.Head ());
923 }
924 
925 std::ostream& operator<< (std::ostream& os, const Packet &packet)
926 {
927  packet.Print (os);
928  return os;
929 }
930 
931 } // namespace ns3
bool HasNext(void) const
Definition: packet.cc:69
Protocol header serialization and deserialization.
Definition: header.h:42
uint32_t RemoveHeader(Header &header)
Definition: packet.cc:285
uint32_t GetAttributeN(void) const
Definition: type-id.cc:592
bool FindFirstMatchingByteTag(Tag &tag) const
Definition: packet.cc:850
bool Remove(Tag &tag)
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
void PrintPacketTags(std::ostream &os) const
Definition: packet.cc:895
Control the scheduling of simulation events.
Definition: simulator.h:58
Callback template class.
Definition: callback.h:369
void RemoveAtEnd(uint32_t end)
Definition: buffer.cc:497
void RemoveAtStart(uint32_t start)
Definition: buffer.cc:452
virtual uint32_t GetSerializedSize(void) const =0
automatically resized byte buffer
Definition: buffer.h:92
Ptr< NixVector > Copy(void) const
Definition: nix-vector.cc:71
void AddPacketTag(const Tag &tag) const
Definition: packet.cc:868
uint64_t GetUid(void) const
Definition: packet.cc:412
keep track of the tags stored in a packet.
Definition: byte-tag-list.h:68
#define NS_ASSERT(condition)
Definition: assert.h:64
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
TagBuffer Add(TypeId tid, uint32_t bufferSize, int32_t start, int32_t end)
uint32_t GetSerializedSize(void) const
Definition: buffer.cc:570
#define NS_LOG_FUNCTION_NOARGS()
Definition: log.h:275
implement the ns-3 type and attribute system
Definition: object-base.h:55
void Print(std::ostream &os) const
Definition: packet.cc:450
network packets
Definition: packet.h:203
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72
PacketTagIterator GetPacketTagIterator(void) const
Definition: packet.cc:919
iterator in a Buffer instance
Definition: buffer.h:98
Callback< ObjectBase * > GetConstructor(void) const
Definition: type-id.cc:576
bool HasConstructor(void) const
Definition: type-id.cc:526
void GetTag(Tag &tag) const
Definition: packet.cc:122
Ptr< Packet > CreateFragment(uint32_t start, uint32_t length) const
Definition: packet.cc:243
uint32_t PeekTrailer(Trailer &trailer)
Definition: packet.cc:326
void AddAtEnd(Ptr< const Packet > packet)
Definition: packet.cc:334
uint32_t Deserialize(const uint8_t *buffer, uint32_t size)
Definition: buffer.cc:660
uint8_t const * PeekData(void) const NS_DEPRECATED
Definition: packet.cc:385
bool PeekPacketTag(Tag &tag) const
Definition: packet.cc:881
void RemoveAllPacketTags(void)
Definition: packet.cc:888
bool HasNext(void) const
Definition: packet.cc:96
void RemoveAtStart(uint32_t size)
Definition: packet.cc:370
static void EnablePrinting(void)
Definition: packet.cc:575
PacketMetadata CreateFragment(uint32_t start, uint32_t end) const
uint32_t Serialize(uint32_t *buffer, uint32_t maxSize) const
Definition: nix-vector.cc:224
uint32_t GetSerializedSize(void) const
Definition: nix-vector.cc:213
Buffer::Iterator End(void) const
Definition: buffer.h:881
static void EnableChecking(void)
Definition: packet.cc:582
uint8_t const * PeekData(void) const
Definition: buffer.cc:729
void AddPaddingAtEnd(uint32_t size)
Definition: packet.cc:350
virtual void Serialize(Buffer::Iterator start) const =0
ByteTagIterator GetByteTagIterator(void) const
Definition: packet.cc:843
void CopyData(std::ostream *os, uint32_t size) const
Definition: buffer.cc:739
virtual uint32_t Deserialize(Buffer::Iterator end)=0
Item Next(void)
Definition: packet.cc:74
uint32_t GetEnd(void) const
Definition: packet.cc:45
Iterator over the set of 'packet' tags in a packet.
Definition: packet.h:113
void PrintByteTags(std::ostream &os) const
Definition: packet.cc:419
void AddAtEnd(int32_t adjustment, int32_t appendOffset)
Buffer::Iterator Begin(void) const
Definition: buffer.h:875
virtual uint32_t Deserialize(Buffer::Iterator start)=0
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:43
Ptr< Packet > Copy(void) const
Definition: packet.cc:131
uint32_t PeekHeader(Header &header) const
Definition: packet.cc:294
Protocol trailer serialization and deserialization.
Definition: trailer.h:40
virtual void Serialize(TagBuffer i) const =0
tag a set of bytes in a packet
Definition: tag.h:36
virtual uint32_t GetSerializedSize(void) const =0
PacketMetadata::ItemIterator BeginItem(void) const
Definition: packet.cc:568
void AddTrailer(const Trailer &trailer)
Definition: packet.cc:301
void RemoveAtEnd(uint32_t size)
Definition: packet.cc:363
Iterator over the set of tags in a packet.
Definition: packet.h:50
virtual void Deserialize(TagBuffer i)=0
uint32_t RemoveTrailer(Trailer &trailer)
Definition: packet.cc:317
std::string GetName(void) const
Definition: type-id.cc:518
TypeId GetTypeId(void) const
Definition: packet.cc:34
void GetAttribute(std::string name, AttributeValue &value) const
Definition: object-base.cc:198
uint32_t GetSize(void) const
Definition: buffer.h:869
TypeId GetTypeId(void) const
Definition: packet.cc:117
Buffer CreateFragment(uint32_t start, uint32_t length) const
Definition: buffer.cc:533
bool AddAtEnd(uint32_t end)
Definition: buffer.cc:356
void GetTag(Tag &tag) const
Definition: packet.cc:51
uint32_t Serialize(uint8_t *buffer, uint32_t maxSize) const
Definition: buffer.cc:590
ByteTagList::Iterator Begin(int32_t offsetStart, int32_t offsetEnd) const
#define PACKET_TAG_MAX_SIZE
Tag maximum size The maximum size (in bytes) of a Tag is stored in this constant. ...
read and write tag data
Definition: tag-buffer.h:51
uint32_t GetStart(void) const
Definition: packet.cc:39
uint32_t GetSerializedSize(void) const
Definition: packet.cc:588
virtual TypeId GetInstanceTypeId(void) const =0
bool RemovePacketTag(Tag &tag)
Definition: packet.cc:874
void RemoveAllByteTags(void)
Definition: packet.cc:378
virtual uint32_t GetSerializedSize(void) const =0
void Write(uint8_t const *buffer, uint32_t size)
Definition: buffer.cc:978
uint32_t CopyData(uint8_t *buffer, uint32_t size) const
Definition: packet.cc:398
virtual void Serialize(Buffer::Iterator start) const =0
bool AddAtStart(uint32_t start)
Definition: buffer.cc:305
a unique identifier for an interface.
Definition: type-id.h:44
abstract base class for ns3::Header and ns3::Trailer
Definition: chunk.h:14
void AddHeader(const Header &header)
Definition: packet.cc:270
virtual void Print(std::ostream &os) const =0
void AddAtStart(int32_t adjustment, int32_t prependOffset)
handle packet metadata about packet headers and trailers
void AddByteTag(const Tag &tag) const
Definition: packet.cc:833