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 ())
129  .AddConstructor<HistoryHeader<N> > ()
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 ())
266  .AddConstructor<HistoryTrailer<N> > ()
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 ();
329  void CheckHistory (Ptr<Packet> p, uint32_t n, ...);
330  virtual void DoRun (void);
331 private:
337  Ptr<Packet> DoAddHeader (Ptr<Packet> p);
338 };
339 
341  : TestCase ("Packet metadata")
342 {
343 }
344 
346 {
347 }
348 
349 void
351 {
352  std::list<int> expected;
353  va_list ap;
354  va_start (ap, n);
355  for (uint32_t j = 0; j < n; j++)
356  {
357  int v = va_arg (ap, int);
358  expected.push_back (v);
359  }
360  va_end (ap);
361 
363  std::list<int> got;
364  while (k.HasNext ())
365  {
366  struct PacketMetadata::Item item = k.Next ();
367  if (item.isFragment || item.type == PacketMetadata::Item::PAYLOAD)
368  {
369  got.push_back (item.currentSize);
370  continue;
371  }
372  if (item.type == PacketMetadata::Item::HEADER)
373  {
374  Callback<ObjectBase *> constructor = item.tid.GetConstructor ();
375  HistoryHeaderBase *header = dynamic_cast<HistoryHeaderBase *> (constructor ());
376  if (header == 0)
377  {
378  goto error;
379  }
380  header->Deserialize (item.current);
381  if (!header->IsOk ())
382  {
383  delete header;
384  goto error;
385  }
386  delete header;
387  }
388  else if (item.type == PacketMetadata::Item::TRAILER)
389  {
390  Callback<ObjectBase *> constructor = item.tid.GetConstructor ();
391  HistoryTrailerBase *trailer = dynamic_cast<HistoryTrailerBase *> (constructor ());
392  if (trailer == 0)
393  {
394  goto error;
395  }
396  trailer->Deserialize (item.current);
397  if (!trailer->IsOk ())
398  {
399  delete trailer;
400  goto error;
401  }
402  delete trailer;
403  }
404  got.push_back (item.currentSize);
405  }
406 
407  for (std::list<int>::iterator i = got.begin (),
408  j = expected.begin ();
409  i != got.end (); i++, j++)
410  {
411  NS_ASSERT (j != expected.end ());
412  if (*j != *i)
413  {
414  goto error;
415  }
416  }
417  return;
418 error:
419  std::ostringstream failure;
420  failure << "PacketMetadata error. Got:\"";
421  for (std::list<int>::iterator i = got.begin ();
422  i != got.end (); i++)
423  {
424  failure << *i << ", ";
425  }
426  failure << "\", expected: \"";
427  for (std::list<int>::iterator j = expected.begin ();
428  j != expected.end (); j++)
429  {
430  failure << *j << ", ";
431  }
432  failure << "\"";
433  NS_TEST_ASSERT_MSG_EQ (false, true, failure.str ());
434 }
435 
436 #define ADD_HEADER(p, n) \
437  { \
438  HistoryHeader<n> header; \
439  p->AddHeader (header); \
440  }
441 #define ADD_TRAILER(p, n) \
442  { \
443  HistoryTrailer<n> trailer; \
444  p->AddTrailer (trailer); \
445  }
446 #define REM_HEADER(p, n) \
447  { \
448  HistoryHeader<n> header; \
449  p->RemoveHeader (header); \
450  }
451 #define REM_TRAILER(p, n) \
452  { \
453  HistoryTrailer<n> trailer; \
454  p->RemoveTrailer (trailer); \
455  }
456 #define CHECK_HISTORY(p, ...) \
457  { \
458  CheckHistory (p, __VA_ARGS__); \
459  uint32_t size = p->GetSerializedSize (); \
460  uint8_t* buffer = new uint8_t[size]; \
461  p->Serialize (buffer, size); \
462  Ptr<Packet> otherPacket = Create<Packet> (buffer, size, true); \
463  delete [] buffer; \
464  CheckHistory (otherPacket, __VA_ARGS__); \
465  }
466 
467 
470 {
471  ADD_HEADER (p, 10);
472  return p;
473 }
474 
475 void
477 {
478  PacketMetadata::Enable ();
479 
480  Ptr<Packet> p = Create<Packet> (0);
481  Ptr<Packet> p1 = Create<Packet> (0);
482 
483  p = Create<Packet> (10);
484  ADD_TRAILER (p, 100);
485  CHECK_HISTORY (p, 2, 10, 100);
486 
487 
488  p = Create<Packet> (10);
489  ADD_HEADER (p, 1);
490  ADD_HEADER (p, 2);
491  ADD_HEADER (p, 3);
492  CHECK_HISTORY (p, 4,
493  3, 2, 1, 10);
494  ADD_HEADER (p, 5);
495  CHECK_HISTORY (p, 5,
496  5, 3, 2, 1, 10);
497  ADD_HEADER (p, 6);
498  CHECK_HISTORY (p, 6,
499  6, 5, 3, 2, 1, 10);
500 
501  p = Create<Packet> (10);
502  ADD_HEADER (p, 1);
503  ADD_HEADER (p, 2);
504  ADD_HEADER (p, 3);
505  REM_HEADER (p, 3);
506  CHECK_HISTORY (p, 3,
507  2, 1, 10);
508 
509  p = Create<Packet> (10);
510  ADD_HEADER (p, 1);
511  ADD_HEADER (p, 2);
512  ADD_HEADER (p, 3);
513  REM_HEADER (p, 3);
514  REM_HEADER (p, 2);
515  CHECK_HISTORY (p, 2,
516  1, 10);
517 
518  p = Create<Packet> (10);
519  ADD_HEADER (p, 1);
520  ADD_HEADER (p, 2);
521  ADD_HEADER (p, 3);
522  REM_HEADER (p, 3);
523  REM_HEADER (p, 2);
524  REM_HEADER (p, 1);
525  CHECK_HISTORY (p, 1, 10);
526 
527  p = Create<Packet> (10);
528  ADD_HEADER (p, 1);
529  ADD_HEADER (p, 2);
530  ADD_HEADER (p, 3);
531  p1 = p->Copy ();
532  REM_HEADER (p1, 3);
533  REM_HEADER (p1, 2);
534  REM_HEADER (p1, 1);
535  CHECK_HISTORY (p1, 1, 10);
536  CHECK_HISTORY (p, 4,
537  3, 2, 1, 10);
538  ADD_HEADER (p1, 1);
539  ADD_HEADER (p1, 2);
540  CHECK_HISTORY (p1, 3,
541  2, 1, 10);
542  CHECK_HISTORY (p, 4,
543  3, 2, 1, 10);
544  ADD_HEADER (p, 3);
545  CHECK_HISTORY (p, 5,
546  3, 3, 2, 1, 10);
547  ADD_TRAILER (p, 4);
548  CHECK_HISTORY (p, 6,
549  3, 3, 2, 1, 10, 4);
550  ADD_TRAILER (p, 5);
551  CHECK_HISTORY (p, 7,
552  3, 3, 2, 1, 10, 4, 5);
553  REM_HEADER (p, 3);
554  CHECK_HISTORY (p, 6,
555  3, 2, 1, 10, 4, 5);
556  REM_TRAILER (p, 5);
557  CHECK_HISTORY (p, 5,
558  3, 2, 1, 10, 4);
559  p1 = p->Copy ();
560  REM_TRAILER (p, 4);
561  CHECK_HISTORY (p, 4,
562  3, 2, 1, 10);
563  CHECK_HISTORY (p1, 5,
564  3, 2, 1, 10, 4);
565  p1->RemoveAtStart (3);
566  CHECK_HISTORY (p1, 4,
567  2, 1, 10, 4);
568  p1->RemoveAtStart (1);
569  CHECK_HISTORY (p1, 4,
570  1, 1, 10, 4);
571  p1->RemoveAtStart (1);
572  CHECK_HISTORY (p1, 3,
573  1, 10, 4);
574  p1->RemoveAtEnd (4);
575  CHECK_HISTORY (p1, 2,
576  1, 10);
577  p1->RemoveAtStart (1);
578  CHECK_HISTORY (p1, 1, 10);
579 
580  p = Create<Packet> (10);
581  ADD_HEADER (p, 8);
582  ADD_TRAILER (p, 8);
583  ADD_TRAILER (p, 8);
584  p->RemoveAtStart (8+10+8);
585  CHECK_HISTORY (p, 1, 8);
586 
587  p = Create<Packet> (10);
588  ADD_HEADER (p, 10);
589  ADD_HEADER (p, 8);
590  ADD_TRAILER (p, 6);
591  ADD_TRAILER (p, 7);
592  ADD_TRAILER (p, 9);
593  p->RemoveAtStart (5);
594  p->RemoveAtEnd (12);
595  CHECK_HISTORY (p, 5, 3, 10, 10, 6, 4);
596 
597  p = Create<Packet> (10);
598  ADD_HEADER (p, 10);
599  ADD_TRAILER (p, 6);
600  p->RemoveAtEnd (18);
601  ADD_TRAILER (p, 5);
602  ADD_HEADER (p, 3);
603  CHECK_HISTORY (p, 3, 3, 8, 5);
604  p->RemoveAtStart (12);
605  CHECK_HISTORY (p, 1, 4);
606  p->RemoveAtEnd (2);
607  CHECK_HISTORY (p, 1, 2);
608  ADD_HEADER (p, 10);
609  CHECK_HISTORY (p, 2, 10, 2);
610  p->RemoveAtEnd (5);
611  CHECK_HISTORY (p, 1, 7);
612 
613  Ptr<Packet> p2 = Create<Packet> (0);
614  Ptr<Packet> p3 = Create<Packet> (0);
615 
616  p = Create<Packet> (40);
617  ADD_HEADER (p, 5);
618  ADD_HEADER (p, 8);
619  CHECK_HISTORY (p, 3, 8, 5, 40);
620  p1 = p->CreateFragment (0, 5);
621  p2 = p->CreateFragment (5, 5);
622  p3 = p->CreateFragment (10, 43);
623  CHECK_HISTORY (p1, 1, 5);
624  CHECK_HISTORY (p2, 2, 3, 2);
625  CHECK_HISTORY (p3, 2, 3, 40);
626  p1->AddAtEnd (p2);
627  CHECK_HISTORY (p1, 2, 8, 2);
628  CHECK_HISTORY (p2, 2, 3, 2);
629  p1->AddAtEnd (p3);
630  CHECK_HISTORY (p1, 3, 8, 5, 40);
631  CHECK_HISTORY (p2, 2, 3, 2);
632  CHECK_HISTORY (p3, 2, 3, 40);
633  p1 = p->CreateFragment (0, 5);
634  CHECK_HISTORY (p1, 1, 5);
635 
636  p3 = Create<Packet> (50);
637  ADD_HEADER (p3, 8);
638  CHECK_HISTORY (p3, 2, 8, 50);
639  CHECK_HISTORY (p1, 1, 5);
640  p1->AddAtEnd (p3);
641  CHECK_HISTORY (p1, 3, 5, 8, 50);
642  ADD_HEADER (p1, 5);
643  CHECK_HISTORY (p1, 4, 5, 5, 8, 50);
644  ADD_TRAILER (p1, 2);
645  CHECK_HISTORY (p1, 5, 5, 5, 8, 50, 2);
646  REM_HEADER (p1, 5);
647  CHECK_HISTORY (p1, 4, 5, 8, 50, 2);
648  p1->RemoveAtEnd (60);
649  CHECK_HISTORY (p1, 1, 5);
650  p1->AddAtEnd (p2);
651  CHECK_HISTORY (p1, 2, 8, 2);
652  CHECK_HISTORY (p2, 2, 3, 2);
653 
654  p3 = Create<Packet> (40);
655  ADD_HEADER (p3, 5);
656  ADD_HEADER (p3, 5);
657  CHECK_HISTORY (p3, 3, 5, 5, 40);
658  p1 = p3->CreateFragment (0, 5);
659  p2 = p3->CreateFragment (5, 5);
660  CHECK_HISTORY (p1, 1, 5);
661  CHECK_HISTORY (p2, 1, 5);
662  p1->AddAtEnd (p2);
663  CHECK_HISTORY (p1, 2, 5, 5);
664 
665  p = Create<Packet> (0);
666  CHECK_HISTORY (p, 0);
667 
668  p3 = Create<Packet> (0);
669  ADD_HEADER (p3, 5);
670  ADD_HEADER (p3, 5);
671  CHECK_HISTORY (p3, 2, 5, 5);
672  p1 = p3->CreateFragment (0, 4);
673  p2 = p3->CreateFragment (9, 1);
674  CHECK_HISTORY (p1, 1, 4);
675  CHECK_HISTORY (p2, 1, 1);
676  p1->AddAtEnd (p2);
677  CHECK_HISTORY (p1, 2, 4, 1);
678 
679 
680  p = Create<Packet> (2000);
681  CHECK_HISTORY (p, 1, 2000);
682 
683  p = Create<Packet> ();
684  ADD_TRAILER (p, 10);
685  ADD_HEADER (p, 5);
686  p1 = p->CreateFragment (0, 8);
687  p2 = p->CreateFragment (8, 7);
688  p1->AddAtEnd (p2);
689  CHECK_HISTORY (p, 2, 5, 10);
690 
691  p = Create<Packet> ();
692  ADD_TRAILER (p, 10);
693  REM_TRAILER (p, 10);
694  ADD_TRAILER (p, 10);
695  CHECK_HISTORY (p, 1, 10);
696 
697  p = Create<Packet> ();
698  ADD_HEADER (p, 10);
699  REM_HEADER (p, 10);
700  ADD_HEADER (p, 10);
701  CHECK_HISTORY (p, 1, 10);
702 
703  p = Create<Packet> ();
704  ADD_HEADER (p, 10);
705  p = DoAddHeader (p);
706  CHECK_HISTORY (p, 2, 10, 10);
707 
708  p = Create<Packet> (10);
709  ADD_HEADER (p, 8);
710  ADD_TRAILER (p, 8);
711  ADD_TRAILER (p, 8);
712  p->RemoveAtStart (8+10+8);
713  CHECK_HISTORY (p, 1, 8);
714 
715  p = Create<Packet> (0);
716  ADD_HEADER (p, 8);
717  REM_HEADER (p, 8);
718  CHECK_HISTORY (p, 0);
719 
720  p = Create<Packet> (0);
721  ADD_TRAILER (p, 8);
722  REM_TRAILER (p, 8);
723  CHECK_HISTORY (p, 0);
724 
725  p = Create<Packet> (0);
726  ADD_HEADER (p, 8);
727  p->RemoveAtStart (8);
728  CHECK_HISTORY (p, 0);
729 
730  p = Create<Packet> (0);
731  ADD_HEADER (p, 8);
732  ADD_TRAILER (p, 8);
733  REM_TRAILER (p, 8);
734  REM_HEADER (p, 8);
735  CHECK_HISTORY (p, 0);
736 
737  p = Create<Packet> (0);
738  ADD_HEADER (p, 8);
739  ADD_TRAILER (p, 8);
740  REM_HEADER (p, 8);
741  REM_TRAILER (p, 8);
742  CHECK_HISTORY (p, 0);
743 
744  p = Create<Packet> (0);
745  ADD_HEADER (p, 8);
746  ADD_TRAILER (p, 8);
747  REM_TRAILER (p, 8);
748  p->RemoveAtStart (8);
749  CHECK_HISTORY (p, 0);
750 
751  p = Create<Packet> (0);
752  ADD_HEADER (p, 8);
753  ADD_TRAILER (p, 8);
754  REM_HEADER (p, 8);
755  p->RemoveAtEnd (8);
756  CHECK_HISTORY (p, 0);
757 
758  p = Create<Packet> (0);
759  ADD_HEADER (p, 8);
760  ADD_TRAILER (p, 8);
761  REM_TRAILER (p, 8);
762  p->RemoveAtEnd (8);
763  CHECK_HISTORY (p, 0);
764 
765  p = Create<Packet> (0);
766  ADD_HEADER (p, 8);
767  ADD_TRAILER (p, 8);
768  REM_HEADER (p, 8);
769  p->RemoveAtStart (8);
770  CHECK_HISTORY (p, 0);
771 
772  p = Create<Packet> (16383);
773  p = Create<Packet> (16384);
774 
775 
778  p = Create<Packet> (40);
779  p2 = p->CreateFragment (5, 5);
780  p3 = p->CreateFragment (10, 30);
781  ADD_HEADER (p2, 8);
782  ADD_HEADER (p3, 8);
783  REM_HEADER (p2, 8);
784  REM_HEADER (p3, 8);
785  p2->AddAtEnd (p3);
786 
787 
788  p = Create<Packet> (1000);
789  ADD_HEADER (p, 10);
790  ADD_TRAILER (p, 5);
791  p1 = p->Copy ();
792  ADD_HEADER (p1, 20);
793  REM_HEADER (p1, 20);
794  REM_TRAILER (p1, 5);
795  NS_TEST_EXPECT_MSG_EQ (p->GetSize (), 1015, "Correct size");
796 
797 
798  p = Create<Packet> (1510);
799  ADD_HEADER (p, 8);
800  ADD_HEADER (p, 25);
801  REM_HEADER (p, 25);
802  ADD_HEADER (p, 1);
803  p1 = p->CreateFragment (0, 1500);
804  p2 = p1->Copy ();
805  ADD_HEADER (p2, 24);
806  NS_TEST_EXPECT_MSG_EQ (p->GetSize (), 1519, "Correct size");
807 
808  p = Create<Packet> (1000);
809  ADD_HEADER (p, 2);
810  ADD_TRAILER (p, 3);
811  p1 = p->Copy ();
812  CHECK_HISTORY (p1, 3, 2, 1000, 3);
813  REM_HEADER (p, 2);
814  ADD_HEADER (p, 1);
815  CHECK_HISTORY (p, 3, 1, 1000, 3);
816  CHECK_HISTORY (p1, 3, 2, 1000, 3);
817 
818  p = Create<Packet> (200);
819  ADD_HEADER (p, 24);
820  p1 = p->CreateFragment (0, 100);
821  p2 = p->CreateFragment (100, 100);
822  p1->AddAtEnd (p2);
823 
824  p = Create<Packet> ();
825  ADD_HEADER (p, 10);
826  p1 = Create<Packet> ();
827  ADD_HEADER (p1, 11);
828  REM_HEADER (p1, 11);
829  p->AddAtEnd (p1);
830 
831  p = Create<Packet> (500);
832  CHECK_HISTORY (p, 1, 500);
833  ADD_HEADER (p, 10);
834  CHECK_HISTORY (p, 2, 10, 500);
835  REM_HEADER (p, 10);
836  CHECK_HISTORY (p, 1, 500);
837  p->RemoveAtEnd (10);
838  CHECK_HISTORY (p, 1, 490);
839 
840  p = Create<Packet> (500);
841  CHECK_HISTORY (p, 1, 500);
842  ADD_TRAILER (p, 10);
843  CHECK_HISTORY (p, 2, 500, 10);
844  REM_TRAILER (p, 10);
845  CHECK_HISTORY (p, 1, 500);
846  p->RemoveAtStart (10);
847  CHECK_HISTORY (p, 1, 490);
848 
851  p = Create<Packet> (500);
852  ADD_HEADER (p, 10);
853  ADD_HEADER (p, 20);
854  ADD_HEADER (p, 5);
855  CHECK_HISTORY (p, 4, 5, 20, 10, 500);
856  p1 = p->CreateFragment (0,6);
857  p2 = p->CreateFragment (6,535-6);
858  p1->AddAtEnd (p2);
859 
862  p = Create<Packet> (reinterpret_cast<const uint8_t*> ("hello world"), 11);
863  ADD_HEADER (p, 2);
864  CHECK_HISTORY (p, 2, 2, 11);
865  p1 = p->CreateFragment (0, 5);
866  CHECK_HISTORY (p1, 2, 2, 3);
867  p2 = p->CreateFragment (5, 8);
868  CHECK_HISTORY (p2, 1, 8);
869 
870  ADD_HEADER (p1, 8+2+2*6);
871  ADD_TRAILER (p1, 4);
872  CHECK_HISTORY (p1, 4, 22, 2, 3, 4);
873  ADD_HEADER (p2, 8+2+2*6);
874  ADD_TRAILER (p2, 4);
875  CHECK_HISTORY (p2, 3, 22, 8, 4);
876 
877  REM_TRAILER (p1, 4);
878  REM_HEADER (p1, 8+2+2*6);
879  CHECK_HISTORY (p1, 2, 2, 3);
880  REM_TRAILER (p2, 4);
881  REM_HEADER (p2, 8+2+2*6);
882  CHECK_HISTORY (p2, 1, 8);
883 
884  p3 = p1->Copy ();
885  CHECK_HISTORY (p3, 2, 2, 3);
886  p3->AddAtEnd (p2);
887  CHECK_HISTORY (p3, 2, 2, 11);
888 
889  CHECK_HISTORY (p, 2, 2, 11);
890  REM_HEADER (p, 2);
891  CHECK_HISTORY (p, 1, 11);
892  REM_HEADER (p3, 2);
893  CHECK_HISTORY (p3, 1, 11);
894 
895  uint8_t *buf = new uint8_t[p3->GetSize ()];
896  p3->CopyData (buf, p3->GetSize ());
897  std::string msg = std::string (reinterpret_cast<const char *>(buf),
898  p3->GetSize ());
899  delete [] buf;
900  NS_TEST_EXPECT_MSG_EQ (msg, std::string ("hello world"), "Could not find original data in received packet");
901 }
902 
903 
911 {
912 public:
914 };
915 
917  : TestSuite ("packet-metadata", UNIT)
918 {
919  AddTestCase (new PacketMetadataTest, TestCase::QUICK);
920 }
921 
Packet Metadata unit tests.
Ptr< Packet > DoAddHeader(Ptr< Packet > p)
Adds an header to the packet.
virtual void DoRun(void)
Implementation to actually run this TestCase.
void CheckHistory(Ptr< Packet > p, uint32_t n,...)
Checks the packet header and trailer history.
Packet Metadata TestSuite.
Base header-type class to check the proper header concatenation.
bool IsOk(void) const
Checks if the header has deserialization errors.
void ReportError(void)
Signal that an error has been found in deserialization.
Template header-type class to check the proper header concatenation.
virtual TypeId GetInstanceTypeId(void) const
Get the most derived TypeId for this Object.
Base trailer-type class to check the proper trailer concatenation.
void ReportError(void)
Signal that an error has been found in deserialization.
bool IsOk(void) const
Checks if the header has deserialization errors.
Template trailer-type class to check the proper trailer concatenation.
virtual TypeId GetInstanceTypeId(void) const
Get the most derived TypeId for this Object.
iterator in a Buffer instance
Definition: buffer.h:99
Callback template class.
Definition: callback.h:1279
Protocol header serialization and deserialization.
Definition: header.h:43
virtual uint32_t Deserialize(Buffer::Iterator start)=0
Deserialize the object from a buffer iterator.
void AddAtEnd(Ptr< const Packet > packet)
Concatenate the input packet at the end of the current packet.
Definition: packet.cc:335
uint32_t CopyData(uint8_t *buffer, uint32_t size) const
Copy the packet contents to a byte buffer.
Definition: packet.cc:378
void RemoveAtEnd(uint32_t size)
Remove size bytes from the end of the current packet.
Definition: packet.cc:355
void RemoveAtStart(uint32_t size)
Remove size bytes from the start of the current packet.
Definition: packet.cc:362
PacketMetadata::ItemIterator BeginItem(void) const
Returns an iterator which points to the first 'item' stored in this buffer.
Definition: packet.cc:566
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
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:121
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:856
Iterator class for metadata items.
encapsulates test code
Definition: test.h:994
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
A suite of tests to run.
Definition: test.h:1188
Protocol trailer serialization and deserialization.
Definition: trailer.h:41
a unique identifier for an interface.
Definition: type-id.h:59
Callback< ObjectBase * > GetConstructor(void) const
Get the constructor callback.
Definition: type-id.cc:1060
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:922
#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_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition: test.h:141
#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:240
Every class exported by the ns3 library is enclosed in the ns3 namespace.
def start()
Definition: core.py:1853
#define ADD_HEADER(p, n)
#define CHECK_HISTORY(p,...)
#define REM_TRAILER(p, n)
static PacketMetadataTestSuite g_packetMetadataTest
Static variable for test initialization.
#define REM_HEADER(p, n)
#define ADD_TRAILER(p, n)
structure describing a packet metadata item
TypeId tid
TypeId of Header or Trailer.
enum ns3::PacketMetadata::Item::ItemType type
metadata type
bool isFragment
true: this is a fragmented header, trailer, or, payload.
Buffer::Iterator current
an iterator which can be fed to Deserialize.
uint32_t currentSize
size of item.