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
58 };
59 
61  : m_ctrlMoreFrag(0),
62  m_ctrlRetry(0),
63  m_ctrlPowerManagement(0),
64  m_ctrlMoreData(0),
65  m_ctrlWep(0),
66  m_ctrlOrder(0),
67  m_duration(0),
68  m_seqFrag(0),
69  m_seqSeq(0),
70  m_qosEosp(0),
71  m_qosAckPolicy(0), // Normal Ack
72  m_amsduPresent(0)
73 {
74 }
75 
77  : WifiMacHeader()
78 {
79  SetType(type);
80 }
81 
83 {
84 }
85 
86 void
88 {
89  m_ctrlFromDs = 1;
90 }
91 
92 void
94 {
95  m_ctrlFromDs = 0;
96 }
97 
98 void
100 {
101  m_ctrlToDs = 1;
102 }
103 
104 void
106 {
107  m_ctrlToDs = 0;
108 }
109 
110 void
112 {
113  m_addr1 = address;
114 }
115 
116 void
118 {
119  m_addr2 = address;
120 }
121 
122 void
124 {
125  m_addr3 = address;
126 }
127 
128 void
130 {
131  m_addr4 = address;
132 }
133 
134 void
136 {
137  switch (type)
138  {
142  break;
146  break;
150  break;
154  break;
155  case WIFI_MAC_CTL_PSPOLL:
158  break;
159  case WIFI_MAC_CTL_RTS:
162  break;
163  case WIFI_MAC_CTL_CTS:
166  break;
167  case WIFI_MAC_CTL_ACK:
170  break;
171  case WIFI_MAC_CTL_END:
174  break;
178  break;
181  m_ctrlSubtype = 0;
182  break;
185  m_ctrlSubtype = 1;
186  break;
189  m_ctrlSubtype = 2;
190  break;
193  m_ctrlSubtype = 3;
194  break;
197  m_ctrlSubtype = 4;
198  break;
201  m_ctrlSubtype = 5;
202  break;
203  case WIFI_MAC_MGT_BEACON:
205  m_ctrlSubtype = 8;
206  break;
209  m_ctrlSubtype = 10;
210  break;
213  m_ctrlSubtype = 11;
214  break;
217  m_ctrlSubtype = 12;
218  break;
219  case WIFI_MAC_MGT_ACTION:
221  m_ctrlSubtype = 13;
222  break;
225  m_ctrlSubtype = 14;
226  break;
229  m_ctrlSubtype = 15;
230  break;
231  case WIFI_MAC_DATA:
233  m_ctrlSubtype = 0;
234  break;
235  case WIFI_MAC_DATA_CFACK:
237  m_ctrlSubtype = 1;
238  break;
241  m_ctrlSubtype = 2;
242  break;
245  m_ctrlSubtype = 3;
246  break;
247  case WIFI_MAC_DATA_NULL:
249  m_ctrlSubtype = 4;
250  break;
253  m_ctrlSubtype = 5;
254  break;
257  m_ctrlSubtype = 6;
258  break;
261  m_ctrlSubtype = 7;
262  break;
263  case WIFI_MAC_QOSDATA:
265  m_ctrlSubtype = 8;
266  break;
269  m_ctrlSubtype = 9;
270  break;
273  m_ctrlSubtype = 10;
274  break;
277  m_ctrlSubtype = 11;
278  break;
281  m_ctrlSubtype = 12;
282  break;
285  m_ctrlSubtype = 14;
286  break;
289  m_ctrlSubtype = 15;
290  break;
291  default:
292  break;
293  }
294  if (resetToDsFromDs)
295  {
296  m_ctrlToDs = 0;
297  m_ctrlFromDs = 0;
298  }
299 }
300 
301 void
303 {
304  NS_ASSERT(duration <= 32768);
305  m_duration = duration;
306 }
307 
308 void
310 {
311  auto duration_us =
312  static_cast<int64_t>(ceil(static_cast<double>(duration.GetNanoSeconds()) / 1000));
313  NS_ASSERT(duration_us >= 0 && duration_us <= 0x7fff);
314  m_duration = static_cast<uint16_t>(duration_us);
315 }
316 
317 void
319 {
320  m_duration = id;
321 }
322 
323 void
325 {
326  m_seqSeq = seq;
327 }
328 
329 void
331 {
332  m_seqFrag = frag;
333 }
334 
335 void
337 {
338  m_ctrlMoreFrag = 0;
339 }
340 
341 void
343 {
344  m_ctrlMoreFrag = 1;
345 }
346 
347 void
349 {
350  m_ctrlOrder = 1;
351 }
352 
353 void
355 {
356  m_ctrlOrder = 0;
357 }
358 
359 void
361 {
362  m_ctrlRetry = 1;
363 }
364 
365 void
367 {
368  m_ctrlRetry = 0;
369 }
370 
371 void
373 {
374  m_qosTid = tid;
375 }
376 
377 void
379 {
381 }
382 
383 void
385 {
387 }
388 
389 void
391 {
392  m_qosEosp = 1;
393 }
394 
395 void
397 {
398  m_qosEosp = 0;
399 }
400 
401 void
403 {
404  switch (policy)
405  {
406  case NORMAL_ACK:
407  m_qosAckPolicy = 0;
408  break;
409  case NO_ACK:
410  m_qosAckPolicy = 1;
411  break;
412  case NO_EXPLICIT_ACK:
413  m_qosAckPolicy = 2;
414  break;
415  case BLOCK_ACK:
416  m_qosAckPolicy = 3;
417  break;
418  }
419 }
420 
421 void
423 {
424  m_amsduPresent = 1;
425 }
426 
427 void
429 {
430  m_amsduPresent = 0;
431 }
432 
433 void
435 {
436  m_qosStuff = txop;
437 }
438 
439 void
441 {
442  m_qosEosp = 1;
443  m_qosStuff = size;
444 }
445 
446 void
448 {
449  // Mark bit 0 of this variable instead of bit 8, since m_qosStuff is
450  // shifted by one byte when serialized
451  m_qosStuff = m_qosStuff | 0x01; // bit 8 of QoS Control Field
452 }
453 
454 void
456 {
457  // Clear bit 0 of this variable instead of bit 8, since m_qosStuff is
458  // shifted by one byte when serialized
459  m_qosStuff = m_qosStuff & 0xfe; // bit 8 of QoS Control Field
460 }
461 
464 {
465  return m_addr1;
466 }
467 
470 {
471  return m_addr2;
472 }
473 
476 {
477  return m_addr3;
478 }
479 
482 {
483  return m_addr4;
484 }
485 
488 {
489  switch (m_ctrlType)
490  {
491  case TYPE_MGT:
492  switch (m_ctrlSubtype)
493  {
494  case 0:
496  case 1:
498  case 2:
500  case 3:
502  case 4:
504  case 5:
506  case 8:
507  return WIFI_MAC_MGT_BEACON;
508  case 10:
510  case 11:
512  case 12:
514  case 13:
515  return WIFI_MAC_MGT_ACTION;
516  case 14:
518  case 15:
520  }
521  break;
522  case TYPE_CTL:
523  switch (m_ctrlSubtype)
524  {
525  case SUBTYPE_CTL_TRIGGER:
526  return WIFI_MAC_CTL_TRIGGER;
527  case SUBTYPE_CTL_BACKREQ:
528  return WIFI_MAC_CTL_BACKREQ;
530  return WIFI_MAC_CTL_BACKRESP;
531  case SUBTYPE_CTL_PSPOLL:
532  return WIFI_MAC_CTL_PSPOLL;
533  case SUBTYPE_CTL_RTS:
534  return WIFI_MAC_CTL_RTS;
535  case SUBTYPE_CTL_CTS:
536  return WIFI_MAC_CTL_CTS;
537  case SUBTYPE_CTL_ACK:
538  return WIFI_MAC_CTL_ACK;
539  case SUBTYPE_CTL_END:
540  return WIFI_MAC_CTL_END;
541  case SUBTYPE_CTL_END_ACK:
542  return WIFI_MAC_CTL_END_ACK;
543  }
544  break;
545  case TYPE_DATA:
546  switch (m_ctrlSubtype)
547  {
548  case 0:
549  return WIFI_MAC_DATA;
550  case 1:
551  return WIFI_MAC_DATA_CFACK;
552  case 2:
553  return WIFI_MAC_DATA_CFPOLL;
554  case 3:
556  case 4:
557  return WIFI_MAC_DATA_NULL;
558  case 5:
560  case 6:
562  case 7:
564  case 8:
565  return WIFI_MAC_QOSDATA;
566  case 9:
567  return WIFI_MAC_QOSDATA_CFACK;
568  case 10:
570  case 11:
572  case 12:
573  return WIFI_MAC_QOSDATA_NULL;
574  case 14:
576  case 15:
578  }
579  break;
580  }
581  // NOTREACHED
582  NS_ASSERT(false);
583  return (WifiMacType)-1;
584 }
585 
586 bool
588 {
589  return m_ctrlFromDs == 1;
590 }
591 
592 bool
594 {
595  return m_ctrlToDs == 1;
596 }
597 
598 bool
600 {
601  return (m_ctrlType == TYPE_DATA);
602 }
603 
604 bool
606 {
607  return (m_ctrlType == TYPE_DATA && (m_ctrlSubtype & 0x08));
608 }
609 
610 bool
612 {
613  return (m_ctrlType == TYPE_CTL);
614 }
615 
616 bool
618 {
619  return (m_ctrlType == TYPE_MGT);
620 }
621 
622 bool
624 {
625  switch (GetType())
626  {
635  return true;
636  default:
637  return false;
638  }
639 }
640 
641 bool
643 {
644  switch (GetType())
645  {
646  case WIFI_MAC_CTL_END:
648  return true;
649  default:
650  return false;
651  }
652 }
653 
654 bool
656 {
657  switch (GetType())
658  {
659  case WIFI_MAC_DATA_CFACK:
664  return true;
665  default:
666  return false;
667  }
668 }
669 
670 bool
672 {
673  switch (GetType())
674  {
675  case WIFI_MAC_DATA:
676  case WIFI_MAC_DATA_CFACK:
679  case WIFI_MAC_QOSDATA:
683  return true;
684  default:
685  return false;
686  }
687 }
688 
689 bool
691 {
692  return (GetType() == WIFI_MAC_CTL_RTS);
693 }
694 
695 bool
697 {
698  return (GetType() == WIFI_MAC_CTL_CTS);
699 }
700 
701 bool
703 {
704  return (GetType() == WIFI_MAC_CTL_PSPOLL);
705 }
706 
707 bool
709 {
710  return (GetType() == WIFI_MAC_CTL_ACK);
711 }
712 
713 bool
715 {
717 }
718 
719 bool
721 {
723 }
724 
725 bool
727 {
729 }
730 
731 bool
733 {
735 }
736 
737 bool
739 {
740  return (GetType() == WIFI_MAC_MGT_PROBE_REQUEST);
741 }
742 
743 bool
745 {
746  return (GetType() == WIFI_MAC_MGT_PROBE_RESPONSE);
747 }
748 
749 bool
751 {
752  return (GetType() == WIFI_MAC_MGT_BEACON);
753 }
754 
755 bool
757 {
758  return (GetType() == WIFI_MAC_MGT_DISASSOCIATION);
759 }
760 
761 bool
763 {
764  return (GetType() == WIFI_MAC_MGT_AUTHENTICATION);
765 }
766 
767 bool
769 {
771 }
772 
773 bool
775 {
776  return (GetType() == WIFI_MAC_MGT_ACTION);
777 }
778 
779 bool
781 {
782  return (GetType() == WIFI_MAC_MGT_ACTION_NO_ACK);
783 }
784 
785 bool
787 {
789 }
790 
791 bool
793 {
794  return (GetType() == WIFI_MAC_CTL_BACKREQ);
795 }
796 
797 bool
799 {
800  return (GetType() == WIFI_MAC_CTL_BACKRESP);
801 }
802 
803 bool
805 {
806  return (GetType() == WIFI_MAC_CTL_TRIGGER);
807 }
808 
809 uint16_t
811 {
812  return m_duration;
813 }
814 
815 Time
817 {
818  return MicroSeconds(m_duration);
819 }
820 
821 uint16_t
823 {
824  return (m_seqSeq << 4) | m_seqFrag;
825 }
826 
827 uint16_t
829 {
830  return m_seqSeq;
831 }
832 
833 uint8_t
835 {
836  return m_seqFrag;
837 }
838 
839 bool
841 {
842  return (m_ctrlRetry == 1);
843 }
844 
845 bool
847 {
848  return (m_ctrlMoreData == 1);
849 }
850 
851 bool
853 {
854  return (m_ctrlMoreFrag == 1);
855 }
856 
857 bool
859 {
860  return (m_ctrlPowerManagement == 1);
861 }
862 
863 bool
865 {
866  NS_ASSERT(IsQosData());
867  return (m_qosAckPolicy == 3);
868 }
869 
870 bool
872 {
873  NS_ASSERT(IsQosData());
874  return (m_qosAckPolicy == 1);
875 }
876 
877 bool
879 {
880  NS_ASSERT(IsQosData());
881  return (m_qosAckPolicy == 0);
882 }
883 
884 bool
886 {
887  NS_ASSERT(IsQosData());
888  return (m_qosEosp == 1);
889 }
890 
893 {
894  NS_ASSERT(IsQosData());
895  QosAckPolicy policy;
896 
897  switch (m_qosAckPolicy)
898  {
899  case 0:
900  policy = NORMAL_ACK;
901  break;
902  case 1:
903  policy = NO_ACK;
904  break;
905  case 2:
906  policy = NO_EXPLICIT_ACK;
907  break;
908  case 3:
909  policy = BLOCK_ACK;
910  break;
911  default:
912  NS_ABORT_MSG("Unknown QoS Ack policy");
913  }
914  return policy;
915 }
916 
917 bool
919 {
920  NS_ASSERT(IsQosData());
921  return (m_amsduPresent == 1);
922 }
923 
924 uint8_t
926 {
927  NS_ASSERT(IsQosData());
928  return m_qosTid;
929 }
930 
931 uint8_t
933 {
934  NS_ASSERT(m_qosEosp == 1);
935  return m_qosStuff;
936 }
937 
938 uint16_t
940 {
941  uint16_t val = 0;
942  val |= (m_ctrlType << 2) & (0x3 << 2);
943  val |= (m_ctrlSubtype << 4) & (0xf << 4);
944  val |= (m_ctrlToDs << 8) & (0x1 << 8);
945  val |= (m_ctrlFromDs << 9) & (0x1 << 9);
946  val |= (m_ctrlMoreFrag << 10) & (0x1 << 10);
947  val |= (m_ctrlRetry << 11) & (0x1 << 11);
948  val |= (m_ctrlPowerManagement << 12) & (0x1 << 12);
949  val |= (m_ctrlMoreData << 13) & (0x1 << 13);
950  val |= (m_ctrlWep << 14) & (0x1 << 14);
951  val |= (m_ctrlOrder << 15) & (0x1 << 15);
952  return val;
953 }
954 
955 uint16_t
957 {
958  uint16_t val = 0;
959  val |= m_qosTid;
960  val |= m_qosEosp << 4;
961  val |= m_qosAckPolicy << 5;
962  val |= m_amsduPresent << 7;
963  val |= m_qosStuff << 8;
964  return val;
965 }
966 
967 void
969 {
970  m_ctrlType = (ctrl >> 2) & 0x03;
971  m_ctrlSubtype = (ctrl >> 4) & 0x0f;
972  m_ctrlToDs = (ctrl >> 8) & 0x01;
973  m_ctrlFromDs = (ctrl >> 9) & 0x01;
974  m_ctrlMoreFrag = (ctrl >> 10) & 0x01;
975  m_ctrlRetry = (ctrl >> 11) & 0x01;
976  m_ctrlPowerManagement = (ctrl >> 12) & 0x01;
977  m_ctrlMoreData = (ctrl >> 13) & 0x01;
978  m_ctrlWep = (ctrl >> 14) & 0x01;
979  m_ctrlOrder = (ctrl >> 15) & 0x01;
980 }
981 
982 void
984 {
985  m_seqFrag = seq & 0x0f;
986  m_seqSeq = (seq >> 4) & 0x0fff;
987 }
988 
989 void
991 {
992  m_qosTid = qos & 0x000f;
993  m_qosEosp = (qos >> 4) & 0x0001;
994  m_qosAckPolicy = (qos >> 5) & 0x0003;
995  m_amsduPresent = (qos >> 7) & 0x0001;
996  m_qosStuff = (qos >> 8) & 0x00ff;
997 }
998 
999 uint32_t
1001 {
1002  uint32_t size = 0;
1003  switch (m_ctrlType)
1004  {
1005  case TYPE_MGT:
1006  size = 2 + 2 + 6 + 6 + 6 + 2;
1007  break;
1008  case TYPE_CTL:
1009  switch (m_ctrlSubtype)
1010  {
1011  case SUBTYPE_CTL_PSPOLL:
1012  case SUBTYPE_CTL_RTS:
1013  case SUBTYPE_CTL_BACKREQ:
1014  case SUBTYPE_CTL_BACKRESP:
1015  case SUBTYPE_CTL_TRIGGER:
1016  case SUBTYPE_CTL_END:
1017  case SUBTYPE_CTL_END_ACK:
1018  size = 2 + 2 + 6 + 6;
1019  break;
1020  case SUBTYPE_CTL_CTS:
1021  case SUBTYPE_CTL_ACK:
1022  size = 2 + 2 + 6;
1023  break;
1025  size = 2 + 2 + 6 + 2 + 4;
1026  break;
1027  }
1028  break;
1029  case TYPE_DATA:
1030  size = 2 + 2 + 6 + 6 + 6 + 2;
1031  if (m_ctrlToDs && m_ctrlFromDs)
1032  {
1033  size += 6;
1034  }
1035  if (m_ctrlSubtype & 0x08)
1036  {
1037  size += 2;
1038  }
1039  break;
1040  }
1041  return size;
1042 }
1043 
1044 const char*
1046 {
1047 #define CASE_WIFI_MAC_TYPE(x) \
1048  case WIFI_MAC_##x: \
1049  return #x;
1050 
1051  switch (GetType())
1052  {
1053  CASE_WIFI_MAC_TYPE(CTL_RTS);
1054  CASE_WIFI_MAC_TYPE(CTL_CTS);
1055  CASE_WIFI_MAC_TYPE(CTL_ACK);
1056  CASE_WIFI_MAC_TYPE(CTL_BACKREQ);
1057  CASE_WIFI_MAC_TYPE(CTL_BACKRESP);
1058  CASE_WIFI_MAC_TYPE(CTL_END);
1059  CASE_WIFI_MAC_TYPE(CTL_END_ACK);
1060  CASE_WIFI_MAC_TYPE(CTL_PSPOLL);
1061  CASE_WIFI_MAC_TYPE(CTL_TRIGGER);
1062 
1063  CASE_WIFI_MAC_TYPE(MGT_BEACON);
1064  CASE_WIFI_MAC_TYPE(MGT_ASSOCIATION_REQUEST);
1065  CASE_WIFI_MAC_TYPE(MGT_ASSOCIATION_RESPONSE);
1066  CASE_WIFI_MAC_TYPE(MGT_DISASSOCIATION);
1067  CASE_WIFI_MAC_TYPE(MGT_REASSOCIATION_REQUEST);
1068  CASE_WIFI_MAC_TYPE(MGT_REASSOCIATION_RESPONSE);
1069  CASE_WIFI_MAC_TYPE(MGT_PROBE_REQUEST);
1070  CASE_WIFI_MAC_TYPE(MGT_PROBE_RESPONSE);
1071  CASE_WIFI_MAC_TYPE(MGT_AUTHENTICATION);
1072  CASE_WIFI_MAC_TYPE(MGT_DEAUTHENTICATION);
1073  CASE_WIFI_MAC_TYPE(MGT_ACTION);
1074  CASE_WIFI_MAC_TYPE(MGT_ACTION_NO_ACK);
1075  CASE_WIFI_MAC_TYPE(MGT_MULTIHOP_ACTION);
1076 
1078  CASE_WIFI_MAC_TYPE(DATA_CFACK);
1079  CASE_WIFI_MAC_TYPE(DATA_CFPOLL);
1080  CASE_WIFI_MAC_TYPE(DATA_CFACK_CFPOLL);
1081  CASE_WIFI_MAC_TYPE(DATA_NULL);
1082  CASE_WIFI_MAC_TYPE(DATA_NULL_CFACK);
1083  CASE_WIFI_MAC_TYPE(DATA_NULL_CFPOLL);
1084  CASE_WIFI_MAC_TYPE(DATA_NULL_CFACK_CFPOLL);
1085  CASE_WIFI_MAC_TYPE(QOSDATA);
1086  CASE_WIFI_MAC_TYPE(QOSDATA_CFACK);
1087  CASE_WIFI_MAC_TYPE(QOSDATA_CFPOLL);
1088  CASE_WIFI_MAC_TYPE(QOSDATA_CFACK_CFPOLL);
1089  CASE_WIFI_MAC_TYPE(QOSDATA_NULL);
1090  CASE_WIFI_MAC_TYPE(QOSDATA_NULL_CFPOLL);
1091  CASE_WIFI_MAC_TYPE(QOSDATA_NULL_CFACK_CFPOLL);
1092  default:
1093  return "ERROR";
1094  }
1095 #undef CASE_WIFI_MAC_TYPE
1096 #ifndef _WIN32
1097  // needed to make gcc 4.0.1 ppc darwin happy.
1098  return "BIG_ERROR";
1099 #endif
1100 }
1101 
1102 TypeId
1104 {
1105  static TypeId tid = TypeId("ns3::WifiMacHeader")
1106  .SetParent<Header>()
1107  .SetGroupName("Wifi")
1108  .AddConstructor<WifiMacHeader>();
1109  return tid;
1110 }
1111 
1112 TypeId
1114 {
1115  return GetTypeId();
1116 }
1117 
1118 void
1119 WifiMacHeader::PrintFrameControl(std::ostream& os) const
1120 {
1121  os << "ToDS=" << std::hex << static_cast<int>(m_ctrlToDs)
1122  << ", FromDS=" << static_cast<int>(m_ctrlFromDs)
1123  << ", MoreFrag=" << static_cast<int>(m_ctrlMoreFrag)
1124  << ", Retry=" << static_cast<int>(m_ctrlRetry)
1125  << ", PowerManagement=" << static_cast<int>(m_ctrlPowerManagement)
1126  << ", MoreData=" << static_cast<int>(m_ctrlMoreData) << std::dec;
1127 }
1128 
1129 void
1130 WifiMacHeader::Print(std::ostream& os) const
1131 {
1132  os << GetTypeString() << " ";
1133  switch (GetType())
1134  {
1135  case WIFI_MAC_CTL_PSPOLL:
1136  os << "Duration/ID=" << std::hex << m_duration << std::dec << ", BSSID(RA)=" << m_addr1
1137  << ", TA=" << m_addr2;
1138  break;
1139  case WIFI_MAC_CTL_RTS:
1140  case WIFI_MAC_CTL_TRIGGER:
1141  os << "Duration/ID=" << m_duration << "us"
1142  << ", RA=" << m_addr1 << ", TA=" << m_addr2;
1143  break;
1144  case WIFI_MAC_CTL_CTS:
1145  case WIFI_MAC_CTL_ACK:
1146  os << "Duration/ID=" << m_duration << "us"
1147  << ", RA=" << m_addr1;
1148  break;
1149  case WIFI_MAC_MGT_BEACON:
1159  PrintFrameControl(os);
1160  os << " Duration/ID=" << m_duration << "us"
1161  << ", DA=" << m_addr1 << ", SA=" << m_addr2 << ", BSSID=" << m_addr3
1162  << ", FragNumber=" << std::hex << (int)m_seqFrag << std::dec
1163  << ", SeqNumber=" << m_seqSeq;
1164  break;
1165  case WIFI_MAC_MGT_ACTION:
1167  PrintFrameControl(os);
1168  os << " Duration/ID=" << m_duration << "us"
1169  << ", DA=" << m_addr1 << ", SA=" << m_addr2 << ", BSSID=" << m_addr3
1170  << ", FragNumber=" << std::hex << (int)m_seqFrag << std::dec
1171  << ", SeqNumber=" << m_seqSeq;
1172  break;
1174  os << " Duration/ID=" << m_duration << "us"
1175  << ", RA=" << m_addr1 << ", TA=" << m_addr2 << ", DA=" << m_addr3
1176  << ", FragNumber=" << std::hex << (int)m_seqFrag << std::dec
1177  << ", SeqNumber=" << m_seqSeq;
1178  break;
1179  case WIFI_MAC_DATA:
1180  PrintFrameControl(os);
1181  os << " Duration/ID=" << m_duration << "us";
1182  if (!m_ctrlToDs && !m_ctrlFromDs)
1183  {
1184  os << ", DA=" << m_addr1 << ", SA=" << m_addr2 << ", BSSID=" << m_addr3;
1185  }
1186  else if (!m_ctrlToDs && m_ctrlFromDs)
1187  {
1188  os << ", DA=" << m_addr1 << ", SA=" << m_addr3 << ", BSSID=" << m_addr2;
1189  }
1190  else if (m_ctrlToDs && !m_ctrlFromDs)
1191  {
1192  os << ", DA=" << m_addr3 << ", SA=" << m_addr2 << ", BSSID=" << m_addr1;
1193  }
1194  else if (m_ctrlToDs && m_ctrlFromDs)
1195  {
1196  os << ", DA=" << m_addr3 << ", SA=" << m_addr4 << ", RA=" << m_addr1
1197  << ", TA=" << m_addr2;
1198  }
1199  else
1200  {
1201  NS_FATAL_ERROR("Impossible ToDs and FromDs flags combination");
1202  }
1203  os << ", FragNumber=" << std::hex << (int)m_seqFrag << std::dec
1204  << ", SeqNumber=" << m_seqSeq;
1205  break;
1206  case WIFI_MAC_CTL_BACKREQ:
1207  case WIFI_MAC_CTL_BACKRESP:
1209  case WIFI_MAC_CTL_END:
1210  case WIFI_MAC_CTL_END_ACK:
1211  case WIFI_MAC_DATA_CFACK:
1212  case WIFI_MAC_DATA_CFPOLL:
1214  case WIFI_MAC_DATA_NULL:
1218  case WIFI_MAC_QOSDATA:
1222  case WIFI_MAC_QOSDATA_NULL:
1225  default:
1226  break;
1227  }
1228 }
1229 
1230 uint32_t
1232 {
1233  return GetSize();
1234 }
1235 
1236 void
1238 {
1241  WriteTo(i, m_addr1);
1242  switch (m_ctrlType)
1243  {
1244  case TYPE_MGT:
1245  WriteTo(i, m_addr2);
1246  WriteTo(i, m_addr3);
1248  break;
1249  case TYPE_CTL:
1250  switch (m_ctrlSubtype)
1251  {
1252  case SUBTYPE_CTL_PSPOLL:
1253  case SUBTYPE_CTL_RTS:
1254  case SUBTYPE_CTL_TRIGGER:
1255  case SUBTYPE_CTL_BACKREQ:
1256  case SUBTYPE_CTL_BACKRESP:
1257  case SUBTYPE_CTL_END:
1258  case SUBTYPE_CTL_END_ACK:
1259  WriteTo(i, m_addr2);
1260  break;
1261  case SUBTYPE_CTL_CTS:
1262  case SUBTYPE_CTL_ACK:
1263  break;
1264  default:
1265  // NOTREACHED
1266  NS_ASSERT(false);
1267  break;
1268  }
1269  break;
1270  case TYPE_DATA: {
1271  WriteTo(i, m_addr2);
1272  WriteTo(i, m_addr3);
1274  if (m_ctrlToDs && m_ctrlFromDs)
1275  {
1276  WriteTo(i, m_addr4);
1277  }
1278  if (m_ctrlSubtype & 0x08)
1279  {
1281  }
1282  }
1283  break;
1284  default:
1285  // NOTREACHED
1286  NS_ASSERT(false);
1287  break;
1288  }
1289 }
1290 
1291 uint32_t
1293 {
1294  Buffer::Iterator i = start;
1295  uint16_t frame_control = i.ReadLsbtohU16();
1296  SetFrameControl(frame_control);
1297  m_duration = i.ReadLsbtohU16();
1298  ReadFrom(i, m_addr1);
1299  switch (m_ctrlType)
1300  {
1301  case TYPE_MGT:
1302  ReadFrom(i, m_addr2);
1303  ReadFrom(i, m_addr3);
1305  break;
1306  case TYPE_CTL:
1307  switch (m_ctrlSubtype)
1308  {
1309  case SUBTYPE_CTL_PSPOLL:
1310  case SUBTYPE_CTL_RTS:
1311  case SUBTYPE_CTL_TRIGGER:
1312  case SUBTYPE_CTL_BACKREQ:
1313  case SUBTYPE_CTL_BACKRESP:
1314  case SUBTYPE_CTL_END:
1315  case SUBTYPE_CTL_END_ACK:
1316  ReadFrom(i, m_addr2);
1317  break;
1318  case SUBTYPE_CTL_CTS:
1319  case SUBTYPE_CTL_ACK:
1320  break;
1321  }
1322  break;
1323  case TYPE_DATA:
1324  ReadFrom(i, m_addr2);
1325  ReadFrom(i, m_addr3);
1327  if (m_ctrlToDs && m_ctrlFromDs)
1328  {
1329  ReadFrom(i, m_addr4);
1330  }
1331  if (m_ctrlSubtype & 0x08)
1332  {
1334  }
1335  break;
1336  }
1337  return i.GetDistanceFrom(start);
1338 }
1339 
1340 } // namespace ns3
iterator in a Buffer instance
Definition: buffer.h:100
void WriteHtolsbU16(uint16_t data)
Definition: buffer.cc:902
uint16_t ReadLsbtohU16()
Definition: buffer.cc:1064
uint32_t GetDistanceFrom(const Iterator &o) const
Definition: buffer.cc:780
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:418
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:931
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.
uint8_t m_ctrlPowerManagement
control power management
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.
virtual uint16_t GetFrameControl() const
Return the raw Frame Control field.
Mac48Address GetAddr4() const
Return the address in the Address 4 field.
virtual 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.
virtual WifiMacType GetType() const
Return the type (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).
virtual 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.
virtual 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.
virtual 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.
virtual 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
virtual 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.
bool IsPsPoll() const
Return true if the header is a PS-POLL header.
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
bool IsPowerManagement() const
Return if the Power Management bit is set.
void SetPowerManagement()
Set the Power Management bit in the Frame Control field.
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.
void SetNoPowerManagement()
Un-set the Power Management bit in the Frame Control field.
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:1350
address
Definition: first.py:47
Every class exported by the ns3 library is enclosed in the ns3 namespace.
@ SUBTYPE_CTL_PSPOLL
@ 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_PSPOLL
@ 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 CASE_WIFI_MAC_TYPE(x)