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 
33 class HistoryHeaderBase : public Header
34 {
35 public:
36  static TypeId GetTypeId (void);
38  bool IsOk (void) const;
39 protected:
40  void ReportError (void);
41 private:
42  bool m_ok;
43 };
44 
45 TypeId
46 HistoryHeaderBase::GetTypeId (void)
47 {
48  static TypeId tid = TypeId ("ns3::HistoryHeaderBase")
49  .SetParent<Header> ()
50  ;
51  return tid;
52 }
53 
54 HistoryHeaderBase::HistoryHeaderBase ()
55  : m_ok (true)
56 {
57 }
58 
59 bool
61 {
62  return m_ok;
63 }
64 void
66 {
67  m_ok = false;
68 }
69 
70 
71 template <int N>
73 {
74 public:
75  HistoryHeader ();
76  static TypeId GetTypeId (void);
77  virtual TypeId GetInstanceTypeId (void) const;
78  virtual void Print (std::ostream &os) const;
79  virtual uint32_t GetSerializedSize (void) const;
80  virtual void Serialize (Buffer::Iterator start) const;
81  virtual uint32_t Deserialize (Buffer::Iterator start);
82 };
83 
84 template <int N>
87 {
88 }
89 
90 template <int N>
91 TypeId
93 {
94  std::ostringstream oss;
95  oss << "ns3::HistoryHeader<"<<N<<">";
96  static TypeId tid = TypeId (oss.str ().c_str ())
97  .SetParent<HistoryHeaderBase> ()
99  ;
100  return tid;
101 }
102 
103 template <int N>
104 TypeId
106 {
107  return GetTypeId ();
108 }
109 template <int N>
110 void
111 HistoryHeader<N>::Print (std::ostream &os) const
112 {
113  NS_ASSERT (false);
114 }
115 template <int N>
116 uint32_t
118 {
119  return N;
120 }
121 template <int N>
122 void
124 {
125  start.WriteU8 (N, N);
126 }
127 template <int N>
128 uint32_t
130 {
131  for (int i = 0; i < N; i++)
132  {
133  if (start.ReadU8 () != N)
134  {
135  ReportError ();
136  }
137  }
138  return N;
139 }
140 
142 {
143 public:
144  static TypeId GetTypeId (void);
146  bool IsOk (void) const;
147 protected:
148  void ReportError (void);
149 private:
150  bool m_ok;
151 };
152 
153 TypeId
155 {
156  static TypeId tid = TypeId ("ns3::HistoryTrailerBase")
157  .SetParent<Trailer> ()
158  ;
159  return tid;
160 }
162  : m_ok (true)
163 {
164 }
165 bool
167 {
168  return m_ok;
169 }
170 void
172 {
173  m_ok = false;
174 }
175 
176 
177 template <int N>
179 {
180 public:
181  HistoryTrailer ();
182 
183  static TypeId GetTypeId (void);
184  virtual TypeId GetInstanceTypeId (void) const;
185  virtual void Print (std::ostream &os) const;
186  virtual uint32_t GetSerializedSize (void) const;
187  virtual void Serialize (Buffer::Iterator start) const;
188  virtual uint32_t Deserialize (Buffer::Iterator start);
189 private:
190  bool m_ok;
191 };
192 
193 template <int N>
195 {
196 }
197 
198 template <int N>
199 TypeId
201 {
202  std::ostringstream oss;
203  oss << "ns3::HistoryTrailer<"<<N<<">";
204  static TypeId tid = TypeId (oss.str ().c_str ())
205  .SetParent<HistoryTrailerBase> ()
207  ;
208  return tid;
209 }
210 
211 template <int N>
212 TypeId
214 {
215  return GetTypeId ();
216 }
217 template <int N>
218 void
219 HistoryTrailer<N>::Print (std::ostream &os) const
220 {
221  NS_ASSERT (false);
222 }
223 template <int N>
224 uint32_t
226 {
227  return N;
228 }
229 template <int N>
230 void
232 {
233  start.Prev (N);
234  start.WriteU8 (N, N);
235 }
236 template <int N>
237 uint32_t
239 {
240  start.Prev (N);
241  for (int i = 0; i < N; i++)
242  {
243  if (start.ReadU8 () != N)
244  {
245  ReportError ();
246  }
247  }
248  return N;
249 }
250 
251 }
252 
253 class PacketMetadataTest : public TestCase {
254 public:
256  virtual ~PacketMetadataTest ();
257  void CheckHistory (Ptr<Packet> p, const char *file, int line, uint32_t n, ...);
258  virtual void DoRun (void);
259 private:
260  Ptr<Packet> DoAddHeader (Ptr<Packet> p);
261 };
262 
264  : TestCase ("Packet metadata")
265 {
266 }
267 
269 {
270 }
271 
272 void
273 PacketMetadataTest::CheckHistory (Ptr<Packet> p, const char *file, int line, uint32_t n, ...)
274 {
275  std::list<int> expected;
276  va_list ap;
277  va_start (ap, n);
278  for (uint32_t j = 0; j < n; j++)
279  {
280  int v = va_arg (ap, int);
281  expected.push_back (v);
282  }
283  va_end (ap);
284 
286  std::list<int> got;
287  while (k.HasNext ())
288  {
289  struct PacketMetadata::Item item = k.Next ();
290  if (item.isFragment || item.type == PacketMetadata::Item::PAYLOAD)
291  {
292  got.push_back (item.currentSize);
293  continue;
294  }
295  if (item.type == PacketMetadata::Item::HEADER)
296  {
297  Callback<ObjectBase *> constructor = item.tid.GetConstructor ();
298  HistoryHeaderBase *header = dynamic_cast<HistoryHeaderBase *> (constructor ());
299  if (header == 0)
300  {
301  goto error;
302  }
303  header->Deserialize (item.current);
304  if (!header->IsOk ())
305  {
306  delete header;
307  goto error;
308  }
309  delete header;
310  }
311  else if (item.type == PacketMetadata::Item::TRAILER)
312  {
313  Callback<ObjectBase *> constructor = item.tid.GetConstructor ();
314  HistoryTrailerBase *trailer = dynamic_cast<HistoryTrailerBase *> (constructor ());
315  if (trailer == 0)
316  {
317  goto error;
318  }
319  trailer->Deserialize (item.current);
320  if (!trailer->IsOk ())
321  {
322  delete trailer;
323  goto error;
324  }
325  delete trailer;
326  }
327  got.push_back (item.currentSize);
328  }
329 
330  for (std::list<int>::iterator i = got.begin (),
331  j = expected.begin ();
332  i != got.end (); i++, j++)
333  {
334  NS_ASSERT (j != expected.end ());
335  if (*j != *i)
336  {
337  goto error;
338  }
339  }
340  return;
341 error:
342  std::ostringstream failure;
343  failure << "PacketMetadata error. Got:\"";
344  for (std::list<int>::iterator i = got.begin ();
345  i != got.end (); i++)
346  {
347  failure << *i << ", ";
348  }
349  failure << "\", expected: \"";
350  for (std::list<int>::iterator j = expected.begin ();
351  j != expected.end (); j++)
352  {
353  failure << *j << ", ";
354  }
355  failure << "\"";
356  NS_TEST_ASSERT_MSG_EQ_INTERNAL (false, true, failure.str (), file, line);
357 }
358 
359 #define ADD_HEADER(p, n) \
360  { \
361  HistoryHeader<n> header; \
362  p->AddHeader (header); \
363  }
364 #define ADD_TRAILER(p, n) \
365  { \
366  HistoryTrailer<n> trailer; \
367  p->AddTrailer (trailer); \
368  }
369 #define REM_HEADER(p, n) \
370  { \
371  HistoryHeader<n> header; \
372  p->RemoveHeader (header); \
373  }
374 #define REM_TRAILER(p, n) \
375  { \
376  HistoryTrailer<n> trailer; \
377  p->RemoveTrailer (trailer); \
378  }
379 #define CHECK_HISTORY(p, ...) \
380  { \
381  CheckHistory (p, __FILE__, __LINE__, __VA_ARGS__); \
382  uint32_t size = p->GetSerializedSize (); \
383  uint8_t* buffer = new uint8_t[size]; \
384  p->Serialize (buffer, size); \
385  Ptr<Packet> otherPacket = Create<Packet> (buffer, size, true); \
386  delete [] buffer; \
387  CheckHistory (otherPacket, __FILE__, __LINE__, __VA_ARGS__); \
388  }
389 
390 
393 {
394  ADD_HEADER (p, 10);
395  return p;
396 }
397 
398 void
400 {
401  PacketMetadata::Enable ();
402 
403  Ptr<Packet> p = Create<Packet> (0);
404  Ptr<Packet> p1 = Create<Packet> (0);
405 
406  p = Create<Packet> (10);
407  ADD_TRAILER (p, 100);
408  CHECK_HISTORY (p, 2, 10, 100);
409 
410 
411  p = Create<Packet> (10);
412  ADD_HEADER (p, 1);
413  ADD_HEADER (p, 2);
414  ADD_HEADER (p, 3);
415  CHECK_HISTORY (p, 4,
416  3, 2, 1, 10);
417  ADD_HEADER (p, 5);
418  CHECK_HISTORY (p, 5,
419  5, 3, 2, 1, 10);
420  ADD_HEADER (p, 6);
421  CHECK_HISTORY (p, 6,
422  6, 5, 3, 2, 1, 10);
423 
424  p = Create<Packet> (10);
425  ADD_HEADER (p, 1);
426  ADD_HEADER (p, 2);
427  ADD_HEADER (p, 3);
428  REM_HEADER (p, 3);
429  CHECK_HISTORY (p, 3,
430  2, 1, 10);
431 
432  p = Create<Packet> (10);
433  ADD_HEADER (p, 1);
434  ADD_HEADER (p, 2);
435  ADD_HEADER (p, 3);
436  REM_HEADER (p, 3);
437  REM_HEADER (p, 2);
438  CHECK_HISTORY (p, 2,
439  1, 10);
440 
441  p = Create<Packet> (10);
442  ADD_HEADER (p, 1);
443  ADD_HEADER (p, 2);
444  ADD_HEADER (p, 3);
445  REM_HEADER (p, 3);
446  REM_HEADER (p, 2);
447  REM_HEADER (p, 1);
448  CHECK_HISTORY (p, 1, 10);
449 
450  p = Create<Packet> (10);
451  ADD_HEADER (p, 1);
452  ADD_HEADER (p, 2);
453  ADD_HEADER (p, 3);
454  p1 = p->Copy ();
455  REM_HEADER (p1, 3);
456  REM_HEADER (p1, 2);
457  REM_HEADER (p1, 1);
458  CHECK_HISTORY (p1, 1, 10);
459  CHECK_HISTORY (p, 4,
460  3, 2, 1, 10);
461  ADD_HEADER (p1, 1);
462  ADD_HEADER (p1, 2);
463  CHECK_HISTORY (p1, 3,
464  2, 1, 10);
465  CHECK_HISTORY (p, 4,
466  3, 2, 1, 10);
467  ADD_HEADER (p, 3);
468  CHECK_HISTORY (p, 5,
469  3, 3, 2, 1, 10);
470  ADD_TRAILER (p, 4);
471  CHECK_HISTORY (p, 6,
472  3, 3, 2, 1, 10, 4);
473  ADD_TRAILER (p, 5);
474  CHECK_HISTORY (p, 7,
475  3, 3, 2, 1, 10, 4, 5);
476  REM_HEADER (p, 3);
477  CHECK_HISTORY (p, 6,
478  3, 2, 1, 10, 4, 5);
479  REM_TRAILER (p, 5);
480  CHECK_HISTORY (p, 5,
481  3, 2, 1, 10, 4);
482  p1 = p->Copy ();
483  REM_TRAILER (p, 4);
484  CHECK_HISTORY (p, 4,
485  3, 2, 1, 10);
486  CHECK_HISTORY (p1, 5,
487  3, 2, 1, 10, 4);
488  p1->RemoveAtStart (3);
489  CHECK_HISTORY (p1, 4,
490  2, 1, 10, 4);
491  p1->RemoveAtStart (1);
492  CHECK_HISTORY (p1, 4,
493  1, 1, 10, 4);
494  p1->RemoveAtStart (1);
495  CHECK_HISTORY (p1, 3,
496  1, 10, 4);
497  p1->RemoveAtEnd (4);
498  CHECK_HISTORY (p1, 2,
499  1, 10);
500  p1->RemoveAtStart (1);
501  CHECK_HISTORY (p1, 1, 10);
502 
503  p = Create<Packet> (10);
504  ADD_HEADER (p, 8);
505  ADD_TRAILER (p, 8);
506  ADD_TRAILER (p, 8);
507  p->RemoveAtStart (8+10+8);
508  CHECK_HISTORY (p, 1, 8);
509 
510  p = Create<Packet> (10);
511  ADD_HEADER (p, 10);
512  ADD_HEADER (p, 8);
513  ADD_TRAILER (p, 6);
514  ADD_TRAILER (p, 7);
515  ADD_TRAILER (p, 9);
516  p->RemoveAtStart (5);
517  p->RemoveAtEnd (12);
518  CHECK_HISTORY (p, 5, 3, 10, 10, 6, 4);
519 
520  p = Create<Packet> (10);
521  ADD_HEADER (p, 10);
522  ADD_TRAILER (p, 6);
523  p->RemoveAtEnd (18);
524  ADD_TRAILER (p, 5);
525  ADD_HEADER (p, 3);
526  CHECK_HISTORY (p, 3, 3, 8, 5);
527  p->RemoveAtStart (12);
528  CHECK_HISTORY (p, 1, 4);
529  p->RemoveAtEnd (2);
530  CHECK_HISTORY (p, 1, 2);
531  ADD_HEADER (p, 10);
532  CHECK_HISTORY (p, 2, 10, 2);
533  p->RemoveAtEnd (5);
534  CHECK_HISTORY (p, 1, 7);
535 
536  Ptr<Packet> p2 = Create<Packet> (0);
537  Ptr<Packet> p3 = Create<Packet> (0);
538 
539  p = Create<Packet> (40);
540  ADD_HEADER (p, 5);
541  ADD_HEADER (p, 8);
542  CHECK_HISTORY (p, 3, 8, 5, 40);
543  p1 = p->CreateFragment (0, 5);
544  p2 = p->CreateFragment (5, 5);
545  p3 = p->CreateFragment (10, 43);
546  CHECK_HISTORY (p1, 1, 5);
547  CHECK_HISTORY (p2, 2, 3, 2);
548  CHECK_HISTORY (p3, 2, 3, 40);
549  p1->AddAtEnd (p2);
550  CHECK_HISTORY (p1, 2, 8, 2);
551  CHECK_HISTORY (p2, 2, 3, 2);
552  p1->AddAtEnd (p3);
553  CHECK_HISTORY (p1, 3, 8, 5, 40);
554  CHECK_HISTORY (p2, 2, 3, 2);
555  CHECK_HISTORY (p3, 2, 3, 40);
556  p1 = p->CreateFragment (0, 5);
557  CHECK_HISTORY (p1, 1, 5);
558 
559  p3 = Create<Packet> (50);
560  ADD_HEADER (p3, 8);
561  CHECK_HISTORY (p3, 2, 8, 50);
562  CHECK_HISTORY (p1, 1, 5);
563  p1->AddAtEnd (p3);
564  CHECK_HISTORY (p1, 3, 5, 8, 50);
565  ADD_HEADER (p1, 5);
566  CHECK_HISTORY (p1, 4, 5, 5, 8, 50);
567  ADD_TRAILER (p1, 2);
568  CHECK_HISTORY (p1, 5, 5, 5, 8, 50, 2);
569  REM_HEADER (p1, 5);
570  CHECK_HISTORY (p1, 4, 5, 8, 50, 2);
571  p1->RemoveAtEnd (60);
572  CHECK_HISTORY (p1, 1, 5);
573  p1->AddAtEnd (p2);
574  CHECK_HISTORY (p1, 2, 8, 2);
575  CHECK_HISTORY (p2, 2, 3, 2);
576 
577  p3 = Create<Packet> (40);
578  ADD_HEADER (p3, 5);
579  ADD_HEADER (p3, 5);
580  CHECK_HISTORY (p3, 3, 5, 5, 40);
581  p1 = p3->CreateFragment (0, 5);
582  p2 = p3->CreateFragment (5, 5);
583  CHECK_HISTORY (p1, 1, 5);
584  CHECK_HISTORY (p2, 1, 5);
585  p1->AddAtEnd (p2);
586  CHECK_HISTORY (p1, 2, 5, 5);
587 
588  p = Create<Packet> (0);
589  CHECK_HISTORY (p, 0);
590 
591  p3 = Create<Packet> (0);
592  ADD_HEADER (p3, 5);
593  ADD_HEADER (p3, 5);
594  CHECK_HISTORY (p3, 2, 5, 5);
595  p1 = p3->CreateFragment (0, 4);
596  p2 = p3->CreateFragment (9, 1);
597  CHECK_HISTORY (p1, 1, 4);
598  CHECK_HISTORY (p2, 1, 1);
599  p1->AddAtEnd (p2);
600  CHECK_HISTORY (p1, 2, 4, 1);
601 
602 
603  p = Create<Packet> (2000);
604  CHECK_HISTORY (p, 1, 2000);
605 
606  p = Create<Packet> ();
607  ADD_TRAILER (p, 10);
608  ADD_HEADER (p, 5);
609  p1 = p->CreateFragment (0, 8);
610  p2 = p->CreateFragment (8, 7);
611  p1->AddAtEnd (p2);
612  CHECK_HISTORY (p, 2, 5, 10);
613 
614  p = Create<Packet> ();
615  ADD_TRAILER (p, 10);
616  REM_TRAILER (p, 10);
617  ADD_TRAILER (p, 10);
618  CHECK_HISTORY (p, 1, 10);
619 
620  p = Create<Packet> ();
621  ADD_HEADER (p, 10);
622  REM_HEADER (p, 10);
623  ADD_HEADER (p, 10);
624  CHECK_HISTORY (p, 1, 10);
625 
626  p = Create<Packet> ();
627  ADD_HEADER (p, 10);
628  p = DoAddHeader (p);
629  CHECK_HISTORY (p, 2, 10, 10);
630 
631  p = Create<Packet> (10);
632  ADD_HEADER (p, 8);
633  ADD_TRAILER (p, 8);
634  ADD_TRAILER (p, 8);
635  p->RemoveAtStart (8+10+8);
636  CHECK_HISTORY (p, 1, 8);
637 
638  p = Create<Packet> (0);
639  ADD_HEADER (p, 8);
640  REM_HEADER (p, 8);
641  CHECK_HISTORY (p, 0);
642 
643  p = Create<Packet> (0);
644  ADD_TRAILER (p, 8);
645  REM_TRAILER (p, 8);
646  CHECK_HISTORY (p, 0);
647 
648  p = Create<Packet> (0);
649  ADD_HEADER (p, 8);
650  p->RemoveAtStart (8);
651  CHECK_HISTORY (p, 0);
652 
653  p = Create<Packet> (0);
654  ADD_HEADER (p, 8);
655  ADD_TRAILER (p, 8);
656  REM_TRAILER (p, 8);
657  REM_HEADER (p, 8);
658  CHECK_HISTORY (p, 0);
659 
660  p = Create<Packet> (0);
661  ADD_HEADER (p, 8);
662  ADD_TRAILER (p, 8);
663  REM_HEADER (p, 8);
664  REM_TRAILER (p, 8);
665  CHECK_HISTORY (p, 0);
666 
667  p = Create<Packet> (0);
668  ADD_HEADER (p, 8);
669  ADD_TRAILER (p, 8);
670  REM_TRAILER (p, 8);
671  p->RemoveAtStart (8);
672  CHECK_HISTORY (p, 0);
673 
674  p = Create<Packet> (0);
675  ADD_HEADER (p, 8);
676  ADD_TRAILER (p, 8);
677  REM_HEADER (p, 8);
678  p->RemoveAtEnd (8);
679  CHECK_HISTORY (p, 0);
680 
681  p = Create<Packet> (0);
682  ADD_HEADER (p, 8);
683  ADD_TRAILER (p, 8);
684  REM_TRAILER (p, 8);
685  p->RemoveAtEnd (8);
686  CHECK_HISTORY (p, 0);
687 
688  p = Create<Packet> (0);
689  ADD_HEADER (p, 8);
690  ADD_TRAILER (p, 8);
691  REM_HEADER (p, 8);
692  p->RemoveAtStart (8);
693  CHECK_HISTORY (p, 0);
694 
695  p = Create<Packet> (16383);
696  p = Create<Packet> (16384);
697 
698 
701  p = Create<Packet> (40);
702  p2 = p->CreateFragment (5, 5);
703  p3 = p->CreateFragment (10, 30);
704  ADD_HEADER (p2, 8);
705  ADD_HEADER (p3, 8);
706  REM_HEADER (p2, 8);
707  REM_HEADER (p3, 8);
708  p2->AddAtEnd (p3);
709 
710 
711  p = Create<Packet> (1000);
712  ADD_HEADER (p, 10);
713  ADD_TRAILER (p, 5);
714  p1 = p->Copy ();
715  ADD_HEADER (p1, 20);
716  REM_HEADER (p1, 20);
717  REM_TRAILER (p1, 5);
718  NS_TEST_EXPECT_MSG_EQ (p->GetSize (), 1015, "Correct size");
719 
720 
721  p = Create<Packet> (1510);
722  ADD_HEADER (p, 8);
723  ADD_HEADER (p, 25);
724  REM_HEADER (p, 25);
725  ADD_HEADER (p, 1);
726  p1 = p->CreateFragment (0, 1500);
727  p2 = p1->Copy ();
728  ADD_HEADER (p2, 24);
729  NS_TEST_EXPECT_MSG_EQ (p->GetSize (), 1519, "Correct size");
730 
731  p = Create<Packet> (1000);
732  ADD_HEADER (p, 2);
733  ADD_TRAILER (p, 3);
734  p1 = p->Copy ();
735  CHECK_HISTORY (p1, 3, 2, 1000, 3);
736  REM_HEADER (p, 2);
737  ADD_HEADER (p, 1);
738  CHECK_HISTORY (p, 3, 1, 1000, 3);
739  CHECK_HISTORY (p1, 3, 2, 1000, 3);
740 
741  p = Create<Packet> (200);
742  ADD_HEADER (p, 24);
743  p1 = p->CreateFragment (0, 100);
744  p2 = p->CreateFragment (100, 100);
745  p1->AddAtEnd (p2);
746 
747  p = Create<Packet> ();
748  ADD_HEADER (p, 10);
749  p1 = Create<Packet> ();
750  ADD_HEADER (p1, 11);
751  REM_HEADER (p1, 11);
752  p->AddAtEnd (p1);
753 
754  p = Create<Packet> (500);
755  CHECK_HISTORY (p, 1, 500);
756  ADD_HEADER (p, 10);
757  CHECK_HISTORY (p, 2, 10, 500);
758  REM_HEADER (p, 10);
759  CHECK_HISTORY (p, 1, 500);
760  p->RemoveAtEnd (10);
761  CHECK_HISTORY (p, 1, 490);
762 
763  p = Create<Packet> (500);
764  CHECK_HISTORY (p, 1, 500);
765  ADD_TRAILER (p, 10);
766  CHECK_HISTORY (p, 2, 500, 10);
767  REM_TRAILER (p, 10);
768  CHECK_HISTORY (p, 1, 500);
769  p->RemoveAtStart (10);
770  CHECK_HISTORY (p, 1, 490);
771 
774  p = Create<Packet> (500);
775  ADD_HEADER (p, 10);
776  ADD_HEADER (p, 20);
777  ADD_HEADER (p, 5);
778  CHECK_HISTORY (p, 4, 5, 20, 10, 500);
779  p1 = p->CreateFragment (0,6);
780  p2 = p->CreateFragment (6,535-6);
781  p1->AddAtEnd (p2);
782 
785  p = Create<Packet> (reinterpret_cast<const uint8_t*> ("hello world"), 11);
786  ADD_HEADER (p, 2);
787  CHECK_HISTORY (p, 2, 2, 11);
788  p1 = p->CreateFragment (0, 5);
789  CHECK_HISTORY (p1, 2, 2, 3);
790  p2 = p->CreateFragment (5, 8);
791  CHECK_HISTORY (p2, 1, 8);
792 
793  ADD_HEADER (p1, 8+2+2*6);
794  ADD_TRAILER (p1, 4);
795  CHECK_HISTORY (p1, 4, 22, 2, 3, 4);
796  ADD_HEADER (p2, 8+2+2*6);
797  ADD_TRAILER (p2, 4);
798  CHECK_HISTORY (p2, 3, 22, 8, 4);
799 
800  REM_TRAILER (p1, 4);
801  REM_HEADER (p1, 8+2+2*6);
802  CHECK_HISTORY (p1, 2, 2, 3);
803  REM_TRAILER (p2, 4);
804  REM_HEADER (p2, 8+2+2*6);
805  CHECK_HISTORY (p2, 1, 8);
806 
807  p3 = p1->Copy ();
808  CHECK_HISTORY (p3, 2, 2, 3);
809  p3->AddAtEnd (p2);
810  CHECK_HISTORY (p3, 2, 2, 11);
811 
812  CHECK_HISTORY (p, 2, 2, 11);
813  REM_HEADER (p, 2);
814  CHECK_HISTORY (p, 1, 11);
815  REM_HEADER (p3, 2);
816  CHECK_HISTORY (p3, 1, 11);
817 
818  uint8_t *buf = new uint8_t[p3->GetSize ()];
819  p3->CopyData (buf, p3->GetSize ());
820  std::string msg = std::string (reinterpret_cast<const char *>(buf),
821  p3->GetSize ());
822  delete [] buf;
823  NS_TEST_EXPECT_MSG_EQ (msg, std::string ("hello world"), "Could not find original data in received packet");
824 }
825 //-----------------------------------------------------------------------------
827 {
828 public:
830 };
831 
833  : TestSuite ("packet-metadata", UNIT)
834 {
835  AddTestCase (new PacketMetadataTest, TestCase::QUICK);
836 }
837 
Protocol header serialization and deserialization.
Definition: header.h:42
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)
A suite of tests to run.
Definition: test.h:1333
PacketMetadataTestSuite g_packetMetadataTest
#define ADD_TRAILER(p, n)
Item Next(void)
Retrieve the next metadata item.
def start()
Definition: core.py:1482
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:278
encapsulates test code
Definition: test.h:1147
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:113
iterator in a Buffer instance
Definition: buffer.h:98
Callback< ObjectBase * > GetConstructor(void) const
Get the constructor callback.
Definition: type-id.cc:1042
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:228
void AddAtEnd(Ptr< const Packet > packet)
Concatenate the input packet at the end of the current packet.
Definition: packet.cc:313
void AddTestCase(TestCase *testCase, enum TestDuration duration)
Add an individual child TestCase to this test suite.
Definition: test.cc:298
void Prev(void)
go backward by one byte
Definition: buffer.h:850
Iterator class for metadata items.
bool HasNext(void) const
Checks if there is another metadata item.
virtual TypeId GetInstanceTypeId(void) const
Get the most derived TypeId for this Object.
Protocol trailer serialization and deserialization.
Definition: trailer.h:40
Every class exported by the ns3 library is enclosed in the ns3 namespace.
PacketMetadata::ItemIterator BeginItem(void) const
Returns an iterator which points to the first 'item' stored in this buffer.
Definition: packet.cc:529
enum ns3::PacketMetadata::Item::@79 type
metadata type
virtual void Serialize(Buffer::Iterator start) const
void CheckHistory(Ptr< Packet > p, const char *file, int line, uint32_t n,...)
uint32_t currentSize
size of item.
#define REM_HEADER(p, n)
void WriteU8(uint8_t data)
Definition: buffer.h:868
uint8_t ReadU8(void)
Definition: buffer.h:1020
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:904
#define ADD_HEADER(p, n)