A Discrete-Event Network Simulator
API
packet-metadata-test.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 <cstdarg>
21 #include <iostream>
22 #include <sstream>
23 #include "ns3/test.h"
24 #include "ns3/header.h"
25 #include "ns3/trailer.h"
26 #include "ns3/packet.h"
27 #include "ns3/packet-metadata.h"
28 
29 using namespace ns3;
30 
31 namespace {
32 
41 class HistoryHeaderBase : public Header
42 {
43 public:
48  static TypeId GetTypeId (void);
54  bool IsOk (void) const;
55 protected:
59  void ReportError (void);
60 private:
61  bool m_ok;
62 };
63 
64 TypeId
65 HistoryHeaderBase::GetTypeId (void)
66 {
67  static TypeId tid = TypeId ("ns3::HistoryHeaderBase")
68  .SetParent<Header> ()
69  ;
70  return tid;
71 }
72 
73 HistoryHeaderBase::HistoryHeaderBase ()
74  : m_ok (true)
75 {
76 }
77 
78 bool
80 {
81  return m_ok;
82 }
83 void
85 {
86  m_ok = false;
87 }
88 
89 
98 template <int N>
100 {
101 public:
102  HistoryHeader ();
107  static TypeId GetTypeId (void);
108  virtual TypeId GetInstanceTypeId (void) const;
109  virtual void Print (std::ostream &os) const;
110  virtual uint32_t GetSerializedSize (void) const;
111  virtual void Serialize (Buffer::Iterator start) const;
112  virtual uint32_t Deserialize (Buffer::Iterator start);
113 };
114 
115 template <int N>
117  : HistoryHeaderBase ()
118 {
119 }
120 
121 template <int N>
122 TypeId
124 {
125  std::ostringstream oss;
126  oss << "ns3::HistoryHeader<"<<N<<">";
127  static TypeId tid = TypeId (oss.str ().c_str ())
128  .SetParent<HistoryHeaderBase> ()
130  ;
131  return tid;
132 }
133 
134 template <int N>
135 TypeId
137 {
138  return GetTypeId ();
139 }
140 template <int N>
141 void
142 HistoryHeader<N>::Print (std::ostream &os) const
143 {
144  NS_ASSERT (false);
145 }
146 template <int N>
147 uint32_t
149 {
150  return N;
151 }
152 template <int N>
153 void
155 {
156  start.WriteU8 (N, N);
157 }
158 template <int N>
159 uint32_t
161 {
162  for (int i = 0; i < N; i++)
163  {
164  if (start.ReadU8 () != N)
165  {
166  ReportError ();
167  }
168  }
169  return N;
170 }
171 
181 {
182 public:
187  static TypeId GetTypeId (void);
193  bool IsOk (void) const;
194 protected:
198  void ReportError (void);
199 private:
200  bool m_ok;
201 };
202 
203 TypeId
205 {
206  static TypeId tid = TypeId ("ns3::HistoryTrailerBase")
207  .SetParent<Trailer> ()
208  ;
209  return tid;
210 }
212  : m_ok (true)
213 {
214 }
215 bool
217 {
218  return m_ok;
219 }
220 void
222 {
223  m_ok = false;
224 }
225 
226 
235 template <int N>
237 {
238 public:
239  HistoryTrailer ();
240 
245  static TypeId GetTypeId (void);
246  virtual TypeId GetInstanceTypeId (void) const;
247  virtual void Print (std::ostream &os) const;
248  virtual uint32_t GetSerializedSize (void) const;
249  virtual void Serialize (Buffer::Iterator start) const;
250  virtual uint32_t Deserialize (Buffer::Iterator start);
251 };
252 
253 template <int N>
255 {
256 }
257 
258 template <int N>
259 TypeId
261 {
262  std::ostringstream oss;
263  oss << "ns3::HistoryTrailer<"<<N<<">";
264  static TypeId tid = TypeId (oss.str ().c_str ())
265  .SetParent<HistoryTrailerBase> ()
267  ;
268  return tid;
269 }
270 
271 template <int N>
272 TypeId
274 {
275  return GetTypeId ();
276 }
277 template <int N>
278 void
279 HistoryTrailer<N>::Print (std::ostream &os) const
280 {
281  NS_ASSERT (false);
282 }
283 template <int N>
284 uint32_t
286 {
287  return N;
288 }
289 template <int N>
290 void
292 {
293  start.Prev (N);
294  start.WriteU8 (N, N);
295 }
296 template <int N>
297 uint32_t
299 {
300  start.Prev (N);
301  for (int i = 0; i < N; i++)
302  {
303  if (start.ReadU8 () != N)
304  {
305  ReportError ();
306  }
307  }
308  return N;
309 }
310 
311 }
312 
319 class PacketMetadataTest : public TestCase {
320 public:
322  virtual ~PacketMetadataTest ();
331  void CheckHistory (Ptr<Packet> p, const char *file, int line, uint32_t n, ...);
332  virtual void DoRun (void);
333 private:
339  Ptr<Packet> DoAddHeader (Ptr<Packet> p);
340 };
341 
343  : TestCase ("Packet metadata")
344 {
345 }
346 
348 {
349 }
350 
351 void
352 PacketMetadataTest::CheckHistory (Ptr<Packet> p, const char *file, int line, uint32_t n, ...)
353 {
354  std::list<int> expected;
355  va_list ap;
356  va_start (ap, n);
357  for (uint32_t j = 0; j < n; j++)
358  {
359  int v = va_arg (ap, int);
360  expected.push_back (v);
361  }
362  va_end (ap);
363 
365  std::list<int> got;
366  while (k.HasNext ())
367  {
368  struct PacketMetadata::Item item = k.Next ();
369  if (item.isFragment || item.type == PacketMetadata::Item::PAYLOAD)
370  {
371  got.push_back (item.currentSize);
372  continue;
373  }
374  if (item.type == PacketMetadata::Item::HEADER)
375  {
376  Callback<ObjectBase *> constructor = item.tid.GetConstructor ();
377  HistoryHeaderBase *header = dynamic_cast<HistoryHeaderBase *> (constructor ());
378  if (header == 0)
379  {
380  goto error;
381  }
382  header->Deserialize (item.current);
383  if (!header->IsOk ())
384  {
385  delete header;
386  goto error;
387  }
388  delete header;
389  }
390  else if (item.type == PacketMetadata::Item::TRAILER)
391  {
392  Callback<ObjectBase *> constructor = item.tid.GetConstructor ();
393  HistoryTrailerBase *trailer = dynamic_cast<HistoryTrailerBase *> (constructor ());
394  if (trailer == 0)
395  {
396  goto error;
397  }
398  trailer->Deserialize (item.current);
399  if (!trailer->IsOk ())
400  {
401  delete trailer;
402  goto error;
403  }
404  delete trailer;
405  }
406  got.push_back (item.currentSize);
407  }
408 
409  for (std::list<int>::iterator i = got.begin (),
410  j = expected.begin ();
411  i != got.end (); i++, j++)
412  {
413  NS_ASSERT (j != expected.end ());
414  if (*j != *i)
415  {
416  goto error;
417  }
418  }
419  return;
420 error:
421  std::ostringstream failure;
422  failure << "PacketMetadata error. Got:\"";
423  for (std::list<int>::iterator i = got.begin ();
424  i != got.end (); i++)
425  {
426  failure << *i << ", ";
427  }
428  failure << "\", expected: \"";
429  for (std::list<int>::iterator j = expected.begin ();
430  j != expected.end (); j++)
431  {
432  failure << *j << ", ";
433  }
434  failure << "\"";
435  NS_TEST_ASSERT_MSG_EQ_INTERNAL (false, true, failure.str (), file, line);
436 }
437 
438 #define ADD_HEADER(p, n) \
439  { \
440  HistoryHeader<n> header; \
441  p->AddHeader (header); \
442  }
443 #define ADD_TRAILER(p, n) \
444  { \
445  HistoryTrailer<n> trailer; \
446  p->AddTrailer (trailer); \
447  }
448 #define REM_HEADER(p, n) \
449  { \
450  HistoryHeader<n> header; \
451  p->RemoveHeader (header); \
452  }
453 #define REM_TRAILER(p, n) \
454  { \
455  HistoryTrailer<n> trailer; \
456  p->RemoveTrailer (trailer); \
457  }
458 #define CHECK_HISTORY(p, ...) \
459  { \
460  CheckHistory (p, __FILE__, __LINE__, __VA_ARGS__); \
461  uint32_t size = p->GetSerializedSize (); \
462  uint8_t* buffer = new uint8_t[size]; \
463  p->Serialize (buffer, size); \
464  Ptr<Packet> otherPacket = Create<Packet> (buffer, size, true); \
465  delete [] buffer; \
466  CheckHistory (otherPacket, __FILE__, __LINE__, __VA_ARGS__); \
467  }
468 
469 
472 {
473  ADD_HEADER (p, 10);
474  return p;
475 }
476 
477 void
479 {
480  PacketMetadata::Enable ();
481 
482  Ptr<Packet> p = Create<Packet> (0);
483  Ptr<Packet> p1 = Create<Packet> (0);
484 
485  p = Create<Packet> (10);
486  ADD_TRAILER (p, 100);
487  CHECK_HISTORY (p, 2, 10, 100);
488 
489 
490  p = Create<Packet> (10);
491  ADD_HEADER (p, 1);
492  ADD_HEADER (p, 2);
493  ADD_HEADER (p, 3);
494  CHECK_HISTORY (p, 4,
495  3, 2, 1, 10);
496  ADD_HEADER (p, 5);
497  CHECK_HISTORY (p, 5,
498  5, 3, 2, 1, 10);
499  ADD_HEADER (p, 6);
500  CHECK_HISTORY (p, 6,
501  6, 5, 3, 2, 1, 10);
502 
503  p = Create<Packet> (10);
504  ADD_HEADER (p, 1);
505  ADD_HEADER (p, 2);
506  ADD_HEADER (p, 3);
507  REM_HEADER (p, 3);
508  CHECK_HISTORY (p, 3,
509  2, 1, 10);
510 
511  p = Create<Packet> (10);
512  ADD_HEADER (p, 1);
513  ADD_HEADER (p, 2);
514  ADD_HEADER (p, 3);
515  REM_HEADER (p, 3);
516  REM_HEADER (p, 2);
517  CHECK_HISTORY (p, 2,
518  1, 10);
519 
520  p = Create<Packet> (10);
521  ADD_HEADER (p, 1);
522  ADD_HEADER (p, 2);
523  ADD_HEADER (p, 3);
524  REM_HEADER (p, 3);
525  REM_HEADER (p, 2);
526  REM_HEADER (p, 1);
527  CHECK_HISTORY (p, 1, 10);
528 
529  p = Create<Packet> (10);
530  ADD_HEADER (p, 1);
531  ADD_HEADER (p, 2);
532  ADD_HEADER (p, 3);
533  p1 = p->Copy ();
534  REM_HEADER (p1, 3);
535  REM_HEADER (p1, 2);
536  REM_HEADER (p1, 1);
537  CHECK_HISTORY (p1, 1, 10);
538  CHECK_HISTORY (p, 4,
539  3, 2, 1, 10);
540  ADD_HEADER (p1, 1);
541  ADD_HEADER (p1, 2);
542  CHECK_HISTORY (p1, 3,
543  2, 1, 10);
544  CHECK_HISTORY (p, 4,
545  3, 2, 1, 10);
546  ADD_HEADER (p, 3);
547  CHECK_HISTORY (p, 5,
548  3, 3, 2, 1, 10);
549  ADD_TRAILER (p, 4);
550  CHECK_HISTORY (p, 6,
551  3, 3, 2, 1, 10, 4);
552  ADD_TRAILER (p, 5);
553  CHECK_HISTORY (p, 7,
554  3, 3, 2, 1, 10, 4, 5);
555  REM_HEADER (p, 3);
556  CHECK_HISTORY (p, 6,
557  3, 2, 1, 10, 4, 5);
558  REM_TRAILER (p, 5);
559  CHECK_HISTORY (p, 5,
560  3, 2, 1, 10, 4);
561  p1 = p->Copy ();
562  REM_TRAILER (p, 4);
563  CHECK_HISTORY (p, 4,
564  3, 2, 1, 10);
565  CHECK_HISTORY (p1, 5,
566  3, 2, 1, 10, 4);
567  p1->RemoveAtStart (3);
568  CHECK_HISTORY (p1, 4,
569  2, 1, 10, 4);
570  p1->RemoveAtStart (1);
571  CHECK_HISTORY (p1, 4,
572  1, 1, 10, 4);
573  p1->RemoveAtStart (1);
574  CHECK_HISTORY (p1, 3,
575  1, 10, 4);
576  p1->RemoveAtEnd (4);
577  CHECK_HISTORY (p1, 2,
578  1, 10);
579  p1->RemoveAtStart (1);
580  CHECK_HISTORY (p1, 1, 10);
581 
582  p = Create<Packet> (10);
583  ADD_HEADER (p, 8);
584  ADD_TRAILER (p, 8);
585  ADD_TRAILER (p, 8);
586  p->RemoveAtStart (8+10+8);
587  CHECK_HISTORY (p, 1, 8);
588 
589  p = Create<Packet> (10);
590  ADD_HEADER (p, 10);
591  ADD_HEADER (p, 8);
592  ADD_TRAILER (p, 6);
593  ADD_TRAILER (p, 7);
594  ADD_TRAILER (p, 9);
595  p->RemoveAtStart (5);
596  p->RemoveAtEnd (12);
597  CHECK_HISTORY (p, 5, 3, 10, 10, 6, 4);
598 
599  p = Create<Packet> (10);
600  ADD_HEADER (p, 10);
601  ADD_TRAILER (p, 6);
602  p->RemoveAtEnd (18);
603  ADD_TRAILER (p, 5);
604  ADD_HEADER (p, 3);
605  CHECK_HISTORY (p, 3, 3, 8, 5);
606  p->RemoveAtStart (12);
607  CHECK_HISTORY (p, 1, 4);
608  p->RemoveAtEnd (2);
609  CHECK_HISTORY (p, 1, 2);
610  ADD_HEADER (p, 10);
611  CHECK_HISTORY (p, 2, 10, 2);
612  p->RemoveAtEnd (5);
613  CHECK_HISTORY (p, 1, 7);
614 
615  Ptr<Packet> p2 = Create<Packet> (0);
616  Ptr<Packet> p3 = Create<Packet> (0);
617 
618  p = Create<Packet> (40);
619  ADD_HEADER (p, 5);
620  ADD_HEADER (p, 8);
621  CHECK_HISTORY (p, 3, 8, 5, 40);
622  p1 = p->CreateFragment (0, 5);
623  p2 = p->CreateFragment (5, 5);
624  p3 = p->CreateFragment (10, 43);
625  CHECK_HISTORY (p1, 1, 5);
626  CHECK_HISTORY (p2, 2, 3, 2);
627  CHECK_HISTORY (p3, 2, 3, 40);
628  p1->AddAtEnd (p2);
629  CHECK_HISTORY (p1, 2, 8, 2);
630  CHECK_HISTORY (p2, 2, 3, 2);
631  p1->AddAtEnd (p3);
632  CHECK_HISTORY (p1, 3, 8, 5, 40);
633  CHECK_HISTORY (p2, 2, 3, 2);
634  CHECK_HISTORY (p3, 2, 3, 40);
635  p1 = p->CreateFragment (0, 5);
636  CHECK_HISTORY (p1, 1, 5);
637 
638  p3 = Create<Packet> (50);
639  ADD_HEADER (p3, 8);
640  CHECK_HISTORY (p3, 2, 8, 50);
641  CHECK_HISTORY (p1, 1, 5);
642  p1->AddAtEnd (p3);
643  CHECK_HISTORY (p1, 3, 5, 8, 50);
644  ADD_HEADER (p1, 5);
645  CHECK_HISTORY (p1, 4, 5, 5, 8, 50);
646  ADD_TRAILER (p1, 2);
647  CHECK_HISTORY (p1, 5, 5, 5, 8, 50, 2);
648  REM_HEADER (p1, 5);
649  CHECK_HISTORY (p1, 4, 5, 8, 50, 2);
650  p1->RemoveAtEnd (60);
651  CHECK_HISTORY (p1, 1, 5);
652  p1->AddAtEnd (p2);
653  CHECK_HISTORY (p1, 2, 8, 2);
654  CHECK_HISTORY (p2, 2, 3, 2);
655 
656  p3 = Create<Packet> (40);
657  ADD_HEADER (p3, 5);
658  ADD_HEADER (p3, 5);
659  CHECK_HISTORY (p3, 3, 5, 5, 40);
660  p1 = p3->CreateFragment (0, 5);
661  p2 = p3->CreateFragment (5, 5);
662  CHECK_HISTORY (p1, 1, 5);
663  CHECK_HISTORY (p2, 1, 5);
664  p1->AddAtEnd (p2);
665  CHECK_HISTORY (p1, 2, 5, 5);
666 
667  p = Create<Packet> (0);
668  CHECK_HISTORY (p, 0);
669 
670  p3 = Create<Packet> (0);
671  ADD_HEADER (p3, 5);
672  ADD_HEADER (p3, 5);
673  CHECK_HISTORY (p3, 2, 5, 5);
674  p1 = p3->CreateFragment (0, 4);
675  p2 = p3->CreateFragment (9, 1);
676  CHECK_HISTORY (p1, 1, 4);
677  CHECK_HISTORY (p2, 1, 1);
678  p1->AddAtEnd (p2);
679  CHECK_HISTORY (p1, 2, 4, 1);
680 
681 
682  p = Create<Packet> (2000);
683  CHECK_HISTORY (p, 1, 2000);
684 
685  p = Create<Packet> ();
686  ADD_TRAILER (p, 10);
687  ADD_HEADER (p, 5);
688  p1 = p->CreateFragment (0, 8);
689  p2 = p->CreateFragment (8, 7);
690  p1->AddAtEnd (p2);
691  CHECK_HISTORY (p, 2, 5, 10);
692 
693  p = Create<Packet> ();
694  ADD_TRAILER (p, 10);
695  REM_TRAILER (p, 10);
696  ADD_TRAILER (p, 10);
697  CHECK_HISTORY (p, 1, 10);
698 
699  p = Create<Packet> ();
700  ADD_HEADER (p, 10);
701  REM_HEADER (p, 10);
702  ADD_HEADER (p, 10);
703  CHECK_HISTORY (p, 1, 10);
704 
705  p = Create<Packet> ();
706  ADD_HEADER (p, 10);
707  p = DoAddHeader (p);
708  CHECK_HISTORY (p, 2, 10, 10);
709 
710  p = Create<Packet> (10);
711  ADD_HEADER (p, 8);
712  ADD_TRAILER (p, 8);
713  ADD_TRAILER (p, 8);
714  p->RemoveAtStart (8+10+8);
715  CHECK_HISTORY (p, 1, 8);
716 
717  p = Create<Packet> (0);
718  ADD_HEADER (p, 8);
719  REM_HEADER (p, 8);
720  CHECK_HISTORY (p, 0);
721 
722  p = Create<Packet> (0);
723  ADD_TRAILER (p, 8);
724  REM_TRAILER (p, 8);
725  CHECK_HISTORY (p, 0);
726 
727  p = Create<Packet> (0);
728  ADD_HEADER (p, 8);
729  p->RemoveAtStart (8);
730  CHECK_HISTORY (p, 0);
731 
732  p = Create<Packet> (0);
733  ADD_HEADER (p, 8);
734  ADD_TRAILER (p, 8);
735  REM_TRAILER (p, 8);
736  REM_HEADER (p, 8);
737  CHECK_HISTORY (p, 0);
738 
739  p = Create<Packet> (0);
740  ADD_HEADER (p, 8);
741  ADD_TRAILER (p, 8);
742  REM_HEADER (p, 8);
743  REM_TRAILER (p, 8);
744  CHECK_HISTORY (p, 0);
745 
746  p = Create<Packet> (0);
747  ADD_HEADER (p, 8);
748  ADD_TRAILER (p, 8);
749  REM_TRAILER (p, 8);
750  p->RemoveAtStart (8);
751  CHECK_HISTORY (p, 0);
752 
753  p = Create<Packet> (0);
754  ADD_HEADER (p, 8);
755  ADD_TRAILER (p, 8);
756  REM_HEADER (p, 8);
757  p->RemoveAtEnd (8);
758  CHECK_HISTORY (p, 0);
759 
760  p = Create<Packet> (0);
761  ADD_HEADER (p, 8);
762  ADD_TRAILER (p, 8);
763  REM_TRAILER (p, 8);
764  p->RemoveAtEnd (8);
765  CHECK_HISTORY (p, 0);
766 
767  p = Create<Packet> (0);
768  ADD_HEADER (p, 8);
769  ADD_TRAILER (p, 8);
770  REM_HEADER (p, 8);
771  p->RemoveAtStart (8);
772  CHECK_HISTORY (p, 0);
773 
774  p = Create<Packet> (16383);
775  p = Create<Packet> (16384);
776 
777 
780  p = Create<Packet> (40);
781  p2 = p->CreateFragment (5, 5);
782  p3 = p->CreateFragment (10, 30);
783  ADD_HEADER (p2, 8);
784  ADD_HEADER (p3, 8);
785  REM_HEADER (p2, 8);
786  REM_HEADER (p3, 8);
787  p2->AddAtEnd (p3);
788 
789 
790  p = Create<Packet> (1000);
791  ADD_HEADER (p, 10);
792  ADD_TRAILER (p, 5);
793  p1 = p->Copy ();
794  ADD_HEADER (p1, 20);
795  REM_HEADER (p1, 20);
796  REM_TRAILER (p1, 5);
797  NS_TEST_EXPECT_MSG_EQ (p->GetSize (), 1015, "Correct size");
798 
799 
800  p = Create<Packet> (1510);
801  ADD_HEADER (p, 8);
802  ADD_HEADER (p, 25);
803  REM_HEADER (p, 25);
804  ADD_HEADER (p, 1);
805  p1 = p->CreateFragment (0, 1500);
806  p2 = p1->Copy ();
807  ADD_HEADER (p2, 24);
808  NS_TEST_EXPECT_MSG_EQ (p->GetSize (), 1519, "Correct size");
809 
810  p = Create<Packet> (1000);
811  ADD_HEADER (p, 2);
812  ADD_TRAILER (p, 3);
813  p1 = p->Copy ();
814  CHECK_HISTORY (p1, 3, 2, 1000, 3);
815  REM_HEADER (p, 2);
816  ADD_HEADER (p, 1);
817  CHECK_HISTORY (p, 3, 1, 1000, 3);
818  CHECK_HISTORY (p1, 3, 2, 1000, 3);
819 
820  p = Create<Packet> (200);
821  ADD_HEADER (p, 24);
822  p1 = p->CreateFragment (0, 100);
823  p2 = p->CreateFragment (100, 100);
824  p1->AddAtEnd (p2);
825 
826  p = Create<Packet> ();
827  ADD_HEADER (p, 10);
828  p1 = Create<Packet> ();
829  ADD_HEADER (p1, 11);
830  REM_HEADER (p1, 11);
831  p->AddAtEnd (p1);
832 
833  p = Create<Packet> (500);
834  CHECK_HISTORY (p, 1, 500);
835  ADD_HEADER (p, 10);
836  CHECK_HISTORY (p, 2, 10, 500);
837  REM_HEADER (p, 10);
838  CHECK_HISTORY (p, 1, 500);
839  p->RemoveAtEnd (10);
840  CHECK_HISTORY (p, 1, 490);
841 
842  p = Create<Packet> (500);
843  CHECK_HISTORY (p, 1, 500);
844  ADD_TRAILER (p, 10);
845  CHECK_HISTORY (p, 2, 500, 10);
846  REM_TRAILER (p, 10);
847  CHECK_HISTORY (p, 1, 500);
848  p->RemoveAtStart (10);
849  CHECK_HISTORY (p, 1, 490);
850 
853  p = Create<Packet> (500);
854  ADD_HEADER (p, 10);
855  ADD_HEADER (p, 20);
856  ADD_HEADER (p, 5);
857  CHECK_HISTORY (p, 4, 5, 20, 10, 500);
858  p1 = p->CreateFragment (0,6);
859  p2 = p->CreateFragment (6,535-6);
860  p1->AddAtEnd (p2);
861 
864  p = Create<Packet> (reinterpret_cast<const uint8_t*> ("hello world"), 11);
865  ADD_HEADER (p, 2);
866  CHECK_HISTORY (p, 2, 2, 11);
867  p1 = p->CreateFragment (0, 5);
868  CHECK_HISTORY (p1, 2, 2, 3);
869  p2 = p->CreateFragment (5, 8);
870  CHECK_HISTORY (p2, 1, 8);
871 
872  ADD_HEADER (p1, 8+2+2*6);
873  ADD_TRAILER (p1, 4);
874  CHECK_HISTORY (p1, 4, 22, 2, 3, 4);
875  ADD_HEADER (p2, 8+2+2*6);
876  ADD_TRAILER (p2, 4);
877  CHECK_HISTORY (p2, 3, 22, 8, 4);
878 
879  REM_TRAILER (p1, 4);
880  REM_HEADER (p1, 8+2+2*6);
881  CHECK_HISTORY (p1, 2, 2, 3);
882  REM_TRAILER (p2, 4);
883  REM_HEADER (p2, 8+2+2*6);
884  CHECK_HISTORY (p2, 1, 8);
885 
886  p3 = p1->Copy ();
887  CHECK_HISTORY (p3, 2, 2, 3);
888  p3->AddAtEnd (p2);
889  CHECK_HISTORY (p3, 2, 2, 11);
890 
891  CHECK_HISTORY (p, 2, 2, 11);
892  REM_HEADER (p, 2);
893  CHECK_HISTORY (p, 1, 11);
894  REM_HEADER (p3, 2);
895  CHECK_HISTORY (p3, 1, 11);
896 
897  uint8_t *buf = new uint8_t[p3->GetSize ()];
898  p3->CopyData (buf, p3->GetSize ());
899  std::string msg = std::string (reinterpret_cast<const char *>(buf),
900  p3->GetSize ());
901  delete [] buf;
902  NS_TEST_EXPECT_MSG_EQ (msg, std::string ("hello world"), "Could not find original data in received packet");
903 }
904 
905 
913 {
914 public:
916 };
917 
919  : TestSuite ("packet-metadata", UNIT)
920 {
921  AddTestCase (new PacketMetadataTest, TestCase::QUICK);
922 }
923 
Protocol header serialization and deserialization.
Definition: header.h:42
Packet Metadata TestSuite.
Callback< ObjectBase * > GetConstructor(void) const
Get the constructor callback.
Definition: type-id.cc:1061
Packet Metadata unit tests.
TypeId AddConstructor(void)
Record in this TypeId the fact that the default constructor is accessible.
Definition: type-id.h:638
Callback template class.
Definition: callback.h:1278
#define REM_TRAILER(p, n)
Buffer::Iterator current
an iterator which can be fed to Deserialize.
#define CHECK_HISTORY(p,...)
Ptr< Packet > DoAddHeader(Ptr< Packet > p)
Adds an header to the packet.
Template header-type class to check the proper header concatenation.
A suite of tests to run.
Definition: test.h:1343
static PacketMetadataTestSuite g_packetMetadataTest
Static variable for test initialization.
#define ADD_TRAILER(p, n)
Item Next(void)
Retrieve the next metadata item.
def start()
Definition: core.py:1855
structure describing a packet metadata item
bool isFragment
true: this is a fragmented header, trailer, or, payload.
TypeId tid
TypeId of Header or Trailer.
Ptr< Packet > CreateFragment(uint32_t start, uint32_t length) const
Create a new packet which contains a fragment of the original packet.
Definition: packet.cc:227
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
#define NS_TEST_EXPECT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report if not.
Definition: test.h:283
bool IsOk(void) const
Checks if the header has deserialization errors.
encapsulates test code
Definition: test.h:1153
Template trailer-type class to check the proper trailer concatenation.
virtual void DoRun(void)
Implementation to actually run this TestCase.
#define NS_TEST_ASSERT_MSG_EQ_INTERNAL(actual, limit, msg, file, line)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition: test.h:118
iterator in a Buffer instance
Definition: buffer.h:98
void AddAtEnd(Ptr< const Packet > packet)
Concatenate the input packet at the end of the current packet.
Definition: packet.cc:335
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
virtual TypeId GetInstanceTypeId(void) const
Get the most derived TypeId for this Object.
enum ns3::PacketMetadata::Item::ItemType type
metadata type
Iterator class for metadata items.
bool IsOk(void) const
Checks if the header has deserialization errors.
bool HasNext(void) const
Checks if there is another metadata item.
Protocol trailer serialization and deserialization.
Definition: trailer.h:40
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void ReportError(void)
Signal that an error has been found in deserialization.
Base header-type class to check the proper header concatenation.
void CheckHistory(Ptr< Packet > p, const char *file, int line, uint32_t n,...)
Checks the packet header and trailer history.
PacketMetadata::ItemIterator BeginItem(void) const
Returns an iterator which points to the first &#39;item&#39; stored in this buffer.
Definition: packet.cc:566
uint32_t currentSize
size of item.
void ReportError(void)
Signal that an error has been found in deserialization.
#define REM_HEADER(p, n)
virtual TypeId GetInstanceTypeId(void) const
Get the most derived TypeId for this Object.
Base trailer-type class to check the proper trailer concatenation.
a unique identifier for an interface.
Definition: type-id.h:58
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:923
#define ADD_HEADER(p, n)