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.
Packet Metadata unit tests.
TypeId AddConstructor(void)
Record in this TypeId the fact that the default constructor is accessible.
Definition: type-id.h:652
Callback template class.
Definition: callback.h:1176
#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:1342
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:1806
structure describing a packet metadata item
bool isFragment
true: this is a fragmented header, trailer, or, payload.
TypeId tid
TypeId of Header or Trailer.
#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:285
virtual void Print(std::ostream &os) const =0
encapsulates test code
Definition: test.h:1155
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:120
iterator in a Buffer instance
Definition: buffer.h:98
Callback< ObjectBase * > GetConstructor(void) const
Get the constructor callback.
Definition: type-id.cc:1053
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
void AddAtEnd(Ptr< const Packet > packet)
Concatenate the input packet at the end of the current packet.
Definition: packet.cc:335
void Prev(void)
go backward by one byte
Definition: buffer.h:851
virtual void Print(std::ostream &os) const =0
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
enum ns3::PacketMetadata::Item::ItemType type
metadata type
Iterator class for metadata items.
virtual void Serialize(Buffer::Iterator start) const =0
bool HasNext(void) const
Checks if there is another metadata item.
virtual uint32_t Deserialize(Buffer::Iterator end)=0
virtual TypeId GetInstanceTypeId(void) const
Get the most derived TypeId for this Object.
virtual uint32_t Deserialize(Buffer::Iterator start)=0
Protocol trailer serialization and deserialization.
Definition: trailer.h:40
Every class exported by the ns3 library is enclosed in the ns3 namespace.
virtual uint32_t GetSerializedSize(void) const =0
PacketMetadata::ItemIterator BeginItem(void) const
Returns an iterator which points to the first &#39;item&#39; stored in this buffer.
Definition: packet.cc:566
void ReportError(void)
Signal that an error has been found in deserialization.
virtual void Serialize(Buffer::Iterator start) const
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.
uint32_t currentSize
size of item.
void ReportError(void)
Signal that an error has been found in deserialization.
#define REM_HEADER(p, n)
bool IsOk(void) const
Checks if the header has deserialization errors.
bool IsOk(void) const
Checks if the header has deserialization errors.
void WriteU8(uint8_t data)
Definition: buffer.h:869
virtual TypeId GetInstanceTypeId(void) const =0
Get the most derived TypeId for this Object.
virtual uint32_t GetSerializedSize(void) const =0
uint8_t ReadU8(void)
Definition: buffer.h:1021
virtual void Serialize(Buffer::Iterator start) const =0
Base trailer-type class to check the proper trailer concatenation.
virtual TypeId GetInstanceTypeId(void) const
Get the most derived TypeId for this Object.
a unique identifier for an interface.
Definition: type-id.h:58
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:915
#define ADD_HEADER(p, n)