A Discrete-Event Network Simulator
API
sixlowpan-header.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2013 Universita' di Firenze, Italy
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Tommaso Pecorella <tommaso.pecorella@unifi.it>
19  * Michele Muccio <michelemuccio@virgilio.it>
20  */
21 
22 #include "ns3/assert.h"
23 #include "ns3/log.h"
24 #include "ns3/abort.h"
25 #include "ns3/ipv6-header.h"
26 #include "ns3/mac64-address.h"
27 #include "ns3/mac16-address.h"
28 #include "ns3/ipv6-header.h"
29 #include "sixlowpan-header.h"
30 
31 
32 namespace ns3 {
33 
34 /*
35  * SixLowPanDispatch
36  */
37 
38 
40 {
41 }
42 
43 
46 {
47  if (dispatch <= LOWPAN_NALP_N)
48  {
49  return LOWPAN_NALP;
50  }
51  else if (dispatch == LOWPAN_IPv6)
52  {
53  return LOWPAN_IPv6;
54  }
55  else if (dispatch == LOWPAN_HC1)
56  {
57  return LOWPAN_HC1;
58  }
59  else if (dispatch == LOWPAN_BC0)
60  {
61  return LOWPAN_BC0;
62  }
63  else if ((dispatch >= LOWPAN_IPHC) && (dispatch <= LOWPAN_IPHC_N))
64  {
65  return LOWPAN_IPHC;
66  }
67  else if ((dispatch >= LOWPAN_MESH) && (dispatch <= LOWPAN_MESH_N))
68  {
69  return LOWPAN_MESH;
70  }
71  else if ((dispatch >= LOWPAN_FRAG1) && (dispatch <= LOWPAN_FRAG1_N))
72  {
73  return LOWPAN_FRAG1;
74  }
75  else if ((dispatch >= LOWPAN_FRAGN) && (dispatch <= LOWPAN_FRAGN_N))
76  {
77  return LOWPAN_FRAGN;
78  }
79  return LOWPAN_UNSUPPORTED;
80 }
81 
84 {
85  if ((dispatch >= LOWPAN_NHC) && (dispatch <= LOWPAN_NHC_N))
86  {
87  return LOWPAN_NHC;
88  }
89  else if ((dispatch >= LOWPAN_UDPNHC) && (dispatch <= LOWPAN_UDPNHC_N))
90  {
91  return LOWPAN_UDPNHC;
92  }
93  return LOWPAN_NHCUNSUPPORTED;
94 }
95 
96 
97 /*
98  * SixLowPanHc1
99  */
101 
103  : m_hopLimit (0)
104 {
105 }
106 
108 {
109  static TypeId tid = TypeId ("ns3::SixLowPanHc1")
110  .SetParent<Header> ()
111  .SetGroupName ("SixLowPan")
112  .AddConstructor<SixLowPanHc1> ();
113  return tid;
114 }
115 
117 {
118  return GetTypeId ();
119 }
120 
121 void SixLowPanHc1::Print (std::ostream & os) const
122 {
123  uint8_t encoding;
124  encoding = m_srcCompression;
125  encoding <<= 2;
126  encoding |= m_dstCompression;
127  encoding <<= 1;
128  encoding |= m_tcflCompression;
129  encoding <<= 2;
130  encoding |= m_nextHeaderCompression;
131  encoding <<= 1;
132  encoding |= m_hc2HeaderPresent;
133 
134  os << "encoding " << +encoding << ", hopLimit " << +m_hopLimit;
135 }
136 
138 {
139  uint32_t serializedSize = 3;
140 
141  switch (m_srcCompression)
142  {
143  case HC1_PIII:
144  serializedSize += 16;
145  break;
146  case HC1_PIIC:
147  serializedSize += 8;
148  break;
149  case HC1_PCII:
150  serializedSize += 8;
151  break;
152  case HC1_PCIC:
153  break;
154  }
155  switch (m_dstCompression)
156  {
157  case HC1_PIII:
158  serializedSize += 16;
159  break;
160  case HC1_PIIC:
161  serializedSize += 8;
162  break;
163  case HC1_PCII:
164  serializedSize += 8;
165  break;
166  case HC1_PCIC:
167  break;
168  }
169 
170  if (m_tcflCompression == false )
171  {
172  serializedSize += 4;
173  }
174 
176  {
177  serializedSize++;
178  }
179 
180  return serializedSize;
181 }
182 
184 {
186  uint8_t encoding;
187  encoding = m_srcCompression;
188  encoding <<= 2;
189  encoding |= m_dstCompression;
190  encoding <<= 1;
191  encoding |= m_tcflCompression;
192  encoding <<= 2;
193  encoding |= m_nextHeaderCompression;
194  encoding <<= 1;
195  encoding |= m_hc2HeaderPresent;
196 
198  i.WriteU8 (encoding);
199  i.WriteU8 (m_hopLimit);
200  switch (m_srcCompression)
201  {
202  case HC1_PIII:
203  for ( int j = 0; j < 8; j++ )
204  {
205  i.WriteU8 (m_srcPrefix[j]);
206  }
207  for ( int j = 0; j < 8; j++ )
208  {
209  i.WriteU8 (m_srcInterface[j]);
210  }
211  break;
212  case HC1_PIIC:
213  for ( int j = 0; j < 8; j++ )
214  {
215  i.WriteU8 (m_srcPrefix[j]);
216  }
217  break;
218  case HC1_PCII:
219  for ( int j = 0; j < 8; j++ )
220  {
221  i.WriteU8 (m_srcInterface[j]);
222  }
223  break;
224  case HC1_PCIC:
225  break;
226  }
227  switch (m_dstCompression)
228  {
229  case HC1_PIII:
230  for ( int j = 0; j < 8; j++ )
231  {
232  i.WriteU8 (m_dstPrefix[j]);
233  }
234  for ( int j = 0; j < 8; j++ )
235  {
236  i.WriteU8 (m_dstInterface[j]);
237  }
238  break;
239  case HC1_PIIC:
240  for ( int j = 0; j < 8; j++ )
241  {
242  i.WriteU8 (m_dstPrefix[j]);
243  }
244  break;
245  case HC1_PCII:
246  for ( int j = 0; j < 8; j++ )
247  {
248  i.WriteU8 (m_dstInterface[j]);
249  }
250  break;
251  case HC1_PCIC:
252  break;
253  }
254 
255  if ( m_tcflCompression == false )
256  {
258  uint8_t temp[3];
259  temp[0] = uint8_t (m_flowLabel & 0xff);
260  temp[1] = uint8_t ((m_flowLabel >> 8) & 0xff);
261  temp[2] = uint8_t ((m_flowLabel >> 16) & 0xff);
262  i.Write (temp, 3);
263  }
264 
266  {
267  i.WriteU8 (m_nextHeader);
268  }
269 
270  // TODO: HC2 is not yet supported. Should be.
271  NS_ASSERT_MSG ( m_hc2HeaderPresent != true, "Can not compress HC2, exiting. Very sorry." );
272 }
273 
275 {
277  uint32_t serializedSize = 3;
278 
279  uint8_t dispatch = i.ReadU8 ();
280  if (dispatch != SixLowPanDispatch::LOWPAN_HC1)
281  {
282  return 0;
283  }
284 
285  uint8_t encoding = i.ReadU8 ();
286  m_hopLimit = i.ReadU8 ();
287 
288  m_srcCompression = LowPanHc1Addr_e (encoding >> 6);
289  m_dstCompression = LowPanHc1Addr_e ( (encoding >> 4) & 0x3);
290  m_tcflCompression = (encoding >> 3) & 0x1;
291  m_nextHeaderCompression = LowPanHc1NextHeader_e ( (encoding >> 1) & 0x3);
292  m_hc2HeaderPresent = encoding & 0x1;
293 
294  switch (m_srcCompression)
295  {
296  case HC1_PIII:
297  for ( int j = 0; j < 8; j++)
298  {
299  m_srcPrefix[j] = i.ReadU8 ();
300  }
301  for ( int j = 0; j < 8; j++)
302  {
303  m_srcInterface[j] = i.ReadU8 ();
304  }
305  serializedSize += 16;
306  break;
307  case HC1_PIIC:
308  for ( int j = 0; j < 8; j++)
309  {
310  m_srcPrefix[j] = i.ReadU8 ();
311  }
312  serializedSize += 8;
313  break;
314  case HC1_PCII:
315  for ( int j = 0; j < 8; j++)
316  {
317  m_srcInterface[j] = i.ReadU8 ();
318  }
319  serializedSize += 8;
320  break;
321  case HC1_PCIC:
322  break;
323  }
324  switch (m_dstCompression)
325  {
326  case HC1_PIII:
327  for ( int j = 0; j < 8; j++)
328  {
329  m_dstPrefix[j] = i.ReadU8 ();
330  }
331  for ( int j = 0; j < 8; j++)
332  {
333  m_dstInterface[j] = i.ReadU8 ();
334  }
335  serializedSize += 16;
336  break;
337  case HC1_PIIC:
338  for ( int j = 0; j < 8; j++)
339  {
340  m_dstPrefix[j] = i.ReadU8 ();
341  }
342  serializedSize += 8;
343  break;
344  case HC1_PCII:
345  for ( int j = 0; j < 8; j++)
346  {
347  m_dstInterface[j] = i.ReadU8 ();
348  }
349  serializedSize += 8;
350  break;
351  case HC1_PCIC:
352  break;
353  }
354 
355  if ( m_tcflCompression == false )
356  {
357  m_trafficClass = i.ReadU8 ();
358  uint8_t temp[3];
359  i.Read (temp, 3);
360  m_flowLabel = temp[2];
361  m_flowLabel = (m_flowLabel << 8) | temp[1];
362  m_flowLabel = (m_flowLabel << 8) | temp[0];
363  serializedSize += 4;
364  }
365 
366  switch ( m_nextHeaderCompression )
367  {
368  case HC1_NC:
369  m_nextHeader = i.ReadU8 ();
370  serializedSize++;
371  break;
372  case HC1_TCP:
374  break;
375  case HC1_UDP:
377  break;
378  case HC1_ICMP:
380  break;
381  }
382 
383  NS_ASSERT_MSG ( m_hc2HeaderPresent != true, "Can not compress HC2, exiting. Very sorry." );
384 
385  return GetSerializedSize ();
386 }
387 
388 void SixLowPanHc1::SetHopLimit (uint8_t limit)
389 {
390  m_hopLimit = limit;
391 }
392 
394 {
395  return m_hopLimit;
396 }
397 
399 {
400  return m_dstCompression;
401 }
402 
403 const uint8_t* SixLowPanHc1::GetDstInterface () const
404 {
405  return m_dstInterface;
406 }
407 
408 const uint8_t* SixLowPanHc1::GetDstPrefix () const
409 {
410  return m_dstPrefix;
411 }
412 
413 uint32_t SixLowPanHc1::GetFlowLabel () const
414 {
415  return m_flowLabel;
416 }
417 
419 {
420  return m_nextHeader;
421 }
422 
424 {
425  return m_srcCompression;
426 }
427 
428 const uint8_t* SixLowPanHc1::GetSrcInterface () const
429 {
430  return m_srcInterface;
431 }
432 
433 const uint8_t* SixLowPanHc1::GetSrcPrefix () const
434 {
435  return m_srcPrefix;
436 }
437 
439 {
440  return m_trafficClass;
441 }
442 
444 {
445  return m_tcflCompression;
446 }
447 
449 {
450  return m_hc2HeaderPresent;
451 }
452 
454 {
455  m_dstCompression = dstCompression;
456 }
457 
458 void SixLowPanHc1::SetDstInterface (const uint8_t* dstInterface)
459 {
460  for ( int i = 0; i < 8; i++)
461  {
462  m_dstInterface[i] = dstInterface[i];
463  }
464 }
465 
466 void SixLowPanHc1::SetDstPrefix (const uint8_t* dstPrefix)
467 {
468  for ( int i = 0; i < 8; i++)
469  {
470  m_dstPrefix[i] = dstPrefix[i];
471  }
472 }
473 
474 void SixLowPanHc1::SetFlowLabel (uint32_t flowLabel)
475 {
476  m_flowLabel = flowLabel;
477 }
478 
479 void SixLowPanHc1::SetNextHeader (uint8_t nextHeader)
480 {
481  m_nextHeader = nextHeader;
482 
483  switch (m_nextHeader)
484  {
487  break;
490  break;
493  break;
494  default:
496  break;
497  }
498 }
499 
501 {
502  m_srcCompression = srcCompression;
503 }
504 
505 void SixLowPanHc1::SetSrcInterface (const uint8_t* srcInterface)
506 {
507  for ( int i = 0; i < 8; i++)
508  {
509  m_srcInterface[i] = srcInterface[i];
510  }
511 }
512 
513 void SixLowPanHc1::SetSrcPrefix (const uint8_t* srcPrefix)
514 {
515  for ( int i = 0; i < 8; i++)
516  {
517  m_srcPrefix[i] = srcPrefix[i];
518  }
519 }
520 
521 void SixLowPanHc1::SetTcflCompression (bool tcflCompression)
522 {
523  m_tcflCompression = tcflCompression;
524 }
525 
526 void SixLowPanHc1::SetTrafficClass (uint8_t trafficClass)
527 {
528  m_trafficClass = trafficClass;
529 }
530 
531 
532 void SixLowPanHc1::SetHc2HeaderPresent (bool hc2HeaderPresent)
533 {
534  m_hc2HeaderPresent = hc2HeaderPresent;
535 }
536 
537 
538 std::ostream & operator << (std::ostream & os, const SixLowPanHc1 & h)
539 {
540  h.Print (os);
541  return os;
542 }
543 
544 /*
545  * SixLowPanFrag1
546  */
547 NS_OBJECT_ENSURE_REGISTERED (SixLowPanFrag1);
548 
550  : m_datagramSize (0),
551  m_datagramTag (0)
552 {
553 }
554 
556 {
557  static TypeId tid = TypeId ("ns3::SixLowPanFrag1")
558  .SetParent<Header> ()
559  .SetGroupName ("SixLowPan")
560  .AddConstructor<SixLowPanFrag1> ();
561  return tid;
562 }
563 
565 {
566  return GetTypeId ();
567 }
568 
569 void SixLowPanFrag1::Print (std::ostream & os) const
570 {
571  os << "datagram size " << m_datagramSize << " tag " << m_datagramTag;
572 }
573 
575 {
576  return 4;
577 }
578 
580 {
582 
583  uint16_t temp = m_datagramSize | ( uint16_t (SixLowPanDispatch::LOWPAN_FRAG1) << 8 );
584 
585  i.WriteU8 (uint8_t (temp >> 8));
586  i.WriteU8 (uint8_t (temp & 0xff));
587 
589 }
590 
592 {
594 
595  uint8_t temp = i.ReadU8 ();
596  m_datagramSize = (uint16_t (temp) << 8) | i.ReadU8 ();
597  m_datagramSize &= 0x7FF;
598 
599  m_datagramTag = i.ReadU16 ();
600  return GetSerializedSize ();
601 }
602 
603 void SixLowPanFrag1::SetDatagramSize (uint16_t datagramSize)
604 {
605  m_datagramSize = datagramSize & 0x7FF;
606 }
607 
609 {
610  return m_datagramSize & 0x7FF;
611 }
612 
613 void SixLowPanFrag1::SetDatagramTag (uint16_t datagramTag)
614 {
615  m_datagramTag = datagramTag;
616 }
617 
619 {
620  return m_datagramTag;
621 }
622 
623 std::ostream & operator << (std::ostream & os, const SixLowPanFrag1 & h)
624 {
625  h.Print (os);
626  return os;
627 }
628 
629 
630 /*
631  * SixLowPanFragN
632  */
633 
634 NS_OBJECT_ENSURE_REGISTERED (SixLowPanFragN);
635 
637  : m_datagramSize (0),
638  m_datagramTag (0),
639  m_datagramOffset (0)
640 {
641 }
642 /*
643  * SixLowPanFragmentOffset
644  */
646 {
647  static TypeId tid = TypeId ("ns3::SixLowPanFragN")
648  .SetParent<Header> ()
649  .SetGroupName ("SixLowPan")
650  .AddConstructor<SixLowPanFragN> ();
651  return tid;
652 }
653 
655 {
656  return GetTypeId ();
657 }
658 
659 void SixLowPanFragN::Print (std::ostream & os) const
660 {
661  os << "datagram size " << m_datagramSize << " tag " << m_datagramTag << " offset " << +m_datagramOffset;
662 }
663 
665 {
666  return 5;
667 }
668 
670 {
672 
673  uint16_t temp = m_datagramSize | ( uint16_t (SixLowPanDispatch::LOWPAN_FRAGN) << 8 );
674 
675  i.WriteU8 (uint8_t (temp >> 8));
676  i.WriteU8 (uint8_t (temp & 0xff));
677 
680 }
681 
683 {
685 
686  uint8_t temp = i.ReadU8 ();
687  m_datagramSize = (uint16_t (temp) << 8) | i.ReadU8 ();
688  m_datagramSize &= 0x7FF;
689 
690  m_datagramTag = i.ReadU16 ();
691  m_datagramOffset = i.ReadU8 ();
692 
693  return GetSerializedSize ();
694 }
695 
696 void SixLowPanFragN::SetDatagramSize (uint16_t datagramSize)
697 {
698  m_datagramSize = datagramSize & 0x7FF;
699 }
700 
702 {
703  return m_datagramSize & 0x7FF;
704 }
705 
706 void SixLowPanFragN::SetDatagramTag (uint16_t datagramTag)
707 {
708  m_datagramTag = datagramTag;
709 }
710 
712 {
713  return m_datagramTag;
714 }
715 
716 void SixLowPanFragN::SetDatagramOffset (uint8_t datagramOffset)
717 {
718  m_datagramOffset = datagramOffset;
719 }
720 
722 {
723  return m_datagramOffset;
724 }
725 
726 std::ostream & operator << (std::ostream & os, const SixLowPanFragN & h)
727 {
728  h.Print (os);
729  return os;
730 }
731 
732 /*
733  * SixLowPanIpv6
734  */
735 
736 NS_OBJECT_ENSURE_REGISTERED (SixLowPanIpv6);
737 
739 {
740 }
741 
743 {
744  static TypeId tid = TypeId ("ns3::SixLowPanIpv6")
745  .SetParent<Header> ()
746  .SetGroupName ("SixLowPan")
747  .AddConstructor<SixLowPanIpv6> ();
748  return tid;
749 }
750 
752 {
753  return GetTypeId ();
754 }
755 
756 void SixLowPanIpv6::Print (std::ostream & os) const
757 {
758  os << "Uncompressed IPv6";
759 }
760 
762 {
763  return 1;
764 }
765 
767 {
769 
771 }
772 
774 {
776  i.ReadU8 ();
777 
778  return GetSerializedSize ();
779 }
780 
781 std::ostream & operator << (std::ostream & os, const SixLowPanIpv6 & h)
782 {
783  h.Print (os);
784  return os;
785 }
786 
787 /*
788  * SixLowPanIphcHeader
789  */
790 NS_OBJECT_ENSURE_REGISTERED (SixLowPanIphc);
791 
793 {
794  // 011x xxxx xxxx xxxx
795  m_baseFormat = 0x6000;
796 }
797 
799 {
800  // 011x xxxx xxxx xxxx
801  m_baseFormat = dispatch;
802  m_baseFormat <<= 8;
803 }
804 
806 {
807  static TypeId tid = TypeId ("ns3::SixLowPanIphc")
808  .SetParent<Header> ()
809  .SetGroupName ("SixLowPan")
810  .AddConstructor<SixLowPanIphc> ();
811  return tid;
812 }
813 
815 {
816  return GetTypeId ();
817 }
818 
819 void SixLowPanIphc::Print (std::ostream & os) const
820 {
821  os << "Compression kind: " << +m_baseFormat;
822 }
823 
825 {
826  uint32_t serializedSize = 2;
827 
828  if ( GetCid () )
829  {
830  serializedSize++;
831  }
832  switch ( GetTf () )
833  {
834  case TF_FULL:
835  serializedSize += 4;
836  break;
837  case TF_DSCP_ELIDED:
838  serializedSize += 3;
839  break;
840  case TF_FL_ELIDED:
841  serializedSize++;
842  break;
843  default:
844  break;
845  }
846  if ( GetNh () == false )
847  {
848  serializedSize++;
849  }
850  if ( GetHlim () == HLIM_INLINE)
851  {
852  serializedSize++;
853  }
854  switch (GetSam () )
855  {
856  case HC_INLINE:
857  if ( GetSac () == false )
858  {
859  serializedSize += 16;
860  }
861  break;
862  case HC_COMPR_64:
863  serializedSize += 8;
864  break;
865  case HC_COMPR_16:
866  serializedSize += 2;
867  break;
868  case HC_COMPR_0:
869  default:
870  break;
871  }
872  if ( GetM () == false)
873  {
874  switch (GetDam () )
875  {
876  case HC_INLINE:
877  if ( GetDac () == false )
878  {
879  serializedSize += 16;
880  }
881  break;
882  case HC_COMPR_64:
883  serializedSize += 8;
884  break;
885  case HC_COMPR_16:
886  serializedSize += 2;
887  break;
888  case HC_COMPR_0:
889  default:
890  break;
891  }
892  }
893  else
894  {
895  switch (GetDam () )
896  {
897  case HC_INLINE:
898  if ( GetDac () == false )
899  {
900  serializedSize += 16;
901  }
902  else
903  {
904  serializedSize += 6;
905  }
906  break;
907  case HC_COMPR_64:
908  if ( GetDac () == false )
909  {
910  serializedSize += 6;
911  }
912  break;
913  case HC_COMPR_16:
914  if ( GetDac () == false )
915  {
916  serializedSize += 4;
917  }
918  break;
919  case HC_COMPR_0:
920  default:
921  if ( GetDac () == false )
922  {
923  serializedSize++;
924  }
925  break;
926  }
927  }
928 
929 
930 
931  return serializedSize;
932 }
933 
935 {
937 
939 
940  if ( GetCid () )
941  {
943  }
944  // Traffic Class and Flow Label
945  switch ( GetTf () )
946  {
947  uint8_t temp;
948  case TF_FULL:
949  temp = (m_ecn << 6) | m_dscp;
950  i.WriteU8 (temp);
951  temp = m_flowLabel >> 16;
952  i.WriteU8 (temp);
953  temp = (m_flowLabel >> 8) & 0xff;
954  i.WriteU8 (temp);
955  temp = m_flowLabel & 0xff;
956  i.WriteU8 (temp);
957  break;
958  case TF_DSCP_ELIDED:
959  temp = (m_ecn << 6) | (m_flowLabel >> 16 );
960  i.WriteU8 (temp);
961  temp = (m_flowLabel >> 8) & 0xff;
962  i.WriteU8 (temp);
963  temp = m_flowLabel & 0xff;
964  i.WriteU8 (temp);
965  break;
966  case TF_FL_ELIDED:
967  temp = (m_ecn << 6) | m_dscp;
968  i.WriteU8 (temp);
969  break;
970  default:
971  break;
972  }
973  // Next Header
974  if ( GetNh () == false )
975  {
976  i.WriteU8 (m_nextHeader);
977  }
978  // Hop Limit
979  if ( GetHlim () == HLIM_INLINE )
980  {
981  i.WriteU8 (m_hopLimit);
982  }
983  // Source Address
984  switch (GetSam () )
985  {
986  uint8_t temp[16];
987  case HC_INLINE:
988  if ( GetSac () == false )
989  {
990  uint8_t temp[16];
991  m_srcAddress.Serialize (temp);
992  i.Write (temp, 16);
993  }
994  break;
995  case HC_COMPR_64:
996  m_srcAddress.Serialize (temp);
997  i.Write (temp + 8, 8);
998  break;
999  case HC_COMPR_16:
1000  m_srcAddress.Serialize (temp);
1001  i.Write (temp + 14, 2);
1002  break;
1003  case HC_COMPR_0:
1004  default:
1005  break;
1006  }
1007  // Destination Address
1008  if ( GetM () == false)
1009  {
1010  uint8_t temp[16];
1011  switch (GetDam () )
1012  {
1013  case HC_INLINE:
1014  if ( GetDac () == false )
1015  {
1016  m_dstAddress.Serialize (temp);
1017  i.Write (temp, 16);
1018  }
1019  break;
1020  case HC_COMPR_64:
1021  m_dstAddress.Serialize (temp);
1022  i.Write (temp + 8, 8);
1023  break;
1024  case HC_COMPR_16:
1025  m_dstAddress.Serialize (temp);
1026  i.Write (temp + 14, 2);
1027  break;
1028  case HC_COMPR_0:
1029  default:
1030  break;
1031  }
1032  }
1033  else
1034  {
1035  switch (GetDam () )
1036  {
1037  uint8_t temp[16];
1038  case HC_INLINE:
1039  if ( GetDac () == false )
1040  {
1041  m_dstAddress.Serialize (temp);
1042  i.Write (temp, 16);
1043  }
1044  else
1045  {
1046  m_dstAddress.Serialize (temp);
1047  i.Write (temp + 1, 2);
1048  i.Write (temp + 12, 4);
1049  }
1050  break;
1051  case HC_COMPR_64:
1052  if ( GetDac () == false )
1053  {
1054  m_dstAddress.Serialize (temp);
1055  i.Write (temp + 1, 1);
1056  i.Write (temp + 11, 5);
1057  }
1058  break;
1059  case HC_COMPR_16:
1060  if ( GetDac () == false )
1061  {
1062  m_dstAddress.Serialize (temp);
1063  i.Write (temp + 1, 1);
1064  i.Write (temp + 13, 3);
1065  }
1066  break;
1067  case HC_COMPR_0:
1068  default:
1069  if ( GetDac () == false )
1070  {
1071  m_dstAddress.Serialize (temp);
1072  i.WriteU8 (temp[15]);
1073  }
1074  break;
1075  }
1076  }
1077 }
1078 
1080 {
1081  Buffer::Iterator i = start;
1082 
1083  m_baseFormat = i.ReadNtohU16 ();
1084 
1085  if ( GetCid () )
1086  {
1087  m_srcdstContextId = i.ReadU8 ();
1088  }
1089  // Traffic Class and Flow Label
1090  switch ( GetTf () )
1091  {
1092  uint8_t temp;
1093  case TF_FULL:
1094  temp = i.ReadU8 ();
1095  m_ecn = temp >> 6;
1096  m_dscp = temp & 0x3F;
1097  temp = i.ReadU8 ();
1098  m_flowLabel = temp;
1099  temp = i.ReadU8 ();
1100  m_flowLabel = (m_flowLabel << 8) | temp;
1101  temp = i.ReadU8 ();
1102  m_flowLabel = (m_flowLabel << 8) | temp;
1103  break;
1104  case TF_DSCP_ELIDED:
1105  temp = i.ReadU8 ();
1106  m_ecn = temp >> 6;
1107  m_flowLabel = temp & 0x3F;
1108  temp = i.ReadU8 ();
1109  m_flowLabel = (m_flowLabel << 8) | temp;
1110  temp = i.ReadU8 ();
1111  m_flowLabel = (m_flowLabel << 8) | temp;
1112  break;
1113  case TF_FL_ELIDED:
1114  temp = i.ReadU8 ();
1115  m_ecn = temp >> 6;
1116  m_dscp = temp & 0x3F;
1117  break;
1118  default:
1119  break;
1120  }
1121  // Next Header
1122  if ( GetNh () == false )
1123  {
1124  m_nextHeader = i.ReadU8 ();
1125  }
1126  // Hop Limit
1127  switch ( GetHlim () )
1128  {
1129  case HLIM_INLINE:
1130  m_hopLimit = i.ReadU8 ();
1131  break;
1132  case HLIM_COMPR_1:
1133  m_hopLimit = 1;
1134  break;
1135  case HLIM_COMPR_64:
1136  m_hopLimit = 64;
1137  break;
1138  case HLIM_COMPR_255:
1139  default:
1140  m_hopLimit = 255;
1141  break;
1142 
1143  }
1144  // Source Address
1145  switch (GetSam () )
1146  {
1147  uint8_t temp[16];
1148  case HC_INLINE:
1149  if ( GetSac () == false )
1150  {
1151  i.Read (temp, 16);
1153  }
1154  break;
1155  case HC_COMPR_64:
1156  memset (temp, 0x00, sizeof (temp));
1157  i.Read (temp + 8, 8);
1158  temp[0] = 0xfe;
1159  temp[1] = 0x80;
1161  break;
1162  case HC_COMPR_16:
1163  memset (temp, 0x00, sizeof (temp));
1164  i.Read (temp + 14, 2);
1165  temp[0] = 0xfe;
1166  temp[1] = 0x80;
1167  temp[11] = 0xff;
1168  temp[12] = 0xfe;
1170  break;
1171  case HC_COMPR_0:
1172  default:
1173  break;
1174  }
1175  if ( GetSac () == true )
1176  {
1177  PostProcessSac ();
1178  }
1179  // Destination Address
1180  if ( GetM () == false)
1181  {
1182  uint8_t temp[16];
1183  switch (GetDam () )
1184  {
1185  case HC_INLINE:
1186  if ( GetDac () == false )
1187  {
1188  i.Read (temp, 16);
1190  }
1191  break;
1192  case HC_COMPR_64:
1193  memset (temp, 0x00, sizeof (temp));
1194  i.Read (temp + 8, 8);
1195  temp[0] = 0xfe;
1196  temp[1] = 0x80;
1198  break;
1199  case HC_COMPR_16:
1200  memset (temp, 0x00, sizeof (temp));
1201  i.Read (temp + 14, 2);
1202  temp[0] = 0xfe;
1203  temp[1] = 0x80;
1204  temp[11] = 0xff;
1205  temp[12] = 0xfe;
1207  break;
1208  case HC_COMPR_0:
1209  default:
1210  break;
1211  }
1212  }
1213  else
1214  {
1215  switch (GetDam () )
1216  {
1217  uint8_t temp[16];
1218  case HC_INLINE:
1219  if ( GetDac () == false )
1220  {
1221  i.Read (temp, 16);
1223  }
1224  else
1225  {
1226  memset (temp, 0x00, sizeof (temp));
1227  i.Read (temp + 1, 2);
1228  i.Read (temp + 12, 4);
1229  temp[0] = 0xff;
1231  }
1232  break;
1233  case HC_COMPR_64:
1234  if ( GetDac () == false )
1235  {
1236  memset (temp, 0x00, sizeof (temp));
1237  i.Read (temp + 1, 1);
1238  i.Read (temp + 11, 5);
1239  temp[0] = 0xff;
1241  }
1242  break;
1243  case HC_COMPR_16:
1244  if ( GetDac () == false )
1245  {
1246  memset (temp, 0x00, sizeof (temp));
1247  i.Read (temp + 1, 1);
1248  i.Read (temp + 13, 3);
1249  temp[0] = 0xff;
1251  }
1252  break;
1253  case HC_COMPR_0:
1254  default:
1255  if ( GetDac () == false )
1256  {
1257  memset (temp, 0x00, sizeof (temp));
1258  temp[15] = i.ReadU8 ();
1259  temp[0] = 0xff;
1260  temp[1] = 0x02;
1262  }
1263  break;
1264  }
1265  }
1266  if ( GetDac () == true )
1267  {
1268  PostProcessDac ();
1269  }
1270  return GetSerializedSize ();
1271 }
1272 
1274 {
1275  uint16_t field = tfField;
1276  m_baseFormat |= (field << 11);
1277 }
1278 
1280 {
1281  return TrafficClassFlowLabel_e ((m_baseFormat >> 11) & 0x3);
1282 }
1283 
1284 void SixLowPanIphc::SetNh (bool nhField)
1285 {
1286  uint16_t field = nhField;
1287  m_baseFormat |= (field << 10);
1288 }
1289 
1290 bool SixLowPanIphc::GetNh (void) const
1291 {
1292  return ((m_baseFormat >> 10) & 0x1);
1293 }
1294 
1296 {
1297  uint16_t field = hlimField;
1298  m_baseFormat |= (field << 8);
1299 }
1300 
1302 {
1303  return Hlim_e ((m_baseFormat >> 8) & 0x3);
1304 }
1305 
1306 void SixLowPanIphc::SetCid (bool cidField)
1307 {
1308  uint16_t field = cidField;
1309  m_baseFormat |= (field << 7);
1310 }
1311 
1312 bool SixLowPanIphc::GetCid (void) const
1313 {
1314  return ((m_baseFormat >> 7) & 0x1);
1315 }
1316 
1317 void SixLowPanIphc::SetSac (bool sacField)
1318 {
1319  uint16_t field = sacField;
1320  m_baseFormat |= (field << 6);
1321 }
1322 
1323 bool SixLowPanIphc::GetSac (void) const
1324 {
1325  return ((m_baseFormat >> 6) & 0x1);
1326 }
1327 
1329 {
1330  uint16_t field = samField;
1331  m_baseFormat |= (field << 4);
1332 }
1333 
1335 {
1336  return HeaderCompression_e ((m_baseFormat >> 4) & 0x3);
1337 }
1338 
1339 void SixLowPanIphc::SetM (bool mField)
1340 {
1341  uint16_t field = mField;
1342  m_baseFormat |= (field << 3);
1343 }
1344 
1345 bool SixLowPanIphc::GetM (void) const
1346 {
1347  return ((m_baseFormat >> 3) & 0x1);
1348 }
1349 
1350 void SixLowPanIphc::SetDac (bool dacField)
1351 {
1352  uint16_t field = dacField;
1353  m_baseFormat |= (field << 2);
1354 }
1355 
1356 bool SixLowPanIphc::GetDac (void) const
1357 {
1358  return ((m_baseFormat >> 2) & 0x1);
1359 }
1360 
1362 {
1363  uint16_t field = damField;
1364  m_baseFormat |= field;
1365 }
1366 
1368 {
1369  return HeaderCompression_e (m_baseFormat & 0x3);
1370 }
1371 
1372 void SixLowPanIphc::SetSrcContextId (uint8_t srcContextId)
1373 {
1374  NS_ASSERT_MSG (srcContextId < 16, "Src Context ID too large");
1375  m_srcdstContextId |= srcContextId << 4;
1376 }
1377 
1379 {
1380  return ( m_srcdstContextId >> 4);
1381 }
1382 
1383 void SixLowPanIphc::SetDstContextId (uint8_t dstContextId)
1384 {
1385  NS_ASSERT_MSG (dstContextId < 16, "Dst Context ID too large");
1386  m_srcdstContextId |= (dstContextId & 0xF);
1387 }
1388 
1390 {
1391  return (m_srcdstContextId & 0xF);
1392 }
1393 
1394 void SixLowPanIphc::SetEcn (uint8_t ecn)
1395 {
1396  NS_ASSERT_MSG (ecn < 4, "ECN too large");
1397  m_ecn = ecn;
1398 }
1399 
1400 uint8_t SixLowPanIphc::GetEcn (void) const
1401 {
1402  return m_ecn;
1403 }
1404 
1405 void SixLowPanIphc::SetDscp (uint8_t dscp)
1406 {
1407  NS_ASSERT_MSG (dscp < 64, "DSCP too large");
1408  m_dscp = dscp;
1409 }
1410 
1411 uint8_t SixLowPanIphc::GetDscp (void) const
1412 {
1413  return m_dscp;
1414 }
1415 
1416 void SixLowPanIphc::SetFlowLabel (uint32_t flowLabel)
1417 {
1418  NS_ASSERT_MSG (flowLabel < 0x100000, "Flow Label too large");
1419  m_flowLabel = flowLabel;
1420 }
1421 
1422 uint32_t SixLowPanIphc::GetFlowLabel (void) const
1423 {
1424  return m_flowLabel;
1425 }
1426 
1427 void SixLowPanIphc::SetNextHeader (uint8_t nextHeader)
1428 {
1429  m_nextHeader = nextHeader;
1430 }
1431 
1432 uint8_t SixLowPanIphc::GetNextHeader (void) const
1433 {
1434  return m_nextHeader;
1435 }
1436 
1437 void SixLowPanIphc::SetHopLimit (uint8_t hopLimit)
1438 {
1439  m_hopLimit = hopLimit;
1440 }
1441 
1442 uint8_t SixLowPanIphc::GetHopLimit (void) const
1443 {
1444  return m_hopLimit;
1445 }
1446 
1448 {
1449  m_srcAddress = srcAddress;
1450 }
1451 
1453 {
1454  return m_srcAddress;
1455 }
1456 
1458 {
1459  m_dstAddress = dstAddress;
1460 }
1461 
1463 {
1464  return m_dstAddress;
1465 }
1466 
1468 {
1469  NS_ABORT_MSG ("Unsupported; Context destination is not implemented");
1470  return;
1471 }
1472 
1474 {
1475  NS_ABORT_MSG ("Unsupported; Context destination is not implemented");
1476  return;
1477 }
1478 
1479 std::ostream & operator << (std::ostream & os, const SixLowPanIphc & h)
1480 {
1481  h.Print (os);
1482  return os;
1483 }
1484 
1485 /*
1486  * SixLowPanNhcExtensionHeader
1487  */
1488 NS_OBJECT_ENSURE_REGISTERED (SixLowPanNhcExtension);
1489 
1491 {
1492  // 1110 xxxx
1493  m_nhcExtensionHeader = 0xE0;
1494  m_nhcNextHeader = 0;
1495  m_nhcBlobLength = 0;
1496 }
1497 
1499 {
1500  static TypeId tid = TypeId ("ns3::SixLowPanNhcExtension")
1501  .SetParent<Header> ()
1502  .SetGroupName ("SixLowPan")
1503  .AddConstructor<SixLowPanNhcExtension> ();
1504  return tid;
1505 }
1506 
1508 {
1509  return GetTypeId ();
1510 }
1511 
1512 void SixLowPanNhcExtension::Print (std::ostream & os) const
1513 {
1514  os << "Compression kind: " << +m_nhcExtensionHeader << " Size: " << GetSerializedSize ();
1515 }
1516 
1518 {
1519  uint32_t serializedSize = 2;
1520  if ( GetNh () == false )
1521  {
1522  serializedSize++;
1523  }
1524  return serializedSize + m_nhcBlobLength;
1525 }
1526 
1528 {
1529  Buffer::Iterator i = start;
1531  if ( GetNh () == false )
1532  {
1534  }
1537 }
1538 
1540 {
1541  Buffer::Iterator i = start;
1543  if ( GetNh () == false )
1544  {
1545  m_nhcNextHeader = i.ReadU8 ();
1546  }
1547  m_nhcBlobLength = i.ReadU8 ();
1549 
1550  return GetSerializedSize ();
1551 }
1552 
1555 {
1557 }
1558 
1559 void SixLowPanNhcExtension::SetEid (Eid_e extensionHeaderType)
1560 {
1561  uint8_t field = extensionHeaderType;
1562  m_nhcExtensionHeader |= (field << 1);
1563 }
1564 
1566 {
1567  return Eid_e ((m_nhcExtensionHeader >> 1) & 0x7);
1568 }
1569 
1570 void SixLowPanNhcExtension::SetNextHeader (uint8_t nextHeader)
1571 {
1572  m_nhcNextHeader = nextHeader;
1573 }
1574 
1576 {
1577  return m_nhcNextHeader;
1578 }
1579 
1580 void SixLowPanNhcExtension::SetNh (bool nhField)
1581 {
1582  uint8_t field = nhField;
1583  m_nhcExtensionHeader |= field;
1584 }
1585 
1587 {
1588  return m_nhcExtensionHeader & 0x01;
1589 }
1590 
1591 void SixLowPanNhcExtension::SetBlob (const uint8_t* blob, uint32_t size)
1592 {
1593  NS_ASSERT_MSG ( size < 255, "Buffer too long" );
1594 
1595  m_nhcBlobLength = size;
1596  std::memcpy (m_nhcBlob, blob, size);
1597 }
1598 
1599 uint32_t SixLowPanNhcExtension::CopyBlob (uint8_t* blob, uint32_t size) const
1600 {
1601  NS_ASSERT_MSG ( size > m_nhcBlobLength, "Buffer too short" );
1602 
1603  std::memcpy (blob, m_nhcBlob, m_nhcBlobLength);
1604  return m_nhcBlobLength;
1605 }
1606 
1607 std::ostream & operator << (std::ostream & os, const SixLowPanNhcExtension & h)
1608 {
1609  h.Print (os);
1610  return os;
1611 }
1612 
1613 /*
1614  * SixLowPanUdpNhcExtension
1615  */
1616 NS_OBJECT_ENSURE_REGISTERED (SixLowPanUdpNhcExtension);
1617 
1619 {
1620  // 1111 0xxx
1621  m_baseFormat = 0xF0;
1622  m_checksum = 0;
1623  m_srcPort = 0;
1624  m_dstPort = 0;
1625 }
1626 
1628 {
1629  static TypeId tid = TypeId ("ns3::SixLowPanUdpNhcExtension")
1630  .SetParent<Header> ()
1631  .SetGroupName ("SixLowPan")
1632  .AddConstructor<SixLowPanUdpNhcExtension> ();
1633  return tid;
1634 }
1635 
1637 {
1638  return GetTypeId ();
1639 }
1640 
1641 void SixLowPanUdpNhcExtension::Print (std::ostream & os) const
1642 {
1643  os << "Compression kind: " << +m_baseFormat;
1644 }
1645 
1647 {
1648  uint32_t serializedSize = 1;
1649  if ( !GetC () )
1650  {
1651  serializedSize += 2;
1652  }
1653  switch (GetPorts ())
1654  {
1655  case PORTS_INLINE:
1656  serializedSize += 4;
1657  break;
1660  serializedSize += 3;
1661  break;
1663  serializedSize += 1;
1664  break;
1665  default:
1666  break;
1667  }
1668  return serializedSize;
1669 }
1670 
1672 {
1673  Buffer::Iterator i = start;
1674  i.WriteU8 (m_baseFormat);
1675  uint8_t temp;
1676 
1677  // Ports
1678  switch ( GetPorts () )
1679  {
1680  case PORTS_INLINE:
1681  i.WriteHtonU16 (m_srcPort);
1682  i.WriteHtonU16 (m_dstPort);
1683  break;
1685  i.WriteHtonU16 (m_srcPort);
1686  i.WriteU8 (m_dstPort & 0xff);
1687  break;
1689  i.WriteU8 (m_srcPort & 0xff);
1690  i.WriteHtonU16 (m_dstPort);
1691  break;
1693  temp = ((m_srcPort & 0xf) << 4) | (m_dstPort & 0xf);
1694  i.WriteU8 (temp);
1695  break;
1696  default:
1697  break;
1698  }
1699 
1700  // Checksum
1701  if ( !GetC () )
1702  {
1703  i.WriteU16 (m_checksum);
1704  }
1705 
1706 }
1707 
1709 {
1710  Buffer::Iterator i = start;
1711  m_baseFormat = i.ReadU8 ();
1712  uint8_t temp;
1713 
1714  // Ports
1715  switch ( GetPorts () )
1716  {
1717  case PORTS_INLINE:
1718  m_srcPort = i.ReadNtohU16 ();
1719  m_dstPort = i.ReadNtohU16 ();
1720  break;
1722  m_srcPort = i.ReadNtohU16 ();
1723  m_dstPort = i.ReadU8 ();
1724  break;
1726  m_srcPort = i.ReadU8 ();
1727  m_dstPort = i.ReadNtohU16 ();
1728  break;
1730  temp = i.ReadU8 ();
1731  m_srcPort = temp >> 4;
1732  m_dstPort = temp & 0xf;
1733  break;
1734  default:
1735  break;
1736  }
1737 
1738  // Checksum
1739  if ( !GetC () )
1740  {
1741  m_checksum = i.ReadU16 ();
1742  }
1743 
1744  return GetSerializedSize ();
1745 }
1746 
1749 {
1751 }
1752 
1754 {
1755  uint16_t field = ports;
1756  m_baseFormat |= field;
1757 }
1758 
1760 {
1761  return Ports_e (m_baseFormat & 0x3);
1762 }
1763 
1765 {
1766  m_srcPort = srcport;
1767 }
1768 
1770 {
1771  return m_srcPort;
1772 }
1773 
1775 {
1776  m_dstPort = dstport;
1777 }
1778 
1780 {
1781  return m_dstPort;
1782 }
1783 
1785 {
1786  uint16_t field = cField;
1787  m_baseFormat |= (field << 2);
1788 }
1789 
1791 {
1792  return ((m_baseFormat >> 2) & 0x1);
1793 }
1794 
1796 {
1797  m_checksum = checksum;
1798 }
1799 
1801 {
1802  return m_checksum;
1803 }
1804 
1805 std::ostream & operator << (std::ostream & os, const SixLowPanUdpNhcExtension & h)
1806 {
1807  h.Print (os);
1808  return os;
1809 }
1810 
1811 /*
1812  * SixLowPanBc0
1813  */
1814 NS_OBJECT_ENSURE_REGISTERED (SixLowPanBc0);
1815 
1817 {
1818  m_seqNumber = 66;
1819 }
1820 
1822 {
1823  static TypeId tid = TypeId ("ns3::SixLowPanBc0")
1824  .SetParent<Header> ()
1825  .SetGroupName ("SixLowPan")
1826  .AddConstructor<SixLowPanBc0> ();
1827  return tid;
1828 }
1829 
1831 {
1832  return GetTypeId ();
1833 }
1834 
1835 void SixLowPanBc0::Print (std::ostream & os) const
1836 {
1837  os << "Sequence number: " << +m_seqNumber;
1838 }
1839 
1841 {
1842  return 2;
1843 }
1844 
1846 {
1847  Buffer::Iterator i = start;
1848  i.WriteU8 (0x50);
1849  i.WriteU8 (m_seqNumber);
1850 
1851 }
1852 
1854 {
1855  Buffer::Iterator i = start;
1856  uint8_t dispatch = i.ReadU8 ();
1857 
1858  if (dispatch != 0x50)
1859  {
1860  return 0;
1861  }
1862 
1863  m_seqNumber = i.ReadU8 ();
1864 
1865  return GetSerializedSize ();
1866 }
1867 
1868 void SixLowPanBc0::SetSequenceNumber (uint8_t seqNumber)
1869 {
1870  m_seqNumber = seqNumber;
1871 }
1872 
1874 {
1875  return m_seqNumber;
1876 }
1877 
1878 std::ostream & operator << (std::ostream & os, const SixLowPanBc0 & h)
1879 {
1880  h.Print (os);
1881  return os;
1882 }
1883 
1884 /*
1885  * SixLowPanMesh
1886  */
1887 NS_OBJECT_ENSURE_REGISTERED (SixLowPanMesh);
1888 
1890 {
1891  m_hopsLeft = 0;
1892  m_src = Address ();
1893  m_dst = Address ();
1894  m_v = false;
1895  m_f = false;
1896 }
1897 
1899 {
1900  static TypeId tid = TypeId ("ns3::SixLowPanMesh")
1901  .SetParent<Header> ()
1902  .SetGroupName ("SixLowPan")
1903  .AddConstructor<SixLowPanMesh> ();
1904  return tid;
1905 }
1906 
1908 {
1909  return GetTypeId ();
1910 }
1911 
1912 void SixLowPanMesh::Print (std::ostream & os) const
1913 {
1914  os << "Hops left: " << +m_hopsLeft << ", src: ";
1916  {
1918  }
1919  else
1920  {
1922  }
1923  os << ", dst: ";
1925  {
1927  }
1928  else
1929  {
1931  }
1932 }
1933 
1935 {
1936  uint32_t serializedSize = 1;
1937 
1938  if (m_hopsLeft >= 0xF)
1939  {
1940  serializedSize++;
1941  }
1942 
1943  if (m_v)
1944  {
1945  serializedSize += 2;
1946  }
1947  else
1948  {
1949  serializedSize += 8;
1950  }
1951 
1952  if (m_f)
1953  {
1954  serializedSize += 2;
1955  }
1956  else
1957  {
1958  serializedSize += 8;
1959  }
1960 
1961  return serializedSize;
1962 }
1963 
1965 {
1966  Buffer::Iterator i = start;
1967 
1968  uint8_t dispatch = 0x80;
1969 
1970  if (m_v)
1971  {
1972  dispatch |= 0x20;
1973  }
1974  if (m_f)
1975  {
1976  dispatch |= 0x10;
1977  }
1978 
1979  if (m_hopsLeft < 0xF)
1980  {
1981  dispatch |= m_hopsLeft;
1982  i.WriteU8 (dispatch);
1983  }
1984  else
1985  {
1986  dispatch |= 0xF;
1987  i.WriteU8 (dispatch);
1988  i.WriteU8 (m_hopsLeft);
1989  }
1990 
1991  uint8_t buffer[8];
1992 
1993  m_src.CopyTo (buffer);
1994  if (m_v)
1995  {
1996  i.Write (buffer, 2);
1997  }
1998  else
1999  {
2000  i.Write (buffer, 8);
2001  }
2002 
2003  m_dst.CopyTo (buffer);
2004  if (m_f)
2005  {
2006  i.Write (buffer, 2);
2007  }
2008  else
2009  {
2010  i.Write (buffer, 8);
2011  }
2012 }
2013 
2015 {
2016  Buffer::Iterator i = start;
2017  uint8_t temp = i.ReadU8 ();
2018 
2019  if ((temp & 0xC0) != 0x80)
2020  {
2021  return 0;
2022  }
2023 
2024  m_v = temp & 0x20;
2025  m_f = temp & 0x10;
2026  m_hopsLeft = temp & 0xF;
2027 
2028  if (m_hopsLeft == 0xF)
2029  {
2030  m_hopsLeft = i.ReadU8 ();
2031  }
2032 
2033  uint8_t buffer[8];
2034  uint8_t addrSize;
2035 
2036  if (m_v)
2037  {
2038  addrSize = 2;
2039  }
2040  else
2041  {
2042  addrSize = 8;
2043  }
2044  i.Read (buffer, addrSize);
2045  m_src.CopyFrom (buffer, addrSize);
2046 
2047  if (m_f)
2048  {
2049  addrSize = 2;
2050  }
2051  else
2052  {
2053  addrSize = 8;
2054  }
2055  i.Read (buffer, addrSize);
2056  m_dst.CopyFrom (buffer, addrSize);
2057 
2058  return GetSerializedSize ();
2059 }
2060 
2062 {
2063  if (Mac64Address::IsMatchingType (originator))
2064  {
2065  m_v = false;
2066  }
2067  else if (Mac16Address::IsMatchingType (originator))
2068  {
2069  m_v = true;
2070  }
2071  else
2072  {
2073  NS_ABORT_MSG ("SixLowPanMesh::SetOriginator - incompatible address");
2074  }
2075 
2076  m_src = originator;
2077 }
2078 
2080 {
2081  return m_src;
2082 }
2083 
2085 {
2086  if (Mac64Address::IsMatchingType (finalDst))
2087  {
2088  m_f = false;
2089  }
2090  else if (Mac16Address::IsMatchingType (finalDst))
2091  {
2092  m_f = true;
2093  }
2094  else
2095  {
2096  NS_ABORT_MSG ("SixLowPanMesh::SetFinalDst - incompatible address");
2097  }
2098 
2099  m_dst = finalDst;
2100 }
2101 
2103 {
2104  return m_dst;
2105 }
2106 
2107 void SixLowPanMesh::SetHopsLeft (uint8_t hopsLeft)
2108 {
2109  m_hopsLeft = hopsLeft;
2110 }
2111 
2112 uint8_t SixLowPanMesh::GetHopsLeft (void) const
2113 {
2114  return m_hopsLeft;
2115 }
2116 
2117 std::ostream & operator << (std::ostream & os, const SixLowPanMesh & h)
2118 {
2119  h.Print (os);
2120  return os;
2121 }
2122 
2123 }
2124 
uint16_t ReadU16(void)
Definition: buffer.h:1029
uint8_t GetEcn(void) const
Get the ECN.
Protocol header serialization and deserialization.
Definition: header.h:42
static TypeId GetTypeId(void)
Get the type ID.
void SetCid(bool cidField)
Set the CID (Context Identifier Extension) compression.
uint8_t GetNextHeader(void) const
Get the Next Header field value.
Address GetOriginator(void) const
Get the "Originator" address.
NhcDispatch_e
Dispatch values for Next Header compression.
uint8_t GetDstContextId(void) const
Get the DstContextId.
void SetTcflCompression(bool tcflCompression)
Set the Traffic Class and Flow Labels as compressed.
uint8_t m_ecn
ECN bits.
Ipv6Address m_dstAddress
Dst address.
TrafficClassFlowLabel_e
TF: Traffic Class, Flow Label.
uint16_t m_dstPort
Destination port.
static TypeId GetTypeId(void)
Get the type ID.
void SetHopLimit(uint8_t hopLimit)
Set the Hop Limit field.
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:50
void SetDstCompression(LowPanHc1Addr_e dstCompression)
Set Destination Compression type.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
static TypeId GetTypeId(void)
Get the type ID.
uint8_t GetHopsLeft(void) const
Get the "Hops Left" field.
6LoWPAN IPv6 uncompressed header - see RFC 4944.
uint8_t GetDscp(void) const
Get the DSCP.
uint16_t GetDstPort() const
Get the Destination Port.
void SetNextHeader(uint8_t nextHeader)
Set the Next Header field values.
bool m_f
True if Destination address is 16 bit.
uint8_t GetSequenceNumber(void) const
Get the "Sequence Number" field.
static Mac16Address ConvertFrom(const Address &address)
virtual void Print(std::ostream &os) const
static bool IsMatchingType(const Address &address)
uint8_t m_nhcBlob[256]
NHC compressed header.
static Ipv6Address Deserialize(const uint8_t buf[16])
Deserialize this address.
virtual void Serialize(Buffer::Iterator start) const
Serialize the packet.
static Dispatch_e GetDispatchType(uint8_t dispatch)
Get the Dispatch type.
LOWPAN_IPHC base Encoding - see RFC 6282.
def start()
Definition: core.py:1855
void PostProcessDac()
Post-process the Destination address stateful compression.
Hlim_e GetHlim(void) const
Get the HLIM (Hop Limit) compression.
void SetPorts(Ports_e port)
Set the compressed Src and Dst Ports.
void SetSrcCompression(LowPanHc1Addr_e srcCompression)
Set Source Compression type.
void SetSrcContextId(uint8_t srcContextId)
Set the SrcContextId.
virtual uint32_t GetSerializedSize(void) const
Get the serialized size of the packet.
HeaderCompression_e GetSam(void) const
Get the SAM (Source Address Mode) compression.
LowPanHc1Addr_e m_srcCompression
Source compression type.
bool GetNh(void) const
Get the Next Header field value.
LOWPAN_NHC Extension Header Encoding - see RFC 6282.
Hlim_e
HLIM: Hop Limit.
void SetDatagramOffset(uint8_t datagramOffset)
Set the datagram offset.
void SetSam(HeaderCompression_e samField)
Set the SAM (Source Address Mode) compression.
6LoWPAN FRAGN header - see RFC 4944.
uint32_t GetFlowLabel(void) const
Get the Flow Label.
uint8_t m_seqNumber
Sequence number.
virtual uint32_t GetSerializedSize(void) const
Get the serialized size of the packet.
void SetDatagramSize(uint16_t datagramSize)
Set the datagram size.
virtual uint32_t Deserialize(Buffer::Iterator start)
Deserialize the packet.
static TypeId GetTypeId(void)
Get the type ID.
const uint8_t * GetSrcInterface() const
Get the source interface.
virtual uint32_t Deserialize(Buffer::Iterator start)
Deserialize the packet.
void SetTrafficClass(uint8_t trafficClass)
Set the Traffic Class value.
iterator in a Buffer instance
Definition: buffer.h:98
a polymophic address class
Definition: address.h:90
uint8_t m_srcPrefix[8]
Source prefix.
void SetSequenceNumber(uint8_t seqNumber)
Set the "Sequence Number" field.
virtual uint32_t GetSerializedSize(void) const
Get the serialized size of the packet.
void SetHopsLeft(uint8_t hopsLeft)
Set the "Hops Left" field.
virtual uint32_t GetSerializedSize(void) const
Get the serialized size of the packet.
static TypeId GetTypeId(void)
Get the type ID.
void SetHlim(Hlim_e hlimField)
Set the HLIM (Hop Limit) compression.
virtual void Print(std::ostream &os) const
uint16_t m_srcPort
Source port.
virtual void Print(std::ostream &os) const
uint8_t GetHopLimit(void) const
Get the "Hop limit" field (TTL).
uint8_t GetSrcContextId(void) const
Get the SrcContextId.
void SetBlob(const uint8_t *blob, uint32_t size)
Set the option header data blob.
HeaderCompression_e GetDam(void) const
Get the DAM (Destination Address Mode) compression.
void SetHc2HeaderPresent(bool hc2HeaderPresent)
Set the next header a HC2 compressed header.
Address GetFinalDst(void) const
Get the "Final Destination" address.
void SetDscp(uint8_t dscp)
Set the DSCP (6bits).
uint16_t m_datagramTag
Datagram tag.
uint8_t m_hopLimit
Hop Limit.
virtual void Serialize(Buffer::Iterator start) const
Serialize the packet.
virtual TypeId GetInstanceTypeId(void) const
Return the instance type identifier.
Address m_src
Originator (source) address.
void SetDstInterface(const uint8_t *dstInterface)
Set the destination interface.
LowPanHc1Addr_e m_dstCompression
Destination compression type.
Address m_dst
Destination (final) address.
bool GetNh(void) const
Get the NH (Next Header) compression.
void SetOriginator(Address originator)
Set the "Originator" address.
void SetSac(bool sacField)
Set the SAC (Source Address Compression) compression.
void WriteU16(uint16_t data)
Definition: buffer.cc:870
void WriteHtonU16(uint16_t data)
Definition: buffer.h:905
6LoWPAN BC0 header - see RFC 4944.
uint16_t m_datagramSize
Datagram size.
void SetNh(bool nhField)
Set the NH (Next Header) compression.
virtual void Print(std::ostream &os) const
uint8_t m_hopsLeft
Hops left.
void SetChecksum(uint16_t checksum)
Set the Checksum field values.
static TypeId GetTypeId(void)
Get the type ID.
Ipv6Address GetSrcAddress() const
Get the Source Address.
uint8_t GetNextHeader(void) const
Get the Next Header field.
virtual void Serialize(Buffer::Iterator start) const
Serialize the packet.
void SetDstPort(uint16_t port)
Set the Destination Port.
virtual TypeId GetInstanceTypeId(void) const
Return the instance type identifier.
uint32_t m_flowLabel
Flow Label.
uint8_t GetTrafficClass() const
Get the Traffic Class value.
void SetDatagramSize(uint16_t datagramSize)
Set the datagram size.
static TypeId GetTypeId(void)
Get the type ID.
bool IsHc2HeaderPresent() const
Check if there is a HC2 compressed header.
virtual void Print(std::ostream &os) const
virtual void Print(std::ostream &os) const
void SetSrcPort(uint16_t port)
Set the Source Port.
virtual TypeId GetInstanceTypeId(void) const
Return the instance type identifier.
virtual TypeId GetInstanceTypeId(void) const
Return the instance type identifier.
std::ostream & operator<<(std::ostream &os, const Angles &a)
print a struct Angles to output
Definition: angles.cc:42
uint16_t m_datagramTag
Datagram tag.
virtual uint32_t Deserialize(Buffer::Iterator start)
Deserialize the packet.
virtual TypeId GetInstanceTypeId(void) const
Return the instance type identifier.
uint8_t m_dscp
DSCP bits.
const uint8_t * GetDstPrefix() const
Get the destination prefix.
static TypeId GetTypeId(void)
Get the type ID.
virtual uint32_t Deserialize(Buffer::Iterator start)
Deserialize the packet.
bool GetCid(void) const
Get the CID (Context Identifier Extension) compression.
virtual TypeId GetInstanceTypeId(void) const
Return the instance type identifier.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void SetNextHeader(uint8_t nextHeader)
Set the Next Header field.
TrafficClassFlowLabel_e GetTf(void) const
Get the TF (Traffic Class, Flow Label) compression.
uint32_t CopyFrom(const uint8_t *buffer, uint8_t len)
Definition: address.cc:101
virtual uint32_t Deserialize(Buffer::Iterator start)
Deserialize the packet.
virtual uint32_t GetSerializedSize(void) const
Get the serialized size of the packet.
bool IsTcflCompression() const
Check if the Traffic Class and Flow Labels are compressed.
virtual void Serialize(Buffer::Iterator start) const
Serialize the packet.
uint8_t m_trafficClass
Traffic Class.
virtual void Print(std::ostream &os) const
uint16_t GetSrcPort() const
Get the Source Port.
void SetDstContextId(uint8_t dstContextId)
Set the DstContextId.
virtual uint32_t GetSerializedSize(void) const
Get the serialized size of the packet.
LowPanHc1Addr_e GetDstCompression() const
Get Destination Compression type.
virtual SixLowPanDispatch::NhcDispatch_e GetNhcDispatchType(void) const
Get the NhcDispatch type.
void SetSrcAddress(Ipv6Address srcAddress)
Set the Source Address.
uint8_t GetDatagramOffset(void) const
Get the datagram offset.
LowPanHc1NextHeader_e m_nextHeaderCompression
Next header compression.
void Read(uint8_t *buffer, uint32_t size)
Definition: buffer.cc:1123
bool GetSac(void) const
Get the SAC (Source Address Compression) compression.
uint16_t GetChecksum(void) const
Get the Checksum field value.
virtual uint32_t Deserialize(Buffer::Iterator start)
Deserialize the packet.
uint16_t GetDatagramSize(void) const
Get the datagram size.
6LoWPAN HC1 header - see RFC 4944.
void SetHopLimit(uint8_t limit)
Set the "Hop limit" field (TTL).
void SetDac(bool dacField)
Set the DAC (Destination Address Compression) compression.
uint8_t m_hopLimit
Hop Limit.
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:88
uint8_t m_nhcExtensionHeader
NHC extension header type.
void SetSrcInterface(const uint8_t *srcInterface)
Set the source interface.
void SetDstPrefix(const uint8_t *dstPrefix)
Set the destination prefix.
uint16_t GetDatagramTag(void) const
Get the datagram tag.
virtual TypeId GetInstanceTypeId(void) const
Return the instance type identifier.
Describes an IPv6 address.
Definition: ipv6-address.h:49
Ipv6Address m_srcAddress
Src address.
uint32_t GetFlowLabel() const
Get the Flow Label value.
virtual uint32_t GetSerializedSize(void) const
Get the serialized size of the packet.
virtual void Serialize(Buffer::Iterator start) const
Serialize the packet.
void SetFlowLabel(uint32_t flowLabel)
Set the Flow Label (20bits).
void WriteU8(uint8_t data)
Definition: buffer.h:869
void SetFinalDst(Address finalDst)
Set the "Final Destination" address.
virtual uint32_t GetSerializedSize(void) const
Get the serialized size of the packet.
static Mac64Address ConvertFrom(const Address &address)
uint8_t m_datagramOffset
Datagram offset.
virtual void Serialize(Buffer::Iterator start) const
Serialize the packet.
bool m_tcflCompression
Is TC and FL compressed.
uint32_t m_flowLabel
Flow Label bits.
uint8_t GetHopLimit(void) const
Get the Hop Limit field.
virtual TypeId GetInstanceTypeId(void) const
Return the instance type identifier.
6LoWPAN Mesh header - see RFC 4944.
uint8_t m_dstPrefix[8]
Destination prefix.
virtual uint32_t Deserialize(Buffer::Iterator start)
Deserialize the packet.
uint16_t m_datagramSize
Datagram size.
uint8_t m_baseFormat
Dispatch + encoding fields.
uint8_t m_srcInterface[8]
Source interface.
LowPanHc1Addr_e GetSrcCompression() const
Get Source Compression type.
uint8_t m_nhcBlobLength
Length of the NHC compressed header.
virtual void Print(std::ostream &os) const
static NhcDispatch_e GetNhcDispatchType(uint8_t dispatch)
Get the NhcDispatch type.
uint16_t m_baseFormat
Dispatch + encoding fields.
Eid_e
EID: IPv6 Extension Header ID.
void SetEid(Eid_e extensionHeaderType)
Set the Extension Header Type.
uint8_t ReadU8(void)
Definition: buffer.h:1021
Eid_e GetEid(void) const
Get the Extension Header Type.
void Write(uint8_t const *buffer, uint32_t size)
Definition: buffer.cc:953
virtual void Serialize(Buffer::Iterator start) const
Serialize the packet.
bool m_hc2HeaderPresent
Is next header HC2 compressed.
Ports_e GetPorts(void) const
Get the compressed Src and Dst Ports.
void SetNh(bool nhField)
Set the NH field values.
uint8_t m_nhcNextHeader
Next header.
void SetTf(TrafficClassFlowLabel_e tfField)
Set the TF (Traffic Class, Flow Label) compression.
uint16_t GetDatagramSize(void) const
Get the datagram size.
virtual TypeId GetInstanceTypeId(void) const
Return the instance type identifier.
Dispatch_e
Dispatch values, as defined in RFC 4944 and RFC 6282
LowPanHc1NextHeader_e
Next header information.
virtual uint32_t GetSerializedSize(void) const
Get the serialized size of the packet.
HeaderCompression_e
Source or Destination Address Mode.
void SetDstAddress(Ipv6Address dstAddress)
Set the Destination Address.
uint8_t m_nextHeader
Next header.
static TypeId GetTypeId(void)
Get the type ID.
void SetM(bool mField)
Set the M (Multicast) compression.
virtual SixLowPanDispatch::NhcDispatch_e GetNhcDispatchType(void) const
Get the NhcDispatch type.
void SetSrcPrefix(const uint8_t *srcPrefix)
Set the source prefix.
bool GetM(void) const
Get the M (Multicast) compression.
virtual void Serialize(Buffer::Iterator start) const
Serialize the packet.
static bool IsMatchingType(const Address &address)
virtual uint32_t Deserialize(Buffer::Iterator start)
Deserialize the packet.
uint16_t ReadNtohU16(void)
Definition: buffer.h:946
virtual uint32_t Deserialize(Buffer::Iterator start)
Deserialize the packet.
uint32_t CopyBlob(uint8_t *blob, uint32_t size) const
Get the option header data blob.
void SetDatagramTag(uint16_t datagramTag)
Set the datagram tag.
void SetEcn(uint8_t ecn)
Set the ECN (2bits).
virtual void Serialize(Buffer::Iterator start) const
Serialize the packet.
bool GetC(void) const
Get the C (Checksum).
uint16_t GetDatagramTag(void) const
Get the datagram tag.
6LoWPAN FRAG1 header - see RFC 4944.
a unique identifier for an interface.
Definition: type-id.h:58
bool GetDac(void) const
Get the DAC (Destination Address Compression) compression.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:923
uint8_t m_dstInterface[8]
Destination interface.
UDP LOWPAN_NHC Extension Header Encoding - see RFC 6282.
uint8_t m_nextHeader
Next header.
void SetC(bool cField)
Set the C (Checksum).
const uint8_t * GetSrcPrefix() const
Get the source prefix.
uint8_t m_srcdstContextId
Src and Dst Context ID.
void SetNextHeader(uint8_t nextHeader)
Set the Next Header value.
void SetDam(HeaderCompression_e damField)
Set the DAM (Destination Address Mode) compression.
bool m_v
True if Originator address is 16 bit.
LowPanHc1Addr_e
Kind of address compression.
void SetFlowLabel(uint32_t flowLabel)
Set the Flow Label value.
void Serialize(uint8_t buf[16]) const
Serialize this address to a 16-byte buffer.
Ipv6Address GetDstAddress() const
Get the Destination Address.
void SetDatagramTag(uint16_t datagramTag)
Set the datagram tag.
uint32_t CopyTo(uint8_t buffer[MAX_SIZE]) const
Copy the address bytes into a buffer.
Definition: address.cc:82
void PostProcessSac()
Post-process the Source address stateful compression.
const uint8_t * GetDstInterface() const
Get the destination interface.
uint8_t GetNextHeader() const
Get the Next Header value.
virtual void Print(std::ostream &os) const