A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
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 * SPDX-License-Identifier: GPL-2.0-only
6 *
7 * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
8 * Mirko Banchi <mk.banchi@gmail.com>
9 */
10
11#include "mgt-action-headers.h"
12
13#include "addba-extension.h"
14
15#include "ns3/multi-link-element.h"
16#include "ns3/packet.h"
17#include "ns3/simulator.h"
18
19#include <vector>
20
21namespace ns3
22{
23
27
31
32void
35{
36 m_category = static_cast<uint8_t>(type);
37 switch (type)
38 {
40 break;
41 }
42 case QOS: {
43 m_actionValue = static_cast<uint8_t>(action.qos);
44 break;
45 }
46 case BLOCK_ACK: {
47 m_actionValue = static_cast<uint8_t>(action.blockAck);
48 break;
49 }
50 case PUBLIC: {
51 m_actionValue = static_cast<uint8_t>(action.publicAction);
52 break;
53 }
54 case RADIO_MEASUREMENT: {
55 m_actionValue = static_cast<uint8_t>(action.radioMeasurementAction);
56 break;
57 }
58 case MESH: {
59 m_actionValue = static_cast<uint8_t>(action.meshAction);
60 break;
61 }
62 case MULTIHOP: {
63 m_actionValue = static_cast<uint8_t>(action.multihopAction);
64 break;
65 }
66 case SELF_PROTECTED: {
67 m_actionValue = static_cast<uint8_t>(action.selfProtectedAction);
68 break;
69 }
70 case DMG: {
71 m_actionValue = static_cast<uint8_t>(action.dmgAction);
72 break;
73 }
74 case FST: {
75 m_actionValue = static_cast<uint8_t>(action.fstAction);
76 break;
77 }
78 case UNPROTECTED_DMG: {
79 m_actionValue = static_cast<uint8_t>(action.unprotectedDmgAction);
80 break;
81 }
82 case PROTECTED_EHT: {
83 m_actionValue = static_cast<uint8_t>(action.protectedEhtAction);
84 break;
85 }
87 break;
88 }
89 }
90}
91
94{
95 switch (m_category)
96 {
97 case QOS:
98 return QOS;
99 case BLOCK_ACK:
100 return BLOCK_ACK;
101 case PUBLIC:
102 return PUBLIC;
104 return RADIO_MEASUREMENT;
105 case MESH:
106 return MESH;
107 case MULTIHOP:
108 return MULTIHOP;
109 case SELF_PROTECTED:
110 return SELF_PROTECTED;
111 case DMG:
112 return DMG;
113 case FST:
114 return FST;
115 case UNPROTECTED_DMG:
116 return UNPROTECTED_DMG;
117 case PROTECTED_EHT:
118 return PROTECTED_EHT;
121 default:
122 NS_FATAL_ERROR("Unknown action value");
123 return SELF_PROTECTED;
124 }
125}
126
129{
130 ActionValue retval;
131 retval.selfProtectedAction =
132 PEER_LINK_OPEN; // Needs to be initialized to something to quiet valgrind in default cases
133 switch (m_category)
134 {
135 case QOS:
136 switch (m_actionValue)
137 {
138 case ADDTS_REQUEST:
139 retval.qos = ADDTS_REQUEST;
140 break;
141 case ADDTS_RESPONSE:
142 retval.qos = ADDTS_RESPONSE;
143 break;
144 case DELTS:
145 retval.qos = DELTS;
146 break;
147 case SCHEDULE:
148 retval.qos = SCHEDULE;
149 break;
151 retval.qos = QOS_MAP_CONFIGURE;
152 break;
153 default:
154 NS_FATAL_ERROR("Unknown qos action code");
155 retval.qos = ADDTS_REQUEST; /* quiet compiler */
156 }
157 break;
158
159 case BLOCK_ACK:
160 switch (m_actionValue)
161 {
164 break;
167 break;
168 case BLOCK_ACK_DELBA:
169 retval.blockAck = BLOCK_ACK_DELBA;
170 break;
171 default:
172 NS_FATAL_ERROR("Unknown block ack action code");
173 retval.blockAck = BLOCK_ACK_ADDBA_REQUEST; /* quiet compiler */
174 }
175 break;
176
177 case PUBLIC:
178 switch (m_actionValue)
179 {
180 case QAB_REQUEST:
181 retval.publicAction = QAB_REQUEST;
182 break;
183 case QAB_RESPONSE:
184 retval.publicAction = QAB_RESPONSE;
185 break;
186 case FILS_DISCOVERY:
188 break;
189 default:
190 NS_FATAL_ERROR("Unknown public action code");
191 retval.publicAction = QAB_REQUEST; /* quiet compiler */
192 }
193 break;
194
196 switch (m_actionValue)
197 {
200 break;
203 break;
206 break;
209 break;
212 break;
215 break;
216 default:
217 NS_FATAL_ERROR("Unknown radio measurement action code");
218 retval.radioMeasurementAction = RADIO_MEASUREMENT_REQUEST; /* quiet compiler */
219 }
220 break;
221
222 case SELF_PROTECTED:
223 switch (m_actionValue)
224 {
225 case PEER_LINK_OPEN:
227 break;
230 break;
231 case PEER_LINK_CLOSE:
233 break;
234 case GROUP_KEY_INFORM:
236 break;
237 case GROUP_KEY_ACK:
239 break;
240 default:
241 NS_FATAL_ERROR("Unknown mesh peering management action code");
242 retval.selfProtectedAction = PEER_LINK_OPEN; /* quiet compiler */
243 }
244 break;
245
246 case MESH:
247 switch (m_actionValue)
248 {
251 break;
252 case PATH_SELECTION:
253 retval.meshAction = PATH_SELECTION;
254 break;
257 break;
260 break;
263 break;
264 case MDA_SETUP_REPLY:
266 break;
269 break;
272 break;
275 break;
278 break;
281 break;
282 default:
283 NS_FATAL_ERROR("Unknown mesh peering management action code");
284 retval.meshAction = LINK_METRIC_REPORT; /* quiet compiler */
285 }
286 break;
287
288 case MULTIHOP: // not yet supported
289 switch (m_actionValue)
290 {
291 case PROXY_UPDATE: // not used so far
292 case PROXY_UPDATE_CONFIRMATION: // not used so far
294 break;
295 default:
296 NS_FATAL_ERROR("Unknown mesh peering management action code");
297 retval.multihopAction = PROXY_UPDATE; /* quiet compiler */
298 }
299 break;
300
301 case DMG:
302 switch (m_actionValue)
303 {
306 break;
309 break;
312 break;
315 break;
318 break;
321 break;
322 case DMG_DTP_REQUEST:
323 retval.dmgAction = DMG_DTP_REQUEST;
324 break;
325 case DMG_DTP_RESPONSE:
327 break;
330 break;
333 break;
336 break;
339 break;
340 case DMG_RLS_REQUEST:
341 retval.dmgAction = DMG_RLS_REQUEST;
342 break;
343 case DMG_RLS_RESPONSE:
345 break;
348 break;
349 case DMG_RLS_TEARDOWN:
351 break;
354 break;
357 break;
358 case DMG_TPA_REQUEST:
359 retval.dmgAction = DMG_TPA_REQUEST;
360 break;
361 case DMG_TPA_RESPONSE:
363 break;
364 case DMG_ROC_REQUEST:
365 retval.dmgAction = DMG_ROC_REQUEST;
366 break;
367 case DMG_ROC_RESPONSE:
369 break;
370 default:
371 NS_FATAL_ERROR("Unknown DMG management action code");
372 retval.dmgAction = DMG_POWER_SAVE_CONFIGURATION_REQUEST; /* quiet compiler */
373 }
374 break;
375
376 case FST:
377 switch (m_actionValue)
378 {
381 break;
384 break;
385 case FST_TEAR_DOWN:
386 retval.fstAction = FST_TEAR_DOWN;
387 break;
388 case FST_ACK_REQUEST:
389 retval.fstAction = FST_ACK_REQUEST;
390 break;
391 case FST_ACK_RESPONSE:
393 break;
396 break;
397 default:
398 NS_FATAL_ERROR("Unknown FST management action code");
399 retval.fstAction = FST_SETUP_REQUEST; /* quiet compiler */
400 }
401 break;
402
403 case UNPROTECTED_DMG:
404 switch (m_actionValue)
405 {
408 break;
411 break;
414 break;
417 break;
420 break;
423 break;
424 default:
425 NS_FATAL_ERROR("Unknown Unprotected DMG action code");
426 retval.unprotectedDmgAction = UNPROTECTED_DMG_ANNOUNCE; /* quiet compiler */
427 }
428 break;
429
430 case PROTECTED_EHT:
431 switch (m_actionValue)
432 {
435 break;
438 break;
441 break;
444 break;
447 break;
450 break;
453 break;
456 break;
459 break;
462 break;
463 default:
464 NS_FATAL_ERROR("Unknown Protected EHT action code");
465 retval.protectedEhtAction =
467 }
468 break;
469
470 default:
471 NS_FATAL_ERROR("Unsupported action");
472 retval.selfProtectedAction = PEER_LINK_OPEN; /* quiet compiler */
473 }
474 return retval;
475}
476
477TypeId
479{
480 static TypeId tid = TypeId("ns3::WifiActionHeader")
481 .SetParent<Header>()
482 .SetGroupName("Wifi")
483 .AddConstructor<WifiActionHeader>();
484 return tid;
485}
486
487TypeId
489{
490 return GetTypeId();
491}
492
493std::pair<WifiActionHeader::CategoryValue, WifiActionHeader::ActionValue>
495{
496 WifiActionHeader actionHdr;
497 pkt->PeekHeader(actionHdr);
498 return {actionHdr.GetCategory(), actionHdr.GetAction()};
499}
500
501std::pair<WifiActionHeader::CategoryValue, WifiActionHeader::ActionValue>
503{
504 WifiActionHeader actionHdr;
505 pkt->RemoveHeader(actionHdr);
506 return {actionHdr.GetCategory(), actionHdr.GetAction()};
507}
508
509void
510WifiActionHeader::Print(std::ostream& os) const
511{
512#define CASE_ACTION_VALUE(x) \
513 case x: \
514 os << #x << "]"; \
515 break;
516
517 switch (m_category)
518 {
519 case QOS:
520 os << "QOS[";
521 switch (m_actionValue)
522 {
528 default:
529 NS_FATAL_ERROR("Unknown qos action code");
530 }
531 break;
532 case BLOCK_ACK:
533 os << "BLOCK_ACK[";
534 switch (m_actionValue)
535 {
539 default:
540 NS_FATAL_ERROR("Unknown block ack action code");
541 }
542 break;
543 case PUBLIC:
544 os << "PUBLIC[";
545 switch (m_actionValue)
546 {
550 default:
551 NS_FATAL_ERROR("Unknown public action code");
552 }
553 break;
555 os << "RADIO_MEASUREMENT[";
556 switch (m_actionValue)
557 {
564 default:
565 NS_FATAL_ERROR("Unknown radio measurement action code");
566 }
567 break;
568 case MESH:
569 os << "MESH[";
570 switch (m_actionValue)
571 {
583 default:
584 NS_FATAL_ERROR("Unknown mesh peering management action code");
585 }
586 break;
587 case MULTIHOP:
588 os << "MULTIHOP[";
589 switch (m_actionValue)
590 {
591 CASE_ACTION_VALUE(PROXY_UPDATE); // not used so far
593 default:
594 NS_FATAL_ERROR("Unknown mesh peering management action code");
595 }
596 break;
597 case SELF_PROTECTED:
598 os << "SELF_PROTECTED[";
599 switch (m_actionValue)
600 {
606 default:
607 NS_FATAL_ERROR("Unknown mesh peering management action code");
608 }
609 break;
610 case DMG:
611 os << "DMG[";
612 switch (m_actionValue)
613 {
636 default:
637 NS_FATAL_ERROR("Unknown DMG management action code");
638 }
639 break;
640 case FST:
641 os << "FST[";
642 switch (m_actionValue)
643 {
650 default:
651 NS_FATAL_ERROR("Unknown FST management action code");
652 }
653 break;
654 case UNPROTECTED_DMG:
655 os << "UNPROTECTED_DMG[";
656 switch (m_actionValue)
657 {
664 default:
665 NS_FATAL_ERROR("Unknown Unprotected DMG action code");
666 }
667 break;
668 case PROTECTED_EHT:
669 os << "PROTECTED_EHT[";
670 switch (m_actionValue)
671 {
682 default:
683 NS_FATAL_ERROR("Unknown Protected EHT action code");
684 }
685 break;
687 os << "VENDOR_SPECIFIC_ACTION";
688 break;
689 default:
690 NS_FATAL_ERROR("Unknown action value");
691 }
692#undef CASE_ACTION_VALUE
693}
694
697{
698 return 2;
699}
700
701void
703{
704 start.WriteU8(m_category);
705 start.WriteU8(m_actionValue);
706}
707
710{
711 Buffer::Iterator i = start;
712 m_category = i.ReadU8();
713 m_actionValue = i.ReadU8();
714 return i.GetDistanceFrom(start);
715}
716
717/***************************************************
718 * ADDBARequest
719 ****************************************************/
720
722
723TypeId
725{
726 static TypeId tid = TypeId("ns3::MgtAddBaRequestHeader")
727 .SetParent<Header>()
728 .SetGroupName("Wifi")
729 .AddConstructor<MgtAddBaRequestHeader>();
730 return tid;
731}
732
733TypeId
738
739void
740MgtAddBaRequestHeader::Print(std::ostream& os) const
741{
742}
743
746{
747 uint32_t size = 0;
748 size += 1; // Dialog token
749 size += 2; // Block ack parameter set
750 size += 2; // Block ack timeout value
751 size += 2; // Starting sequence control
752 if (m_bufferSize >= 1024)
753 {
754 // an ADDBA Extension element has to be added
756 }
757 return size;
758}
759
760void
762{
763 Buffer::Iterator i = start;
768 if (m_bufferSize >= 1024)
769 {
770 AddbaExtension addbaExt;
771 addbaExt.m_extParamSet.extBufferSize = m_bufferSize / 1024;
772 i = addbaExt.Serialize(i);
773 }
774}
775
778{
779 Buffer::Iterator i = start;
780 m_dialogToken = i.ReadU8();
784 AddbaExtension addbaExt;
785 auto tmp = i;
786 i = addbaExt.DeserializeIfPresent(i);
787 if (i.GetDistanceFrom(tmp) != 0)
788 {
789 // the buffer size is Extended Buffer Size × 1024 + Buffer Size
790 // (Sec. 9.4.2.138 of 802.11be D4.0)
791 m_bufferSize += addbaExt.m_extParamSet.extBufferSize * 1024;
792 }
793 return i.GetDistanceFrom(start);
794}
795
796void
801
802void
807
808void
810{
811 NS_ASSERT(tid < 16);
812 m_tid = tid;
813}
814
815void
820
821void
823{
824 m_bufferSize = size;
825}
826
827void
832
833void
835{
836 m_startingSeq = (seqControl >> 4) & 0x0fff;
837}
838
839void
841{
842 m_amsduSupport = supported;
843}
844
845uint8_t
847{
848 return m_tid;
849}
850
851bool
853{
854 return m_policy == 1;
855}
856
857uint16_t
862
863uint16_t
868
869bool
874
875uint16_t
880
881uint16_t
883{
884 return (m_startingSeq << 4) & 0xfff0;
885}
886
887uint16_t
889{
890 uint16_t res = 0;
891 res |= m_amsduSupport;
892 res |= m_policy << 1;
893 res |= m_tid << 2;
894 res |= (m_bufferSize % 1024) << 6;
895 return res;
896}
897
898void
900{
901 m_amsduSupport = params & 0x01;
902 m_policy = (params >> 1) & 0x01;
903 m_tid = (params >> 2) & 0x0f;
904 m_bufferSize = (params >> 6) & 0x03ff;
905}
906
907/***************************************************
908 * ADDBAResponse
909 ****************************************************/
910
912
913TypeId
915{
916 static TypeId tid = TypeId("ns3::MgtAddBaResponseHeader")
917 .SetParent<Header>()
918 .SetGroupName("Wifi")
919 .AddConstructor<MgtAddBaResponseHeader>();
920 return tid;
921}
922
923TypeId
928
929void
930MgtAddBaResponseHeader::Print(std::ostream& os) const
931{
932 os << "status code=" << m_code;
933}
934
937{
938 uint32_t size = 0;
939 size += 1; // Dialog token
940 size += m_code.GetSerializedSize(); // Status code
941 size += 2; // Block ack parameter set
942 size += 2; // Block ack timeout value
943 if (m_bufferSize >= 1024)
944 {
945 // an ADDBA Extension element has to be added
947 }
948 return size;
949}
950
951void
953{
954 Buffer::Iterator i = start;
956 i = m_code.Serialize(i);
959 if (m_bufferSize >= 1024)
960 {
961 AddbaExtension addbaExt;
962 addbaExt.m_extParamSet.extBufferSize = m_bufferSize / 1024;
963 i = addbaExt.Serialize(i);
964 }
965}
966
969{
970 Buffer::Iterator i = start;
971 m_dialogToken = i.ReadU8();
972 i = m_code.Deserialize(i);
975 AddbaExtension addbaExt;
976 auto tmp = i;
977 i = addbaExt.DeserializeIfPresent(i);
978 if (i.GetDistanceFrom(tmp) != 0)
979 {
980 // the buffer size is Extended Buffer Size × 1024 + Buffer Size
981 // (Sec. 9.4.2.138 of 802.11be D4.0)
982 m_bufferSize += addbaExt.m_extParamSet.extBufferSize * 1024;
983 }
984 return i.GetDistanceFrom(start);
985}
986
987void
992
993void
998
999void
1001{
1002 NS_ASSERT(tid < 16);
1003 m_tid = tid;
1004}
1005
1006void
1011
1012void
1014{
1015 m_bufferSize = size;
1016}
1017
1018void
1023
1024void
1026{
1027 m_amsduSupport = supported;
1028}
1029
1032{
1033 return m_code;
1034}
1035
1036uint8_t
1038{
1039 return m_tid;
1040}
1041
1042bool
1044{
1045 return m_policy == 1;
1046}
1047
1048uint16_t
1053
1054uint16_t
1059
1060bool
1062{
1063 return m_amsduSupport == 1;
1064}
1065
1066uint16_t
1068{
1069 uint16_t res = 0;
1070 res |= m_amsduSupport;
1071 res |= m_policy << 1;
1072 res |= m_tid << 2;
1073 res |= (m_bufferSize % 1024) << 6;
1074 return res;
1075}
1076
1077void
1079{
1080 m_amsduSupport = params & 0x01;
1081 m_policy = (params >> 1) & 0x01;
1082 m_tid = (params >> 2) & 0x0f;
1083 m_bufferSize = (params >> 6) & 0x03ff;
1084}
1085
1086/***************************************************
1087 * DelBa
1088 ****************************************************/
1089
1091
1092TypeId
1094{
1095 static TypeId tid = TypeId("ns3::MgtDelBaHeader")
1096 .SetParent<Header>()
1097 .SetGroupName("Wifi")
1098 .AddConstructor<MgtDelBaHeader>();
1099 return tid;
1100}
1101
1102TypeId
1104{
1105 return GetTypeId();
1106}
1107
1108void
1109MgtDelBaHeader::Print(std::ostream& os) const
1110{
1111}
1112
1115{
1116 uint32_t size = 0;
1117 size += 2; // DelBa parameter set
1118 size += 2; // Reason code
1119 return size;
1120}
1121
1122void
1129
1132{
1133 Buffer::Iterator i = start;
1136 return i.GetDistanceFrom(start);
1137}
1138
1139bool
1141{
1142 return m_initiator == 1;
1143}
1144
1145uint8_t
1147{
1148 NS_ASSERT(m_tid < 16);
1149 auto tid = static_cast<uint8_t>(m_tid);
1150 return tid;
1151}
1152
1153void
1158
1159void
1164
1165void
1167{
1168 NS_ASSERT(tid < 16);
1169 m_tid = static_cast<uint16_t>(tid);
1170}
1171
1172uint16_t
1174{
1175 uint16_t res = 0;
1176 res |= m_initiator << 11;
1177 res |= m_tid << 12;
1178 return res;
1179}
1180
1181void
1183{
1184 m_initiator = (params >> 11) & 0x01;
1185 m_tid = (params >> 12) & 0x0f;
1186}
1187
1188/***************************************************
1189 * EMLSR Operating Mode Notification
1190 ****************************************************/
1191
1193
1194TypeId
1196{
1197 static TypeId tid = TypeId("ns3::MgtEmlOperatingModeNotification")
1198 .SetParent<Header>()
1199 .SetGroupName("Wifi")
1200 .AddConstructor<MgtEmlOmn>();
1201 return tid;
1202}
1203
1204TypeId
1206{
1207 return GetTypeId();
1208}
1209
1210void
1211MgtEmlOmn::Print(std::ostream& os) const
1212{
1213 os << "EMLSR Mode=" << +m_emlControl.emlsrMode << " EMLMR Mode=" << +m_emlControl.emlmrMode
1214 << " EMLSR Parameter Update Control=" << +m_emlControl.emlsrParamUpdateCtrl;
1216 {
1217 os << " Link bitmap=" << std::hex << *m_emlControl.linkBitmap << std::dec;
1218 }
1220 {
1221 os << " EMLSR Padding Delay="
1223 .As(Time::US)
1224 << " EMLSR Transition Delay="
1226 .As(Time::US);
1227 }
1228}
1229
1232{
1233 uint32_t size = 2; // Dialog Token (1) + first byte of EML Control
1235 {
1236 size += 2;
1237 }
1239 {
1240 size += 1;
1241 }
1242 // TODO add size of EMLMR Supported MCS And NSS Set subfield when implemented
1244 {
1245 size += 1; // EMLSR Parameter Update field
1246 }
1247 return size;
1248}
1249
1250void
1252{
1253 start.WriteU8(m_dialogToken);
1254
1256 "EMLSR Mode and EMLMR Mode cannot be both set to 1");
1257 uint8_t val = m_emlControl.emlsrMode | (m_emlControl.emlmrMode << 1) |
1259 start.WriteU8(val);
1260
1263 "The EMLSR/EMLMR Link Bitmap is present if and only if either of the EMLSR "
1264 "Mode and EMLMR Mode subfields are set to 1");
1266 {
1267 start.WriteHtolsbU16(*m_emlControl.linkBitmap);
1268 }
1269 // TODO serialize MCS Map Count Control and EMLMR Supported MCS And NSS Set subfields
1270 // when implemented
1271
1273 "The EMLSR Parameter Update field is present "
1274 << std::boolalpha << m_emlsrParamUpdate.has_value()
1275 << " if and only if the EMLSR "
1276 "Parameter Update Control subfield is set to 1 "
1279 {
1280 val = m_emlsrParamUpdate->paddingDelay | (m_emlsrParamUpdate->transitionDelay << 3);
1281 start.WriteU8(val);
1282 }
1283}
1284
1287{
1288 Buffer::Iterator i = start;
1289
1290 m_dialogToken = i.ReadU8();
1291
1292 uint8_t val = i.ReadU8();
1293 m_emlControl.emlsrMode = val & 0x01;
1294 m_emlControl.emlmrMode = (val >> 1) & 0x01;
1295 m_emlControl.emlsrParamUpdateCtrl = (val >> 2) & 0x01;
1296
1298 "EMLSR Mode and EMLMR Mode cannot be both set to 1");
1299
1301 {
1303 }
1304 // TODO deserialize MCS Map Count Control and EMLMR Supported MCS And NSS Set subfields
1305 // when implemented
1306
1308 {
1309 val = i.ReadU8();
1311 m_emlsrParamUpdate->paddingDelay = val & 0x07;
1312 m_emlsrParamUpdate->transitionDelay = (val >> 3) & 0x07;
1313 }
1314
1315 return i.GetDistanceFrom(start);
1316}
1317
1318void
1320{
1321 NS_ABORT_MSG_IF(linkId > 15, "Link ID must not exceed 15");
1323 {
1325 }
1327}
1328
1329std::list<uint8_t>
1331{
1332 std::list<uint8_t> list;
1333 NS_ASSERT_MSG(m_emlControl.linkBitmap.has_value(), "No link bitmap");
1334 uint16_t bitmap = *m_emlControl.linkBitmap;
1335 for (uint8_t linkId = 0; linkId < 16; linkId++)
1336 {
1337 if ((bitmap & 0x0001) == 1)
1338 {
1339 list.push_back(linkId);
1340 }
1341 bitmap >>= 1;
1342 }
1343 return list;
1344}
1345
1346/***************************************************
1347 * FILS Discovery
1348 ****************************************************/
1349
1351
1352TypeId
1354{
1355 static TypeId tid = TypeId("ns3::FilsDiscHeader")
1356 .SetParent<Header>()
1357 .SetGroupName("Wifi")
1358 .AddConstructor<FilsDiscHeader>();
1359 return tid;
1360}
1361
1362TypeId
1364{
1365 return GetTypeId();
1366}
1367
1369 : m_len(m_frameCtl.m_lenPresenceInd),
1370 m_fdCap(m_frameCtl.m_capPresenceInd),
1371 m_primaryCh(m_frameCtl.m_primChPresenceInd),
1372 m_apConfigSeqNum(m_frameCtl.m_apCsnPresenceInd),
1373 m_accessNetOpt(m_frameCtl.m_anoPresenceInd),
1374 m_chCntrFreqSeg1(m_frameCtl.m_chCntrFreqSeg1PresenceInd)
1375{
1376}
1377
1378void
1379FilsDiscHeader::SetSsid(const std::string& ssid)
1380{
1381 m_ssid = ssid;
1382 m_frameCtl.m_ssidLen = ssid.length() - 1;
1383}
1384
1385const std::string&
1387{
1388 return m_ssid;
1389}
1390
1393{
1394 auto size = GetSizeNonOptSubfields();
1395 size += m_len.has_value() ? 1 : 0;
1396 size += m_fdCap.has_value() ? 2 : 0;
1397 size += m_opClass.has_value() ? 1 : 0;
1398 size += m_primaryCh.has_value() ? 1 : 0;
1399 size += m_apConfigSeqNum.has_value() ? 1 : 0;
1400 size += m_accessNetOpt.has_value() ? 1 : 0;
1401 size += m_chCntrFreqSeg1.has_value() ? 1 : 0;
1402 return size;
1403}
1404
1407{
1408 auto size = GetInformationFieldSize();
1409 // Optional elements
1410 size += m_rnr.has_value() ? m_rnr->GetSerializedSize() : 0;
1411 size += m_tim.has_value() ? m_tim->GetSerializedSize() : 0;
1412 return size;
1413}
1414
1417{
1418 return 2 /* FILS Discovery Frame Control */
1419 + 8 /* Timestamp */
1420 + 2 /* Beacon Interval */
1421 + m_ssid.length(); /* SSID */
1422}
1423
1424void
1426{
1427 m_len.reset(); // so that Length size is not included by GetInformationFieldSize()
1428 auto infoFieldSize = GetInformationFieldSize();
1429 auto nonOptSubfieldsSize = GetSizeNonOptSubfields();
1430 NS_ABORT_MSG_IF(infoFieldSize < nonOptSubfieldsSize, "Length subfield is less than 0");
1431 m_len = infoFieldSize - nonOptSubfieldsSize;
1432}
1433
1434void
1435FilsDiscHeader::Print(std::ostream& os) const
1436{
1437 os << "Control=" << m_frameCtl << ", "
1438 << "Time Stamp=" << m_timeStamp << ", "
1439 << "Beacon Interval=" << m_beaconInt << ", "
1440 << "SSID=" << m_ssid << ", ";
1441 if (m_len.has_value())
1442 {
1443 os << "Length=" << *m_len << ", ";
1444 }
1445 if (m_fdCap.has_value())
1446 {
1447 os << "FD Capability=" << *m_fdCap << ", ";
1448 }
1449 if (m_opClass.has_value())
1450 {
1451 os << "Operating Class=" << *m_opClass << ", ";
1452 }
1453 if (m_primaryCh.has_value())
1454 {
1455 os << "Primary Channel=" << *m_primaryCh << ", ";
1456 }
1458 {
1459 os << "AP-CSN=" << *m_apConfigSeqNum << ", ";
1460 }
1462 {
1463 os << "ANO=" << *m_accessNetOpt << ", ";
1464 }
1466 {
1467 os << "Channel Center Frequency Seg 1=" << *m_chCntrFreqSeg1 << ", ";
1468 }
1469 if (m_tim.has_value())
1470 {
1471 os << "Traffic Indicator Map=" << *m_tim;
1472 }
1473}
1474
1475void
1477{
1478 Buffer::Iterator i = start;
1480 i.WriteHtolsbU64(Simulator::Now().GetMicroSeconds()); // Time stamp
1482 i.Write(reinterpret_cast<const uint8_t*>(m_ssid.data()), m_ssid.length());
1483 if (m_len.has_value())
1484 {
1485 i.WriteU8(*m_len);
1486 }
1487 if (m_fdCap.has_value())
1488 {
1489 m_fdCap->Serialize(i);
1490 }
1491 NS_ASSERT(m_opClass.has_value() == m_primaryCh.has_value());
1492 if (m_opClass.has_value())
1493 {
1494 i.WriteU8(*m_opClass);
1495 }
1496 if (m_primaryCh.has_value())
1497 {
1498 i.WriteU8(*m_primaryCh);
1499 }
1501 {
1503 }
1505 {
1507 }
1509 {
1511 }
1512 i = m_rnr.has_value() ? m_rnr->Serialize(i) : i;
1513 i = m_tim.has_value() ? m_tim->Serialize(i) : i;
1514}
1515
1518{
1519 Buffer::Iterator i = start;
1520 auto nOctets = m_frameCtl.Deserialize(i);
1521 i.Next(nOctets);
1524 std::vector<uint8_t> ssid(m_frameCtl.m_ssidLen + 2);
1525 i.Read(ssid.data(), m_frameCtl.m_ssidLen + 1);
1526 ssid[m_frameCtl.m_ssidLen + 1] = 0;
1527 m_ssid = std::string(reinterpret_cast<char*>(ssid.data()));
1528 // Optional subfields
1530 {
1531 m_len = i.ReadU8();
1532 }
1534 {
1535 nOctets = m_fdCap->Deserialize(i);
1536 i.Next(nOctets);
1537 }
1539 {
1540 m_opClass = i.ReadU8();
1541 m_primaryCh = i.ReadU8();
1542 }
1544 {
1546 }
1548 {
1549 m_accessNetOpt = i.ReadU8();
1550 }
1552 {
1554 }
1555 // Optional elements
1556 m_rnr.emplace();
1557 auto tmp = i;
1558 i = m_rnr->DeserializeIfPresent(i);
1559 if (i.GetDistanceFrom(tmp) == 0)
1560 {
1561 m_rnr.reset();
1562 }
1563
1564 m_tim.emplace();
1565 tmp = i;
1566 i = m_tim->DeserializeIfPresent(i);
1567 if (i.GetDistanceFrom(tmp) == 0)
1568 {
1569 m_tim.reset();
1570 }
1571
1572 return i.GetDistanceFrom(start);
1573}
1574
1575std::ostream&
1576operator<<(std::ostream& os, const FilsDiscHeader::FilsDiscFrameControl& control)
1577{
1578 os << "ssidLen:" << control.m_ssidLen << " capPresenceInd:" << control.m_capPresenceInd
1579 << " shortSsidInd:" << control.m_shortSsidInd
1580 << " apCsnPresenceInd:" << control.m_apCsnPresenceInd
1581 << " anoPresenceInd:" << control.m_anoPresenceInd
1582 << " chCntrFreqSeg1PresenceInd:" << control.m_chCntrFreqSeg1PresenceInd
1583 << " primChPresenceInd:" << control.m_primChPresenceInd
1584 << " rsnInfoPresenceInd:" << control.m_rsnInfoPresenceInd
1585 << " lenPresenceInd:" << control.m_lenPresenceInd
1586 << " mdPresenceInd:" << control.m_mdPresenceInd;
1587 return os;
1588}
1589
1590void
1592{
1593 uint16_t val = m_ssidLen | ((m_capPresenceInd ? 1 : 0) << 5) | (m_shortSsidInd << 6) |
1594 ((m_apCsnPresenceInd ? 1 : 0) << 7) | ((m_anoPresenceInd ? 1 : 0) << 8) |
1595 ((m_chCntrFreqSeg1PresenceInd ? 1 : 0) << 9) |
1596 ((m_primChPresenceInd ? 1 : 0) << 10) | (m_rsnInfoPresenceInd << 11) |
1597 ((m_lenPresenceInd ? 1 : 0) << 12) | (m_mdPresenceInd << 13);
1598 start.WriteHtolsbU16(val);
1599}
1600
1603{
1604 auto val = start.ReadLsbtohU16();
1605
1606 m_ssidLen = val & 0x001f;
1607 m_capPresenceInd = ((val >> 5) & 0x0001) == 1;
1608 m_shortSsidInd = (val >> 6) & 0x0001;
1609 m_apCsnPresenceInd = ((val >> 7) & 0x0001) == 1;
1610 m_anoPresenceInd = ((val >> 8) & 0x0001) == 1;
1611 m_chCntrFreqSeg1PresenceInd = ((val >> 9) & 0x0001) == 1;
1612 m_primChPresenceInd = ((val >> 10) & 0x0001) == 1;
1613 m_rsnInfoPresenceInd = (val >> 11) & 0x0001;
1614 m_lenPresenceInd = ((val >> 12) & 0x0001) == 1;
1615 m_mdPresenceInd = (val >> 13) & 0x0001;
1616
1617 return 2;
1618}
1619
1620std::ostream&
1621operator<<(std::ostream& os, const FilsDiscHeader::FdCapability& capability)
1622{
1623 os << "ess:" << capability.m_ess << " privacy:" << capability.m_privacy
1624 << " channelWidth:" << capability.m_chWidth << " maxNss:" << capability.m_maxNss
1625 << " multiBssidInd:" << capability.m_multiBssidPresenceInd
1626 << " phyIdx:" << capability.m_phyIdx << " minRate:" << capability.m_minRate;
1627 return os;
1628}
1629
1630void
1632{
1633 uint16_t val = m_ess | (m_privacy << 1) | (m_chWidth << 2) | (m_maxNss << 5) |
1634 (m_multiBssidPresenceInd << 9) | (m_phyIdx << 10) | (m_minRate << 13);
1635 start.WriteHtolsbU16(val);
1636}
1637
1640{
1641 auto val = start.ReadLsbtohU16();
1642
1643 m_ess = val & 0x0001;
1644 m_privacy = (val >> 1) & 0x0001;
1645 m_chWidth = (val >> 2) & 0x0007;
1646 m_maxNss = (val >> 5) & 0x0007;
1647 m_multiBssidPresenceInd = (val >> 9) & 0x0001;
1648 m_phyIdx = (val >> 10) & 0x0007;
1649 m_minRate = (val >> 13) & 0x0007;
1650
1651 return 2;
1652}
1653
1654void
1656{
1657 m_chWidth = (width == 20 || width == 22) ? 0
1658 : (width == 40) ? 1
1659 : (width == 80) ? 2
1660 : (width == 160) ? 3
1661 : 4;
1662}
1663
1664MHz_u
1666{
1667 switch (m_chWidth)
1668 {
1669 case 0:
1670 return m_phyIdx == 0 ? 22 : 20; // PHY Index 0 indicates 802.11b
1671 case 1:
1672 return 40;
1673 case 2:
1674 return 80;
1675 case 3:
1676 return 160;
1677 default:
1678 NS_ABORT_MSG("Reserved value: " << +m_chWidth);
1679 }
1680 return 0;
1681}
1682
1683void
1685{
1686 NS_ABORT_MSG_IF(maxNss < 1, "NSS is equal to 0");
1687 maxNss--;
1688 // 4 is the maximum value for the Maximum Number of Spatial Streams subfield
1689 m_maxNss = std::min<uint8_t>(maxNss, 4);
1690}
1691
1692uint8_t
1694{
1695 return m_maxNss + 1;
1696}
1697
1698void
1700{
1701 switch (standard)
1702 {
1704 m_phyIdx = 0;
1705 break;
1708 m_phyIdx = 1;
1709 break;
1711 m_phyIdx = 2;
1712 break;
1714 m_phyIdx = 3;
1715 break;
1717 m_phyIdx = 4;
1718 break;
1720 m_phyIdx = 5;
1721 break;
1722 default:
1723 NS_ABORT_MSG("Unsupported standard: " << standard);
1724 }
1725}
1726
1729{
1730 switch (m_phyIdx)
1731 {
1732 case 0:
1733 return WIFI_STANDARD_80211b;
1734 case 1:
1736 "Invalid PHY band (" << band << ") with PHY index of 1");
1738 case 2:
1739 return WIFI_STANDARD_80211n;
1740 case 3:
1741 return WIFI_STANDARD_80211ac;
1742 case 4:
1743 return WIFI_STANDARD_80211ax;
1744 case 5:
1745 return WIFI_STANDARD_80211be;
1746 default:
1747 NS_ABORT_MSG("Invalid PHY index: " << m_phyIdx);
1748 }
1749
1751}
1752
1753} // 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:89
void WriteHtolsbU16(uint16_t data)
Definition buffer.cc:891
void WriteU8(uint8_t data)
Definition buffer.h:870
void Write(const uint8_t *buffer, uint32_t size)
Definition buffer.cc:937
uint16_t ReadLsbtohU16()
Definition buffer.cc:1053
void Read(uint8_t *buffer, uint32_t size)
Definition buffer.cc:1114
uint64_t ReadLsbtohU64()
Definition buffer.cc:1083
void WriteHtolsbU64(uint64_t data)
Definition buffer.cc:909
uint32_t GetDistanceFrom(const Iterator &o) const
Definition buffer.cc:769
void Next()
go forward by one byte
Definition buffer.h:842
Implement the FILS (Fast Initial Link Setup) action frame.
uint16_t m_beaconInt
Beacon Interval in TU (1024 us)
std::optional< ReducedNeighborReport > m_rnr
Reduced Neighbor Report.
OptFieldWithPresenceInd< uint8_t > m_chCntrFreqSeg1
Channel Center Frequency Segment 1.
uint32_t GetSerializedSize() const override
OptFieldWithPresenceInd< uint8_t > m_primaryCh
Primary Channel.
OptFieldWithPresenceInd< uint8_t > m_accessNetOpt
Access Network Options.
const std::string & GetSsid() const
void SetSsid(const std::string &ssid)
Set the SSID field.
uint32_t Deserialize(Buffer::Iterator start) override
FilsDiscFrameControl m_frameCtl
FILS Discovery Frame Control.
OptFieldWithPresenceInd< FdCapability > m_fdCap
FD Capability.
std::optional< uint8_t > m_opClass
Operating Class.
void Print(std::ostream &os) const override
uint32_t GetSizeNonOptSubfields() const
OptFieldWithPresenceInd< uint8_t > m_len
Length.
uint32_t GetInformationFieldSize() const
uint64_t m_timeStamp
Timestamp.
void SetLengthSubfield()
sets value of Length subfield
TypeId GetInstanceTypeId() const override
Get the most derived TypeId for this Object.
void Serialize(Buffer::Iterator start) const override
std::string m_ssid
SSID.
OptFieldWithPresenceInd< uint8_t > m_apConfigSeqNum
AP Configuration Sequence Number (AP-CSN)
std::optional< Tim > m_tim
Traffic Indication Map element.
Protocol header serialization and deserialization.
Definition header.h:33
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.
uint32_t Deserialize(Buffer::Iterator start) override
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.
uint32_t Deserialize(Buffer::Iterator start) override
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).
uint32_t Deserialize(Buffer::Iterator start) override
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.
uint32_t Deserialize(Buffer::Iterator start) override
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.
constexpr void reset()
Destroy the value (if any) contained in the optional field.
constexpr bool has_value() const
Check whether this object contains a value.
Smart pointer class similar to boost::intrusive_ptr.
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:197
Status code for association response.
Definition status-code.h:21
Buffer::Iterator Serialize(Buffer::Iterator start) const
Buffer::Iterator Deserialize(Buffer::Iterator start)
uint32_t GetSerializedSize() const
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition time.cc:404
@ US
microsecond
Definition nstime.h:107
a unique identifier for an interface.
Definition type-id.h:48
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
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.
uint32_t Deserialize(Buffer::Iterator start) override
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:55
#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:75
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition abort.h:38
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition abort.h:97
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
WifiStandard
Identifies the IEEE 802.11 specifications that a Wifi device can be configured to use.
WifiPhyBand
Identifies the PHY band.
@ WIFI_STANDARD_80211a
@ WIFI_STANDARD_80211be
@ WIFI_STANDARD_80211n
@ WIFI_STANDARD_80211g
@ WIFI_STANDARD_80211ax
@ WIFI_STANDARD_UNSPECIFIED
@ WIFI_STANDARD_80211ac
@ WIFI_STANDARD_80211b
@ WIFI_PHY_BAND_2_4GHZ
The 2.4 GHz band.
@ WIFI_PHY_BAND_5GHZ
The 5 GHz band.
#define CASE_ACTION_VALUE(x)
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition angles.cc:148
#define list
ns3::Time timeout
uint8_t extBufferSize
extended buffer size
static Time DecodeEmlsrTransitionDelay(uint8_t value)
static Time DecodeEmlsrPaddingDelay(uint8_t value)
FD Capability subfield of FILS Discovery Information field.
WifiStandard GetStandard(WifiPhyBand band) const
void SetOpChannelWidth(MHz_u width)
Set the BSS Operating Channel Width field based on the operating channel width.
uint8_t GetMaxNss() const
Note that this function returns 5 if the maximum number of supported spatial streams is greater than ...
uint8_t m_minRate
FILS Minimum Rate.
void SetMaxNss(uint8_t maxNss)
Set the Maximum Number of Spatial Streams field.
uint8_t m_chWidth
BSS Operating Channel Width.
uint8_t m_multiBssidPresenceInd
Multiple BSSIDs Presence Indicator.
uint8_t m_maxNss
Maximum Number of Spatial Streams.
void Serialize(Buffer::Iterator &start) const
serialize content to a given buffer
uint32_t Deserialize(Buffer::Iterator start)
read content from a given buffer
void SetStandard(WifiStandard standard)
Set the PHY Index field based on the given wifi standard.
FILS Discovery Frame Control subfield of FILS Discovery Information field.
bool m_apCsnPresenceInd
AP-CSN Presence Indicator.
bool m_chCntrFreqSeg1PresenceInd
Channel Center Frequency Segment 1 Presence Indicator.
uint8_t m_shortSsidInd
Short SSID Indicator (not supported)
void Serialize(Buffer::Iterator &start) const
serialize content to a given buffer
uint8_t m_rsnInfoPresenceInd
RSN info Presence Indicator (not supported)
bool m_capPresenceInd
Capability Presence Indicator.
uint8_t m_mdPresenceInd
MD Presence Indicator (not supported)
uint32_t Deserialize(Buffer::Iterator start)
read content from a given buffer
bool m_lenPresenceInd
Length Presence Indicator.
bool m_primChPresenceInd
Primary Channel Presence Indicator.
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.
uint8_t paddingDelay
EMLSR Padding Delay.
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
BlockAckActionValue blockAck
block ack