A Discrete-Event Network Simulator
API
wifi-mac-header.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2006, 2009 INRIA
3  * Copyright (c) 2009 MIRKO BANCHI
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  * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19  * Mirko Banchi <mk.banchi@gmail.com>
20  */
21 
22 #include "wifi-mac-header.h"
23 
24 #include "ns3/address-utils.h"
25 #include "ns3/nstime.h"
26 
27 namespace ns3
28 {
29 
30 NS_OBJECT_ENSURE_REGISTERED(WifiMacHeader);
31 
33 enum
34 {
35  TYPE_MGT = 0,
36  TYPE_CTL = 1,
37  TYPE_DATA = 2
38 };
39 
41 enum
42 {
43  // Reserved: 0 - 1
45  // Reserved: 3
57 };
58 
60  : m_ctrlMoreFrag(0),
61  m_ctrlRetry(0),
62  m_ctrlMoreData(0),
63  m_ctrlWep(0),
64  m_ctrlOrder(0),
65  m_duration(0),
66  m_seqFrag(0),
67  m_seqSeq(0),
68  m_qosEosp(0),
69  m_qosAckPolicy(0), // Normal Ack
70  m_amsduPresent(0)
71 {
72 }
73 
75  : WifiMacHeader()
76 {
77  SetType(type);
78 }
79 
81 {
82 }
83 
84 void
86 {
87  m_ctrlFromDs = 1;
88 }
89 
90 void
92 {
93  m_ctrlFromDs = 0;
94 }
95 
96 void
98 {
99  m_ctrlToDs = 1;
100 }
101 
102 void
104 {
105  m_ctrlToDs = 0;
106 }
107 
108 void
110 {
111  m_addr1 = address;
112 }
113 
114 void
116 {
117  m_addr2 = address;
118 }
119 
120 void
122 {
123  m_addr3 = address;
124 }
125 
126 void
128 {
129  m_addr4 = address;
130 }
131 
132 void
134 {
135  switch (type)
136  {
140  break;
144  break;
148  break;
152  break;
153  case WIFI_MAC_CTL_RTS:
156  break;
157  case WIFI_MAC_CTL_CTS:
160  break;
161  case WIFI_MAC_CTL_ACK:
164  break;
165  case WIFI_MAC_CTL_END:
168  break;
172  break;
175  m_ctrlSubtype = 0;
176  break;
179  m_ctrlSubtype = 1;
180  break;
183  m_ctrlSubtype = 2;
184  break;
187  m_ctrlSubtype = 3;
188  break;
191  m_ctrlSubtype = 4;
192  break;
195  m_ctrlSubtype = 5;
196  break;
197  case WIFI_MAC_MGT_BEACON:
199  m_ctrlSubtype = 8;
200  break;
203  m_ctrlSubtype = 10;
204  break;
207  m_ctrlSubtype = 11;
208  break;
211  m_ctrlSubtype = 12;
212  break;
213  case WIFI_MAC_MGT_ACTION:
215  m_ctrlSubtype = 13;
216  break;
219  m_ctrlSubtype = 14;
220  break;
223  m_ctrlSubtype = 15;
224  break;
225  case WIFI_MAC_DATA:
227  m_ctrlSubtype = 0;
228  break;
229  case WIFI_MAC_DATA_CFACK:
231  m_ctrlSubtype = 1;
232  break;
235  m_ctrlSubtype = 2;
236  break;
239  m_ctrlSubtype = 3;
240  break;
241  case WIFI_MAC_DATA_NULL:
243  m_ctrlSubtype = 4;
244  break;
247  m_ctrlSubtype = 5;
248  break;
251  m_ctrlSubtype = 6;
252  break;
255  m_ctrlSubtype = 7;
256  break;
257  case WIFI_MAC_QOSDATA:
259  m_ctrlSubtype = 8;
260  break;
263  m_ctrlSubtype = 9;
264  break;
267  m_ctrlSubtype = 10;
268  break;
271  m_ctrlSubtype = 11;
272  break;
275  m_ctrlSubtype = 12;
276  break;
279  m_ctrlSubtype = 14;
280  break;
283  m_ctrlSubtype = 15;
284  break;
285  default:
286  break;
287  }
288  if (resetToDsFromDs)
289  {
290  m_ctrlToDs = 0;
291  m_ctrlFromDs = 0;
292  }
293 }
294 
295 void
297 {
298  NS_ASSERT(duration <= 32768);
299  m_duration = duration;
300 }
301 
302 void
304 {
305  int64_t duration_us =
306  static_cast<int64_t>(ceil(static_cast<double>(duration.GetNanoSeconds()) / 1000));
307  NS_ASSERT(duration_us >= 0 && duration_us <= 0x7fff);
308  m_duration = static_cast<uint16_t>(duration_us);
309 }
310 
311 void
313 {
314  m_duration = id;
315 }
316 
317 void
319 {
320  m_seqSeq = seq;
321 }
322 
323 void
325 {
326  m_seqFrag = frag;
327 }
328 
329 void
331 {
332  m_ctrlMoreFrag = 0;
333 }
334 
335 void
337 {
338  m_ctrlMoreFrag = 1;
339 }
340 
341 void
343 {
344  m_ctrlOrder = 1;
345 }
346 
347 void
349 {
350  m_ctrlOrder = 0;
351 }
352 
353 void
355 {
356  m_ctrlRetry = 1;
357 }
358 
359 void
361 {
362  m_ctrlRetry = 0;
363 }
364 
365 void
367 {
368  m_qosTid = tid;
369 }
370 
371 void
373 {
374  m_qosEosp = 1;
375 }
376 
377 void
379 {
380  m_qosEosp = 0;
381 }
382 
383 void
385 {
386  switch (policy)
387  {
388  case NORMAL_ACK:
389  m_qosAckPolicy = 0;
390  break;
391  case NO_ACK:
392  m_qosAckPolicy = 1;
393  break;
394  case NO_EXPLICIT_ACK:
395  m_qosAckPolicy = 2;
396  break;
397  case BLOCK_ACK:
398  m_qosAckPolicy = 3;
399  break;
400  }
401 }
402 
403 void
405 {
406  m_amsduPresent = 1;
407 }
408 
409 void
411 {
412  m_amsduPresent = 0;
413 }
414 
415 void
417 {
418  m_qosStuff = txop;
419 }
420 
421 void
423 {
424  m_qosEosp = 1;
425  m_qosStuff = size;
426 }
427 
428 void
430 {
431  // Mark bit 0 of this variable instead of bit 8, since m_qosStuff is
432  // shifted by one byte when serialized
433  m_qosStuff = m_qosStuff | 0x01; // bit 8 of QoS Control Field
434 }
435 
436 void
438 {
439  // Clear bit 0 of this variable instead of bit 8, since m_qosStuff is
440  // shifted by one byte when serialized
441  m_qosStuff = m_qosStuff & 0xfe; // bit 8 of QoS Control Field
442 }
443 
446 {
447  return m_addr1;
448 }
449 
452 {
453  return m_addr2;
454 }
455 
458 {
459  return m_addr3;
460 }
461 
464 {
465  return m_addr4;
466 }
467 
470 {
471  switch (m_ctrlType)
472  {
473  case TYPE_MGT:
474  switch (m_ctrlSubtype)
475  {
476  case 0:
478  case 1:
480  case 2:
482  case 3:
484  case 4:
486  case 5:
488  case 8:
489  return WIFI_MAC_MGT_BEACON;
490  case 10:
492  case 11:
494  case 12:
496  case 13:
497  return WIFI_MAC_MGT_ACTION;
498  case 14:
500  case 15:
502  }
503  break;
504  case TYPE_CTL:
505  switch (m_ctrlSubtype)
506  {
507  case SUBTYPE_CTL_TRIGGER:
508  return WIFI_MAC_CTL_TRIGGER;
509  case SUBTYPE_CTL_BACKREQ:
510  return WIFI_MAC_CTL_BACKREQ;
512  return WIFI_MAC_CTL_BACKRESP;
513  case SUBTYPE_CTL_RTS:
514  return WIFI_MAC_CTL_RTS;
515  case SUBTYPE_CTL_CTS:
516  return WIFI_MAC_CTL_CTS;
517  case SUBTYPE_CTL_ACK:
518  return WIFI_MAC_CTL_ACK;
519  case SUBTYPE_CTL_END:
520  return WIFI_MAC_CTL_END;
521  case SUBTYPE_CTL_END_ACK:
522  return WIFI_MAC_CTL_END_ACK;
523  }
524  break;
525  case TYPE_DATA:
526  switch (m_ctrlSubtype)
527  {
528  case 0:
529  return WIFI_MAC_DATA;
530  case 1:
531  return WIFI_MAC_DATA_CFACK;
532  case 2:
533  return WIFI_MAC_DATA_CFPOLL;
534  case 3:
536  case 4:
537  return WIFI_MAC_DATA_NULL;
538  case 5:
540  case 6:
542  case 7:
544  case 8:
545  return WIFI_MAC_QOSDATA;
546  case 9:
547  return WIFI_MAC_QOSDATA_CFACK;
548  case 10:
550  case 11:
552  case 12:
553  return WIFI_MAC_QOSDATA_NULL;
554  case 14:
556  case 15:
558  }
559  break;
560  }
561  // NOTREACHED
562  NS_ASSERT(false);
563  return (WifiMacType)-1;
564 }
565 
566 bool
568 {
569  return m_ctrlFromDs == 1;
570 }
571 
572 bool
574 {
575  return m_ctrlToDs == 1;
576 }
577 
578 bool
580 {
581  return (m_ctrlType == TYPE_DATA);
582 }
583 
584 bool
586 {
587  return (m_ctrlType == TYPE_DATA && (m_ctrlSubtype & 0x08));
588 }
589 
590 bool
592 {
593  return (m_ctrlType == TYPE_CTL);
594 }
595 
596 bool
598 {
599  return (m_ctrlType == TYPE_MGT);
600 }
601 
602 bool
604 {
605  switch (GetType())
606  {
615  return true;
616  default:
617  return false;
618  }
619 }
620 
621 bool
623 {
624  switch (GetType())
625  {
626  case WIFI_MAC_CTL_END:
628  return true;
629  default:
630  return false;
631  }
632 }
633 
634 bool
636 {
637  switch (GetType())
638  {
639  case WIFI_MAC_DATA_CFACK:
644  return true;
645  default:
646  return false;
647  break;
648  }
649 }
650 
651 bool
653 {
654  switch (GetType())
655  {
656  case WIFI_MAC_DATA:
657  case WIFI_MAC_DATA_CFACK:
660  case WIFI_MAC_QOSDATA:
664  return true;
665  default:
666  return false;
667  }
668 }
669 
670 bool
672 {
673  return (GetType() == WIFI_MAC_CTL_RTS);
674 }
675 
676 bool
678 {
679  return (GetType() == WIFI_MAC_CTL_CTS);
680 }
681 
682 bool
684 {
685  return (GetType() == WIFI_MAC_CTL_ACK);
686 }
687 
688 bool
690 {
692 }
693 
694 bool
696 {
698 }
699 
700 bool
702 {
704 }
705 
706 bool
708 {
710 }
711 
712 bool
714 {
715  return (GetType() == WIFI_MAC_MGT_PROBE_REQUEST);
716 }
717 
718 bool
720 {
721  return (GetType() == WIFI_MAC_MGT_PROBE_RESPONSE);
722 }
723 
724 bool
726 {
727  return (GetType() == WIFI_MAC_MGT_BEACON);
728 }
729 
730 bool
732 {
733  return (GetType() == WIFI_MAC_MGT_DISASSOCIATION);
734 }
735 
736 bool
738 {
739  return (GetType() == WIFI_MAC_MGT_AUTHENTICATION);
740 }
741 
742 bool
744 {
746 }
747 
748 bool
750 {
751  return (GetType() == WIFI_MAC_MGT_ACTION);
752 }
753 
754 bool
756 {
757  return (GetType() == WIFI_MAC_MGT_ACTION_NO_ACK);
758 }
759 
760 bool
762 {
764 }
765 
766 bool
768 {
769  return (GetType() == WIFI_MAC_CTL_BACKREQ);
770 }
771 
772 bool
774 {
775  return (GetType() == WIFI_MAC_CTL_BACKRESP);
776 }
777 
778 bool
780 {
781  return (GetType() == WIFI_MAC_CTL_TRIGGER);
782 }
783 
784 uint16_t
786 {
787  return m_duration;
788 }
789 
790 Time
792 {
793  return MicroSeconds(m_duration);
794 }
795 
796 uint16_t
798 {
799  return (m_seqSeq << 4) | m_seqFrag;
800 }
801 
802 uint16_t
804 {
805  return m_seqSeq;
806 }
807 
808 uint8_t
810 {
811  return m_seqFrag;
812 }
813 
814 bool
816 {
817  return (m_ctrlRetry == 1);
818 }
819 
820 bool
822 {
823  return (m_ctrlMoreData == 1);
824 }
825 
826 bool
828 {
829  return (m_ctrlMoreFrag == 1);
830 }
831 
832 bool
834 {
835  NS_ASSERT(IsQosData());
836  return (m_qosAckPolicy == 3);
837 }
838 
839 bool
841 {
842  NS_ASSERT(IsQosData());
843  return (m_qosAckPolicy == 1);
844 }
845 
846 bool
848 {
849  NS_ASSERT(IsQosData());
850  return (m_qosAckPolicy == 0);
851 }
852 
853 bool
855 {
856  NS_ASSERT(IsQosData());
857  return (m_qosEosp == 1);
858 }
859 
862 {
863  NS_ASSERT(IsQosData());
864  QosAckPolicy policy;
865 
866  switch (m_qosAckPolicy)
867  {
868  case 0:
869  policy = NORMAL_ACK;
870  break;
871  case 1:
872  policy = NO_ACK;
873  break;
874  case 2:
875  policy = NO_EXPLICIT_ACK;
876  break;
877  case 3:
878  policy = BLOCK_ACK;
879  break;
880  default:
881  NS_ABORT_MSG("Unknown QoS Ack policy");
882  }
883  return policy;
884 }
885 
886 bool
888 {
889  NS_ASSERT(IsQosData());
890  return (m_amsduPresent == 1);
891 }
892 
893 uint8_t
895 {
896  NS_ASSERT(IsQosData());
897  return m_qosTid;
898 }
899 
900 uint8_t
902 {
903  NS_ASSERT(m_qosEosp == 1);
904  return m_qosStuff;
905 }
906 
907 uint16_t
909 {
910  uint16_t val = 0;
911  val |= (m_ctrlType << 2) & (0x3 << 2);
912  val |= (m_ctrlSubtype << 4) & (0xf << 4);
913  val |= (m_ctrlToDs << 8) & (0x1 << 8);
914  val |= (m_ctrlFromDs << 9) & (0x1 << 9);
915  val |= (m_ctrlMoreFrag << 10) & (0x1 << 10);
916  val |= (m_ctrlRetry << 11) & (0x1 << 11);
917  val |= (m_ctrlMoreData << 13) & (0x1 << 13);
918  val |= (m_ctrlWep << 14) & (0x1 << 14);
919  val |= (m_ctrlOrder << 15) & (0x1 << 15);
920  return val;
921 }
922 
923 uint16_t
925 {
926  uint16_t val = 0;
927  val |= m_qosTid;
928  val |= m_qosEosp << 4;
929  val |= m_qosAckPolicy << 5;
930  val |= m_amsduPresent << 7;
931  val |= m_qosStuff << 8;
932  return val;
933 }
934 
935 void
937 {
938  m_ctrlType = (ctrl >> 2) & 0x03;
939  m_ctrlSubtype = (ctrl >> 4) & 0x0f;
940  m_ctrlToDs = (ctrl >> 8) & 0x01;
941  m_ctrlFromDs = (ctrl >> 9) & 0x01;
942  m_ctrlMoreFrag = (ctrl >> 10) & 0x01;
943  m_ctrlRetry = (ctrl >> 11) & 0x01;
944  m_ctrlMoreData = (ctrl >> 13) & 0x01;
945  m_ctrlWep = (ctrl >> 14) & 0x01;
946  m_ctrlOrder = (ctrl >> 15) & 0x01;
947 }
948 
949 void
951 {
952  m_seqFrag = seq & 0x0f;
953  m_seqSeq = (seq >> 4) & 0x0fff;
954 }
955 
956 void
958 {
959  m_qosTid = qos & 0x000f;
960  m_qosEosp = (qos >> 4) & 0x0001;
961  m_qosAckPolicy = (qos >> 5) & 0x0003;
962  m_amsduPresent = (qos >> 7) & 0x0001;
963  m_qosStuff = (qos >> 8) & 0x00ff;
964 }
965 
966 uint32_t
968 {
969  uint32_t size = 0;
970  switch (m_ctrlType)
971  {
972  case TYPE_MGT:
973  size = 2 + 2 + 6 + 6 + 6 + 2;
974  break;
975  case TYPE_CTL:
976  switch (m_ctrlSubtype)
977  {
978  case SUBTYPE_CTL_RTS:
979  case SUBTYPE_CTL_BACKREQ:
981  case SUBTYPE_CTL_TRIGGER:
982  case SUBTYPE_CTL_END:
983  case SUBTYPE_CTL_END_ACK:
984  size = 2 + 2 + 6 + 6;
985  break;
986  case SUBTYPE_CTL_CTS:
987  case SUBTYPE_CTL_ACK:
988  size = 2 + 2 + 6;
989  break;
991  size = 2 + 2 + 6 + 2 + 4;
992  break;
993  }
994  break;
995  case TYPE_DATA:
996  size = 2 + 2 + 6 + 6 + 6 + 2;
997  if (m_ctrlToDs && m_ctrlFromDs)
998  {
999  size += 6;
1000  }
1001  if (m_ctrlSubtype & 0x08)
1002  {
1003  size += 2;
1004  }
1005  break;
1006  }
1007  return size;
1008 }
1009 
1010 const char*
1012 {
1013 #define FOO(x) \
1014  case WIFI_MAC_##x: \
1015  return #x; \
1016  break;
1017 
1018  switch (GetType())
1019  {
1020  FOO(CTL_RTS);
1021  FOO(CTL_CTS);
1022  FOO(CTL_ACK);
1023  FOO(CTL_BACKREQ);
1024  FOO(CTL_BACKRESP);
1025  FOO(CTL_END);
1026  FOO(CTL_END_ACK);
1027  FOO(CTL_TRIGGER);
1028 
1029  FOO(MGT_BEACON);
1030  FOO(MGT_ASSOCIATION_REQUEST);
1031  FOO(MGT_ASSOCIATION_RESPONSE);
1032  FOO(MGT_DISASSOCIATION);
1033  FOO(MGT_REASSOCIATION_REQUEST);
1034  FOO(MGT_REASSOCIATION_RESPONSE);
1035  FOO(MGT_PROBE_REQUEST);
1036  FOO(MGT_PROBE_RESPONSE);
1037  FOO(MGT_AUTHENTICATION);
1038  FOO(MGT_DEAUTHENTICATION);
1039  FOO(MGT_ACTION);
1040  FOO(MGT_ACTION_NO_ACK);
1041  FOO(MGT_MULTIHOP_ACTION);
1042 
1043  FOO(DATA);
1044  FOO(DATA_CFACK);
1045  FOO(DATA_CFPOLL);
1046  FOO(DATA_CFACK_CFPOLL);
1047  FOO(DATA_NULL);
1048  FOO(DATA_NULL_CFACK);
1049  FOO(DATA_NULL_CFPOLL);
1050  FOO(DATA_NULL_CFACK_CFPOLL);
1051  FOO(QOSDATA);
1052  FOO(QOSDATA_CFACK);
1053  FOO(QOSDATA_CFPOLL);
1054  FOO(QOSDATA_CFACK_CFPOLL);
1055  FOO(QOSDATA_NULL);
1056  FOO(QOSDATA_NULL_CFPOLL);
1057  FOO(QOSDATA_NULL_CFACK_CFPOLL);
1058  default:
1059  return "ERROR";
1060  }
1061 #undef FOO
1062 #ifndef _WIN32
1063  // needed to make gcc 4.0.1 ppc darwin happy.
1064  return "BIG_ERROR";
1065 #endif
1066 }
1067 
1068 TypeId
1070 {
1071  static TypeId tid = TypeId("ns3::WifiMacHeader")
1072  .SetParent<Header>()
1073  .SetGroupName("Wifi")
1074  .AddConstructor<WifiMacHeader>();
1075  return tid;
1076 }
1077 
1078 TypeId
1080 {
1081  return GetTypeId();
1082 }
1083 
1084 void
1085 WifiMacHeader::PrintFrameControl(std::ostream& os) const
1086 {
1087  os << "ToDS=" << std::hex << (int)m_ctrlToDs << ", FromDS=" << std::hex << (int)m_ctrlFromDs
1088  << ", MoreFrag=" << std::hex << (int)m_ctrlMoreFrag << ", Retry=" << std::hex
1089  << (int)m_ctrlRetry << ", MoreData=" << std::hex << (int)m_ctrlMoreData << std::dec;
1090 }
1091 
1092 void
1093 WifiMacHeader::Print(std::ostream& os) const
1094 {
1095  os << GetTypeString() << " ";
1096  switch (GetType())
1097  {
1098  case WIFI_MAC_CTL_RTS:
1099  case WIFI_MAC_CTL_TRIGGER:
1100  os << "Duration/ID=" << m_duration << "us"
1101  << ", RA=" << m_addr1 << ", TA=" << m_addr2;
1102  break;
1103  case WIFI_MAC_CTL_CTS:
1104  case WIFI_MAC_CTL_ACK:
1105  os << "Duration/ID=" << m_duration << "us"
1106  << ", RA=" << m_addr1;
1107  break;
1108  case WIFI_MAC_MGT_BEACON:
1118  PrintFrameControl(os);
1119  os << " Duration/ID=" << m_duration << "us"
1120  << ", DA=" << m_addr1 << ", SA=" << m_addr2 << ", BSSID=" << m_addr3
1121  << ", FragNumber=" << std::hex << (int)m_seqFrag << std::dec
1122  << ", SeqNumber=" << m_seqSeq;
1123  break;
1124  case WIFI_MAC_MGT_ACTION:
1126  PrintFrameControl(os);
1127  os << " Duration/ID=" << m_duration << "us"
1128  << ", DA=" << m_addr1 << ", SA=" << m_addr2 << ", BSSID=" << m_addr3
1129  << ", FragNumber=" << std::hex << (int)m_seqFrag << std::dec
1130  << ", SeqNumber=" << m_seqSeq;
1131  break;
1133  os << " Duration/ID=" << m_duration << "us"
1134  << ", RA=" << m_addr1 << ", TA=" << m_addr2 << ", DA=" << m_addr3
1135  << ", FragNumber=" << std::hex << (int)m_seqFrag << std::dec
1136  << ", SeqNumber=" << m_seqSeq;
1137  break;
1138  case WIFI_MAC_DATA:
1139  PrintFrameControl(os);
1140  os << " Duration/ID=" << m_duration << "us";
1141  if (!m_ctrlToDs && !m_ctrlFromDs)
1142  {
1143  os << ", DA=" << m_addr1 << ", SA=" << m_addr2 << ", BSSID=" << m_addr3;
1144  }
1145  else if (!m_ctrlToDs && m_ctrlFromDs)
1146  {
1147  os << ", DA=" << m_addr1 << ", SA=" << m_addr3 << ", BSSID=" << m_addr2;
1148  }
1149  else if (m_ctrlToDs && !m_ctrlFromDs)
1150  {
1151  os << ", DA=" << m_addr3 << ", SA=" << m_addr2 << ", BSSID=" << m_addr1;
1152  }
1153  else if (m_ctrlToDs && m_ctrlFromDs)
1154  {
1155  os << ", DA=" << m_addr3 << ", SA=" << m_addr4 << ", RA=" << m_addr1
1156  << ", TA=" << m_addr2;
1157  }
1158  else
1159  {
1160  NS_FATAL_ERROR("Impossible ToDs and FromDs flags combination");
1161  }
1162  os << ", FragNumber=" << std::hex << (int)m_seqFrag << std::dec
1163  << ", SeqNumber=" << m_seqSeq;
1164  break;
1165  case WIFI_MAC_CTL_BACKREQ:
1166  case WIFI_MAC_CTL_BACKRESP:
1168  case WIFI_MAC_CTL_END:
1169  case WIFI_MAC_CTL_END_ACK:
1170  case WIFI_MAC_DATA_CFACK:
1171  case WIFI_MAC_DATA_CFPOLL:
1173  case WIFI_MAC_DATA_NULL:
1177  case WIFI_MAC_QOSDATA:
1181  case WIFI_MAC_QOSDATA_NULL:
1184  default:
1185  break;
1186  }
1187 }
1188 
1189 uint32_t
1191 {
1192  return GetSize();
1193 }
1194 
1195 void
1197 {
1200  WriteTo(i, m_addr1);
1201  switch (m_ctrlType)
1202  {
1203  case TYPE_MGT:
1204  WriteTo(i, m_addr2);
1205  WriteTo(i, m_addr3);
1207  break;
1208  case TYPE_CTL:
1209  switch (m_ctrlSubtype)
1210  {
1211  case SUBTYPE_CTL_RTS:
1212  case SUBTYPE_CTL_TRIGGER:
1213  case SUBTYPE_CTL_BACKREQ:
1214  case SUBTYPE_CTL_BACKRESP:
1215  case SUBTYPE_CTL_END:
1216  case SUBTYPE_CTL_END_ACK:
1217  WriteTo(i, m_addr2);
1218  break;
1219  case SUBTYPE_CTL_CTS:
1220  case SUBTYPE_CTL_ACK:
1221  break;
1222  default:
1223  // NOTREACHED
1224  NS_ASSERT(false);
1225  break;
1226  }
1227  break;
1228  case TYPE_DATA: {
1229  WriteTo(i, m_addr2);
1230  WriteTo(i, m_addr3);
1232  if (m_ctrlToDs && m_ctrlFromDs)
1233  {
1234  WriteTo(i, m_addr4);
1235  }
1236  if (m_ctrlSubtype & 0x08)
1237  {
1239  }
1240  }
1241  break;
1242  default:
1243  // NOTREACHED
1244  NS_ASSERT(false);
1245  break;
1246  }
1247 }
1248 
1249 uint32_t
1251 {
1252  Buffer::Iterator i = start;
1253  uint16_t frame_control = i.ReadLsbtohU16();
1254  SetFrameControl(frame_control);
1255  m_duration = i.ReadLsbtohU16();
1256  ReadFrom(i, m_addr1);
1257  switch (m_ctrlType)
1258  {
1259  case TYPE_MGT:
1260  ReadFrom(i, m_addr2);
1261  ReadFrom(i, m_addr3);
1263  break;
1264  case TYPE_CTL:
1265  switch (m_ctrlSubtype)
1266  {
1267  case SUBTYPE_CTL_RTS:
1268  case SUBTYPE_CTL_TRIGGER:
1269  case SUBTYPE_CTL_BACKREQ:
1270  case SUBTYPE_CTL_BACKRESP:
1271  case SUBTYPE_CTL_END:
1272  case SUBTYPE_CTL_END_ACK:
1273  ReadFrom(i, m_addr2);
1274  break;
1275  case SUBTYPE_CTL_CTS:
1276  case SUBTYPE_CTL_ACK:
1277  break;
1278  }
1279  break;
1280  case TYPE_DATA:
1281  ReadFrom(i, m_addr2);
1282  ReadFrom(i, m_addr3);
1284  if (m_ctrlToDs && m_ctrlFromDs)
1285  {
1286  ReadFrom(i, m_addr4);
1287  }
1288  if (m_ctrlSubtype & 0x08)
1289  {
1291  }
1292  break;
1293  }
1294  return i.GetDistanceFrom(start);
1295 }
1296 
1297 } // namespace ns3
iterator in a Buffer instance
Definition: buffer.h:100
void WriteHtolsbU16(uint16_t data)
Definition: buffer.cc:905
uint16_t ReadLsbtohU16()
Definition: buffer.cc:1067
uint32_t GetDistanceFrom(const Iterator &o) const
Definition: buffer.cc:783
Protocol header serialization and deserialization.
Definition: header.h:44
virtual uint32_t Deserialize(Buffer::Iterator start)=0
Deserialize the object from a buffer iterator.
an EUI-48 address
Definition: mac48-address.h:46
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
int64_t GetNanoSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:417
a unique identifier for an interface.
Definition: type-id.h:60
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
Implements the IEEE 802.11 MAC header.
uint8_t GetQosTid() const
Return the Traffic ID of a QoS header.
bool IsCfAck() const
Return true if the header is a CF-Ack header.
uint8_t m_qosEosp
QoS EOSP.
uint8_t m_ctrlRetry
control retry
uint8_t m_qosTid
QoS TID.
bool IsAssocReq() const
Return true if the header is an Association Request header.
bool IsCfPoll() const
Return true if the Type/Subtype is one of the possible CF-Poll headers.
void SetQosAckPolicy(QosAckPolicy policy)
Set the QoS Ack policy in the QoS control field.
bool IsAck() const
Return true if the header is an Ack header.
uint16_t GetRawDuration() const
Return the raw duration from the Duration/ID field.
void SetRawDuration(uint16_t duration)
Set the Duration/ID field with the given raw uint16_t value.
bool IsProbeReq() const
Return true if the header is a Probe Request header.
bool IsBlockAckReq() const
Return true if the header is a BlockAckRequest header.
bool IsQosAmsdu() const
Check if the A-MSDU present bit is set in the QoS control field.
bool IsCts() const
Return true if the header is a CTS header.
Mac48Address GetAddr3() const
Return the address in the Address 3 field.
void SetQosAmsdu()
Set that A-MSDU is present.
uint16_t GetFrameControl() const
Return the raw Frame Control field.
Mac48Address GetAddr4() const
Return the address in the Address 4 field.
void SetFrameControl(uint16_t control)
Set the Frame Control field with the given raw value.
bool IsBeacon() const
Return true if the header is a Beacon header.
uint32_t GetSerializedSize() const override
bool IsAssocResp() const
Return true if the header is an Association Response header.
Mac48Address GetAddr1() const
Return the address in the Address 1 field.
uint16_t GetSequenceNumber() const
Return the sequence number of the header.
bool IsDisassociation() const
Return true if the header is a Disassociation header.
Mac48Address m_addr1
address 1
uint16_t m_seqSeq
sequence sequence
bool IsMoreFragments() const
Return if the More Fragment bit is set.
void SetRetry()
Set the Retry bit in the Frame Control field.
uint16_t GetSequenceControl() const
Return the raw Sequence Control field.
bool IsTrigger() const
Return true if the header is a Trigger header.
void SetQosTxopLimit(uint8_t txop)
Set TXOP limit in the QoS control field.
WifiMacType GetType() const
Return the type (enum WifiMacType)
void SetNoMoreFragments()
Un-set the More Fragment bit in the Frame Control Field.
bool IsRetry() const
Return if the Retry bit is set.
bool IsActionNoAck() const
Return true if the header is an Action No Ack header.
bool IsMgt() const
Return true if the Type is Management.
bool IsCtl() const
Return true if the Type is Control.
Time GetDuration() const
Return the duration from the Duration/ID field (Time object).
void SetQosControl(uint16_t qos)
Set the QoS Control field with the given raw value.
uint8_t m_ctrlSubtype
control subtype
void SetSequenceNumber(uint16_t seq)
Set the sequence number of the header.
void SetNoOrder()
Unset order bit in the frame control field.
uint32_t GetSize() const
Return the size of the WifiMacHeader in octets.
uint8_t m_amsduPresent
A-MSDU present.
bool IsCfEnd() const
Return true if the header is a CF-End header.
void SetDsNotFrom()
Un-set the From DS bit in the Frame Control field.
uint16_t GetQosControl() const
Return the raw QoS Control field.
bool IsProbeResp() const
Return true if the header is a Probe Response header.
bool IsAction() const
Return true if the header is an Action header.
void SetMoreFragments()
Set the More Fragment bit in the Frame Control field.
bool IsQosEosp() const
Return if the end of service period (EOSP) is set.
Mac48Address m_addr4
address 4
Mac48Address m_addr2
address 2
void SetAddr1(Mac48Address address)
Fill the Address 1 field with the given address.
void SetOrder()
Set order bit in the frame control field.
void SetSequenceControl(uint16_t seq)
Set the Sequence Control field with the given raw value.
void SetQosQueueSize(uint8_t size)
Set the Queue Size subfield in the QoS control field.
void SetQosNoAmsdu()
Set that A-MSDU is not present.
bool IsBlockAck() const
Return true if the header is a BlockAck header.
void SetType(WifiMacType type, bool resetToDsFromDs=true)
Set Type/Subtype values with the correct values depending on the given type.
void SetAddr4(Mac48Address address)
Fill the Address 4 field with the given address.
uint8_t m_ctrlOrder
control order (set to 1 for QoS Data and Management frames to signify that HT/VHT/HE control field is...
uint8_t m_ctrlFromDs
control from DS
Mac48Address GetAddr2() const
Return the address in the Address 2 field.
uint16_t m_duration
duration
const char * GetTypeString() const
Return a string corresponds to the header type.
uint8_t m_ctrlWep
control WEP
bool HasData() const
Return true if the header type is DATA and is not DATA_NULL.
bool IsReassocReq() const
Return true if the header is a Reassociation Request header.
void SetQosTid(uint8_t tid)
Set the TID for the QoS header.
QosAckPolicy GetQosAckPolicy() const
Return the QoS Ack policy in the QoS control field.
void SetDuration(Time duration)
Set the Duration/ID field with the given duration (Time object).
bool IsData() const
Return true if the Type is DATA.
void SetQosNoEosp()
Un-set the end of service period (EOSP) bit in the QoS control field.
uint8_t m_seqFrag
sequence fragment
uint8_t m_ctrlMoreData
control more data
bool IsReassocResp() const
Return true if the header is a Reassociation Response header.
bool IsRts() const
Return true if the header is a RTS header.
static TypeId GetTypeId()
Get the type ID.
bool IsQosAck() const
Return if the QoS Ack policy is Normal Ack.
void Print(std::ostream &os) const override
bool IsMoreData() const
Return if the More Data bit is set.
void SetQosNoMeshControlPresent()
Clear the Mesh Control Present flag for the QoS header.
void SetDsFrom()
Set the From DS bit in the Frame Control field.
bool IsQosNoAck() const
Return if the QoS Ack policy is No Ack.
uint8_t m_qosStuff
QoS stuff.
void SetDsTo()
Set the To DS bit in the Frame Control field.
void PrintFrameControl(std::ostream &os) const
Print the Frame Control field to the output stream.
uint8_t m_ctrlType
control type
void SetAddr2(Mac48Address address)
Fill the Address 2 field with the given address.
void SetId(uint16_t id)
Set the Duration/ID field with the given ID.
bool IsQosBlockAck() const
Return if the QoS Ack policy is Block Ack.
uint8_t GetFragmentNumber() const
Return the fragment number of the header.
bool IsQosData() const
Return true if the Type is DATA and Subtype is one of the possible values for QoS Data.
void SetQosEosp()
Set the end of service period (EOSP) bit in the QoS control field.
void Serialize(Buffer::Iterator start) const override
uint8_t GetQosQueueSize() const
Get the Queue Size subfield in the QoS control field.
void SetAddr3(Mac48Address address)
Fill the Address 3 field with the given address.
void SetDsNotTo()
Un-set the To DS bit in the Frame Control field.
TypeId GetInstanceTypeId() const override
Get the most derived TypeId for this Object.
void SetFragmentNumber(uint8_t frag)
Set the fragment number of the header.
void SetQosMeshControlPresent()
Set the Mesh Control Present flag for the QoS header.
Mac48Address m_addr3
address 3
uint8_t m_ctrlMoreFrag
control more fragments
QosAckPolicy
Ack policy for QoS frames.
bool IsMultihopAction() const
Check if the header is a Multihop action header.
void SetNoRetry()
Un-set the Retry bit in the Frame Control field.
bool IsDeauthentication() const
Return true if the header is a Deauthentication header.
~WifiMacHeader() override
uint8_t m_ctrlToDs
control to DS
bool IsAuthentication() const
Return true if the header is an Authentication header.
uint8_t m_qosAckPolicy
QoS Ack policy.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:49
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1360
address
Definition: first.py:40
Every class exported by the ns3 library is enclosed in the ns3 namespace.
@ SUBTYPE_CTL_END
@ SUBTYPE_CTL_BACKREQ
@ SUBTYPE_CTL_NDPANNOUNCE
@ SUBTYPE_CTL_END_ACK
@ SUBTYPE_CTL_CTLWRAPPER
@ SUBTYPE_CTL_TRIGGER
@ SUBTYPE_CTL_CTS
@ SUBTYPE_CTL_BACKRESP
@ SUBTYPE_CTL_RTS
@ SUBTYPE_CTL_BEAMFORMINGRPOLL
@ SUBTYPE_CTL_CTLFRAMEEXT
@ SUBTYPE_CTL_ACK
@ DATA
Definition: ul-job.h:41
WifiMacType
Combination of valid MAC header type/subtype.
@ WIFI_MAC_QOSDATA_NULL_CFACK_CFPOLL
@ WIFI_MAC_CTL_TRIGGER
@ WIFI_MAC_MGT_PROBE_REQUEST
@ WIFI_MAC_CTL_END_ACK
@ WIFI_MAC_DATA_CFACK
@ WIFI_MAC_CTL_BACKREQ
@ WIFI_MAC_DATA_NULL
@ WIFI_MAC_CTL_RTS
@ WIFI_MAC_CTL_CTS
@ WIFI_MAC_MGT_AUTHENTICATION
@ WIFI_MAC_MGT_MULTIHOP_ACTION
@ WIFI_MAC_CTL_CTLWRAPPER
@ WIFI_MAC_QOSDATA_CFACK_CFPOLL
@ WIFI_MAC_MGT_BEACON
@ WIFI_MAC_MGT_ACTION
@ WIFI_MAC_MGT_ASSOCIATION_RESPONSE
@ WIFI_MAC_CTL_ACK
@ WIFI_MAC_MGT_DISASSOCIATION
@ WIFI_MAC_QOSDATA_NULL_CFPOLL
@ WIFI_MAC_MGT_ASSOCIATION_REQUEST
@ WIFI_MAC_DATA_NULL_CFACK_CFPOLL
@ WIFI_MAC_MGT_REASSOCIATION_REQUEST
@ WIFI_MAC_QOSDATA_CFACK
@ WIFI_MAC_CTL_BACKRESP
@ WIFI_MAC_DATA_CFACK_CFPOLL
@ WIFI_MAC_DATA_CFPOLL
@ WIFI_MAC_CTL_END
@ WIFI_MAC_DATA_NULL_CFACK
@ WIFI_MAC_MGT_ACTION_NO_ACK
@ WIFI_MAC_MGT_DEAUTHENTICATION
@ WIFI_MAC_QOSDATA_NULL
@ WIFI_MAC_DATA_NULL_CFPOLL
@ WIFI_MAC_MGT_PROBE_RESPONSE
@ WIFI_MAC_QOSDATA_CFPOLL
@ WIFI_MAC_DATA
@ WIFI_MAC_MGT_REASSOCIATION_RESPONSE
@ WIFI_MAC_QOSDATA
void WriteTo(Buffer::Iterator &i, Ipv4Address ad)
Write an Ipv4Address to a Buffer.
void ReadFrom(Buffer::Iterator &i, Ipv4Address &ad)
Read an Ipv4Address from a Buffer.
#define FOO(x)