A Discrete-Event Network Simulator
API
mgt-action-headers.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2006 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 "mgt-action-headers.h"
23 
24 #include "addba-extension.h"
25 
26 #include "ns3/multi-link-element.h"
27 #include "ns3/packet.h"
28 
29 namespace ns3
30 {
31 
33 {
34 }
35 
37 {
38 }
39 
40 void
43 {
44  m_category = static_cast<uint8_t>(type);
45  switch (type)
46  {
47  case SPECTRUM_MANAGEMENT: {
48  break;
49  }
50  case QOS: {
51  m_actionValue = static_cast<uint8_t>(action.qos);
52  break;
53  }
54  case BLOCK_ACK: {
55  m_actionValue = static_cast<uint8_t>(action.blockAck);
56  break;
57  }
58  case PUBLIC: {
59  m_actionValue = static_cast<uint8_t>(action.publicAction);
60  break;
61  }
62  case RADIO_MEASUREMENT: {
63  m_actionValue = static_cast<uint8_t>(action.radioMeasurementAction);
64  break;
65  }
66  case MESH: {
67  m_actionValue = static_cast<uint8_t>(action.meshAction);
68  break;
69  }
70  case MULTIHOP: {
71  m_actionValue = static_cast<uint8_t>(action.multihopAction);
72  break;
73  }
74  case SELF_PROTECTED: {
75  m_actionValue = static_cast<uint8_t>(action.selfProtectedAction);
76  break;
77  }
78  case DMG: {
79  m_actionValue = static_cast<uint8_t>(action.dmgAction);
80  break;
81  }
82  case FST: {
83  m_actionValue = static_cast<uint8_t>(action.fstAction);
84  break;
85  }
86  case UNPROTECTED_DMG: {
87  m_actionValue = static_cast<uint8_t>(action.unprotectedDmgAction);
88  break;
89  }
90  case PROTECTED_EHT: {
91  m_actionValue = static_cast<uint8_t>(action.protectedEhtAction);
92  break;
93  }
95  break;
96  }
97  }
98 }
99 
102 {
103  switch (m_category)
104  {
105  case QOS:
106  return QOS;
107  case BLOCK_ACK:
108  return BLOCK_ACK;
109  case PUBLIC:
110  return PUBLIC;
111  case RADIO_MEASUREMENT:
112  return RADIO_MEASUREMENT;
113  case MESH:
114  return MESH;
115  case MULTIHOP:
116  return MULTIHOP;
117  case SELF_PROTECTED:
118  return SELF_PROTECTED;
119  case DMG:
120  return DMG;
121  case FST:
122  return FST;
123  case UNPROTECTED_DMG:
124  return UNPROTECTED_DMG;
125  case PROTECTED_EHT:
126  return PROTECTED_EHT;
128  return VENDOR_SPECIFIC_ACTION;
129  default:
130  NS_FATAL_ERROR("Unknown action value");
131  return SELF_PROTECTED;
132  }
133 }
134 
137 {
138  ActionValue retval;
139  retval.selfProtectedAction =
140  PEER_LINK_OPEN; // Needs to be initialized to something to quiet valgrind in default cases
141  switch (m_category)
142  {
143  case QOS:
144  switch (m_actionValue)
145  {
146  case ADDTS_REQUEST:
147  retval.qos = ADDTS_REQUEST;
148  break;
149  case ADDTS_RESPONSE:
150  retval.qos = ADDTS_RESPONSE;
151  break;
152  case DELTS:
153  retval.qos = DELTS;
154  break;
155  case SCHEDULE:
156  retval.qos = SCHEDULE;
157  break;
158  case QOS_MAP_CONFIGURE:
159  retval.qos = QOS_MAP_CONFIGURE;
160  break;
161  default:
162  NS_FATAL_ERROR("Unknown qos action code");
163  retval.qos = ADDTS_REQUEST; /* quiet compiler */
164  }
165  break;
166 
167  case BLOCK_ACK:
168  switch (m_actionValue)
169  {
172  break;
175  break;
176  case BLOCK_ACK_DELBA:
177  retval.blockAck = BLOCK_ACK_DELBA;
178  break;
179  default:
180  NS_FATAL_ERROR("Unknown block ack action code");
181  retval.blockAck = BLOCK_ACK_ADDBA_REQUEST; /* quiet compiler */
182  }
183  break;
184 
185  case PUBLIC:
186  switch (m_actionValue)
187  {
188  case QAB_REQUEST:
189  retval.publicAction = QAB_REQUEST;
190  break;
191  case QAB_RESPONSE:
192  retval.publicAction = QAB_RESPONSE;
193  break;
194  default:
195  NS_FATAL_ERROR("Unknown public action code");
196  retval.publicAction = QAB_REQUEST; /* quiet compiler */
197  }
198  break;
199 
200  case RADIO_MEASUREMENT:
201  switch (m_actionValue)
202  {
205  break;
208  break;
211  break;
214  break;
217  break;
220  break;
221  default:
222  NS_FATAL_ERROR("Unknown radio measurement action code");
223  retval.radioMeasurementAction = RADIO_MEASUREMENT_REQUEST; /* quiet compiler */
224  }
225  break;
226 
227  case SELF_PROTECTED:
228  switch (m_actionValue)
229  {
230  case PEER_LINK_OPEN:
232  break;
233  case PEER_LINK_CONFIRM:
235  break;
236  case PEER_LINK_CLOSE:
238  break;
239  case GROUP_KEY_INFORM:
241  break;
242  case GROUP_KEY_ACK:
244  break;
245  default:
246  NS_FATAL_ERROR("Unknown mesh peering management action code");
247  retval.selfProtectedAction = PEER_LINK_OPEN; /* quiet compiler */
248  }
249  break;
250 
251  case MESH:
252  switch (m_actionValue)
253  {
254  case LINK_METRIC_REPORT:
256  break;
257  case PATH_SELECTION:
258  retval.meshAction = PATH_SELECTION;
259  break;
260  case PORTAL_ANNOUNCEMENT:
262  break;
265  break;
266  case MDA_SETUP_REQUEST:
267  retval.meshAction = MDA_SETUP_REQUEST;
268  break;
269  case MDA_SETUP_REPLY:
270  retval.meshAction = MDA_SETUP_REPLY;
271  break;
274  break;
277  break;
278  case MDAOP_SET_TEARDOWN:
280  break;
283  break;
286  break;
287  default:
288  NS_FATAL_ERROR("Unknown mesh peering management action code");
289  retval.meshAction = LINK_METRIC_REPORT; /* quiet compiler */
290  }
291  break;
292 
293  case MULTIHOP: // not yet supported
294  switch (m_actionValue)
295  {
296  case PROXY_UPDATE: // not used so far
297  retval.multihopAction = PROXY_UPDATE;
298  break;
299  case PROXY_UPDATE_CONFIRMATION: // not used so far
300  retval.multihopAction = PROXY_UPDATE;
301  break;
302  default:
303  NS_FATAL_ERROR("Unknown mesh peering management action code");
304  retval.multihopAction = PROXY_UPDATE; /* quiet compiler */
305  }
306  break;
307 
308  case DMG:
309  switch (m_actionValue)
310  {
313  break;
316  break;
319  break;
322  break;
325  break;
328  break;
329  case DMG_DTP_REQUEST:
330  retval.dmgAction = DMG_DTP_REQUEST;
331  break;
332  case DMG_DTP_RESPONSE:
333  retval.dmgAction = DMG_DTP_RESPONSE;
334  break;
337  break;
340  break;
343  break;
346  break;
347  case DMG_RLS_REQUEST:
348  retval.dmgAction = DMG_RLS_REQUEST;
349  break;
350  case DMG_RLS_RESPONSE:
351  retval.dmgAction = DMG_RLS_RESPONSE;
352  break;
355  break;
356  case DMG_RLS_TEARDOWN:
357  retval.dmgAction = DMG_RLS_TEARDOWN;
358  break;
361  break;
364  break;
365  case DMG_TPA_REQUEST:
366  retval.dmgAction = DMG_TPA_REQUEST;
367  break;
368  case DMG_TPA_RESPONSE:
369  retval.dmgAction = DMG_TPA_RESPONSE;
370  break;
371  case DMG_ROC_REQUEST:
372  retval.dmgAction = DMG_ROC_REQUEST;
373  break;
374  case DMG_ROC_RESPONSE:
375  retval.dmgAction = DMG_ROC_RESPONSE;
376  break;
377  default:
378  NS_FATAL_ERROR("Unknown DMG management action code");
379  retval.dmgAction = DMG_POWER_SAVE_CONFIGURATION_REQUEST; /* quiet compiler */
380  }
381  break;
382 
383  case FST:
384  switch (m_actionValue)
385  {
386  case FST_SETUP_REQUEST:
387  retval.fstAction = FST_SETUP_REQUEST;
388  break;
389  case FST_SETUP_RESPONSE:
390  retval.fstAction = FST_SETUP_RESPONSE;
391  break;
392  case FST_TEAR_DOWN:
393  retval.fstAction = FST_TEAR_DOWN;
394  break;
395  case FST_ACK_REQUEST:
396  retval.fstAction = FST_ACK_REQUEST;
397  break;
398  case FST_ACK_RESPONSE:
399  retval.fstAction = FST_ACK_RESPONSE;
400  break;
403  break;
404  default:
405  NS_FATAL_ERROR("Unknown FST management action code");
406  retval.fstAction = FST_SETUP_REQUEST; /* quiet compiler */
407  }
408  break;
409 
410  case UNPROTECTED_DMG:
411  switch (m_actionValue)
412  {
415  break;
416  case UNPROTECTED_DMG_BRP:
418  break;
421  break;
424  break;
427  break;
430  break;
431  default:
432  NS_FATAL_ERROR("Unknown Unprotected DMG action code");
433  retval.unprotectedDmgAction = UNPROTECTED_DMG_ANNOUNCE; /* quiet compiler */
434  }
435  break;
436 
437  case PROTECTED_EHT:
438  switch (m_actionValue)
439  {
442  break;
445  break;
448  break;
451  break;
454  break;
457  break;
460  break;
463  break;
466  break;
469  break;
470  default:
471  NS_FATAL_ERROR("Unknown Protected EHT action code");
472  retval.protectedEhtAction =
473  PROTECTED_EHT_TID_TO_LINK_MAPPING_REQUEST; /* quiet compiler */
474  }
475  break;
476 
477  default:
478  NS_FATAL_ERROR("Unsupported action");
479  retval.selfProtectedAction = PEER_LINK_OPEN; /* quiet compiler */
480  }
481  return retval;
482 }
483 
484 TypeId
486 {
487  static TypeId tid = TypeId("ns3::WifiActionHeader")
488  .SetParent<Header>()
489  .SetGroupName("Wifi")
490  .AddConstructor<WifiActionHeader>();
491  return tid;
492 }
493 
494 TypeId
496 {
497  return GetTypeId();
498 }
499 
500 std::pair<WifiActionHeader::CategoryValue, WifiActionHeader::ActionValue>
502 {
503  WifiActionHeader actionHdr;
504  pkt->PeekHeader(actionHdr);
505  return {actionHdr.GetCategory(), actionHdr.GetAction()};
506 }
507 
508 std::pair<WifiActionHeader::CategoryValue, WifiActionHeader::ActionValue>
510 {
511  WifiActionHeader actionHdr;
512  pkt->RemoveHeader(actionHdr);
513  return {actionHdr.GetCategory(), actionHdr.GetAction()};
514 }
515 
516 void
517 WifiActionHeader::Print(std::ostream& os) const
518 {
519 #define CASE_ACTION_VALUE(x) \
520  case x: \
521  os << #x << "]"; \
522  break;
523 
524  switch (m_category)
525  {
526  case QOS:
527  os << "QOS[";
528  switch (m_actionValue)
529  {
535  default:
536  NS_FATAL_ERROR("Unknown qos action code");
537  }
538  break;
539  case BLOCK_ACK:
540  os << "BLOCK_ACK[";
541  switch (m_actionValue)
542  {
546  default:
547  NS_FATAL_ERROR("Unknown block ack action code");
548  }
549  break;
550  case PUBLIC:
551  os << "PUBLIC[";
552  switch (m_actionValue)
553  {
556  default:
557  NS_FATAL_ERROR("Unknown public action code");
558  }
559  break;
560  case RADIO_MEASUREMENT:
561  os << "RADIO_MEASUREMENT[";
562  switch (m_actionValue)
563  {
570  default:
571  NS_FATAL_ERROR("Unknown radio measurement action code");
572  }
573  break;
574  case MESH:
575  os << "MESH[";
576  switch (m_actionValue)
577  {
589  default:
590  NS_FATAL_ERROR("Unknown mesh peering management action code");
591  }
592  break;
593  case MULTIHOP:
594  os << "MULTIHOP[";
595  switch (m_actionValue)
596  {
597  CASE_ACTION_VALUE(PROXY_UPDATE); // not used so far
598  CASE_ACTION_VALUE(PROXY_UPDATE_CONFIRMATION); // not used so far
599  default:
600  NS_FATAL_ERROR("Unknown mesh peering management action code");
601  }
602  break;
603  case SELF_PROTECTED:
604  os << "SELF_PROTECTED[";
605  switch (m_actionValue)
606  {
612  default:
613  NS_FATAL_ERROR("Unknown mesh peering management action code");
614  }
615  break;
616  case DMG:
617  os << "DMG[";
618  switch (m_actionValue)
619  {
642  default:
643  NS_FATAL_ERROR("Unknown DMG management action code");
644  }
645  break;
646  case FST:
647  os << "FST[";
648  switch (m_actionValue)
649  {
656  default:
657  NS_FATAL_ERROR("Unknown FST management action code");
658  }
659  break;
660  case UNPROTECTED_DMG:
661  os << "UNPROTECTED_DMG[";
662  switch (m_actionValue)
663  {
670  default:
671  NS_FATAL_ERROR("Unknown Unprotected DMG action code");
672  }
673  break;
674  case PROTECTED_EHT:
675  os << "PROTECTED_EHT[";
676  switch (m_actionValue)
677  {
688  default:
689  NS_FATAL_ERROR("Unknown Protected EHT action code");
690  }
691  break;
693  os << "VENDOR_SPECIFIC_ACTION";
694  break;
695  default:
696  NS_FATAL_ERROR("Unknown action value");
697  }
698 #undef CASE_ACTION_VALUE
699 }
700 
701 uint32_t
703 {
704  return 2;
705 }
706 
707 void
709 {
710  start.WriteU8(m_category);
711  start.WriteU8(m_actionValue);
712 }
713 
714 uint32_t
716 {
718  m_category = i.ReadU8();
719  m_actionValue = i.ReadU8();
720  return i.GetDistanceFrom(start);
721 }
722 
723 /***************************************************
724  * ADDBARequest
725  ****************************************************/
726 
728 
729 TypeId
731 {
732  static TypeId tid = TypeId("ns3::MgtAddBaRequestHeader")
733  .SetParent<Header>()
734  .SetGroupName("Wifi")
735  .AddConstructor<MgtAddBaRequestHeader>();
736  return tid;
737 }
738 
739 TypeId
741 {
742  return GetTypeId();
743 }
744 
745 void
746 MgtAddBaRequestHeader::Print(std::ostream& os) const
747 {
748 }
749 
750 uint32_t
752 {
753  uint32_t size = 0;
754  size += 1; // Dialog token
755  size += 2; // Block ack parameter set
756  size += 2; // Block ack timeout value
757  size += 2; // Starting sequence control
758  if (m_bufferSize >= 1024)
759  {
760  // an ADDBA Extension element has to be added
761  size += AddbaExtension().GetSerializedSize();
762  }
763  return size;
764 }
765 
766 void
768 {
774  if (m_bufferSize >= 1024)
775  {
776  AddbaExtension addbaExt;
777  addbaExt.m_extParamSet.extBufferSize = m_bufferSize / 1024;
778  i = addbaExt.Serialize(i);
779  }
780 }
781 
782 uint32_t
784 {
786  m_dialogToken = i.ReadU8();
790  AddbaExtension addbaExt;
791  auto tmp = i;
792  i = addbaExt.DeserializeIfPresent(i);
793  if (i.GetDistanceFrom(tmp) != 0)
794  {
795  // the buffer size is Extended Buffer Size × 1024 + Buffer Size
796  // (Sec. 9.4.2.138 of 802.11be D4.0)
797  m_bufferSize += addbaExt.m_extParamSet.extBufferSize * 1024;
798  }
799  return i.GetDistanceFrom(start);
800 }
801 
802 void
804 {
805  m_policy = 0;
806 }
807 
808 void
810 {
811  m_policy = 1;
812 }
813 
814 void
816 {
817  NS_ASSERT(tid < 16);
818  m_tid = tid;
819 }
820 
821 void
823 {
825 }
826 
827 void
829 {
830  m_bufferSize = size;
831 }
832 
833 void
835 {
836  m_startingSeq = seq;
837 }
838 
839 void
841 {
842  m_startingSeq = (seqControl >> 4) & 0x0fff;
843 }
844 
845 void
847 {
848  m_amsduSupport = supported;
849 }
850 
851 uint8_t
853 {
854  return m_tid;
855 }
856 
857 bool
859 {
860  return m_policy == 1;
861 }
862 
863 uint16_t
865 {
866  return m_timeoutValue;
867 }
868 
869 uint16_t
871 {
872  return m_bufferSize;
873 }
874 
875 bool
877 {
878  return m_amsduSupport == 1;
879 }
880 
881 uint16_t
883 {
884  return m_startingSeq;
885 }
886 
887 uint16_t
889 {
890  return (m_startingSeq << 4) & 0xfff0;
891 }
892 
893 uint16_t
895 {
896  uint16_t res = 0;
897  res |= m_amsduSupport;
898  res |= m_policy << 1;
899  res |= m_tid << 2;
900  res |= (m_bufferSize % 1024) << 6;
901  return res;
902 }
903 
904 void
906 {
907  m_amsduSupport = params & 0x01;
908  m_policy = (params >> 1) & 0x01;
909  m_tid = (params >> 2) & 0x0f;
910  m_bufferSize = (params >> 6) & 0x03ff;
911 }
912 
913 /***************************************************
914  * ADDBAResponse
915  ****************************************************/
916 
918 
919 TypeId
921 {
922  static TypeId tid = TypeId("ns3::MgtAddBaResponseHeader")
923  .SetParent<Header>()
924  .SetGroupName("Wifi")
925  .AddConstructor<MgtAddBaResponseHeader>();
926  return tid;
927 }
928 
929 TypeId
931 {
932  return GetTypeId();
933 }
934 
935 void
936 MgtAddBaResponseHeader::Print(std::ostream& os) const
937 {
938  os << "status code=" << m_code;
939 }
940 
941 uint32_t
943 {
944  uint32_t size = 0;
945  size += 1; // Dialog token
946  size += m_code.GetSerializedSize(); // Status code
947  size += 2; // Block ack parameter set
948  size += 2; // Block ack timeout value
949  if (m_bufferSize >= 1024)
950  {
951  // an ADDBA Extension element has to be added
952  size += AddbaExtension().GetSerializedSize();
953  }
954  return size;
955 }
956 
957 void
959 {
962  i = m_code.Serialize(i);
965  if (m_bufferSize >= 1024)
966  {
967  AddbaExtension addbaExt;
968  addbaExt.m_extParamSet.extBufferSize = m_bufferSize / 1024;
969  i = addbaExt.Serialize(i);
970  }
971 }
972 
973 uint32_t
975 {
977  m_dialogToken = i.ReadU8();
978  i = m_code.Deserialize(i);
981  AddbaExtension addbaExt;
982  auto tmp = i;
983  i = addbaExt.DeserializeIfPresent(i);
984  if (i.GetDistanceFrom(tmp) != 0)
985  {
986  // the buffer size is Extended Buffer Size × 1024 + Buffer Size
987  // (Sec. 9.4.2.138 of 802.11be D4.0)
988  m_bufferSize += addbaExt.m_extParamSet.extBufferSize * 1024;
989  }
990  return i.GetDistanceFrom(start);
991 }
992 
993 void
995 {
996  m_policy = 0;
997 }
998 
999 void
1001 {
1002  m_policy = 1;
1003 }
1004 
1005 void
1007 {
1008  NS_ASSERT(tid < 16);
1009  m_tid = tid;
1010 }
1011 
1012 void
1014 {
1016 }
1017 
1018 void
1020 {
1021  m_bufferSize = size;
1022 }
1023 
1024 void
1026 {
1027  m_code = code;
1028 }
1029 
1030 void
1032 {
1033  m_amsduSupport = supported;
1034 }
1035 
1036 StatusCode
1038 {
1039  return m_code;
1040 }
1041 
1042 uint8_t
1044 {
1045  return m_tid;
1046 }
1047 
1048 bool
1050 {
1051  return m_policy == 1;
1052 }
1053 
1054 uint16_t
1056 {
1057  return m_timeoutValue;
1058 }
1059 
1060 uint16_t
1062 {
1063  return m_bufferSize;
1064 }
1065 
1066 bool
1068 {
1069  return m_amsduSupport == 1;
1070 }
1071 
1072 uint16_t
1074 {
1075  uint16_t res = 0;
1076  res |= m_amsduSupport;
1077  res |= m_policy << 1;
1078  res |= m_tid << 2;
1079  res |= (m_bufferSize % 1024) << 6;
1080  return res;
1081 }
1082 
1083 void
1085 {
1086  m_amsduSupport = params & 0x01;
1087  m_policy = (params >> 1) & 0x01;
1088  m_tid = (params >> 2) & 0x0f;
1089  m_bufferSize = (params >> 6) & 0x03ff;
1090 }
1091 
1092 /***************************************************
1093  * DelBa
1094  ****************************************************/
1095 
1097 
1098 TypeId
1100 {
1101  static TypeId tid = TypeId("ns3::MgtDelBaHeader")
1102  .SetParent<Header>()
1103  .SetGroupName("Wifi")
1104  .AddConstructor<MgtDelBaHeader>();
1105  return tid;
1106 }
1107 
1108 TypeId
1110 {
1111  return GetTypeId();
1112 }
1113 
1114 void
1115 MgtDelBaHeader::Print(std::ostream& os) const
1116 {
1117 }
1118 
1119 uint32_t
1121 {
1122  uint32_t size = 0;
1123  size += 2; // DelBa parameter set
1124  size += 2; // Reason code
1125  return size;
1126 }
1127 
1128 void
1130 {
1131  Buffer::Iterator i = start;
1134 }
1135 
1136 uint32_t
1138 {
1139  Buffer::Iterator i = start;
1142  return i.GetDistanceFrom(start);
1143 }
1144 
1145 bool
1147 {
1148  return m_initiator == 1;
1149 }
1150 
1151 uint8_t
1153 {
1154  NS_ASSERT(m_tid < 16);
1155  auto tid = static_cast<uint8_t>(m_tid);
1156  return tid;
1157 }
1158 
1159 void
1161 {
1162  m_initiator = 1;
1163 }
1164 
1165 void
1167 {
1168  m_initiator = 0;
1169 }
1170 
1171 void
1173 {
1174  NS_ASSERT(tid < 16);
1175  m_tid = static_cast<uint16_t>(tid);
1176 }
1177 
1178 uint16_t
1180 {
1181  uint16_t res = 0;
1182  res |= m_initiator << 11;
1183  res |= m_tid << 12;
1184  return res;
1185 }
1186 
1187 void
1189 {
1190  m_initiator = (params >> 11) & 0x01;
1191  m_tid = (params >> 12) & 0x0f;
1192 }
1193 
1194 /***************************************************
1195  * EMLSR Operating Mode Notification
1196  ****************************************************/
1197 
1199 
1200 TypeId
1202 {
1203  static TypeId tid = TypeId("ns3::MgtEmlOperatingModeNotification")
1204  .SetParent<Header>()
1205  .SetGroupName("Wifi")
1206  .AddConstructor<MgtEmlOmn>();
1207  return tid;
1208 }
1209 
1210 TypeId
1212 {
1213  return GetTypeId();
1214 }
1215 
1216 void
1217 MgtEmlOmn::Print(std::ostream& os) const
1218 {
1219  os << "EMLSR Mode=" << +m_emlControl.emlsrMode << " EMLMR Mode=" << +m_emlControl.emlmrMode
1220  << " EMLSR Parameter Update Control=" << +m_emlControl.emlsrParamUpdateCtrl;
1222  {
1223  os << " Link bitmap=" << std::hex << *m_emlControl.linkBitmap << std::dec;
1224  }
1225  if (m_emlsrParamUpdate)
1226  {
1227  os << " EMLSR Padding Delay="
1229  .As(Time::US)
1230  << " EMLSR Transition Delay="
1232  .As(Time::US);
1233  }
1234 }
1235 
1236 uint32_t
1238 {
1239  uint32_t size = 2; // Dialog Token (1) + first byte of EML Control
1241  {
1242  size += 2;
1243  }
1245  {
1246  size += 1;
1247  }
1248  // TODO add size of EMLMR Supported MCS And NSS Set subfield when implemented
1249  if (m_emlsrParamUpdate)
1250  {
1251  size += 1; // EMLSR Parameter Update field
1252  }
1253  return size;
1254 }
1255 
1256 void
1258 {
1259  start.WriteU8(m_dialogToken);
1260 
1262  "EMLSR Mode and EMLMR Mode cannot be both set to 1");
1263  uint8_t val = m_emlControl.emlsrMode | (m_emlControl.emlmrMode << 1) |
1265  start.WriteU8(val);
1266 
1267  NS_ABORT_MSG_IF(m_emlControl.linkBitmap.has_value() !=
1269  "The EMLSR/EMLMR Link Bitmap is present if and only if either of the EMLSR "
1270  "Mode and EMLMR Mode subfields are set to 1");
1272  {
1273  start.WriteHtolsbU16(*m_emlControl.linkBitmap);
1274  }
1275  // TODO serialize MCS Map Count Control and EMLMR Supported MCS And NSS Set subfields
1276  // when implemented
1277 
1279  "The EMLSR Parameter Update field is present "
1280  << std::boolalpha << m_emlsrParamUpdate.has_value()
1281  << " if and only if the EMLSR "
1282  "Parameter Update Control subfield is set to 1 "
1284  if (m_emlsrParamUpdate)
1285  {
1286  val = m_emlsrParamUpdate->paddingDelay | (m_emlsrParamUpdate->transitionDelay << 3);
1287  start.WriteU8(val);
1288  }
1289 }
1290 
1291 uint32_t
1293 {
1294  Buffer::Iterator i = start;
1295 
1296  m_dialogToken = i.ReadU8();
1297 
1298  uint8_t val = i.ReadU8();
1299  m_emlControl.emlsrMode = val & 0x01;
1300  m_emlControl.emlmrMode = (val >> 1) & 0x01;
1301  m_emlControl.emlsrParamUpdateCtrl = (val >> 2) & 0x01;
1302 
1304  "EMLSR Mode and EMLMR Mode cannot be both set to 1");
1305 
1306  if (m_emlControl.emlsrMode == 1 || m_emlControl.emlmrMode == 1)
1307  {
1309  }
1310  // TODO deserialize MCS Map Count Control and EMLMR Supported MCS And NSS Set subfields
1311  // when implemented
1312 
1314  {
1315  val = i.ReadU8();
1317  m_emlsrParamUpdate->paddingDelay = val & 0x07;
1318  m_emlsrParamUpdate->transitionDelay = (val >> 3) & 0x07;
1319  }
1320 
1321  return i.GetDistanceFrom(start);
1322 }
1323 
1324 void
1326 {
1327  NS_ABORT_MSG_IF(linkId > 15, "Link ID must not exceed 15");
1328  if (!m_emlControl.linkBitmap)
1329  {
1331  }
1332  m_emlControl.linkBitmap = *m_emlControl.linkBitmap | (1 << linkId);
1333 }
1334 
1335 std::list<uint8_t>
1337 {
1338  std::list<uint8_t> list;
1339  NS_ASSERT_MSG(m_emlControl.linkBitmap.has_value(), "No link bitmap");
1340  uint16_t bitmap = *m_emlControl.linkBitmap;
1341  for (uint8_t linkId = 0; linkId < 16; linkId++)
1342  {
1343  if ((bitmap & 0x0001) == 1)
1344  {
1345  list.push_back(linkId);
1346  }
1347  bitmap >>= 1;
1348  }
1349  return list;
1350 }
1351 
1352 } // namespace ns3
The IEEE 802.11 ADDBA Extension Element (Sec.
ExtParamSet m_extParamSet
ADDBA Extended Parameter Set field.
iterator in a Buffer instance
Definition: buffer.h:100
void WriteHtolsbU16(uint16_t data)
Definition: buffer.cc:902
uint8_t ReadU8()
Definition: buffer.h:1027
void WriteU8(uint8_t data)
Definition: buffer.h:881
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.
Implement the header for management frames of type Add Block Ack request.
void SetParameterSet(uint16_t params)
Set the parameter set from the given raw value.
uint16_t m_startingSeq
Starting sequence number.
void Serialize(Buffer::Iterator start) const override
uint16_t GetStartingSequenceControl() const
Return the raw sequence control.
void SetStartingSequenceControl(uint16_t seqControl)
Set sequence control with the given raw value.
static TypeId GetTypeId()
Register this type.
uint8_t m_amsduSupport
Flag if A-MSDU is supported.
void SetBufferSize(uint16_t size)
Set buffer size.
void Print(std::ostream &os) const override
void SetDelayedBlockAck()
Enable delayed BlockAck.
uint8_t m_dialogToken
Not used for now.
uint16_t GetParameterSet() const
Return the raw parameter set.
void SetAmsduSupport(bool supported)
Enable or disable A-MSDU support.
void SetImmediateBlockAck()
Enable immediate BlockAck.
uint16_t GetBufferSize() const
Return the buffer size.
uint16_t m_bufferSize
Buffer size.
uint16_t GetTimeout() const
Return the timeout.
uint8_t GetTid() const
Return the Traffic ID (TID).
uint16_t GetStartingSequence() const
Return the starting sequence number.
TypeId GetInstanceTypeId() const override
Get the most derived TypeId for this Object.
uint32_t GetSerializedSize() const override
bool IsAmsduSupported() const
Return whether A-MSDU capability is supported.
bool IsImmediateBlockAck() const
Return whether the Block Ack policy is immediate Block Ack.
void SetTimeout(uint16_t timeout)
Set timeout.
void SetTid(uint8_t tid)
Set Traffic ID (TID).
uint8_t m_policy
Block Ack policy.
void SetStartingSequence(uint16_t seq)
Set the starting sequence number.
Implement the header for management frames of type Add Block Ack response.
uint16_t m_bufferSize
Buffer size.
void SetTid(uint8_t tid)
Set Traffic ID (TID).
uint32_t GetSerializedSize() const override
uint8_t m_amsduSupport
Flag if A-MSDU is supported.
uint8_t m_dialogToken
Not used for now.
void Serialize(Buffer::Iterator start) const override
void SetParameterSet(uint16_t params)
Set the parameter set from the given raw value.
uint16_t GetBufferSize() const
Return the buffer size.
bool IsAmsduSupported() const
Return whether A-MSDU capability is supported.
StatusCode GetStatusCode() const
Return the status code.
void SetTimeout(uint16_t timeout)
Set timeout.
uint8_t m_policy
Block ACK policy.
TypeId GetInstanceTypeId() const override
Get the most derived TypeId for this Object.
void SetBufferSize(uint16_t size)
Set buffer size.
void Print(std::ostream &os) const override
void SetStatusCode(StatusCode code)
Set the status code.
uint8_t GetTid() const
Return the Traffic ID (TID).
bool IsImmediateBlockAck() const
Return whether the Block Ack policy is immediate Block Ack.
void SetAmsduSupport(bool supported)
Enable or disable A-MSDU support.
uint16_t GetParameterSet() const
Return the raw parameter set.
uint16_t GetTimeout() const
Return the timeout.
void SetDelayedBlockAck()
Enable delayed BlockAck.
void SetImmediateBlockAck()
Enable immediate BlockAck.
static TypeId GetTypeId()
Register this type.
StatusCode m_code
Status code.
Implement the header for management frames of type Delete Block Ack.
static TypeId GetTypeId()
Register this type.
void SetTid(uint8_t tid)
Set Traffic ID (TID).
void SetByRecipient()
Un-set the initiator bit in the DELBA.
void Print(std::ostream &os) const override
uint16_t m_initiator
initiator
void SetParameterSet(uint16_t params)
Set the parameter set from the given raw value.
TypeId GetInstanceTypeId() const override
Get the most derived TypeId for this Object.
uint8_t GetTid() const
Return the Traffic ID (TID).
uint16_t m_reasonCode
Not used for now.
bool IsByOriginator() const
Check if the initiator bit in the DELBA is set.
uint16_t GetParameterSet() const
Return the raw parameter set.
void Serialize(Buffer::Iterator start) const override
uint16_t m_tid
Traffic ID.
uint32_t GetSerializedSize() const override
void SetByOriginator()
Set the initiator bit in the DELBA.
Implement the header for Action frames of type EML Operating Mode Notification.
void Serialize(Buffer::Iterator start) const override
uint32_t GetSerializedSize() const override
void SetLinkIdInBitmap(uint8_t linkId)
Set the bit position in the link bitmap corresponding to the given link.
EmlControl m_emlControl
EML Control field.
void Print(std::ostream &os) const override
std::optional< EmlsrParamUpdate > m_emlsrParamUpdate
EMLSR Parameter Update field.
TypeId GetInstanceTypeId() const override
Get the most derived TypeId for this Object.
uint8_t m_dialogToken
Dialog Token.
std::list< uint8_t > GetLinkBitmap() const
static TypeId GetTypeId()
Register this type.
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:294
uint32_t PeekHeader(Header &header) const
Deserialize but does not remove the header from the internal buffer.
Definition: packet.cc:305
Status code for association response.
Definition: status-code.h:32
Buffer::Iterator Serialize(Buffer::Iterator start) const
Definition: status-code.cc:54
Buffer::Iterator Deserialize(Buffer::Iterator start)
Definition: status-code.cc:61
uint32_t GetSerializedSize() const
Definition: status-code.cc:48
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:415
@ US
microsecond
Definition: nstime.h:118
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:931
See IEEE 802.11 chapter 7.3.1.11 Header format: | category: 1 | action value: 1 |.
uint32_t GetSerializedSize() const override
CategoryValue
CategoryValue enumeration.
uint8_t m_category
Category of the action.
TypeId GetInstanceTypeId() const override
Get the most derived TypeId for this Object.
uint8_t m_actionValue
Action value.
static std::pair< CategoryValue, ActionValue > Peek(Ptr< const Packet > pkt)
Peek an Action header from the given packet.
void Print(std::ostream &os) const override
static std::pair< CategoryValue, ActionValue > Remove(Ptr< Packet > pkt)
Remove an Action header from the given packet.
static TypeId GetTypeId()
Register this type.
void SetAction(CategoryValue type, ActionValue action)
Set action for this Action header.
void Serialize(Buffer::Iterator start) const override
CategoryValue GetCategory() const
Return the category value.
ActionValue GetAction() const
Return the action value.
uint16_t GetSerializedSize() const
Get the size of the serialized IE including Element ID and length fields (for every element this IE i...
Buffer::Iterator Serialize(Buffer::Iterator i) const
Serialize entire IE including Element ID and length fields.
Buffer::Iterator DeserializeIfPresent(Buffer::Iterator i)
Deserialize entire IE (which may possibly be fragmented into multiple elements) if it is present.
#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_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:86
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
#define CASE_ACTION_VALUE(x)
Every class exported by the ns3 library is enclosed in the ns3 namespace.
params
Fit Fluctuating Two Ray model to the 3GPP TR 38.901 using the Anderson-Darling goodness-of-fit ##.
#define list
ns3::Time timeout
uint8_t extBufferSize
extended buffer size
static Time DecodeEmlsrTransitionDelay(uint8_t value)
static Time DecodeEmlsrPaddingDelay(uint8_t value)
std::optional< uint8_t > mcsMapCountCtrl
MCS Map Count Control.
uint8_t emlsrParamUpdateCtrl
EMLSR Parameter Update Control.
std::optional< uint16_t > linkBitmap
EMLSR/EMLMR Link Bitmap.
EMLSR Parameter Update field.
typedef for union of different ActionValues
UnprotectedDmgActionValue unprotectedDmgAction
unprotected dmg
ProtectedEhtActionValue protectedEhtAction
protected eht
SelfProtectedActionValue selfProtectedAction
self protected
MultihopActionValue multihopAction
multi hop
RadioMeasurementActionValue radioMeasurementAction
radio measurement
PublicActionValue publicAction
public
BlockAckActionValue blockAck
block ack