A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
wimax-tlv.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2009 INRIA, UDcast
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  * Mohamed Amine Ismail <amine.ismail@sophia.inria.fr>
19  *
20  */
21 
22 #include "wimax-tlv.h"
23 
25 
26 namespace ns3 {
27 // NS_OBJECT_ENSURE_REGISTERED ("Tlv");
28 
30 {
31  return GetTypeId ();
32 }
33 
34 void Tlv::Print (std::ostream &os) const
35 {
36  os << "TLV type = " << (uint32_t) m_type << " TLV Length = " << (uint64_t) m_length;
37 }
38 
39 Tlv::Tlv (uint8_t type, uint64_t length, const TlvValue & value)
40 {
41  m_type = type;
42  m_length = length;
43  m_value = value.Copy ();
44 }
45 
47 {
48  m_type = 0;
49  m_length = 0;
50  m_value = 0;
51 }
52 
54 {
55  if (m_value != 0)
56  {
57  delete m_value;
58  m_value = 0;
59  }
60 }
61 
62 TlvValue *
63 Tlv::CopyValue (void) const
64 {
65  return m_value->Copy ();
66 }
67 
68 Tlv::Tlv (const Tlv & tlv)
69 {
70  m_type = tlv.GetType ();
71  m_length = tlv.GetLength ();
72  m_value = tlv.CopyValue ();
73 }
74 
75 Tlv &
77 {
78  if (m_value != 0)
79  {
80  delete m_value;
81  }
82  m_type = o.GetType ();
83  m_length = o.GetLength ();
84  m_value = o.CopyValue ();
85 
86  return *this;
87 }
88 
89 uint32_t
91 {
92  return 1 + GetSizeOfLen () + m_value->GetSerializedSize ();
93 }
94 
95 uint8_t
96 Tlv::GetSizeOfLen (void) const
97 {
98  uint8_t sizeOfLen = 1;
99 
100  if (m_length > 127)
101  {
102  sizeOfLen = 2;
103  uint64_t testValue = 0xFF;
104  while (m_length > testValue)
105  {
106  sizeOfLen++;
107  testValue *= 0xFF;
108  }
109  }
110  return sizeOfLen;
111 }
112 
113 void
115 {
116  i.WriteU8 (m_type);
117  uint8_t lenSize = GetSizeOfLen ();
118  if (lenSize == 1)
119  {
120  i.WriteU8 (m_length);
121  }
122  else
123  {
124  i.WriteU8 ((lenSize-1) | WIMAX_TLV_EXTENDED_LENGTH_MASK);
125  for (int j = 0; j < lenSize - 1; j++)
126  {
127  i.WriteU8 ((uint8_t)(m_length >> ((lenSize - 1 - 1 - j) * 8)));
128  }
129  }
130  m_value->Serialize (i);
131 }
132 
133 uint32_t
135 {
136  // read the type of tlv
137  m_type = i.ReadU8 ();
138 
139  // read the length
140  uint8_t lenSize = i.ReadU8 ();
141  uint32_t serializedSize = 2;
142  if (lenSize < 127)
143  {
144  m_length = lenSize;
145  }
146  else
147  {
148  lenSize &= ~WIMAX_TLV_EXTENDED_LENGTH_MASK;
149  for (int j = 0; j < lenSize; j++)
150  {
151  m_length <<= 8;
152  m_length |= i.ReadU8 ();
153  serializedSize++;
154  }
155  }
156  switch (m_type)
157  {
158  case HMAC_TUPLE:
159  // TODO: implement Deserialize HMAC_TUPLE
160  NS_FATAL_ERROR ("Not implemented-- please implement and contribute a patch");
161  break;
163  // TODO: implement Deserialize MAC_VERSION_ENCODING
164  NS_FATAL_ERROR ("Not implemented-- please implement and contribute a patch");
165  break;
167  // TODO: implement Deserialize CURRENT_TRANSMIT_POWER
168  NS_FATAL_ERROR ("Not implemented-- please implement and contribute a patch");
169  break;
171  {
172  SfVectorTlvValue val;
173  serializedSize += val.Deserialize (i, m_length);
174  m_value = val.Copy ();
175  break;
176  }
177  case UPLINK_SERVICE_FLOW:
178  {
179  SfVectorTlvValue val;
180  serializedSize += val.Deserialize (i, m_length);
181  m_value = val.Copy ();
182  break;
183  }
184  case VENDOR_ID_EMCODING:
185  // TODO: implement Deserialize VENDOR_ID_EMCODING
186  NS_FATAL_ERROR ("Not implemented-- please implement and contribute a patch");
187  break;
189  // TODO: implement Deserialize VENDOR_SPECIFIC_INFORMATION
190  NS_FATAL_ERROR ("Not implemented-- please implement and contribute a patch");
191  break;
192  default:
193  NS_ASSERT_MSG (false, "Unknown tlv type.");
194  break;
195  }
196 
197  return serializedSize;
198 }
199 
200 uint8_t
201 Tlv::GetType (void) const
202 {
203  return m_type;
204 }
205 uint64_t
206 Tlv::GetLength (void) const
207 {
208  return m_length;
209 }
210 TlvValue*
212 {
213  return m_value;
214 }
215 
216 Tlv *
217 Tlv::Copy (void) const
218 {
219  return new Tlv (m_type, m_length, *m_value);
220 }
221 // ==============================================================================
223 {
224  m_tlvList = new std::vector<Tlv*>;
225 }
226 
228 {
229  for (std::vector<Tlv*>::const_iterator iter = m_tlvList->begin (); iter != m_tlvList->end (); ++iter)
230  {
231  delete (*iter);
232  }
233  m_tlvList->clear ();
234  delete m_tlvList;
235 }
236 
237 uint32_t
239 {
240  uint32_t size = 0;
241  for (std::vector<Tlv*>::const_iterator iter = m_tlvList->begin (); iter != m_tlvList->end (); ++iter)
242  {
243  size += (*iter)->GetSerializedSize ();
244  }
245  return size;
246 }
247 
248 void
250 {
251  for (std::vector<Tlv*>::const_iterator iter = m_tlvList->begin (); iter != m_tlvList->end (); ++iter)
252  {
253  (*iter)->Serialize (i);
254  i.Next ((*iter)->GetSerializedSize ());
255  }
256 }
257 
260 {
261  return m_tlvList->begin ();
262 }
263 
266 {
267  return m_tlvList->end ();
268 }
269 
270 void
272 {
273  m_tlvList->push_back (val.Copy ());
274 }
275 
276 // ==============================================================================
278 {
279 
280 }
281 
284 {
285  SfVectorTlvValue * tmp = new SfVectorTlvValue ();
286  for (std::vector<Tlv*>::const_iterator iter = Begin (); iter != End (); ++iter)
287  {
288  tmp->Add (Tlv ((*iter)->GetType (), (*iter)->GetLength (), *(*iter)->PeekValue ()));
289  }
290  return tmp;
291 }
292 
293 uint32_t
295 {
296  uint64_t serializedSize = 0;
297  while (serializedSize < valueLen)
298  {
299  uint8_t type = i.ReadU8 ();
300  // read the length
301  uint8_t lenSize = i.ReadU8 ();
302  serializedSize += 2;
303  uint64_t length = 0;
304  if (lenSize < 127)
305  {
306  length = lenSize;
307  }
308  else
309  {
310  lenSize &= ~WIMAX_TLV_EXTENDED_LENGTH_MASK;
311  for (int j = 0; j < lenSize; j++)
312  {
313  length <<= 8;
314  length |= i.ReadU8 ();
315  serializedSize++;
316  }
317  }
318  switch (type)
319  {
320  case SFID:
321  {
322  U32TlvValue val;
323  serializedSize += val.Deserialize (i);
324  Add (Tlv (SFID, 4, val));
325  break;
326  }
327  case CID:
328  {
329  U16TlvValue val;
330  serializedSize += val.Deserialize (i);
331  Add (Tlv (CID, 2, val));
332  break;
333  }
334  case Service_Class_Name:
335  NS_FATAL_ERROR ("Not implemented-- please implement and contribute a patch");
336  break;
337  case reserved1:
338  // NOTHING
339  break;
341  {
342  U8TlvValue val;
343  serializedSize += val.Deserialize (i);
344  Add (Tlv (QoS_Parameter_Set_Type, 1, val));
345  break;
346  }
347  case Traffic_Priority:
348  {
349  U8TlvValue val;
350  serializedSize += val.Deserialize (i);
351  Add (Tlv (Traffic_Priority, 1, val));
352  break;
353  }
355  {
356  U32TlvValue val;
357  serializedSize += val.Deserialize (i);
359  break;
360  }
362  {
363  U32TlvValue val;
364  serializedSize += val.Deserialize (i);
365  Add (Tlv (Maximum_Traffic_Burst, 4, val));
366  break;
367  }
369  {
370  U32TlvValue val;
371  serializedSize += val.Deserialize (i);
373  break;
374  }
376  {
377  U32TlvValue val;
378  serializedSize += val.Deserialize (i);
380  break;
381  }
383  {
384  U8TlvValue val;
385  serializedSize += val.Deserialize (i);
387  break;
388  }
390  {
391  U32TlvValue val;
392  serializedSize += val.Deserialize (i);
393  Add (Tlv (Request_Transmission_Policy, 4, val));
394  break;
395  }
396  case Tolerated_Jitter:
397  {
398  U32TlvValue val;
399  serializedSize += val.Deserialize (i);
400  Add (Tlv (Tolerated_Jitter, 4, val));
401  break;
402  }
403  case Maximum_Latency:
404  {
405  U32TlvValue val;
406  serializedSize += val.Deserialize (i);
407  Add (Tlv (Maximum_Latency, 4, val));
408  break;
409  }
411  {
412  U8TlvValue val;
413  serializedSize += val.Deserialize (i);
415  break;
416  }
417  case SDU_Size:
418  {
419  U8TlvValue val;
420  serializedSize += val.Deserialize (i);
421  Add (Tlv (SDU_Size, 1, val));
422  break;
423  }
424  case Target_SAID:
425  {
426  U16TlvValue val;
427  serializedSize += val.Deserialize (i);
428  Add (Tlv (Target_SAID, 2, val));
429  break;
430  }
431  case ARQ_Enable:
432  {
433  U8TlvValue val;
434  serializedSize += val.Deserialize (i);
435  Add (Tlv (ARQ_Enable, 1, val));
436  break;
437  }
438  case ARQ_WINDOW_SIZE:
439  {
440  U16TlvValue val;
441  serializedSize += val.Deserialize (i);
442  Add (Tlv (ARQ_WINDOW_SIZE, 2, val));
443  break;
444  }
446  break;
448  break;
449  case ARQ_BLOCK_LIFETIME:
450  break;
451  case ARQ_SYNC_LOSS:
452  break;
454  break;
455  case ARQ_PURGE_TIMEOUT:
456  break;
457  case ARQ_BLOCK_SIZE:
458  break;
459  case reserved2:
460  break;
461  case CS_Specification:
462  {
463  U8TlvValue val;
464  serializedSize += val.Deserialize (i);
465  Add (Tlv (CS_Specification, 1, val));
466  break;
467  }
468  case IPV4_CS_Parameters:
469  {
471  uint32_t size = val.Deserialize (i, length);
472  serializedSize += size;
473  Add (Tlv (IPV4_CS_Parameters, size, val));
474  break;
475  }
476  default:
477  NS_ASSERT_MSG (false, "Unknown tlv type.");
478  break;
479  }
480  i.Next (length);
481  }
482  return serializedSize;
483 }
484 
485 // ==============================================================================
486 
487 U8TlvValue::U8TlvValue (uint8_t value)
488 {
489  m_value = value;
490 }
491 
493 {
494  m_value = 0;
495 }
496 
498 {
499 }
500 uint32_t
502 {
503  return 1;
504 }
505 void
507 {
508  i.WriteU8 (m_value);
509 }
510 uint32_t
512 {
513  return Deserialize (i);
514 }
515 
516 uint32_t
518 {
519  m_value = i.ReadU8 ();
520  return 1;
521 }
522 
523 uint8_t
525 {
526  return m_value;
527 }
528 
529 U8TlvValue *
530 U8TlvValue::Copy (void) const
531 {
532  U8TlvValue * tmp = new U8TlvValue (m_value);
533  return tmp;
534 }
535 // ==============================================================================
536 U16TlvValue::U16TlvValue (uint16_t value)
537 {
538  m_value = value;
539 }
540 
542 {
543  m_value = 0;
544 }
545 
547 {
548 }
549 
550 uint32_t
552 {
553  return 2;
554 }
555 void
557 {
558  i.WriteHtonU16 (m_value);
559 }
560 uint32_t
562 {
563  return Deserialize (i);
564 }
565 
566 uint32_t
568 {
569  m_value = i.ReadNtohU16 ();
570  return 2;
571 }
572 
573 uint16_t
575 {
576  return m_value;
577 }
578 
579 U16TlvValue *
580 U16TlvValue::Copy (void) const
581 {
582  U16TlvValue * tmp = new U16TlvValue (m_value);
583  return tmp;
584 }
585 // ==============================================================================
586 U32TlvValue::U32TlvValue (uint32_t value)
587 {
588  m_value = value;
589 }
590 
592 {
593  m_value = 0;
594 }
595 
597 {
598 }
599 
600 uint32_t U32TlvValue::GetSerializedSize (void) const
601 {
602  return 4;
603 }
604 void
606 {
607  i.WriteHtonU32 (m_value);
608 }
609 uint32_t
611 {
612  return Deserialize (i);
613 }
614 
615 uint32_t
617 {
618  m_value = i.ReadNtohU32 ();
619  return 4;
620 }
621 uint32_t
623 {
624  return m_value;
625 }
626 
627 U32TlvValue *
628 U32TlvValue::Copy (void) const
629 {
630  U32TlvValue * tmp = new U32TlvValue (m_value);
631  return tmp;
632 }
633 // ==============================================================================
634 uint32_t
636 {
637  uint64_t serializedSize = 0;
638  uint8_t lenSize = 0;
639  uint8_t type = 0;
640  while (serializedSize < valueLength)
641  {
642  type = i.ReadU8 ();
643  // read the length
644  lenSize = i.ReadU8 ();
645  serializedSize += 2;
646  uint64_t length = 0;
647  if (lenSize < 127)
648  {
649  length = lenSize;
650  }
651  else
652  {
653  lenSize &= ~WIMAX_TLV_EXTENDED_LENGTH_MASK;
654  for (int j = 0; j < lenSize; j++)
655  {
656  length <<= 8;
657  length |= i.ReadU8 ();
658  serializedSize++;
659  }
660  }
661  switch (type)
662  {
664  {
665  U8TlvValue val;
666  serializedSize += val.Deserialize (i);
667  Add (Tlv (Classifier_DSC_Action, 1, val));
668  break;
669  }
671  {
673  serializedSize += val.Deserialize (i, length);
675  break;
676  }
677  }
678  i.Next (length);
679  }
680  return serializedSize;
681 }
682 
684 {
685 
686 }
687 
690 {
692  for (std::vector<Tlv*>::const_iterator iter = Begin (); iter != End (); ++iter)
693  {
694  tmp->Add (Tlv ((*iter)->GetType (), (*iter)->GetLength (), *(*iter)->PeekValue ()));
695  }
696  return tmp;
697 }
698 // ==============================================================================
699 
701 {
702 
703 }
704 
707 {
709  for (std::vector<Tlv*>::const_iterator iter = Begin (); iter != End (); ++iter)
710  {
711  tmp->Add (Tlv ((*iter)->GetType (), (*iter)->GetLength (), *(*iter)->PeekValue ()));
712  }
713  return tmp;
714 }
715 
716 uint32_t
718 {
719  uint64_t serializedSize = 0;
720  uint8_t lenSize = 0;
721  uint8_t type = 0;
722  while (serializedSize < valueLength)
723  {
724  type = i.ReadU8 ();
725  // read the length
726  lenSize = i.ReadU8 ();
727  serializedSize += 2;
728  uint64_t length = 0;
729  if (lenSize < 127)
730  {
731  length = lenSize;
732  }
733  else
734  {
735  lenSize &= ~WIMAX_TLV_EXTENDED_LENGTH_MASK;
736  for (int j = 0; j < lenSize; j++)
737  {
738  length <<= 8;
739  length |= i.ReadU8 ();
740  serializedSize++;
741  }
742  }
743  switch (type)
744  {
745  case Priority:
746  {
747  U8TlvValue val;
748  serializedSize += val.Deserialize (i);
749  Add (Tlv (Priority, 1, val));
750  break;
751  }
752  case ToS:
753  {
754  TosTlvValue val;
755  serializedSize += val.Deserialize (i, length);
756  Add (Tlv (ToS, val.GetSerializedSize (), val));
757  break;
758  }
759  case Protocol:
760  {
761  ProtocolTlvValue val;
762  serializedSize += val.Deserialize (i, length);
763  Add (Tlv (Protocol, val.GetSerializedSize (), val));
764  break;
765  }
766  case IP_src:
767  {
769  serializedSize += val.Deserialize (i, length);
770  Add (Tlv (IP_src, val.GetSerializedSize (), val));
771  break;
772  }
773  case IP_dst:
774  {
776  serializedSize += val.Deserialize (i, length);
777  Add (Tlv (IP_dst, val.GetSerializedSize (), val));
778  break;
779  }
780  case Port_src:
781  {
782  PortRangeTlvValue val;
783  serializedSize += val.Deserialize (i, length);
784  Add (Tlv (Port_src, val.GetSerializedSize (), val));
785  break;
786  }
787  case Port_dst:
788  {
789  PortRangeTlvValue val;
790  serializedSize += val.Deserialize (i, length);
791  Add (Tlv (Port_dst, val.GetSerializedSize (), val));
792  break;
793  }
794  case Index:
795  {
796  U16TlvValue val;
797  serializedSize += val.Deserialize (i);
798  Add (Tlv (Index, 2, val));
799  break;
800  }
801  }
802  i.Next (length);
803  }
804  return serializedSize;
805 }
806 
807 // ==============================================================================
809 {
810  m_low = 0;
811  m_high = 0;
812  m_mask = 0;
813 }
814 TosTlvValue::TosTlvValue (uint8_t low, uint8_t high, uint8_t mask)
815 {
816  m_low = low;
817  m_high = high;
818  m_mask = mask;
819 }
821 {
822 }
823 
824 uint32_t
826 {
827  return 3;
828 }
829 void
831 {
832  i.WriteU8 (m_low);
833  i.WriteU8 (m_high);
834  i.WriteU8 (m_mask);
835 }
836 uint32_t
838 {
839  m_low = i.ReadU8 ();
840  m_high = i.ReadU8 ();
841  m_mask = i.ReadU8 ();
842  return 3;
843 }
844 uint8_t
846 {
847  return m_low;
848 }
849 uint8_t
851 {
852  return m_high;
853 }
854 uint8_t
856 {
857  return m_mask;
858 }
859 
860 TosTlvValue *
861 TosTlvValue::Copy (void) const
862 {
863  return new TosTlvValue (m_low, m_high, m_mask);
864 }
865 
866 // ==============================================================================
868 {
869  m_portRange = new std::vector<struct PortRange>;
870 }
872 {
873  m_portRange->clear ();
874  delete m_portRange;
875 }
876 
877 uint32_t
879 {
880  return m_portRange->size () * sizeof(struct PortRange);
881 }
882 void
884 {
885  for (std::vector<struct PortRange>::const_iterator iter = m_portRange->begin (); iter != m_portRange->end (); ++iter)
886  {
887  i.WriteHtonU16 ((*iter).PortLow);
888  i.WriteHtonU16 ((*iter).PortHigh);
889  }
890 }
891 uint32_t
893 {
894  uint64_t len = 0;
895  while (len < valueLength)
896  {
897  uint16_t low = i.ReadNtohU16 ();
898  uint16_t high = i.ReadNtohU16 ();
899  Add (low, high);
900  len += 4;
901  }
902  return len;
903 }
904 void
905 PortRangeTlvValue::Add (uint16_t portLow, uint16_t portHigh)
906 {
907  struct PortRange tmp;
908  tmp.PortLow = portLow;
909  tmp.PortHigh = portHigh;
910  m_portRange->push_back (tmp);
911 }
914 {
915  return m_portRange->begin ();
916 }
917 
920 {
921  return m_portRange->end ();
922 }
923 
926 {
927  PortRangeTlvValue * tmp = new PortRangeTlvValue ();
928  for (std::vector<struct PortRange>::const_iterator iter = m_portRange->begin (); iter != m_portRange->end (); ++iter)
929  {
930  tmp->Add ((*iter).PortLow, (*iter).PortHigh);
931  }
932  return tmp;
933 }
934 
935 // ==============================================================================
936 
938 {
939  m_protocol = new std::vector<uint8_t>;
940 }
942 {
943  m_protocol->clear ();
944  if (m_protocol != 0)
945  {
946  delete m_protocol;
947  m_protocol = 0;
948  }
949 }
950 
951 uint32_t
953 {
954  return m_protocol->size ();
955 }
956 
957 void
959 {
960  for (std::vector<uint8_t>::const_iterator iter = m_protocol->begin (); iter != m_protocol->end (); ++iter)
961  {
962  i.WriteU8 ((*iter));
963  }
964 }
965 
966 uint32_t
968 {
969  uint64_t len = 0;
970  while (len < valueLength)
971  {
972  Add (i.ReadU8 ());
973  len++;
974  }
975  return len;
976 }
977 
978 void
979 ProtocolTlvValue::Add (uint8_t protocol)
980 {
981  m_protocol->push_back (protocol);
982 }
983 
986 {
987  return m_protocol->begin ();
988 }
989 
992 {
993  return m_protocol->end ();
994 }
995 
998 {
999  ProtocolTlvValue* tmp = new ProtocolTlvValue ();
1000  for (std::vector<uint8_t>::const_iterator iter = m_protocol->begin (); iter != m_protocol->end (); ++iter)
1001  {
1002  tmp->Add ((*iter));
1003  }
1004  return tmp;
1005 }
1006 
1007 // ==============================================================================
1008 
1010 {
1011  m_ipv4Addr = new std::vector<struct ipv4Addr>;
1012 }
1013 
1015 {
1016  m_ipv4Addr->clear ();
1017  if (m_ipv4Addr != 0)
1018  {
1019  delete m_ipv4Addr;
1020  m_ipv4Addr = 0;
1021  }
1022 }
1023 
1024 uint32_t
1026 {
1027  return m_ipv4Addr->size () * sizeof(struct ipv4Addr);
1028 }
1029 
1030 void
1032 {
1033  for (std::vector<struct ipv4Addr>::const_iterator iter = m_ipv4Addr->begin (); iter != m_ipv4Addr->end (); ++iter)
1034  {
1035  i.WriteHtonU32 ((*iter).Address.Get ());
1036  i.WriteHtonU32 ((*iter).Mask.Get ());
1037  }
1038 }
1039 
1040 uint32_t
1042 {
1043  uint64_t len = 0;
1044  while (len < valueLength)
1045  {
1046  uint32_t addr = i.ReadNtohU32 ();
1047  uint32_t mask = i.ReadNtohU32 ();
1048  Add (Ipv4Address (addr), Ipv4Mask (mask));
1049  len += 8;
1050  }
1051  return len;
1052 }
1053 
1054 void
1056 {
1057  struct ipv4Addr tmp;
1058  tmp.Address = address;
1059  tmp.Mask = Mask;
1060  m_ipv4Addr->push_back (tmp);
1061 }
1062 
1065 {
1066  return m_ipv4Addr->begin ();
1067 }
1068 
1071 {
1072  return m_ipv4Addr->end ();
1073 }
1074 
1077 {
1079  for (std::vector<struct ipv4Addr>::const_iterator iter = m_ipv4Addr->begin (); iter != m_ipv4Addr->end (); ++iter)
1080  {
1081  tmp->Add ((*iter).Address, (*iter).Mask);
1082  }
1083  return tmp;
1084 }
1085 
1086 }