A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
packetbb.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /* vim: set ts=2 sw=2 sta expandtab ai si cin: */
3 /*
4  * Copyright (c) 2009 Drexel University
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation;
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  * Author: Tom Wambold <tom5760@gmail.com>
20  */
21 /* These classes implement RFC 5444 - The Generalized Mobile Ad Hoc Network
22  * (MANET) Packet/PbbMessage Format
23  * See: http://tools.ietf.org/html/rfc5444 for details */
24 
25 #include "ns3/ipv4-address.h"
26 #include "ns3/ipv6-address.h"
27 #include "ns3/assert.h"
28 
29 #include "packetbb.h"
30 
31 static const uint8_t VERSION = 0;
32 /* Packet flags */
33 static const uint8_t PHAS_SEQ_NUM = 0x8;
34 static const uint8_t PHAS_TLV = 0x4;
35 
36 /* PbbMessage flags */
37 static const uint8_t MHAS_ORIG = 0x80;
38 static const uint8_t MHAS_HOP_LIMIT = 0x40;
39 static const uint8_t MHAS_HOP_COUNT = 0x20;
40 static const uint8_t MHAS_SEQ_NUM = 0x10;
41 
42 /* Address block flags */
43 static const uint8_t AHAS_HEAD = 0x80;
44 static const uint8_t AHAS_FULL_TAIL = 0x40;
45 static const uint8_t AHAS_ZERO_TAIL = 0x20;
46 static const uint8_t AHAS_SINGLE_PRE_LEN = 0x10;
47 static const uint8_t AHAS_MULTI_PRE_LEN = 0x08;
48 
49 /* TLV Flags */
50 static const uint8_t THAS_TYPE_EXT = 0x80;
51 static const uint8_t THAS_SINGLE_INDEX = 0x40;
52 static const uint8_t THAS_MULTI_INDEX = 0x20;
53 static const uint8_t THAS_VALUE = 0x10;
54 static const uint8_t THAS_EXT_LEN = 0x08;
55 static const uint8_t TIS_MULTIVALUE = 0x04;
56 
57 namespace ns3 {
58 
59 NS_OBJECT_ENSURE_REGISTERED (PbbPacket);
60 
62 {
63  return;
64 }
65 
67 {
68  Clear ();
69 }
70 
73 {
74  return m_tlvList.begin ();
75 }
76 
78 PbbTlvBlock::Begin (void) const
79 {
80  return m_tlvList.begin ();
81 }
82 
85 {
86  return m_tlvList.end ();
87 }
88 
90 PbbTlvBlock::End (void) const
91 {
92  return m_tlvList.end ();
93 }
94 
95 int
96 PbbTlvBlock::Size (void) const
97 {
98  return m_tlvList.size ();
99 }
100 
101 bool
102 PbbTlvBlock::Empty (void) const
103 {
104  return m_tlvList.empty ();
105 }
106 
108 PbbTlvBlock::Front (void) const
109 {
110  return m_tlvList.front ();
111 }
112 
114 PbbTlvBlock::Back (void) const
115 {
116  return m_tlvList.back ();
117 }
118 
119 void
121 {
122  m_tlvList.push_front (tlv);
123 }
124 
125 void
127 {
128  m_tlvList.pop_front ();
129 }
130 
131 void
133 {
134  m_tlvList.push_back (tlv);
135 }
136 
137 void
139 {
140  m_tlvList.pop_back ();
141 }
142 
145 {
146  return m_tlvList.insert (position, tlv);
147 }
148 
151 {
152  return m_tlvList.erase (position);
153 }
154 
157 {
158  return m_tlvList.erase (first, last);
159 }
160 
161 void
163 {
164  for (Iterator iter = Begin (); iter != End (); iter++)
165  {
166  *iter = 0;
167  }
168  m_tlvList.clear ();
169 }
170 
171 uint32_t
173 {
174  /* tlv size */
175  uint32_t size = 2;
176  for (ConstIterator iter = Begin (); iter != End (); iter++)
177  {
178  size += (*iter)->GetSerializedSize ();
179  }
180  return size;
181 }
182 
183 void
185 {
186  if (Empty ())
187  {
188  start.WriteHtonU16 (0);
189  return;
190  }
191 
192  /* We need to write the size of the TLV block in front, so save its
193  * position. */
194  Buffer::Iterator tlvsize = start;
195  start.Next (2);
196  for (ConstIterator iter = Begin (); iter != End (); iter++)
197  {
198  (*iter)->Serialize (start);
199  }
200  /* - 2 to not include the size field */
201  uint16_t size = start.GetDistanceFrom (tlvsize) - 2;
202  tlvsize.WriteHtonU16 (size);
203 }
204 
205 void
207 {
208  uint16_t size = start.ReadNtohU16 ();
209 
210  Buffer::Iterator tlvstart = start;
211  if (size > 0)
212  {
213  while (start.GetDistanceFrom (tlvstart) < size)
214  {
215  Ptr<PbbTlv> newtlv = Create<PbbTlv> ();
216  newtlv->Deserialize (start);
217  PushBack (newtlv);
218  }
219  }
220 }
221 
222 void
223 PbbTlvBlock::Print (std::ostream &os) const
224 {
225  Print (os, 0);
226 }
227 
228 void
229 PbbTlvBlock::Print (std::ostream &os, int level) const
230 {
231  std::string prefix = "";
232  for (int i = 0; i < level; i++)
233  {
234  prefix.append ("\t");
235  }
236 
237  os << prefix << "TLV Block {" << std::endl;
238  os << prefix << "\tsize = " << Size () << std::endl;
239  os << prefix << "\tmembers [" << std::endl;
240 
241  for (ConstIterator iter = Begin (); iter != End (); iter++)
242  {
243  (*iter)->Print (os, level+2);
244  }
245 
246  os << prefix << "\t]" << std::endl;
247  os << prefix << "}" << std::endl;
248 }
249 
250 bool
252 {
253  if (Size () != other.Size ())
254  {
255  return false;
256  }
257 
258  ConstIterator ti, oi;
259  for (ti = Begin (), oi = other.Begin ();
260  ti != End () && oi != other.End ();
261  ti++, oi++)
262  {
263  if (**ti != **oi)
264  {
265  return false;
266  }
267  }
268  return true;
269 }
270 
271 bool
273 {
274  return !(*this == other);
275 }
276 
277 /* End PbbTlvBlock class */
278 
280 {
281  return;
282 }
283 
285 {
286  Clear ();
287 }
288 
291 {
292  return m_tlvList.begin ();
293 }
294 
297 {
298  return m_tlvList.begin ();
299 }
300 
303 {
304  return m_tlvList.end ();
305 }
306 
309 {
310  return m_tlvList.end ();
311 }
312 
313 int
315 {
316  return m_tlvList.size ();
317 }
318 
319 bool
321 {
322  return m_tlvList.empty ();
323 }
324 
327 {
328  return m_tlvList.front ();
329 }
330 
333 {
334  return m_tlvList.back ();
335 }
336 
337 void
339 {
340  m_tlvList.push_front (tlv);
341 }
342 
343 void
345 {
346  m_tlvList.pop_front ();
347 }
348 
349 void
351 {
352  m_tlvList.push_back (tlv);
353 }
354 
355 void
357 {
358  m_tlvList.pop_back ();
359 }
360 
363 {
364  return m_tlvList.insert (position, tlv);
365 }
366 
369 {
370  return m_tlvList.erase (position);
371 }
372 
375 {
376  return m_tlvList.erase (first, last);
377 }
378 
379 void
381 {
382  for (Iterator iter = Begin (); iter != End (); iter++)
383  {
384  *iter = 0;
385  }
386  m_tlvList.clear ();
387 }
388 
389 uint32_t
391 {
392  /* tlv size */
393  uint32_t size = 2;
394  for (ConstIterator iter = Begin (); iter != End (); iter++)
395  {
396  size += (*iter)->GetSerializedSize ();
397  }
398  return size;
399 }
400 
401 void
403 {
404  if (Empty ())
405  {
406  start.WriteHtonU16 (0);
407  return;
408  }
409 
410  /* We need to write the size of the TLV block in front, so save its
411  * position. */
412  Buffer::Iterator tlvsize = start;
413  start.Next (2);
414  for (ConstIterator iter = Begin (); iter != End (); iter++)
415  {
416  (*iter)->Serialize (start);
417  }
418  /* - 2 to not include the size field */
419  uint16_t size = start.GetDistanceFrom (tlvsize) - 2;
420  tlvsize.WriteHtonU16 (size);
421 }
422 
423 void
425 {
426  uint16_t size = start.ReadNtohU16 ();
427 
428  Buffer::Iterator tlvstart = start;
429  if (size > 0)
430  {
431  while (start.GetDistanceFrom (tlvstart) < size)
432  {
433  Ptr<PbbAddressTlv> newtlv = Create<PbbAddressTlv> ();
434  newtlv->Deserialize (start);
435  PushBack (newtlv);
436  }
437  }
438 }
439 
440 void
441 PbbAddressTlvBlock::Print (std::ostream &os) const
442 {
443  Print (os, 0);
444 }
445 
446 void
447 PbbAddressTlvBlock::Print (std::ostream &os, int level) const
448 {
449  std::string prefix = "";
450  for (int i = 0; i < level; i++)
451  {
452  prefix.append ("\t");
453  }
454 
455  os << prefix << "TLV Block {" << std::endl;
456  os << prefix << "\tsize = " << Size () << std::endl;
457  os << prefix << "\tmembers [" << std::endl;
458 
459  for (ConstIterator iter = Begin (); iter != End (); iter++)
460  {
461  (*iter)->Print (os, level+2);
462  }
463 
464  os << prefix << "\t]" << std::endl;
465  os << prefix << "}" << std::endl;
466 }
467 
468 bool
470 {
471  if (Size () != other.Size ())
472  {
473  return false;
474  }
475 
476  ConstIterator it, ot;
477  for (it = Begin (), ot = other.Begin ();
478  it != End () && ot != other.End ();
479  it++, ot++)
480  {
481  if (**it != **ot)
482  {
483  return false;
484  }
485  }
486  return true;
487 }
488 
489 bool
491 {
492  return !(*this == other);
493 }
494 
495 
496 /* End PbbAddressTlvBlock Class */
497 
499 {
500  m_version = VERSION;
501  m_hasseqnum = false;
502 }
503 
505 {
506  MessageClear ();
507 }
508 
509 uint8_t
511 {
512  return m_version;
513 }
514 
515 void
517 {
518  m_seqnum = number;
519  m_hasseqnum = true;
520 }
521 
522 uint16_t
524 {
526  return m_seqnum;
527 }
528 
529 bool
531 {
532  return m_hasseqnum;
533 }
534 
535 /* Manipulating Packet TLVs */
536 
539 {
540  return m_tlvList.Begin ();
541 }
542 
545 {
546  return m_tlvList.Begin ();
547 }
548 
551 {
552  return m_tlvList.End ();
553 }
554 
556 PbbPacket::TlvEnd (void) const
557 {
558  return m_tlvList.End ();
559 }
560 
561 int
562 PbbPacket::TlvSize (void) const
563 {
564  return m_tlvList.Size ();
565 }
566 
567 bool
569 {
570  return m_tlvList.Empty ();
571 }
572 
575 {
576  return m_tlvList.Front ();
577 }
578 
579 const Ptr<PbbTlv>
581 {
582  return m_tlvList.Front ();
583 }
584 
587 {
588  return m_tlvList.Back ();
589 }
590 
591 const Ptr<PbbTlv>
592 PbbPacket::TlvBack (void) const
593 {
594  return m_tlvList.Back ();
595 }
596 
597 void
599 {
600  m_tlvList.PushFront (tlv);
601 }
602 
603 void
605 {
606  m_tlvList.PopFront ();
607 }
608 
609 void
611 {
612  m_tlvList.PushBack (tlv);
613 }
614 
615 void
617 {
618  m_tlvList.PopBack ();
619 }
620 
623 {
624  return m_tlvList.Erase (position);
625 }
626 
629 {
630  return m_tlvList.Erase (first, last);
631 }
632 
633 void
635 {
636  m_tlvList.Clear ();
637 }
638 
639 /* Manipulating Packet Messages */
640 
643 {
644  return m_messageList.begin ();
645 }
646 
649 {
650  return m_messageList.begin ();
651 }
652 
655 {
656  return m_messageList.end ();
657 }
658 
661 {
662  return m_messageList.end ();
663 }
664 
665 int
667 {
668  return m_messageList.size ();
669 }
670 
671 bool
673 {
674  return m_messageList.empty ();
675 }
676 
679 {
680  return m_messageList.front ();
681 }
682 
683 const Ptr<PbbMessage>
685 {
686  return m_messageList.front ();
687 }
688 
691 {
692  return m_messageList.back ();
693 }
694 
695 const Ptr<PbbMessage>
697 {
698  return m_messageList.back ();
699 }
700 
701 void
703 {
704  m_messageList.push_front (tlv);
705 }
706 
707 void
709 {
710  m_messageList.pop_front ();
711 }
712 
713 void
715 {
716  m_messageList.push_back (tlv);
717 }
718 
719 void
721 {
722  m_messageList.pop_back ();
723 }
724 
727 {
728  return m_messageList.erase (position);
729 }
730 
734 {
735  return m_messageList.erase (first, last);
736 }
737 
738 void
740 {
741  for (MessageIterator iter = MessageBegin (); iter != MessageEnd (); iter++)
742  {
743  *iter = 0;
744  }
745  m_messageList.clear ();
746 }
747 
748 
749 TypeId
751 {
752  static TypeId tid = TypeId ("ns3::PbbPacket")
753  .SetParent<Header> ()
754  .AddConstructor<PbbPacket> ()
755  ;
756  return tid;
757 }
758 
759 TypeId
761 {
762  return GetTypeId ();
763 }
764 
765 uint32_t
767 {
768  /* Version number + flags */
769  uint32_t size = 1;
770 
771  if (HasSequenceNumber ())
772  {
773  size += 2;
774  }
775 
776  if (!TlvEmpty ())
777  {
778  size += m_tlvList.GetSerializedSize ();
779  }
780 
781  for (ConstMessageIterator iter = MessageBegin ();
782  iter != MessageEnd ();
783  iter++)
784  {
785  size += (*iter)->GetSerializedSize ();
786  }
787 
788  return size;
789 }
790 
791 void
793 {
794  /* We remember the start, so we can write the flags after we check for a
795  * sequence number and TLV. */
796  Buffer::Iterator bufref = start;
797  start.Next ();
798 
799  uint8_t flags = VERSION;
800  /* Make room for 4 bit flags */
801  flags <<= 4;
802 
803  if (HasSequenceNumber ())
804  {
805  flags |= PHAS_SEQ_NUM;
806  start.WriteHtonU16 (GetSequenceNumber ());
807  }
808 
809  if (!TlvEmpty ())
810  {
811  flags |= PHAS_TLV;
812  m_tlvList.Serialize (start);
813  }
814 
815  bufref.WriteU8 (flags);
816 
817  for (ConstMessageIterator iter = MessageBegin ();
818  iter != MessageEnd ();
819  iter++)
820  {
821  (*iter)->Serialize (start);
822  }
823 }
824 
825 uint32_t
827 {
828  Buffer::Iterator begin = start;
829 
830  uint8_t flags = start.ReadU8 ();
831 
832  if (flags & PHAS_SEQ_NUM)
833  {
834  SetSequenceNumber (start.ReadNtohU16 ());
835  }
836 
837  if (flags & PHAS_TLV)
838  {
839  m_tlvList.Deserialize (start);
840  }
841 
842  while (!start.IsEnd ())
843  {
845  if (newmsg == 0)
846  {
847  return start.GetDistanceFrom (begin);
848  }
849  MessagePushBack (newmsg);
850  }
851 
852  flags >>= 4;
853  m_version = flags;
854 
855  return start.GetDistanceFrom (begin);
856 }
857 
858 void
859 PbbPacket::Print (std::ostream &os) const
860 {
861  os << "PbbPacket {" << std::endl;
862 
863  if (HasSequenceNumber ())
864  {
865  os << "\tsequence number = " << GetSequenceNumber ();
866  }
867 
868  os << std::endl;
869 
870  m_tlvList.Print (os, 1);
871 
872  for (ConstMessageIterator iter = MessageBegin ();
873  iter != MessageEnd ();
874  iter++)
875  {
876  (*iter)->Print (os, 1);
877  }
878 
879  os << "}" << std::endl;
880 }
881 
882 bool
884 {
885  if (GetVersion () != other.GetVersion ())
886  {
887  return false;
888  }
889 
890  if (HasSequenceNumber () != other.HasSequenceNumber ())
891  {
892  return false;
893  }
894 
895  if (HasSequenceNumber ())
896  {
897  if (GetSequenceNumber () != other.GetSequenceNumber ())
898  return false;
899  }
900 
901  if (m_tlvList != other.m_tlvList)
902  {
903  return false;
904  }
905 
906  if (MessageSize () != other.MessageSize ())
907  {
908  return false;
909  }
910 
911  ConstMessageIterator tmi, omi;
912  for (tmi = MessageBegin (), omi = other.MessageBegin ();
913  tmi != MessageEnd () && omi != other.MessageEnd ();
914  tmi++, omi++)
915  {
916  if (**tmi != **omi)
917  {
918  return false;
919  }
920  }
921  return true;
922 }
923 
924 bool
926 {
927  return !(*this == other);
928 }
929 
930 /* End PbbPacket class */
931 
933 {
934  /* Default to IPv4 */
935  m_addrSize = IPV4;
936  m_hasOriginatorAddress = false;
937  m_hasHopLimit = false;
938  m_hasHopCount = false;
939  m_hasSequenceNumber = false;
940 }
941 
943 {
945 }
946 
947 void
948 PbbMessage::SetType (uint8_t type)
949 {
950  m_type = type;
951 }
952 
953 uint8_t
955 {
956  return m_type;
957 }
958 
961 {
962  return m_addrSize;
963 }
964 
965 void
967 {
968  m_originatorAddress = address;
969  m_hasOriginatorAddress = true;
970 }
971 
972 Address
974 {
976  return m_originatorAddress;
977 }
978 
979 bool
981 {
982  return m_hasOriginatorAddress;
983 }
984 
985 void
986 PbbMessage::SetHopLimit (uint8_t hopLimit)
987 {
988  m_hopLimit = hopLimit;
989  m_hasHopLimit = true;
990 }
991 
992 uint8_t
994 {
995  NS_ASSERT (HasHopLimit ());
996  return m_hopLimit;
997 }
998 
999 bool
1001 {
1002  return m_hasHopLimit;
1003 }
1004 
1005 void
1006 PbbMessage::SetHopCount (uint8_t hopCount)
1007 {
1008  m_hopCount = hopCount;
1009  m_hasHopCount = true;
1010 }
1011 
1012 uint8_t
1014 {
1015  NS_ASSERT (HasHopCount ());
1016  return m_hopCount;
1017 }
1018 
1019 bool
1021 {
1022  return m_hasHopCount;
1023 }
1024 
1025 void
1026 PbbMessage::SetSequenceNumber (uint16_t sequenceNumber)
1027 {
1028  m_sequenceNumber = sequenceNumber;
1029  m_hasSequenceNumber = true;
1030 }
1031 
1032 uint16_t
1034 {
1036  return m_sequenceNumber;
1037 }
1038 
1039 bool
1041 {
1042  return m_hasSequenceNumber;
1043 }
1044 
1045 /* Manipulating PbbMessage TLVs */
1046 
1049 {
1050  return m_tlvList.Begin ();
1051 }
1052 
1055 {
1056  return m_tlvList.Begin ();
1057 }
1058 
1061 {
1062  return m_tlvList.End ();
1063 }
1064 
1067 {
1068  return m_tlvList.End ();
1069 }
1070 
1071 int
1073 {
1074  return m_tlvList.Size ();
1075 }
1076 
1077 bool
1079 {
1080  return m_tlvList.Empty ();
1081 }
1082 
1085 {
1086  return m_tlvList.Front ();
1087 }
1088 
1089 const Ptr<PbbTlv>
1091 {
1092  return m_tlvList.Front ();
1093 }
1094 
1097 {
1098  return m_tlvList.Back ();
1099 }
1100 
1101 const Ptr<PbbTlv>
1103 {
1104  return m_tlvList.Back ();
1105 }
1106 
1107 void
1109 {
1110  m_tlvList.PushFront (tlv);
1111 }
1112 
1113 void
1115 {
1116  m_tlvList.PopFront ();
1117 }
1118 
1119 void
1121 {
1122  m_tlvList.PushBack (tlv);
1123 }
1124 
1125 void
1127 {
1128  m_tlvList.PopBack ();
1129 }
1130 
1133 {
1134  return m_tlvList.Erase (position);
1135 }
1136 
1139 {
1140  return m_tlvList.Erase (first, last);
1141 }
1142 
1143 void
1145 {
1146  m_tlvList.Clear ();
1147 }
1148 
1149 /* Manipulating Address Block and Address TLV pairs */
1150 
1153 {
1154  return m_addressBlockList.begin ();
1155 }
1156 
1159 {
1160  return m_addressBlockList.begin ();
1161 }
1162 
1165 {
1166  return m_addressBlockList.end ();
1167 }
1168 
1171 {
1172  return m_addressBlockList.end ();
1173 }
1174 
1175 int
1177 {
1178  return m_addressBlockList.size ();
1179 }
1180 
1181 bool
1183 {
1184  return m_addressBlockList.empty ();
1185 }
1186 
1189 {
1190  return m_addressBlockList.front ();
1191 }
1192 
1195 {
1196  return m_addressBlockList.front ();
1197 }
1198 
1201 {
1202  return m_addressBlockList.back ();
1203 }
1204 
1207 {
1208  return m_addressBlockList.back ();
1209 }
1210 
1211 void
1213 {
1214  m_addressBlockList.push_front (tlv);
1215 }
1216 
1217 void
1219 {
1220  m_addressBlockList.pop_front ();
1221 }
1222 
1223 void
1225 {
1226  m_addressBlockList.push_back (tlv);
1227 }
1228 
1229 void
1231 {
1232  m_addressBlockList.pop_back ();
1233 }
1234 
1237 {
1238  return m_addressBlockList.erase (position);
1239 }
1240 
1244 {
1245  return m_addressBlockList.erase (first, last);
1246 }
1247 
1248 void
1250 {
1251  for (AddressBlockIterator iter = AddressBlockBegin ();
1252  iter != AddressBlockEnd ();
1253  iter++)
1254  {
1255  *iter = 0;
1256  }
1257  return m_addressBlockList.clear ();
1258 }
1259 
1260 uint32_t
1262 {
1263  /* msg-type + (msg-flags + msg-addr-length) + 2msg-size */
1264  uint32_t size = 4;
1265 
1266  if (HasOriginatorAddress ())
1267  {
1268  size += GetAddressLength () + 1;
1269  }
1270 
1271  if (HasHopLimit ())
1272  {
1273  size++;
1274  }
1275 
1276  if (HasHopCount ())
1277  {
1278  size++;
1279  }
1280 
1281  if (HasSequenceNumber ())
1282  {
1283  size += 2;
1284  }
1285 
1286  size += m_tlvList.GetSerializedSize ();
1287 
1289  iter != AddressBlockEnd ();
1290  iter++)
1291  {
1292  size += (*iter)->GetSerializedSize ();
1293  }
1294 
1295  return size;
1296 }
1297 
1298 void
1300 {
1301  Buffer::Iterator front = start;
1302 
1303  start.WriteU8 (GetType ());
1304 
1305  /* Save a reference to the spot where we will later write the flags */
1306  Buffer::Iterator bufref = start;
1307  start.Next (1);
1308 
1309  uint8_t flags = 0;
1310 
1311  flags = GetAddressLength ();
1312 
1313  Buffer::Iterator sizeref = start;
1314  start.Next (2);
1315 
1316  if (HasOriginatorAddress ())
1317  {
1318  flags |= MHAS_ORIG;
1320  }
1321 
1322  if (HasHopLimit ())
1323  {
1324  flags |= MHAS_HOP_LIMIT;
1325  start.WriteU8 (GetHopLimit ());
1326  }
1327 
1328  if (HasHopCount ())
1329  {
1330  flags |= MHAS_HOP_COUNT;
1331  start.WriteU8 (GetHopCount ());
1332  }
1333 
1334  if (HasSequenceNumber ())
1335  {
1336  flags |= MHAS_SEQ_NUM;
1337  start.WriteHtonU16 (GetSequenceNumber ());
1338  }
1339 
1340  bufref.WriteU8 (flags);
1341 
1342  m_tlvList.Serialize (start);
1343 
1345  iter != AddressBlockEnd ();
1346  iter++)
1347  {
1348  (*iter)->Serialize (start);
1349  }
1350 
1351  sizeref.WriteHtonU16 (front.GetDistanceFrom (start));
1352 }
1353 
1356 {
1357  /* We need to read the msg-addr-len field to determine what kind of object to
1358  * construct. */
1359  start.Next ();
1360  uint8_t addrlen = start.ReadU8 ();
1361  start.Prev (2); /* Go back to the start */
1362 
1363  /* The first four bytes of the flag is the address length. Set the last four
1364  * bytes to 0 to read it. */
1365  addrlen = (addrlen & 0xf);
1366 
1367  Ptr<PbbMessage> newmsg;
1368 
1369  switch (addrlen)
1370  {
1371  case 0:
1372  case IPV4:
1373  newmsg = Create<PbbMessageIpv4> ();
1374  break;
1375  case IPV6:
1376  newmsg = Create<PbbMessageIpv6> ();
1377  break;
1378  default:
1379  return 0;
1380  break;
1381  }
1382  newmsg->Deserialize (start);
1383  return newmsg;
1384 }
1385 
1386 void
1388 {
1389  Buffer::Iterator front = start;
1390  SetType (start.ReadU8 ());
1391  uint8_t flags = start.ReadU8 ();
1392 
1393  uint16_t size = start.ReadNtohU16 ();
1394 
1395  if (flags & MHAS_ORIG)
1396  {
1398  }
1399 
1400  if (flags & MHAS_HOP_LIMIT)
1401  {
1402  SetHopLimit (start.ReadU8 ());
1403  }
1404 
1405  if (flags & MHAS_HOP_COUNT)
1406  {
1407  SetHopCount (start.ReadU8 ());
1408  }
1409 
1410  if (flags & MHAS_SEQ_NUM)
1411  {
1412  SetSequenceNumber (start.ReadNtohU16 ());
1413  }
1414 
1415  m_tlvList.Deserialize (start);
1416 
1417  if (size > 0)
1418  {
1419  while (start.GetDistanceFrom (front) < size)
1420  {
1422  AddressBlockPushBack (newab);
1423  }
1424  }
1425 }
1426 
1427 void
1428 PbbMessage::Print (std::ostream &os) const
1429 {
1430  Print (os, 0);
1431 }
1432 
1433 void
1434 PbbMessage::Print (std::ostream &os, int level) const
1435 {
1436  std::string prefix = "";
1437  for (int i = 0; i < level; i++)
1438  {
1439  prefix.append ("\t");
1440  }
1441 
1442  os << prefix << "PbbMessage {" << std::endl;
1443 
1444  os << prefix << "\tmessage type = " << (int)GetType () << std::endl;
1445  os << prefix << "\taddress size = " << GetAddressLength () << std::endl;
1446 
1447  if (HasOriginatorAddress ())
1448  {
1449  os << prefix << "\toriginator address = ";
1451  os << std::endl;
1452  }
1453 
1454  if (HasHopLimit ())
1455  {
1456  os << prefix << "\thop limit = " << (int)GetHopLimit () << std::endl;
1457  }
1458 
1459  if (HasHopCount ())
1460  {
1461  os << prefix << "\thop count = " << (int)GetHopCount () << std::endl;
1462  }
1463 
1464  if (HasSequenceNumber ())
1465  {
1466  os << prefix << "\tseqnum = " << GetSequenceNumber () << std::endl;
1467  }
1468 
1469  m_tlvList.Print (os, level+1);
1470 
1472  iter != AddressBlockEnd ();
1473  iter++)
1474  {
1475  (*iter)->Print (os, level+1);
1476  }
1477  os << prefix << "}" << std::endl;
1478 }
1479 
1480 bool
1482 {
1483  if (GetAddressLength () != other.GetAddressLength ())
1484  {
1485  return false;
1486  }
1487 
1488  if (GetType () != other.GetType ())
1489  {
1490  return false;
1491  }
1492 
1493  if (HasOriginatorAddress () != other.HasOriginatorAddress ())
1494  {
1495  return false;
1496  }
1497 
1498  if (HasOriginatorAddress ())
1499  {
1500  if (GetOriginatorAddress () != other.GetOriginatorAddress ())
1501  {
1502  return false;
1503  }
1504  }
1505 
1506  if (HasHopLimit () != other.HasHopLimit ())
1507  {
1508  return false;
1509  }
1510 
1511  if (HasHopLimit ())
1512  {
1513  if (GetHopLimit () != other.GetHopLimit ())
1514  {
1515  return false;
1516  }
1517  }
1518 
1519  if (HasHopCount () != other.HasHopCount ())
1520  {
1521  return false;
1522  }
1523 
1524  if (HasHopCount ())
1525  {
1526  if (GetHopCount () != other.GetHopCount ())
1527  {
1528  return false;
1529  }
1530  }
1531 
1532  if (HasSequenceNumber () != other.HasSequenceNumber ())
1533  {
1534  return false;
1535  }
1536 
1537  if (HasSequenceNumber ())
1538  {
1539  if (GetSequenceNumber () != other.GetSequenceNumber ())
1540  {
1541  return false;
1542  }
1543  }
1544 
1545  if (m_tlvList != other.m_tlvList)
1546  {
1547  return false;
1548  }
1549 
1550  if (AddressBlockSize () != other.AddressBlockSize ())
1551  {
1552  return false;
1553  }
1554 
1555  ConstAddressBlockIterator tai, oai;
1556  for (tai = AddressBlockBegin (), oai = other.AddressBlockBegin ();
1557  tai != AddressBlockEnd () && oai != other.AddressBlockEnd ();
1558  tai++, oai++)
1559  {
1560  if (**tai != **oai)
1561  {
1562  return false;
1563  }
1564  }
1565  return true;
1566 }
1567 
1568 bool
1570 {
1571  return !(*this == other);
1572 }
1573 
1574 /* End PbbMessage Class */
1575 
1577 {
1578 }
1579 
1581 {
1582 }
1583 
1586 {
1587  return IPV4;
1588 }
1589 
1590 void
1592 {
1593  uint8_t* buffer = new uint8_t[GetAddressLength () + 1];
1595  start.Write (buffer, GetAddressLength () + 1);
1596  delete[] buffer;
1597 }
1598 
1599 Address
1601 {
1602  uint8_t* buffer = new uint8_t[GetAddressLength () + 1];
1603  start.Read (buffer, GetAddressLength () + 1);
1604  Address result = Ipv4Address::Deserialize (buffer);
1605  delete[] buffer;
1606  return result;
1607 }
1608 
1609 void
1611 {
1613 }
1614 
1617 {
1618  Ptr<PbbAddressBlock> newab = Create<PbbAddressBlockIpv4> ();
1619  newab->Deserialize (start);
1620  return newab;
1621 }
1622 
1623 /* End PbbMessageIpv4 Class */
1624 
1626 {
1627 }
1628 
1630 {
1631 }
1632 
1635 {
1636  return IPV6;
1637 }
1638 
1639 void
1641 {
1642  uint8_t* buffer = new uint8_t[GetAddressLength () + 1];
1644  start.Write (buffer, GetAddressLength () + 1);
1645  delete[] buffer;
1646 }
1647 
1648 Address
1650 {
1651  uint8_t* buffer = new uint8_t[GetAddressLength () + 1];
1652  start.Read (buffer, GetAddressLength () + 1);
1653  Address res = Ipv6Address::Deserialize (buffer);
1654  delete[] buffer;
1655  return res;
1656 }
1657 
1658 void
1660 {
1662 }
1663 
1666 {
1667  Ptr<PbbAddressBlock> newab = Create<PbbAddressBlockIpv6> ();
1668  newab->Deserialize (start);
1669  return newab;
1670 }
1671 
1672 /* End PbbMessageIpv6 Class */
1673 
1675 {
1676 }
1677 
1679 {
1680 }
1681 
1682 /* Manipulating the address block */
1683 
1686 {
1687  return m_addressList.begin ();
1688 }
1689 
1692 {
1693  return m_addressList.begin ();
1694 }
1695 
1698 {
1699  return m_addressList.end ();
1700 }
1701 
1704 {
1705  return m_addressList.end ();
1706 }
1707 
1708 int
1710 {
1711  return m_addressList.size ();
1712 }
1713 
1714 bool
1716 {
1717  return m_addressList.empty ();
1718 }
1719 
1720 Address
1722 {
1723  return m_addressList.front ();
1724 }
1725 
1726 Address
1728 {
1729  return m_addressList.back ();
1730 }
1731 
1732 void
1734 {
1735  m_addressList.push_front (tlv);
1736 }
1737 
1738 void
1740 {
1741  m_addressList.pop_front ();
1742 }
1743 
1744 void
1746 {
1747  m_addressList.push_back (tlv);
1748 }
1749 
1750 void
1752 {
1753  m_addressList.pop_back ();
1754 }
1755 
1758 {
1759  return m_addressList.erase (position);
1760 }
1761 
1765 {
1766  return m_addressList.erase (first, last);
1767 }
1768 
1769 void
1771 {
1772  return m_addressList.clear ();
1773 }
1774 
1775 /* Manipulating the prefix list */
1776 
1779 {
1780  return m_prefixList.begin ();
1781 }
1782 
1785 {
1786  return m_prefixList.begin ();
1787 }
1788 
1791 {
1792  return m_prefixList.end ();
1793 }
1794 
1797 {
1798  return m_prefixList.end ();
1799 }
1800 
1801 int
1803 {
1804  return m_prefixList.size ();
1805 }
1806 
1807 bool
1809 {
1810  return m_prefixList.empty ();
1811 }
1812 
1813 uint8_t
1815 {
1816  return m_prefixList.front ();
1817 }
1818 
1819 uint8_t
1821 {
1822  return m_prefixList.back ();
1823 }
1824 
1825 void
1827 {
1828  m_prefixList.push_front (prefix);
1829 }
1830 
1831 void
1833 {
1834  m_prefixList.pop_front ();
1835 }
1836 
1837 void
1839 {
1840  m_prefixList.push_back (prefix);
1841 }
1842 
1843 void
1845 {
1846  m_prefixList.pop_back ();
1847 }
1848 
1851 {
1852  return m_prefixList.insert (position, value);
1853 }
1854 
1857 {
1858  return m_prefixList.erase (position);
1859 }
1860 
1863 {
1864  return m_prefixList.erase (first, last);
1865 }
1866 
1867 void
1869 {
1870  m_prefixList.clear ();
1871 }
1872 
1873 /* Manipulating the TLV block */
1874 
1877 {
1878  return m_addressTlvList.Begin ();
1879 }
1880 
1883 {
1884  return m_addressTlvList.Begin ();
1885 }
1886 
1889 {
1890  return m_addressTlvList.End ();
1891 }
1892 
1895 {
1896  return m_addressTlvList.End ();
1897 }
1898 
1899 int
1901 {
1902  return m_addressTlvList.Size ();
1903 }
1904 
1905 bool
1907 {
1908  return m_addressTlvList.Empty ();
1909 }
1910 
1913 {
1914  return m_addressTlvList.Front ();
1915 }
1916 
1917 const Ptr<PbbAddressTlv>
1919 {
1920  return m_addressTlvList.Front ();
1921 }
1922 
1925 {
1926  return m_addressTlvList.Back ();
1927 }
1928 
1929 const Ptr<PbbAddressTlv>
1931 {
1932  return m_addressTlvList.Back ();
1933 }
1934 
1935 void
1937 {
1939 }
1940 
1941 void
1943 {
1945 }
1946 
1947 void
1949 {
1950  m_addressTlvList.PushBack (tlv);
1951 }
1952 
1953 void
1955 {
1957 }
1958 
1961 {
1962  return m_addressTlvList.Erase (position);
1963 }
1964 
1968 {
1969  return m_addressTlvList.Erase (first, last);
1970 }
1971 
1972 void
1974 {
1976 }
1977 uint32_t
1979 {
1980  /* num-addr + flags */
1981  uint32_t size = 2;
1982 
1983  if (AddressSize () == 1)
1984  {
1985  size += GetAddressLength () + PrefixSize ();
1986  }
1987  else if (AddressSize () > 0)
1988  {
1989  uint8_t* head = new uint8_t[GetAddressLength ()];
1990  uint8_t headlen = 0;
1991  uint8_t* tail = new uint8_t[GetAddressLength ()];
1992  uint8_t taillen = 0;
1993 
1994  GetHeadTail (head, headlen, tail, taillen);
1995 
1996  if (headlen > 0)
1997  {
1998  size += 1 + headlen;
1999  }
2000 
2001  if (taillen > 0)
2002  {
2003  size++;
2004  if (!HasZeroTail (tail, taillen))
2005  {
2006  size += taillen;
2007  }
2008  }
2009 
2010  /* mid size */
2011  size += (GetAddressLength () - headlen - taillen) * AddressSize ();
2012 
2013  size += PrefixSize ();
2014 
2015  delete[] head;
2016  delete[] tail;
2017  }
2018 
2020 
2021  return size;
2022 }
2023 
2024 void
2026 {
2027  start.WriteU8 (AddressSize ());
2028  Buffer::Iterator bufref = start;
2029  uint8_t flags = 0;
2030  start.Next ();
2031 
2032  if (AddressSize () == 1)
2033  {
2034  uint8_t* buf = new uint8_t[GetAddressLength ()];
2035  SerializeAddress (buf, AddressBegin ());
2036  start.Write (buf, GetAddressLength ());
2037 
2038  if (PrefixSize () == 1)
2039  {
2040  start.WriteU8 (PrefixFront ());
2041  flags |= AHAS_SINGLE_PRE_LEN;
2042  }
2043  bufref.WriteU8 (flags);
2044  delete[] buf;
2045  }
2046  else if (AddressSize () > 0)
2047  {
2048  uint8_t* head = new uint8_t[GetAddressLength ()];
2049  uint8_t* tail = new uint8_t[GetAddressLength ()];
2050  uint8_t headlen = 0;
2051  uint8_t taillen = 0;
2052 
2053  GetHeadTail (head, headlen, tail, taillen);
2054 
2055  if (headlen > 0)
2056  {
2057  flags |= AHAS_HEAD;
2058  start.WriteU8 (headlen);
2059  start.Write (head, headlen);
2060  }
2061 
2062  if (taillen > 0)
2063  {
2064  start.WriteU8 (taillen);
2065 
2066  if (HasZeroTail (tail, taillen))
2067  {
2068  flags |= AHAS_ZERO_TAIL;
2069  }
2070  else
2071  {
2072  flags |= AHAS_FULL_TAIL;
2073  start.Write (tail, taillen);
2074  }
2075  }
2076 
2077  if (headlen + taillen < GetAddressLength ())
2078  {
2079  uint8_t* mid = new uint8_t[GetAddressLength ()];
2081  iter != AddressEnd ();
2082  iter++)
2083  {
2084  SerializeAddress (mid, iter);
2085  start.Write (mid + headlen, GetAddressLength () - headlen - taillen);
2086  }
2087  delete[] mid;
2088  }
2089 
2090  flags |= GetPrefixFlags ();
2091  bufref.WriteU8 (flags);
2092 
2093  for (ConstPrefixIterator iter = PrefixBegin ();
2094  iter != PrefixEnd ();
2095  iter++)
2096  {
2097  start.WriteU8 (*iter);
2098  }
2099 
2100  delete[] head;
2101  delete[] tail;
2102  }
2103 
2104  m_addressTlvList.Serialize (start);
2105 }
2106 
2107 void
2109 {
2110  uint8_t numaddr = start.ReadU8 ();
2111  uint8_t flags = start.ReadU8 ();
2112 
2113  if (numaddr > 0)
2114  {
2115  uint8_t headlen = 0;
2116  uint8_t taillen = 0;
2117  uint8_t* addrtmp = new uint8_t[GetAddressLength ()];
2118  memset (addrtmp, 0, GetAddressLength ());
2119 
2120  if (flags & AHAS_HEAD)
2121  {
2122  headlen = start.ReadU8 ();
2123  start.Read (addrtmp, headlen);
2124  }
2125 
2126  if ((flags & AHAS_FULL_TAIL) ^ (flags & AHAS_ZERO_TAIL))
2127  {
2128  taillen = start.ReadU8 ();
2129 
2130  if (flags & AHAS_FULL_TAIL)
2131  {
2132  start.Read (addrtmp + GetAddressLength () - taillen, taillen);
2133  }
2134  }
2135 
2136  for (int i = 0; i < numaddr; i++)
2137  {
2138  start.Read (addrtmp + headlen, GetAddressLength () - headlen - taillen);
2139  AddressPushBack (DeserializeAddress (addrtmp));
2140  }
2141 
2142  if (flags & AHAS_SINGLE_PRE_LEN)
2143  {
2144  PrefixPushBack (start.ReadU8 ());
2145  }
2146  else if (flags & AHAS_MULTI_PRE_LEN)
2147  {
2148  for (int i = 0; i < numaddr; i++)
2149  {
2150  PrefixPushBack (start.ReadU8 ());
2151  }
2152  }
2153 
2154  delete[] addrtmp;
2155  }
2156 
2157  m_addressTlvList.Deserialize (start);
2158 }
2159 
2160 void
2161 PbbAddressBlock::Print (std::ostream &os) const
2162 {
2163  Print (os, 0);
2164 }
2165 
2166 void
2167 PbbAddressBlock::Print (std::ostream &os, int level) const
2168 {
2169  std::string prefix = "";
2170  for (int i = 0; i < level; i++)
2171  {
2172  prefix.append ("\t");
2173  }
2174 
2175  os << prefix << "PbbAddressBlock {" << std::endl;
2176  os << prefix << "\taddresses = " << std::endl;
2177  for (ConstAddressIterator iter = AddressBegin ();
2178  iter != AddressEnd ();
2179  iter++)
2180  {
2181  os << prefix << "\t\t";
2182  PrintAddress (os, iter);
2183  os << std::endl;
2184  }
2185 
2186  os << prefix << "\tprefixes = " << std::endl;
2187  for (ConstPrefixIterator iter = PrefixBegin ();
2188  iter != PrefixEnd ();
2189  iter++)
2190  {
2191  os << prefix << "\t\t" << (int)(*iter) << std::endl;
2192  }
2193 
2194  m_addressTlvList.Print (os, level+1);
2195 }
2196 
2197 bool
2199 {
2200  if (AddressSize () != other.AddressSize ())
2201  {
2202  return false;
2203  }
2204 
2205  ConstAddressIterator tai, oai;
2206  for (tai = AddressBegin (), oai = other.AddressBegin ();
2207  tai != AddressEnd () && oai != other.AddressEnd ();
2208  tai++, oai++)
2209  {
2210  if (*tai != *oai)
2211  {
2212  return false;
2213  }
2214  }
2215 
2216  if (PrefixSize () != other.PrefixSize ())
2217  {
2218  return false;
2219  }
2220 
2221  ConstPrefixIterator tpi, opi;
2222  for (tpi = PrefixBegin (), opi = other.PrefixBegin ();
2223  tpi != PrefixEnd () && opi != other.PrefixEnd ();
2224  tpi++, opi++)
2225  {
2226  if (*tpi != *opi)
2227  {
2228  return false;
2229  }
2230  }
2231 
2232  if (m_addressTlvList != other.m_addressTlvList)
2233  {
2234  return false;
2235  }
2236 
2237  return true;
2238 }
2239 
2240 bool
2242 {
2243  return !(*this == other);
2244 }
2245 
2246 uint8_t
2248 {
2249  switch (PrefixSize ())
2250  {
2251  case 0:
2252  return 0;
2253  break;
2254  case 1:
2255  return AHAS_SINGLE_PRE_LEN;
2256  break;
2257  default:
2258  return AHAS_MULTI_PRE_LEN;
2259  break;
2260  }
2261 
2262  /* Quiet compiler */
2263  return 0;
2264 }
2265 
2266 void
2267 PbbAddressBlock::GetHeadTail (uint8_t *head, uint8_t &headlen,
2268  uint8_t *tail, uint8_t &taillen) const
2269 {
2270  headlen = GetAddressLength ();
2271  taillen = headlen;
2272 
2273  /* Temporary automatic buffers to store serialized addresses */
2274  uint8_t * buflast = new uint8_t[GetAddressLength ()];
2275  uint8_t * bufcur = new uint8_t[GetAddressLength ()];
2276  uint8_t * tmp;
2277 
2278  SerializeAddress (buflast, AddressBegin ());
2279 
2280  /* Skip the first item */
2282  iter != AddressEnd ();
2283  iter++)
2284  {
2285  SerializeAddress (bufcur, iter);
2286 
2287  int i;
2288  for (i = 0; i < headlen; i++)
2289  {
2290  if (buflast[i] != bufcur[i])
2291  {
2292  headlen = i;
2293  break;
2294  }
2295  }
2296 
2297  /* If headlen == fulllen - 1, then tail is 0 */
2298  if (headlen <= GetAddressLength () - 1)
2299  {
2300  for (i = GetAddressLength () - 1;
2301  GetAddressLength () - 1 - i <= taillen && i > headlen;
2302  i--)
2303  {
2304  if (buflast[i] != bufcur[i])
2305  {
2306  break;
2307  }
2308  }
2309  taillen = GetAddressLength () - 1 - i;
2310  }
2311  else if (headlen == 0)
2312  {
2313  taillen = 0;
2314  break;
2315  }
2316 
2317  tmp = buflast;
2318  buflast = bufcur;
2319  bufcur = tmp;
2320  }
2321 
2322  memcpy (head, bufcur, headlen);
2323  memcpy (tail, bufcur + (GetAddressLength () - taillen), taillen);
2324 
2325  delete[] buflast;
2326  delete[] bufcur;
2327 }
2328 
2329 bool
2330 PbbAddressBlock::HasZeroTail (const uint8_t *tail, uint8_t taillen) const
2331 {
2332  int i;
2333  for (i = 0; i < taillen; i++)
2334  {
2335  if (tail[i] != 0)
2336  {
2337  break;
2338  }
2339  }
2340  return i == taillen;
2341 }
2342 
2343 /* End PbbAddressBlock Class */
2344 
2346 {
2347 }
2348 
2350 {
2351 }
2352 
2353 uint8_t
2355 {
2356  return 4;
2357 }
2358 
2359 void
2361 {
2362  Ipv4Address::ConvertFrom (*iter).Serialize (buffer);
2363 }
2364 
2365 Address
2367 {
2368  return Ipv4Address::Deserialize (buffer);
2369 }
2370 
2371 void
2373 {
2374  Ipv4Address::ConvertFrom (*iter).Print (os);
2375 }
2376 
2377 /* End PbbAddressBlockIpv4 Class */
2378 
2380 {
2381 }
2382 
2384 {
2385 }
2386 
2387 uint8_t
2389 {
2390  return 16;
2391 }
2392 
2393 void
2395 {
2396  Ipv6Address::ConvertFrom (*iter).Serialize (buffer);
2397 }
2398 
2399 Address
2401 {
2402  return Ipv6Address::Deserialize (buffer);
2403 }
2404 
2405 void
2407 {
2408  Ipv6Address::ConvertFrom (*iter).Print (os);
2409 }
2410 
2411 /* End PbbAddressBlockIpv6 Class */
2412 
2414 {
2415  m_hasTypeExt = false;
2416  m_hasIndexStart = false;
2417  m_hasIndexStop = false;
2418  m_isMultivalue = false;
2419  m_hasValue = false;
2420 }
2421 
2423 {
2425 }
2426 
2427 void
2428 PbbTlv::SetType (uint8_t type)
2429 {
2430  m_type = type;
2431 }
2432 
2433 uint8_t
2434 PbbTlv::GetType (void) const
2435 {
2436  return m_type;
2437 }
2438 
2439 void
2440 PbbTlv::SetTypeExt (uint8_t typeExt)
2441 {
2442  m_typeExt = typeExt;
2443  m_hasTypeExt = true;
2444 }
2445 
2446 uint8_t
2448 {
2449  NS_ASSERT (HasTypeExt ());
2450  return m_typeExt;
2451 }
2452 
2453 bool
2455 {
2456  return m_hasTypeExt;
2457 }
2458 
2459 void
2460 PbbTlv::SetIndexStart (uint8_t index)
2461 {
2462  m_indexStart = index;
2463  m_hasIndexStart = true;
2464 }
2465 
2466 uint8_t
2468 {
2469  NS_ASSERT (HasIndexStart ());
2470  return m_indexStart;
2471 }
2472 
2473 bool
2475 {
2476  return m_hasIndexStart;
2477 }
2478 
2479 void
2480 PbbTlv::SetIndexStop (uint8_t index)
2481 {
2482  m_indexStop = index;
2483  m_hasIndexStop = true;
2484 }
2485 
2486 uint8_t
2488 {
2489  NS_ASSERT (HasIndexStop ());
2490  return m_indexStop;
2491 }
2492 
2493 bool
2495 {
2496  return m_hasIndexStop;
2497 }
2498 
2499 void
2500 PbbTlv::SetMultivalue (bool isMultivalue)
2501 {
2502  m_isMultivalue = isMultivalue;
2503 }
2504 
2505 bool
2507 {
2508  return m_isMultivalue;
2509 }
2510 
2511 void
2513 {
2514  m_hasValue = true;
2515  m_value = start;
2516 }
2517 
2518 void
2519 PbbTlv::SetValue (const uint8_t * buffer, uint32_t size)
2520 {
2521  m_hasValue = true;
2522  m_value.AddAtStart (size);
2523  m_value.Begin ().Write (buffer, size);
2524 }
2525 
2526 Buffer
2527 PbbTlv::GetValue (void) const
2528 {
2529  NS_ASSERT (HasValue ());
2530  return m_value;
2531 }
2532 
2533 bool
2534 PbbTlv::HasValue (void) const
2535 {
2536  return m_hasValue;
2537 }
2538 
2539 uint32_t
2541 {
2542  /* type + flags */
2543  uint32_t size = 2;
2544 
2545  if (HasTypeExt ())
2546  {
2547  size++;
2548  }
2549 
2550  if (HasIndexStart ())
2551  {
2552  size++;
2553  }
2554 
2555  if (HasIndexStop ())
2556  {
2557  size++;
2558  }
2559 
2560  if (HasValue ())
2561  {
2562  if (GetValue ().GetSize () > 255)
2563  {
2564  size += 2;
2565  }
2566  else
2567  {
2568  size++;
2569  }
2570  size += GetValue ().GetSize ();
2571  }
2572 
2573  return size;
2574 }
2575 
2576 void
2578 {
2579  start.WriteU8 (GetType ());
2580 
2581  Buffer::Iterator bufref = start;
2582  uint8_t flags = 0;
2583  start.Next ();
2584 
2585  if (HasTypeExt ())
2586  {
2587  flags |= THAS_TYPE_EXT;
2588  start.WriteU8 (GetTypeExt ());
2589  }
2590 
2591  if (HasIndexStart ())
2592  {
2593  start.WriteU8 (GetIndexStart ());
2594 
2595  if (HasIndexStop ())
2596  {
2597  flags |= THAS_MULTI_INDEX;
2598  start.WriteU8 (GetIndexStop ());
2599  }
2600  else
2601  {
2602  flags |= THAS_SINGLE_INDEX;
2603  }
2604  }
2605 
2606  if (HasValue ())
2607  {
2608  flags |= THAS_VALUE;
2609 
2610  uint32_t size = GetValue ().GetSize ();
2611  if (size > 255)
2612  {
2613  flags |= THAS_EXT_LEN;
2614  start.WriteHtonU16 (size);
2615  }
2616  else
2617  {
2618  start.WriteU8 (size);
2619  }
2620 
2621  if (IsMultivalue ())
2622  {
2623  flags |= TIS_MULTIVALUE;
2624  }
2625 
2626  start.Write (GetValue ().Begin (), GetValue ().End ());
2627  }
2628 
2629  bufref.WriteU8 (flags);
2630 }
2631 
2632 void
2634 {
2635  SetType (start.ReadU8 ());
2636 
2637  uint8_t flags = start.ReadU8 ();
2638 
2639  if (flags & THAS_TYPE_EXT)
2640  {
2641  SetTypeExt (start.ReadU8 ());
2642  }
2643 
2644  if (flags & THAS_MULTI_INDEX)
2645  {
2646  SetIndexStart (start.ReadU8 ());
2647  SetIndexStop (start.ReadU8 ());
2648  }
2649  else if (flags & THAS_SINGLE_INDEX)
2650  {
2651  SetIndexStart (start.ReadU8 ());
2652  }
2653 
2654  if (flags & THAS_VALUE)
2655  {
2656  uint16_t len = 0;
2657 
2658  if (flags & THAS_EXT_LEN)
2659  {
2660  len = start.ReadNtohU16 ();
2661  }
2662  else
2663  {
2664  len = start.ReadU8 ();
2665  }
2666 
2667  m_value.AddAtStart (len);
2668 
2669  Buffer::Iterator valueStart = start;
2670  start.Next (len);
2671  m_value.Begin ().Write (valueStart, start);
2672  m_hasValue = true;
2673  }
2674 }
2675 
2676 void
2677 PbbTlv::Print (std::ostream &os) const
2678 {
2679  Print (os, 0);
2680 }
2681 
2682 void
2683 PbbTlv::Print (std::ostream &os, int level) const
2684 {
2685  std::string prefix = "";
2686  for (int i = 0; i < level; i++)
2687  {
2688  prefix.append ("\t");
2689  }
2690 
2691  os << prefix << "PbbTlv {" << std::endl;
2692  os << prefix << "\ttype = " << (int)GetType () << std::endl;
2693 
2694  if (HasTypeExt ())
2695  {
2696  os << prefix << "\ttypeext = " << (int)GetTypeExt () << std::endl;
2697  }
2698 
2699  if (HasIndexStart ())
2700  {
2701  os << prefix << "\tindexStart = " << (int)GetIndexStart () << std::endl;
2702  }
2703 
2704  if (HasIndexStop ())
2705  {
2706  os << prefix << "\tindexStop = " << (int)GetIndexStop () << std::endl;
2707  }
2708 
2709  os << prefix << "\tisMultivalue = " << IsMultivalue () << std::endl;
2710 
2711  if (HasValue ())
2712  {
2713  os << prefix << "\thas value; size = " << GetValue ().GetSize () << std::endl;
2714  }
2715 
2716  os << prefix << "}" << std::endl;
2717 }
2718 
2719 bool
2720 PbbTlv::operator== (const PbbTlv &other) const
2721 {
2722  if (GetType () != other.GetType ())
2723  {
2724  return false;
2725  }
2726 
2727  if (HasTypeExt () != other.HasTypeExt ())
2728  {
2729  return false;
2730  }
2731 
2732  if (HasTypeExt ())
2733  {
2734  if (GetTypeExt () != other.GetTypeExt ())
2735  {
2736  return false;
2737  }
2738  }
2739 
2740  if (HasValue () != other.HasValue ())
2741  {
2742  return false;
2743  }
2744 
2745  if (HasValue ())
2746  {
2747  Buffer tv = GetValue ();
2748  Buffer ov = other.GetValue ();
2749  if (tv.GetSize () != ov.GetSize ())
2750  {
2751  return false;
2752  }
2753 
2754  /* The docs say I probably shouldn't use Buffer::PeekData, but I think it
2755  * is justified in this case. */
2756  if (memcmp (tv.PeekData (), ov.PeekData (), tv.GetSize ()) != 0)
2757  {
2758  return false;
2759  }
2760  }
2761  return true;
2762 }
2763 
2764 bool
2765 PbbTlv::operator!= (const PbbTlv &other) const
2766 {
2767  return !(*this == other);
2768 }
2769 
2770 /* End PbbTlv Class */
2771 
2772 void
2774 {
2775  PbbTlv::SetIndexStart (index);
2776 }
2777 
2778 uint8_t
2780 {
2781  return PbbTlv::GetIndexStart ();
2782 }
2783 
2784 bool
2786 {
2787  return PbbTlv::HasIndexStart ();
2788 }
2789 
2790 void
2792 {
2793  PbbTlv::SetIndexStop (index);
2794 }
2795 
2796 uint8_t
2798 {
2799  return PbbTlv::GetIndexStop ();
2800 }
2801 
2802 bool
2804 {
2805  return PbbTlv::HasIndexStop ();
2806 }
2807 
2808 void
2809 PbbAddressTlv::SetMultivalue (bool isMultivalue)
2810 {
2811  PbbTlv::SetMultivalue (isMultivalue);
2812 }
2813 
2814 bool
2816 {
2817  return PbbTlv::IsMultivalue ();
2818 }
2819 
2820 } /* namespace ns3 */