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 
24 namespace ns3 {
25 
26 NS_LOG_COMPONENT_DEFINE ("Tlv");
27 
28 // NS_OBJECT_ENSURE_REGISTERED ("Tlv");
29 
30 /* static */
31 TypeId
GetTypeId(void)32 Tlv::GetTypeId (void)
33 {
34   static TypeId tid = TypeId ("ns3::Tlv")
35     .SetParent<Header> ()
36     .SetGroupName ("Wimax")
37     .AddConstructor<Tlv> ()
38     ;
39   return tid;
40 }
41 
GetInstanceTypeId(void) const42 TypeId Tlv::GetInstanceTypeId (void) const
43 {
44   return GetTypeId ();
45 }
46 
Print(std::ostream & os) const47 void Tlv::Print (std::ostream &os) const
48 {
49   os << "TLV type = " << (uint32_t) m_type << " TLV Length = " << (uint64_t) m_length;
50 }
51 
Tlv(uint8_t type,uint64_t length,const TlvValue & value)52 Tlv::Tlv (uint8_t type, uint64_t length, const TlvValue & value)
53 {
54   m_type = type;
55   m_length = length;
56   m_value = value.Copy ();
57 }
58 
Tlv()59 Tlv::Tlv ()
60 {
61   m_type = 0;
62   m_length = 0;
63   m_value = 0;
64 }
65 
~Tlv()66 Tlv::~Tlv ()
67 {
68   if (m_value != 0)
69     {
70       delete m_value;
71       m_value = 0;
72     }
73 }
74 
75 TlvValue *
CopyValue(void) const76 Tlv::CopyValue (void) const
77 {
78   return m_value->Copy ();
79 }
80 
Tlv(const Tlv & tlv)81 Tlv::Tlv (const Tlv & tlv)
82 {
83   m_type = tlv.GetType ();
84   m_length = tlv.GetLength ();
85   m_value = tlv.CopyValue ();
86 }
87 
88 Tlv &
operator =(Tlv const & o)89 Tlv::operator = (Tlv const& o)
90 {
91   if (m_value != 0)
92     {
93       delete m_value;
94     }
95   m_type = o.GetType ();
96   m_length = o.GetLength ();
97   m_value = o.CopyValue ();
98 
99   return *this;
100 }
101 
102 uint32_t
GetSerializedSize(void) const103 Tlv::GetSerializedSize (void) const
104 {
105   return 1 + GetSizeOfLen () + m_value->GetSerializedSize ();
106 }
107 
108 uint8_t
GetSizeOfLen(void) const109 Tlv::GetSizeOfLen (void) const
110 {
111   uint8_t sizeOfLen = 1;
112 
113   if (m_length > 127)
114     {
115       sizeOfLen = 2;
116       uint64_t testValue = 0xFF;
117       while (m_length > testValue)
118         {
119           sizeOfLen++;
120           testValue *= 0xFF;
121         }
122     }
123   return sizeOfLen;
124 }
125 
126 void
Serialize(Buffer::Iterator i) const127 Tlv::Serialize (Buffer::Iterator i) const
128 {
129   i.WriteU8 (m_type);
130   uint8_t lenSize = GetSizeOfLen ();
131   if (lenSize == 1)
132     {
133       i.WriteU8 (m_length);
134     }
135   else
136     {
137       i.WriteU8 ((lenSize-1) | WIMAX_TLV_EXTENDED_LENGTH_MASK);
138       for (int j = 0; j < lenSize - 1; j++)
139         {
140           i.WriteU8 ((uint8_t)(m_length >> ((lenSize - 1 - 1 - j) * 8)));
141         }
142     }
143   m_value->Serialize (i);
144 }
145 
146 uint32_t
Deserialize(Buffer::Iterator i)147 Tlv::Deserialize (Buffer::Iterator i)
148 {
149   // read the type of tlv
150   m_type = i.ReadU8 ();
151 
152   // read the length
153   uint8_t lenSize = i.ReadU8 ();
154   uint32_t serializedSize = 2;
155   if (lenSize < 127)
156     {
157       m_length = lenSize;
158     }
159   else
160     {
161       lenSize &= ~WIMAX_TLV_EXTENDED_LENGTH_MASK;
162       for (int j = 0; j < lenSize; j++)
163         {
164           m_length <<= 8;
165           m_length |= i.ReadU8 ();
166           serializedSize++;
167         }
168     }
169   switch (m_type)
170     {
171     case HMAC_TUPLE:
172       /// \todo implement Deserialize HMAC_TUPLE
173       NS_FATAL_ERROR ("Not implemented-- please implement and contribute a patch");
174       break;
175     case MAC_VERSION_ENCODING:
176       /// \todo implement Deserialize MAC_VERSION_ENCODING
177       NS_FATAL_ERROR ("Not implemented-- please implement and contribute a patch");
178       break;
179     case CURRENT_TRANSMIT_POWER:
180       /// \todo implement Deserialize CURRENT_TRANSMIT_POWER
181       NS_FATAL_ERROR ("Not implemented-- please implement and contribute a patch");
182       break;
183     case DOWNLINK_SERVICE_FLOW:
184       {
185         SfVectorTlvValue val;
186         serializedSize += val.Deserialize (i, m_length);
187         m_value = val.Copy ();
188         break;
189       }
190     case UPLINK_SERVICE_FLOW:
191       {
192         SfVectorTlvValue val;
193         serializedSize += val.Deserialize (i, m_length);
194         m_value = val.Copy ();
195         break;
196       }
197     case VENDOR_ID_EMCODING:
198       /// \todo implement Deserialize VENDOR_ID_EMCODING
199       NS_FATAL_ERROR ("Not implemented-- please implement and contribute a patch");
200       break;
201     case VENDOR_SPECIFIC_INFORMATION:
202       /// \todo implement Deserialize  VENDOR_SPECIFIC_INFORMATION
203       NS_FATAL_ERROR ("Not implemented-- please implement and contribute a patch");
204       break;
205     default:
206       NS_ASSERT_MSG (false, "Unknown tlv type.");
207       break;
208     }
209 
210   return serializedSize;
211 }
212 
213 uint8_t
GetType(void) const214 Tlv::GetType (void) const
215 {
216   return m_type;
217 }
218 uint64_t
GetLength(void) const219 Tlv::GetLength (void) const
220 {
221   return m_length;
222 }
223 TlvValue*
PeekValue(void)224 Tlv::PeekValue (void)
225 {
226   return m_value;
227 }
228 
229 Tlv *
Copy(void) const230 Tlv::Copy (void) const
231 {
232   return new Tlv (m_type, m_length, *m_value);
233 }
234 // ==============================================================================
VectorTlvValue()235 VectorTlvValue::VectorTlvValue ()
236 {
237   m_tlvList = new std::vector<Tlv*>;
238 }
239 
~VectorTlvValue()240 VectorTlvValue::~VectorTlvValue ()
241 {
242   for (std::vector<Tlv*>::const_iterator iter = m_tlvList->begin (); iter != m_tlvList->end (); ++iter)
243     {
244       delete (*iter);
245     }
246   m_tlvList->clear ();
247   delete m_tlvList;
248 }
249 
250 uint32_t
GetSerializedSize(void) const251 VectorTlvValue::GetSerializedSize (void) const
252 {
253   uint32_t size = 0;
254   for (std::vector<Tlv*>::const_iterator iter = m_tlvList->begin (); iter != m_tlvList->end (); ++iter)
255     {
256       size += (*iter)->GetSerializedSize ();
257     }
258   return size;
259 }
260 
261 void
Serialize(Buffer::Iterator i) const262 VectorTlvValue::Serialize (Buffer::Iterator i) const
263 {
264   for (std::vector<Tlv*>::const_iterator iter = m_tlvList->begin (); iter != m_tlvList->end (); ++iter)
265     {
266       (*iter)->Serialize (i);
267       i.Next ((*iter)->GetSerializedSize ());
268     }
269 }
270 
271 VectorTlvValue::Iterator
Begin() const272 VectorTlvValue::Begin () const
273 {
274   return m_tlvList->begin ();
275 }
276 
277 VectorTlvValue::Iterator
End() const278 VectorTlvValue::End () const
279 {
280   return m_tlvList->end ();
281 }
282 
283 void
Add(const Tlv & val)284 VectorTlvValue::Add (const Tlv & val)
285 {
286   m_tlvList->push_back (val.Copy ());
287 }
288 
289 // ==============================================================================
SfVectorTlvValue()290 SfVectorTlvValue::SfVectorTlvValue ()
291 {
292 
293 }
294 
295 SfVectorTlvValue *
Copy(void) const296 SfVectorTlvValue::Copy (void) const
297 {
298   SfVectorTlvValue * tmp = new SfVectorTlvValue ();
299   for (std::vector<Tlv*>::const_iterator iter = Begin (); iter != End (); ++iter)
300     {
301       tmp->Add (Tlv ((*iter)->GetType (), (*iter)->GetLength (), *(*iter)->PeekValue ()));
302     }
303   return tmp;
304 }
305 
306 uint32_t
Deserialize(Buffer::Iterator i,uint64_t valueLen)307 SfVectorTlvValue::Deserialize (Buffer::Iterator i, uint64_t valueLen)
308 {
309   uint64_t serializedSize = 0;
310   while (serializedSize < valueLen)
311     {
312       uint8_t type = i.ReadU8 ();
313       // read the length
314       uint8_t lenSize = i.ReadU8 ();
315       serializedSize += 2;
316       uint64_t length = 0;
317       if (lenSize < 127)
318         {
319           length = lenSize;
320         }
321       else
322         {
323           lenSize &= ~WIMAX_TLV_EXTENDED_LENGTH_MASK;
324           for (int j = 0; j < lenSize; j++)
325             {
326               length <<= 8;
327               length |= i.ReadU8 ();
328               serializedSize++;
329             }
330         }
331       switch (type)
332         {
333         case SFID:
334           {
335             U32TlvValue val;
336             serializedSize += val.Deserialize (i);
337             Add (Tlv (SFID, 4, val));
338             break;
339           }
340         case CID:
341           {
342             U16TlvValue val;
343             serializedSize += val.Deserialize (i);
344             Add (Tlv (CID, 2, val));
345             break;
346           }
347         case Service_Class_Name:
348           NS_FATAL_ERROR ("Not implemented-- please implement and contribute a patch");
349           break;
350         case reserved1:
351           // NOTHING
352           break;
353         case QoS_Parameter_Set_Type:
354           {
355             U8TlvValue val;
356             serializedSize += val.Deserialize (i);
357             Add (Tlv (QoS_Parameter_Set_Type, 1, val));
358             break;
359           }
360         case Traffic_Priority:
361           {
362             U8TlvValue val;
363             serializedSize += val.Deserialize (i);
364             Add (Tlv (Traffic_Priority, 1, val));
365             break;
366           }
367         case Maximum_Sustained_Traffic_Rate:
368           {
369             U32TlvValue val;
370             serializedSize += val.Deserialize (i);
371             Add (Tlv (Maximum_Sustained_Traffic_Rate, 4, val));
372             break;
373           }
374         case Maximum_Traffic_Burst:
375           {
376             U32TlvValue val;
377             serializedSize += val.Deserialize (i);
378             Add (Tlv (Maximum_Traffic_Burst, 4, val));
379             break;
380           }
381         case Minimum_Reserved_Traffic_Rate:
382           {
383             U32TlvValue val;
384             serializedSize += val.Deserialize (i);
385             Add (Tlv (Minimum_Reserved_Traffic_Rate, 4, val));
386             break;
387           }
388         case Minimum_Tolerable_Traffic_Rate:
389           {
390             U32TlvValue val;
391             serializedSize += val.Deserialize (i);
392             Add (Tlv (Minimum_Tolerable_Traffic_Rate, 4, val));
393             break;
394           }
395         case Service_Flow_Scheduling_Type:
396           {
397             U8TlvValue val;
398             serializedSize += val.Deserialize (i);
399             Add (Tlv (Service_Flow_Scheduling_Type, 1, val));
400             break;
401           }
402         case Request_Transmission_Policy:
403           {
404             U32TlvValue val;
405             serializedSize += val.Deserialize (i);
406             Add (Tlv (Request_Transmission_Policy, 4, val));
407             break;
408           }
409         case Tolerated_Jitter:
410           {
411             U32TlvValue val;
412             serializedSize += val.Deserialize (i);
413             Add (Tlv (Tolerated_Jitter, 4, val));
414             break;
415           }
416         case Maximum_Latency:
417           {
418             U32TlvValue val;
419             serializedSize += val.Deserialize (i);
420             Add (Tlv (Maximum_Latency, 4, val));
421             break;
422           }
423         case Fixed_length_versus_Variable_length_SDU_Indicator:
424           {
425             U8TlvValue val;
426             serializedSize += val.Deserialize (i);
427             Add (Tlv (Fixed_length_versus_Variable_length_SDU_Indicator, 1, val));
428             break;
429           }
430         case SDU_Size:
431           {
432             U8TlvValue val;
433             serializedSize += val.Deserialize (i);
434             Add (Tlv (SDU_Size, 1, val));
435             break;
436           }
437         case Target_SAID:
438           {
439             U16TlvValue val;
440             serializedSize += val.Deserialize (i);
441             Add (Tlv (Target_SAID, 2, val));
442             break;
443           }
444         case ARQ_Enable:
445           {
446             U8TlvValue val;
447             serializedSize += val.Deserialize (i);
448             Add (Tlv (ARQ_Enable, 1, val));
449             break;
450           }
451         case ARQ_WINDOW_SIZE:
452           {
453             U16TlvValue val;
454             serializedSize += val.Deserialize (i);
455             Add (Tlv (ARQ_WINDOW_SIZE, 2, val));
456             break;
457           }
458         case ARQ_RETRY_TIMEOUT_Transmitter_Delay:
459           break;
460         case ARQ_RETRY_TIMEOUT_Receiver_Delay:
461           break;
462         case ARQ_BLOCK_LIFETIME:
463           break;
464         case ARQ_SYNC_LOSS:
465           break;
466         case ARQ_DELIVER_IN_ORDER:
467           break;
468         case ARQ_PURGE_TIMEOUT:
469           break;
470         case ARQ_BLOCK_SIZE:
471           break;
472         case reserved2:
473           break;
474         case CS_Specification:
475           {
476             U8TlvValue val;
477             serializedSize += val.Deserialize (i);
478             Add (Tlv (CS_Specification, 1, val));
479             break;
480           }
481         case IPV4_CS_Parameters:
482           {
483             CsParamVectorTlvValue val;
484             uint32_t size = val.Deserialize (i, length);
485             serializedSize += size;
486             Add (Tlv (IPV4_CS_Parameters, size, val));
487             break;
488           }
489         default:
490           NS_ASSERT_MSG (false, "Unknown tlv type.");
491           break;
492         }
493       i.Next (length);
494     }
495   return serializedSize;
496 }
497 
498 // ==============================================================================
499 
U8TlvValue(uint8_t value)500 U8TlvValue::U8TlvValue (uint8_t value)
501 {
502   m_value = value;
503 }
504 
U8TlvValue()505 U8TlvValue::U8TlvValue ()
506 {
507   m_value = 0;
508 }
509 
~U8TlvValue()510 U8TlvValue::~U8TlvValue ()
511 {
512 }
513 uint32_t
GetSerializedSize(void) const514 U8TlvValue::GetSerializedSize (void) const
515 {
516   return 1;
517 }
518 void
Serialize(Buffer::Iterator i) const519 U8TlvValue::Serialize (Buffer::Iterator i) const
520 {
521   i.WriteU8 (m_value);
522 }
523 uint32_t
Deserialize(Buffer::Iterator i,uint64_t valueLen)524 U8TlvValue::Deserialize (Buffer::Iterator i, uint64_t valueLen)
525 {
526   return Deserialize (i);
527 }
528 
529 uint32_t
Deserialize(Buffer::Iterator i)530 U8TlvValue::Deserialize (Buffer::Iterator i)
531 {
532   m_value = i.ReadU8 ();
533   return 1;
534 }
535 
536 uint8_t
GetValue(void) const537 U8TlvValue::GetValue (void) const
538 {
539   return m_value;
540 }
541 
542 U8TlvValue *
Copy(void) const543 U8TlvValue::Copy (void) const
544 {
545   U8TlvValue * tmp = new U8TlvValue (m_value);
546   return tmp;
547 }
548 // ==============================================================================
U16TlvValue(uint16_t value)549 U16TlvValue::U16TlvValue (uint16_t value)
550 {
551   m_value = value;
552 }
553 
U16TlvValue()554 U16TlvValue::U16TlvValue ()
555 {
556   m_value = 0;
557 }
558 
~U16TlvValue(void)559 U16TlvValue::~U16TlvValue (void)
560 {
561 }
562 
563 uint32_t
GetSerializedSize(void) const564 U16TlvValue::GetSerializedSize (void) const
565 {
566   return 2;
567 }
568 void
Serialize(Buffer::Iterator i) const569 U16TlvValue::Serialize (Buffer::Iterator i) const
570 {
571   i.WriteHtonU16 (m_value);
572 }
573 uint32_t
Deserialize(Buffer::Iterator i,uint64_t valueLen)574 U16TlvValue::Deserialize (Buffer::Iterator i, uint64_t valueLen)
575 {
576   return Deserialize (i);
577 }
578 
579 uint32_t
Deserialize(Buffer::Iterator i)580 U16TlvValue::Deserialize (Buffer::Iterator i)
581 {
582   m_value = i.ReadNtohU16 ();
583   return 2;
584 }
585 
586 uint16_t
GetValue(void) const587 U16TlvValue::GetValue (void) const
588 {
589   return m_value;
590 }
591 
592 U16TlvValue *
Copy(void) const593 U16TlvValue::Copy (void) const
594 {
595   U16TlvValue * tmp = new U16TlvValue (m_value);
596   return tmp;
597 }
598 // ==============================================================================
U32TlvValue(uint32_t value)599 U32TlvValue::U32TlvValue (uint32_t value)
600 {
601   m_value = value;
602 }
603 
U32TlvValue()604 U32TlvValue::U32TlvValue ()
605 {
606   m_value = 0;
607 }
608 
~U32TlvValue(void)609 U32TlvValue::~U32TlvValue (void)
610 {
611 }
612 
GetSerializedSize(void) const613 uint32_t U32TlvValue::GetSerializedSize (void) const
614 {
615   return 4;
616 }
617 void
Serialize(Buffer::Iterator i) const618 U32TlvValue::Serialize (Buffer::Iterator i) const
619 {
620   i.WriteHtonU32 (m_value);
621 }
622 uint32_t
Deserialize(Buffer::Iterator i,uint64_t valueLen)623 U32TlvValue::Deserialize (Buffer::Iterator i, uint64_t valueLen)
624 {
625   return Deserialize (i);
626 }
627 
628 uint32_t
Deserialize(Buffer::Iterator i)629 U32TlvValue::Deserialize (Buffer::Iterator i)
630 {
631   m_value = i.ReadNtohU32 ();
632   return 4;
633 }
634 uint32_t
GetValue(void) const635 U32TlvValue::GetValue (void) const
636 {
637   return m_value;
638 }
639 
640 U32TlvValue *
Copy(void) const641 U32TlvValue::Copy (void) const
642 {
643   U32TlvValue * tmp = new U32TlvValue (m_value);
644   return tmp;
645 }
646 // ==============================================================================
647 uint32_t
Deserialize(Buffer::Iterator i,uint64_t valueLength)648 CsParamVectorTlvValue::Deserialize (Buffer::Iterator i, uint64_t valueLength)
649 {
650   uint64_t serializedSize = 0;
651   uint8_t lenSize = 0;
652   uint8_t type = 0;
653   while (serializedSize < valueLength)
654     {
655       type = i.ReadU8 ();
656       // read the length
657       lenSize = i.ReadU8 ();
658       serializedSize += 2;
659       uint64_t length = 0;
660       if (lenSize < 127)
661         {
662           length = lenSize;
663         }
664       else
665         {
666           lenSize &= ~WIMAX_TLV_EXTENDED_LENGTH_MASK;
667           for (int j = 0; j < lenSize; j++)
668             {
669               length <<= 8;
670               length |= i.ReadU8 ();
671               serializedSize++;
672             }
673         }
674       switch (type)
675         {
676         case Classifier_DSC_Action:
677           {
678             U8TlvValue val;
679             serializedSize += val.Deserialize (i);
680             Add (Tlv (Classifier_DSC_Action, 1, val));
681             break;
682           }
683         case Packet_Classification_Rule:
684           {
685             ClassificationRuleVectorTlvValue val;
686             serializedSize += val.Deserialize (i, length);
687             Add (Tlv (Packet_Classification_Rule, val.GetSerializedSize (), val));
688             break;
689           }
690         }
691       i.Next (length);
692     }
693   return serializedSize;
694 }
695 
CsParamVectorTlvValue()696 CsParamVectorTlvValue::CsParamVectorTlvValue ()
697 {
698 
699 }
700 
701 CsParamVectorTlvValue *
Copy(void) const702 CsParamVectorTlvValue::Copy (void) const
703 {
704   CsParamVectorTlvValue * tmp = new CsParamVectorTlvValue ();
705   for (std::vector<Tlv*>::const_iterator iter = Begin (); iter != End (); ++iter)
706     {
707       tmp->Add (Tlv ((*iter)->GetType (), (*iter)->GetLength (), *(*iter)->PeekValue ()));
708     }
709   return tmp;
710 }
711 // ==============================================================================
712 
ClassificationRuleVectorTlvValue()713 ClassificationRuleVectorTlvValue::ClassificationRuleVectorTlvValue ()
714 {
715 
716 }
717 
718 ClassificationRuleVectorTlvValue *
Copy(void) const719 ClassificationRuleVectorTlvValue::Copy (void) const
720 {
721   ClassificationRuleVectorTlvValue * tmp = new ClassificationRuleVectorTlvValue ();
722   for (std::vector<Tlv*>::const_iterator iter = Begin (); iter != End (); ++iter)
723     {
724       tmp->Add (Tlv ((*iter)->GetType (), (*iter)->GetLength (), *(*iter)->PeekValue ()));
725     }
726   return tmp;
727 }
728 
729 uint32_t
Deserialize(Buffer::Iterator i,uint64_t valueLength)730 ClassificationRuleVectorTlvValue::Deserialize (Buffer::Iterator i, uint64_t valueLength)
731 {
732   uint64_t serializedSize = 0;
733   uint8_t lenSize = 0;
734   uint8_t type = 0;
735   while (serializedSize < valueLength)
736     {
737       type = i.ReadU8 ();
738       // read the length
739       lenSize = i.ReadU8 ();
740       serializedSize += 2;
741       uint64_t length = 0;
742       if (lenSize < 127)
743         {
744           length = lenSize;
745         }
746       else
747         {
748           lenSize &= ~WIMAX_TLV_EXTENDED_LENGTH_MASK;
749           for (int j = 0; j < lenSize; j++)
750             {
751               length <<= 8;
752               length |= i.ReadU8 ();
753               serializedSize++;
754             }
755         }
756       switch (type)
757         {
758         case Priority:
759           {
760             U8TlvValue val;
761             serializedSize += val.Deserialize (i);
762             Add (Tlv (Priority, 1, val));
763             break;
764           }
765         case ToS:
766           {
767             TosTlvValue val;
768             serializedSize += val.Deserialize (i, length);
769             Add (Tlv (ToS, val.GetSerializedSize (), val));
770             break;
771           }
772         case Protocol:
773           {
774             ProtocolTlvValue val;
775             serializedSize += val.Deserialize (i, length);
776             Add (Tlv (Protocol, val.GetSerializedSize (), val));
777             break;
778           }
779         case IP_src:
780           {
781             Ipv4AddressTlvValue val;
782             serializedSize += val.Deserialize (i, length);
783             Add (Tlv (IP_src, val.GetSerializedSize (), val));
784             break;
785           }
786         case IP_dst:
787           {
788             Ipv4AddressTlvValue val;
789             serializedSize += val.Deserialize (i, length);
790             Add (Tlv (IP_dst, val.GetSerializedSize (), val));
791             break;
792           }
793         case Port_src:
794           {
795             PortRangeTlvValue val;
796             serializedSize += val.Deserialize (i, length);
797             Add (Tlv (Port_src, val.GetSerializedSize (), val));
798             break;
799           }
800         case Port_dst:
801           {
802             PortRangeTlvValue val;
803             serializedSize += val.Deserialize (i, length);
804             Add (Tlv (Port_dst, val.GetSerializedSize (), val));
805             break;
806           }
807         case Index:
808           {
809             U16TlvValue val;
810             serializedSize += val.Deserialize (i);
811             Add (Tlv (Index, 2, val));
812             break;
813           }
814         }
815       i.Next (length);
816     }
817   return serializedSize;
818 }
819 
820 // ==============================================================================
TosTlvValue()821 TosTlvValue::TosTlvValue ()
822 {
823   m_low = 0;
824   m_high = 0;
825   m_mask = 0;
826 }
TosTlvValue(uint8_t low,uint8_t high,uint8_t mask)827 TosTlvValue::TosTlvValue (uint8_t low, uint8_t high, uint8_t mask)
828 {
829   m_low = low;
830   m_high = high;
831   m_mask = mask;
832 }
~TosTlvValue()833 TosTlvValue::~TosTlvValue ()
834 {
835 }
836 
837 uint32_t
GetSerializedSize(void) const838 TosTlvValue::GetSerializedSize (void) const
839 {
840   return 3;
841 }
842 void
Serialize(Buffer::Iterator i) const843 TosTlvValue::Serialize (Buffer::Iterator i) const
844 {
845   i.WriteU8 (m_low);
846   i.WriteU8 (m_high);
847   i.WriteU8 (m_mask);
848 }
849 uint32_t
Deserialize(Buffer::Iterator i,uint64_t valueLength)850 TosTlvValue::Deserialize (Buffer::Iterator i, uint64_t valueLength)
851 {
852   m_low = i.ReadU8 ();
853   m_high = i.ReadU8 ();
854   m_mask = i.ReadU8 ();
855   return 3;
856 }
857 uint8_t
GetLow(void) const858 TosTlvValue::GetLow (void) const
859 {
860   return m_low;
861 }
862 uint8_t
GetHigh(void) const863 TosTlvValue::GetHigh (void) const
864 {
865   return m_high;
866 }
867 uint8_t
GetMask(void) const868 TosTlvValue::GetMask (void) const
869 {
870   return m_mask;
871 }
872 
873 TosTlvValue *
Copy(void) const874 TosTlvValue::Copy (void) const
875 {
876   return new TosTlvValue (m_low, m_high, m_mask);
877 }
878 
879 // ==============================================================================
PortRangeTlvValue()880 PortRangeTlvValue::PortRangeTlvValue ()
881 {
882   m_portRange = new std::vector<struct PortRange>;
883 }
~PortRangeTlvValue()884 PortRangeTlvValue::~PortRangeTlvValue ()
885 {
886   m_portRange->clear ();
887   delete m_portRange;
888 }
889 
890 uint32_t
GetSerializedSize(void) const891 PortRangeTlvValue::GetSerializedSize (void) const
892 {
893   return m_portRange->size () * 4; // a port range is defined by 2 ports, each using 2 bytes
894 }
895 void
Serialize(Buffer::Iterator i) const896 PortRangeTlvValue::Serialize (Buffer::Iterator i) const
897 {
898   for (std::vector<struct PortRange>::const_iterator iter = m_portRange->begin (); iter != m_portRange->end (); ++iter)
899     {
900       i.WriteHtonU16 ((*iter).PortLow);
901       i.WriteHtonU16 ((*iter).PortHigh);
902     }
903 }
904 uint32_t
Deserialize(Buffer::Iterator i,uint64_t valueLength)905 PortRangeTlvValue::Deserialize (Buffer::Iterator i, uint64_t valueLength)
906 {
907   uint64_t len = 0;
908   while (len < valueLength)
909     {
910       uint16_t low = i.ReadNtohU16 ();
911       uint16_t high = i.ReadNtohU16 ();
912       Add (low, high);
913       len += 4;
914     }
915   return len;
916 }
917 void
Add(uint16_t portLow,uint16_t portHigh)918 PortRangeTlvValue::Add (uint16_t portLow, uint16_t portHigh)
919 {
920   struct PortRange tmp;
921   tmp.PortLow = portLow;
922   tmp.PortHigh = portHigh;
923   m_portRange->push_back (tmp);
924 }
925 PortRangeTlvValue::Iterator
Begin(void) const926 PortRangeTlvValue::Begin (void) const
927 {
928   return m_portRange->begin ();
929 }
930 
931 PortRangeTlvValue::Iterator
End(void) const932 PortRangeTlvValue::End (void) const
933 {
934   return m_portRange->end ();
935 }
936 
937 PortRangeTlvValue *
Copy(void) const938 PortRangeTlvValue::Copy (void) const
939 {
940   PortRangeTlvValue * tmp = new PortRangeTlvValue ();
941   for (std::vector<struct PortRange>::const_iterator iter = m_portRange->begin (); iter != m_portRange->end (); ++iter)
942     {
943       tmp->Add ((*iter).PortLow, (*iter).PortHigh);
944     }
945   return tmp;
946 }
947 
948 // ==============================================================================
949 
ProtocolTlvValue()950 ProtocolTlvValue::ProtocolTlvValue ()
951 {
952   m_protocol = new std::vector<uint8_t>;
953 }
~ProtocolTlvValue()954 ProtocolTlvValue::~ProtocolTlvValue ()
955 {
956   if (m_protocol != 0)
957     {
958       m_protocol->clear ();
959       delete m_protocol;
960       m_protocol = 0;
961     }
962 }
963 
964 uint32_t
GetSerializedSize(void) const965 ProtocolTlvValue::GetSerializedSize (void) const
966 {
967   return m_protocol->size ();
968 }
969 
970 void
Serialize(Buffer::Iterator i) const971 ProtocolTlvValue::Serialize (Buffer::Iterator i) const
972 {
973   for (std::vector<uint8_t>::const_iterator iter = m_protocol->begin (); iter != m_protocol->end (); ++iter)
974     {
975       i.WriteU8 ((*iter));
976     }
977 }
978 
979 uint32_t
Deserialize(Buffer::Iterator i,uint64_t valueLength)980 ProtocolTlvValue::Deserialize (Buffer::Iterator i, uint64_t valueLength)
981 {
982   uint64_t len = 0;
983   while (len < valueLength)
984     {
985       Add (i.ReadU8 ());
986       len++;
987     }
988   return len;
989 }
990 
991 void
Add(uint8_t protocol)992 ProtocolTlvValue::Add (uint8_t protocol)
993 {
994   m_protocol->push_back (protocol);
995 }
996 
997 ProtocolTlvValue::Iterator
Begin(void) const998 ProtocolTlvValue::Begin (void) const
999 {
1000   return m_protocol->begin ();
1001 }
1002 
1003 ProtocolTlvValue::Iterator
End(void) const1004 ProtocolTlvValue::End (void) const
1005 {
1006   return m_protocol->end ();
1007 }
1008 
1009 ProtocolTlvValue*
Copy(void) const1010 ProtocolTlvValue::Copy (void) const
1011 {
1012   ProtocolTlvValue* tmp = new ProtocolTlvValue ();
1013   for (std::vector<uint8_t>::const_iterator iter = m_protocol->begin (); iter != m_protocol->end (); ++iter)
1014     {
1015       tmp->Add ((*iter));
1016     }
1017   return tmp;
1018 }
1019 
1020 // ==============================================================================
1021 
Ipv4AddressTlvValue()1022 Ipv4AddressTlvValue::Ipv4AddressTlvValue ()
1023 {
1024   m_ipv4Addr = new std::vector<struct ipv4Addr>;
1025 }
1026 
~Ipv4AddressTlvValue()1027 Ipv4AddressTlvValue::~Ipv4AddressTlvValue ()
1028 {
1029   if (m_ipv4Addr != 0)
1030     {
1031       m_ipv4Addr->clear ();
1032       delete m_ipv4Addr;
1033       m_ipv4Addr = 0;
1034     }
1035 }
1036 
1037 uint32_t
GetSerializedSize(void) const1038 Ipv4AddressTlvValue::GetSerializedSize (void) const
1039 {
1040   return m_ipv4Addr->size () * 8; // IPv4 address and mask are 4 bytes each
1041 }
1042 
1043 void
Serialize(Buffer::Iterator i) const1044 Ipv4AddressTlvValue::Serialize (Buffer::Iterator i) const
1045 {
1046   for (std::vector<struct ipv4Addr>::const_iterator iter = m_ipv4Addr->begin (); iter != m_ipv4Addr->end (); ++iter)
1047     {
1048       i.WriteHtonU32 ((*iter).Address.Get ());
1049       i.WriteHtonU32 ((*iter).Mask.Get ());
1050     }
1051 }
1052 
1053 uint32_t
Deserialize(Buffer::Iterator i,uint64_t valueLength)1054 Ipv4AddressTlvValue::Deserialize (Buffer::Iterator i, uint64_t valueLength)
1055 {
1056   uint64_t len = 0;
1057   while (len < valueLength)
1058     {
1059       uint32_t addr = i.ReadNtohU32 ();
1060       uint32_t mask = i.ReadNtohU32 ();
1061       Add (Ipv4Address (addr), Ipv4Mask (mask));
1062       len += 8;
1063     }
1064   return len;
1065 }
1066 
1067 void
Add(Ipv4Address address,Ipv4Mask Mask)1068 Ipv4AddressTlvValue::Add (Ipv4Address address, Ipv4Mask Mask)
1069 {
1070   struct ipv4Addr tmp;
1071   tmp.Address = address;
1072   tmp.Mask = Mask;
1073   m_ipv4Addr->push_back (tmp);
1074 }
1075 
1076 Ipv4AddressTlvValue::Iterator
Begin() const1077 Ipv4AddressTlvValue::Begin () const
1078 {
1079   return m_ipv4Addr->begin ();
1080 }
1081 
1082 Ipv4AddressTlvValue::Iterator
End() const1083 Ipv4AddressTlvValue::End () const
1084 {
1085   return m_ipv4Addr->end ();
1086 }
1087 
1088 Ipv4AddressTlvValue *
Copy(void) const1089 Ipv4AddressTlvValue::Copy (void) const
1090 {
1091   Ipv4AddressTlvValue * tmp = new Ipv4AddressTlvValue ();
1092   for (std::vector<struct ipv4Addr>::const_iterator iter = m_ipv4Addr->begin (); iter != m_ipv4Addr->end (); ++iter)
1093     {
1094       tmp->Add ((*iter).Address, (*iter).Mask);
1095     }
1096   return tmp;
1097 }
1098 
1099 }
1100