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#include "gcr-group-address.h"
15
16#include "ns3/multi-link-element.h"
17#include "ns3/packet.h"
18#include "ns3/simulator.h"
19
20#include <vector>
21
22namespace ns3
23{
24
28
32
33void
36{
37 m_category = static_cast<uint8_t>(type);
38 switch (type)
39 {
41 break;
42 }
43 case QOS: {
44 m_actionValue = static_cast<uint8_t>(action.qos);
45 break;
46 }
47 case BLOCK_ACK: {
48 m_actionValue = static_cast<uint8_t>(action.blockAck);
49 break;
50 }
51 case PUBLIC: {
52 m_actionValue = static_cast<uint8_t>(action.publicAction);
53 break;
54 }
55 case RADIO_MEASUREMENT: {
56 m_actionValue = static_cast<uint8_t>(action.radioMeasurementAction);
57 break;
58 }
59 case MESH: {
60 m_actionValue = static_cast<uint8_t>(action.meshAction);
61 break;
62 }
63 case MULTIHOP: {
64 m_actionValue = static_cast<uint8_t>(action.multihopAction);
65 break;
66 }
67 case SELF_PROTECTED: {
68 m_actionValue = static_cast<uint8_t>(action.selfProtectedAction);
69 break;
70 }
71 case DMG: {
72 m_actionValue = static_cast<uint8_t>(action.dmgAction);
73 break;
74 }
75 case FST: {
76 m_actionValue = static_cast<uint8_t>(action.fstAction);
77 break;
78 }
79 case UNPROTECTED_DMG: {
80 m_actionValue = static_cast<uint8_t>(action.unprotectedDmgAction);
81 break;
82 }
83 case PROTECTED_EHT: {
84 m_actionValue = static_cast<uint8_t>(action.protectedEhtAction);
85 break;
86 }
88 break;
89 }
90 }
91}
92
95{
96 switch (m_category)
97 {
98 case QOS:
99 return QOS;
100 case BLOCK_ACK:
101 return BLOCK_ACK;
102 case PUBLIC:
103 return PUBLIC;
105 return RADIO_MEASUREMENT;
106 case MESH:
107 return MESH;
108 case MULTIHOP:
109 return MULTIHOP;
110 case SELF_PROTECTED:
111 return SELF_PROTECTED;
112 case DMG:
113 return DMG;
114 case FST:
115 return FST;
116 case UNPROTECTED_DMG:
117 return UNPROTECTED_DMG;
118 case PROTECTED_EHT:
119 return PROTECTED_EHT;
122 default:
123 NS_FATAL_ERROR("Unknown action value");
124 return SELF_PROTECTED;
125 }
126}
127
130{
131 ActionValue retval;
132 retval.selfProtectedAction =
133 PEER_LINK_OPEN; // Needs to be initialized to something to quiet valgrind in default cases
134 switch (m_category)
135 {
136 case QOS:
137 switch (m_actionValue)
138 {
139 case ADDTS_REQUEST:
140 retval.qos = ADDTS_REQUEST;
141 break;
142 case ADDTS_RESPONSE:
143 retval.qos = ADDTS_RESPONSE;
144 break;
145 case DELTS:
146 retval.qos = DELTS;
147 break;
148 case SCHEDULE:
149 retval.qos = SCHEDULE;
150 break;
152 retval.qos = QOS_MAP_CONFIGURE;
153 break;
154 default:
155 NS_FATAL_ERROR("Unknown qos action code");
156 retval.qos = ADDTS_REQUEST; /* quiet compiler */
157 }
158 break;
159
160 case BLOCK_ACK:
161 switch (m_actionValue)
162 {
165 break;
168 break;
169 case BLOCK_ACK_DELBA:
170 retval.blockAck = BLOCK_ACK_DELBA;
171 break;
172 default:
173 NS_FATAL_ERROR("Unknown block ack action code");
174 retval.blockAck = BLOCK_ACK_ADDBA_REQUEST; /* quiet compiler */
175 }
176 break;
177
178 case PUBLIC:
179 switch (m_actionValue)
180 {
181 case QAB_REQUEST:
182 retval.publicAction = QAB_REQUEST;
183 break;
184 case QAB_RESPONSE:
185 retval.publicAction = QAB_RESPONSE;
186 break;
187 case FILS_DISCOVERY:
189 break;
190 default:
191 NS_FATAL_ERROR("Unknown public action code");
192 retval.publicAction = QAB_REQUEST; /* quiet compiler */
193 }
194 break;
195
197 switch (m_actionValue)
198 {
201 break;
204 break;
207 break;
210 break;
213 break;
216 break;
217 default:
218 NS_FATAL_ERROR("Unknown radio measurement action code");
219 retval.radioMeasurementAction = RADIO_MEASUREMENT_REQUEST; /* quiet compiler */
220 }
221 break;
222
223 case SELF_PROTECTED:
224 switch (m_actionValue)
225 {
226 case PEER_LINK_OPEN:
228 break;
231 break;
232 case PEER_LINK_CLOSE:
234 break;
235 case GROUP_KEY_INFORM:
237 break;
238 case GROUP_KEY_ACK:
240 break;
241 default:
242 NS_FATAL_ERROR("Unknown mesh peering management action code");
243 retval.selfProtectedAction = PEER_LINK_OPEN; /* quiet compiler */
244 }
245 break;
246
247 case MESH:
248 switch (m_actionValue)
249 {
252 break;
253 case PATH_SELECTION:
254 retval.meshAction = PATH_SELECTION;
255 break;
258 break;
261 break;
264 break;
265 case MDA_SETUP_REPLY:
267 break;
270 break;
273 break;
276 break;
279 break;
282 break;
283 default:
284 NS_FATAL_ERROR("Unknown mesh peering management action code");
285 retval.meshAction = LINK_METRIC_REPORT; /* quiet compiler */
286 }
287 break;
288
289 case MULTIHOP: // not yet supported
290 switch (m_actionValue)
291 {
292 case PROXY_UPDATE: // not used so far
293 case PROXY_UPDATE_CONFIRMATION: // not used so far
295 break;
296 default:
297 NS_FATAL_ERROR("Unknown mesh peering management action code");
298 retval.multihopAction = PROXY_UPDATE; /* quiet compiler */
299 }
300 break;
301
302 case DMG:
303 switch (m_actionValue)
304 {
307 break;
310 break;
313 break;
316 break;
319 break;
322 break;
323 case DMG_DTP_REQUEST:
324 retval.dmgAction = DMG_DTP_REQUEST;
325 break;
326 case DMG_DTP_RESPONSE:
328 break;
331 break;
334 break;
337 break;
340 break;
341 case DMG_RLS_REQUEST:
342 retval.dmgAction = DMG_RLS_REQUEST;
343 break;
344 case DMG_RLS_RESPONSE:
346 break;
349 break;
350 case DMG_RLS_TEARDOWN:
352 break;
355 break;
358 break;
359 case DMG_TPA_REQUEST:
360 retval.dmgAction = DMG_TPA_REQUEST;
361 break;
362 case DMG_TPA_RESPONSE:
364 break;
365 case DMG_ROC_REQUEST:
366 retval.dmgAction = DMG_ROC_REQUEST;
367 break;
368 case DMG_ROC_RESPONSE:
370 break;
371 default:
372 NS_FATAL_ERROR("Unknown DMG management action code");
373 retval.dmgAction = DMG_POWER_SAVE_CONFIGURATION_REQUEST; /* quiet compiler */
374 }
375 break;
376
377 case FST:
378 switch (m_actionValue)
379 {
382 break;
385 break;
386 case FST_TEAR_DOWN:
387 retval.fstAction = FST_TEAR_DOWN;
388 break;
389 case FST_ACK_REQUEST:
390 retval.fstAction = FST_ACK_REQUEST;
391 break;
392 case FST_ACK_RESPONSE:
394 break;
397 break;
398 default:
399 NS_FATAL_ERROR("Unknown FST management action code");
400 retval.fstAction = FST_SETUP_REQUEST; /* quiet compiler */
401 }
402 break;
403
404 case UNPROTECTED_DMG:
405 switch (m_actionValue)
406 {
409 break;
412 break;
415 break;
418 break;
421 break;
424 break;
425 default:
426 NS_FATAL_ERROR("Unknown Unprotected DMG action code");
427 retval.unprotectedDmgAction = UNPROTECTED_DMG_ANNOUNCE; /* quiet compiler */
428 }
429 break;
430
431 case PROTECTED_EHT:
432 switch (m_actionValue)
433 {
436 break;
439 break;
442 break;
445 break;
448 break;
451 break;
454 break;
457 break;
460 break;
463 break;
464 default:
465 NS_FATAL_ERROR("Unknown Protected EHT action code");
466 retval.protectedEhtAction =
468 }
469 break;
470
471 default:
472 NS_FATAL_ERROR("Unsupported action");
473 retval.selfProtectedAction = PEER_LINK_OPEN; /* quiet compiler */
474 }
475 return retval;
476}
477
478TypeId
480{
481 static TypeId tid = TypeId("ns3::WifiActionHeader")
482 .SetParent<Header>()
483 .SetGroupName("Wifi")
484 .AddConstructor<WifiActionHeader>();
485 return tid;
486}
487
488TypeId
490{
491 return GetTypeId();
492}
493
494std::pair<WifiActionHeader::CategoryValue, WifiActionHeader::ActionValue>
496{
497 WifiActionHeader actionHdr;
498 pkt->PeekHeader(actionHdr);
499 return {actionHdr.GetCategory(), actionHdr.GetAction()};
500}
501
502std::pair<WifiActionHeader::CategoryValue, WifiActionHeader::ActionValue>
504{
505 WifiActionHeader actionHdr;
506 pkt->RemoveHeader(actionHdr);
507 return {actionHdr.GetCategory(), actionHdr.GetAction()};
508}
509
510void
511WifiActionHeader::Print(std::ostream& os) const
512{
513#define CASE_ACTION_VALUE(x) \
514 case x: \
515 os << #x << "]"; \
516 break;
517
518 switch (m_category)
519 {
520 case QOS:
521 os << "QOS[";
522 switch (m_actionValue)
523 {
529 default:
530 NS_FATAL_ERROR("Unknown qos action code");
531 }
532 break;
533 case BLOCK_ACK:
534 os << "BLOCK_ACK[";
535 switch (m_actionValue)
536 {
540 default:
541 NS_FATAL_ERROR("Unknown block ack action code");
542 }
543 break;
544 case PUBLIC:
545 os << "PUBLIC[";
546 switch (m_actionValue)
547 {
551 default:
552 NS_FATAL_ERROR("Unknown public action code");
553 }
554 break;
556 os << "RADIO_MEASUREMENT[";
557 switch (m_actionValue)
558 {
565 default:
566 NS_FATAL_ERROR("Unknown radio measurement action code");
567 }
568 break;
569 case MESH:
570 os << "MESH[";
571 switch (m_actionValue)
572 {
584 default:
585 NS_FATAL_ERROR("Unknown mesh peering management action code");
586 }
587 break;
588 case MULTIHOP:
589 os << "MULTIHOP[";
590 switch (m_actionValue)
591 {
592 CASE_ACTION_VALUE(PROXY_UPDATE); // not used so far
594 default:
595 NS_FATAL_ERROR("Unknown mesh peering management action code");
596 }
597 break;
598 case SELF_PROTECTED:
599 os << "SELF_PROTECTED[";
600 switch (m_actionValue)
601 {
607 default:
608 NS_FATAL_ERROR("Unknown mesh peering management action code");
609 }
610 break;
611 case DMG:
612 os << "DMG[";
613 switch (m_actionValue)
614 {
637 default:
638 NS_FATAL_ERROR("Unknown DMG management action code");
639 }
640 break;
641 case FST:
642 os << "FST[";
643 switch (m_actionValue)
644 {
651 default:
652 NS_FATAL_ERROR("Unknown FST management action code");
653 }
654 break;
655 case UNPROTECTED_DMG:
656 os << "UNPROTECTED_DMG[";
657 switch (m_actionValue)
658 {
665 default:
666 NS_FATAL_ERROR("Unknown Unprotected DMG action code");
667 }
668 break;
669 case PROTECTED_EHT:
670 os << "PROTECTED_EHT[";
671 switch (m_actionValue)
672 {
683 default:
684 NS_FATAL_ERROR("Unknown Protected EHT action code");
685 }
686 break;
688 os << "VENDOR_SPECIFIC_ACTION";
689 break;
690 default:
691 NS_FATAL_ERROR("Unknown action value");
692 }
693#undef CASE_ACTION_VALUE
694}
695
698{
699 return 2;
700}
701
702void
704{
705 start.WriteU8(m_category);
706 start.WriteU8(m_actionValue);
707}
708
711{
712 Buffer::Iterator i = start;
713 m_category = i.ReadU8();
714 m_actionValue = i.ReadU8();
715 return i.GetDistanceFrom(start);
716}
717
718/***************************************************
719 * ADDBARequest
720 ****************************************************/
721
723
724TypeId
726{
727 static TypeId tid = TypeId("ns3::MgtAddBaRequestHeader")
728 .SetParent<Header>()
729 .SetGroupName("Wifi")
730 .AddConstructor<MgtAddBaRequestHeader>();
731 return tid;
732}
733
734TypeId
739
740void
741MgtAddBaRequestHeader::Print(std::ostream& os) const
742{
743 os << "A-MSDU support=" << m_amsduSupport << " Policy=" << +m_policy << " TID=" << +m_tid
744 << " Buffer size=" << m_bufferSize << " Timeout=" << m_timeoutValue
745 << " Starting seq=" << m_startingSeq;
746 if (m_gcrGroupAddress.has_value())
747 {
748 os << " GCR group address=" << m_gcrGroupAddress.value();
749 }
750}
751
754{
755 uint32_t size = 0;
756 size += 1; // Dialog token
757 size += 2; // Block ack parameter set
758 size += 2; // Block ack timeout value
759 size += 2; // Starting sequence control
761 {
762 // a GCR Group Address element has to be added
764 }
765 if (m_bufferSize >= 1024)
766 {
767 // an ADDBA Extension element has to be added
769 }
770 return size;
771}
772
773void
775{
776 Buffer::Iterator i = start;
782 {
783 GcrGroupAddress gcrGroupAddr;
784 gcrGroupAddr.m_gcrGroupAddress = *m_gcrGroupAddress;
785 i = gcrGroupAddr.Serialize(i);
786 }
787 if (m_bufferSize >= 1024)
788 {
789 AddbaExtension addbaExt;
790 addbaExt.m_extParamSet.extBufferSize = m_bufferSize / 1024;
791 i = addbaExt.Serialize(i);
792 }
793}
794
797{
798 Buffer::Iterator i = start;
799 m_dialogToken = i.ReadU8();
803 m_gcrGroupAddress.reset();
804 GcrGroupAddress gcrGroupAddr;
805 auto tmp = i;
806 i = gcrGroupAddr.DeserializeIfPresent(i);
807 if (i.GetDistanceFrom(tmp) != 0)
808 {
810 }
811 AddbaExtension addbaExt;
812 tmp = i;
813 i = addbaExt.DeserializeIfPresent(i);
814 if (i.GetDistanceFrom(tmp) != 0)
815 {
816 // the buffer size is Extended Buffer Size × 1024 + Buffer Size
817 // (Sec. 9.4.2.138 of 802.11be D4.0)
818 m_bufferSize += addbaExt.m_extParamSet.extBufferSize * 1024;
819 }
820 return i.GetDistanceFrom(start);
821}
822
823void
828
829void
834
835void
837{
838 NS_ASSERT(tid < 16);
839 m_tid = tid;
840}
841
842void
847
848void
850{
851 m_bufferSize = size;
852}
853
854void
859
860void
862{
863 m_startingSeq = (seqControl >> 4) & 0x0fff;
864}
865
866void
868{
869 m_amsduSupport = supported;
870}
871
872void
877
878uint8_t
880{
881 return m_tid;
882}
883
884bool
886{
887 return m_policy == 1;
888}
889
890uint16_t
895
896uint16_t
901
902bool
907
908uint16_t
913
914uint16_t
916{
917 return (m_startingSeq << 4) & 0xfff0;
918}
919
920std::optional<Mac48Address>
925
926uint16_t
928{
929 uint16_t res = m_amsduSupport ? 1 : 0;
930 res |= m_policy << 1;
931 res |= m_tid << 2;
932 res |= (m_bufferSize % 1024) << 6;
933 return res;
934}
935
936void
938{
939 m_amsduSupport = ((params & 0x01) == 1);
940 m_policy = (params >> 1) & 0x01;
941 m_tid = (params >> 2) & 0x0f;
942 m_bufferSize = (params >> 6) & 0x03ff;
943}
944
945/***************************************************
946 * ADDBAResponse
947 ****************************************************/
948
950
951TypeId
953{
954 static TypeId tid = TypeId("ns3::MgtAddBaResponseHeader")
955 .SetParent<Header>()
956 .SetGroupName("Wifi")
957 .AddConstructor<MgtAddBaResponseHeader>();
958 return tid;
959}
960
961TypeId
966
967void
968MgtAddBaResponseHeader::Print(std::ostream& os) const
969{
970 os << "Status code=" << m_code << "A-MSDU support=" << m_amsduSupport << " Policy=" << +m_policy
971 << " TID=" << +m_tid << " Buffer size=" << m_bufferSize << " Timeout=" << m_timeoutValue;
972 if (m_gcrGroupAddress.has_value())
973 {
974 os << " GCR group address=" << m_gcrGroupAddress.value();
975 }
976}
977
980{
981 uint32_t size = 0;
982 size += 1; // Dialog token
983 size += m_code.GetSerializedSize(); // Status code
984 size += 2; // Block ack parameter set
985 size += 2; // Block ack timeout value
987 {
988 // a GCR Group Address element has to be added
990 }
991 if (m_bufferSize >= 1024)
992 {
993 // an ADDBA Extension element has to be added
995 }
996 return size;
997}
998
999void
1001{
1002 Buffer::Iterator i = start;
1004 i = m_code.Serialize(i);
1008 {
1009 GcrGroupAddress gcrGroupAddr;
1010 gcrGroupAddr.m_gcrGroupAddress = *m_gcrGroupAddress;
1011 i = gcrGroupAddr.Serialize(i);
1012 }
1013 if (m_bufferSize >= 1024)
1014 {
1015 AddbaExtension addbaExt;
1016 addbaExt.m_extParamSet.extBufferSize = m_bufferSize / 1024;
1017 i = addbaExt.Serialize(i);
1018 }
1019}
1020
1023{
1024 Buffer::Iterator i = start;
1025 m_dialogToken = i.ReadU8();
1026 i = m_code.Deserialize(i);
1029 m_gcrGroupAddress.reset();
1030 GcrGroupAddress gcrGroupAddr;
1031 auto tmp = i;
1032 i = gcrGroupAddr.DeserializeIfPresent(i);
1033 if (i.GetDistanceFrom(tmp) != 0)
1034 {
1035 m_gcrGroupAddress = gcrGroupAddr.m_gcrGroupAddress;
1036 }
1037 AddbaExtension addbaExt;
1038 tmp = i;
1039 i = addbaExt.DeserializeIfPresent(i);
1040 if (i.GetDistanceFrom(tmp) != 0)
1041 {
1042 // the buffer size is Extended Buffer Size × 1024 + Buffer Size
1043 // (Sec. 9.4.2.138 of 802.11be D4.0)
1044 m_bufferSize += addbaExt.m_extParamSet.extBufferSize * 1024;
1045 }
1046 return i.GetDistanceFrom(start);
1047}
1048
1049void
1054
1055void
1060
1061void
1063{
1064 NS_ASSERT(tid < 16);
1065 m_tid = tid;
1066}
1067
1068void
1073
1074void
1076{
1077 m_bufferSize = size;
1078}
1079
1080void
1085
1086void
1088{
1089 m_amsduSupport = supported;
1090}
1091
1092void
1097
1100{
1101 return m_code;
1102}
1103
1104uint8_t
1106{
1107 return m_tid;
1108}
1109
1110bool
1112{
1113 return m_policy == 1;
1114}
1115
1116uint16_t
1121
1122uint16_t
1127
1128bool
1133
1134std::optional<Mac48Address>
1139
1140uint16_t
1142{
1143 uint16_t res = m_amsduSupport ? 1 : 0;
1144 res |= m_policy << 1;
1145 res |= m_tid << 2;
1146 res |= (m_bufferSize % 1024) << 6;
1147 return res;
1148}
1149
1150void
1152{
1153 m_amsduSupport = ((params & 0x01) == 1);
1154 m_policy = (params >> 1) & 0x01;
1155 m_tid = (params >> 2) & 0x0f;
1156 m_bufferSize = (params >> 6) & 0x03ff;
1157}
1158
1159/***************************************************
1160 * DelBa
1161 ****************************************************/
1162
1164
1165TypeId
1167{
1168 static TypeId tid = TypeId("ns3::MgtDelBaHeader")
1169 .SetParent<Header>()
1170 .SetGroupName("Wifi")
1171 .AddConstructor<MgtDelBaHeader>();
1172 return tid;
1173}
1174
1175TypeId
1177{
1178 return GetTypeId();
1179}
1180
1181void
1182MgtDelBaHeader::Print(std::ostream& os) const
1183{
1184 os << "Initiator=" << m_initiator << " TID=" << +m_tid;
1185 if (m_gcrGroupAddress.has_value())
1186 {
1187 os << " GCR group address=" << m_gcrGroupAddress.value();
1188 }
1189}
1190
1193{
1194 uint32_t size = 0;
1195 size += 2; // DelBa parameter set
1196 size += 2; // Reason code
1198 {
1199 // a GCR Group Address element has to be added
1201 }
1202 return size;
1203}
1204
1205void
1207{
1208 Buffer::Iterator i = start;
1212 {
1213 GcrGroupAddress gcrGroupAddr;
1214 gcrGroupAddr.m_gcrGroupAddress = *m_gcrGroupAddress;
1215 i = gcrGroupAddr.Serialize(i);
1216 }
1217}
1218
1221{
1222 Buffer::Iterator i = start;
1225 m_gcrGroupAddress.reset();
1226 GcrGroupAddress gcrGroupAddr;
1227 auto tmp = i;
1228 i = gcrGroupAddr.DeserializeIfPresent(i);
1229 if (i.GetDistanceFrom(tmp) != 0)
1230 {
1231 m_gcrGroupAddress = gcrGroupAddr.m_gcrGroupAddress;
1232 }
1233 return i.GetDistanceFrom(start);
1234}
1235
1236bool
1238{
1239 return m_initiator == 1;
1240}
1241
1242uint8_t
1244{
1245 NS_ASSERT(m_tid < 16);
1246 auto tid = static_cast<uint8_t>(m_tid);
1247 return tid;
1248}
1249
1250void
1255
1256void
1261
1262void
1264{
1265 NS_ASSERT(tid < 16);
1266 m_tid = static_cast<uint16_t>(tid);
1267}
1268
1269void
1271{
1272 m_gcrGroupAddress = address;
1273}
1274
1275std::optional<Mac48Address>
1280
1281uint16_t
1283{
1284 uint16_t res = 0;
1285 res |= m_initiator << 11;
1286 res |= m_tid << 12;
1287 return res;
1288}
1289
1290void
1292{
1293 m_initiator = (params >> 11) & 0x01;
1294 m_tid = (params >> 12) & 0x0f;
1295}
1296
1297/***************************************************
1298 * EMLSR Operating Mode Notification
1299 ****************************************************/
1300
1302
1303TypeId
1305{
1306 static TypeId tid = TypeId("ns3::MgtEmlOperatingModeNotification")
1307 .SetParent<Header>()
1308 .SetGroupName("Wifi")
1309 .AddConstructor<MgtEmlOmn>();
1310 return tid;
1311}
1312
1313TypeId
1315{
1316 return GetTypeId();
1317}
1318
1319void
1320MgtEmlOmn::Print(std::ostream& os) const
1321{
1322 os << "EMLSR Mode=" << +m_emlControl.emlsrMode << " EMLMR Mode=" << +m_emlControl.emlmrMode
1323 << " EMLSR Parameter Update Control=" << +m_emlControl.emlsrParamUpdateCtrl;
1325 {
1326 os << " Link bitmap=" << std::hex << *m_emlControl.linkBitmap << std::dec;
1327 }
1329 {
1330 os << " EMLSR Padding Delay="
1332 .As(Time::US)
1333 << " EMLSR Transition Delay="
1335 .As(Time::US);
1336 }
1337}
1338
1341{
1342 uint32_t size = 2; // Dialog Token (1) + first byte of EML Control
1344 {
1345 size += 2;
1346 }
1348 {
1349 size += 1;
1350 }
1351 // TODO add size of EMLMR Supported MCS And NSS Set subfield when implemented
1353 {
1354 size += 1; // EMLSR Parameter Update field
1355 }
1356 return size;
1357}
1358
1359void
1361{
1362 start.WriteU8(m_dialogToken);
1363
1365 "EMLSR Mode and EMLMR Mode cannot be both set to 1");
1366 uint8_t val = m_emlControl.emlsrMode | (m_emlControl.emlmrMode << 1) |
1368 start.WriteU8(val);
1369
1372 "The EMLSR/EMLMR Link Bitmap is present if and only if either of the EMLSR "
1373 "Mode and EMLMR Mode subfields are set to 1");
1375 {
1376 start.WriteHtolsbU16(*m_emlControl.linkBitmap);
1377 }
1378 // TODO serialize MCS Map Count Control and EMLMR Supported MCS And NSS Set subfields
1379 // when implemented
1380
1382 "The EMLSR Parameter Update field is present "
1383 << std::boolalpha << m_emlsrParamUpdate.has_value()
1384 << " if and only if the EMLSR "
1385 "Parameter Update Control subfield is set to 1 "
1388 {
1389 val = m_emlsrParamUpdate->paddingDelay | (m_emlsrParamUpdate->transitionDelay << 3);
1390 start.WriteU8(val);
1391 }
1392}
1393
1396{
1397 Buffer::Iterator i = start;
1398
1399 m_dialogToken = i.ReadU8();
1400
1401 uint8_t val = i.ReadU8();
1402 m_emlControl.emlsrMode = val & 0x01;
1403 m_emlControl.emlmrMode = (val >> 1) & 0x01;
1404 m_emlControl.emlsrParamUpdateCtrl = (val >> 2) & 0x01;
1405
1407 "EMLSR Mode and EMLMR Mode cannot be both set to 1");
1408
1410 {
1412 }
1413 // TODO deserialize MCS Map Count Control and EMLMR Supported MCS And NSS Set subfields
1414 // when implemented
1415
1417 {
1418 val = i.ReadU8();
1420 m_emlsrParamUpdate->paddingDelay = val & 0x07;
1421 m_emlsrParamUpdate->transitionDelay = (val >> 3) & 0x07;
1422 }
1423
1424 return i.GetDistanceFrom(start);
1425}
1426
1427void
1429{
1430 NS_ABORT_MSG_IF(linkId > 15, "Link ID must not exceed 15");
1432 {
1434 }
1436}
1437
1438std::list<uint8_t>
1440{
1441 std::list<uint8_t> list;
1442 NS_ASSERT_MSG(m_emlControl.linkBitmap.has_value(), "No link bitmap");
1443 uint16_t bitmap = *m_emlControl.linkBitmap;
1444 for (uint8_t linkId = 0; linkId < 16; linkId++)
1445 {
1446 if ((bitmap & 0x0001) == 1)
1447 {
1448 list.push_back(linkId);
1449 }
1450 bitmap >>= 1;
1451 }
1452 return list;
1453}
1454
1455/***************************************************
1456 * FILS Discovery
1457 ****************************************************/
1458
1460
1461TypeId
1463{
1464 static TypeId tid = TypeId("ns3::FilsDiscHeader")
1465 .SetParent<Header>()
1466 .SetGroupName("Wifi")
1467 .AddConstructor<FilsDiscHeader>();
1468 return tid;
1469}
1470
1471TypeId
1473{
1474 return GetTypeId();
1475}
1476
1478 : m_len(m_frameCtl.m_lenPresenceInd),
1479 m_fdCap(m_frameCtl.m_capPresenceInd),
1480 m_primaryCh(m_frameCtl.m_primChPresenceInd),
1481 m_apConfigSeqNum(m_frameCtl.m_apCsnPresenceInd),
1482 m_accessNetOpt(m_frameCtl.m_anoPresenceInd),
1483 m_chCntrFreqSeg1(m_frameCtl.m_chCntrFreqSeg1PresenceInd)
1484{
1485}
1486
1487void
1488FilsDiscHeader::SetSsid(const std::string& ssid)
1489{
1490 m_ssid = ssid;
1491 m_frameCtl.m_ssidLen = ssid.length() - 1;
1492}
1493
1494const std::string&
1496{
1497 return m_ssid;
1498}
1499
1502{
1503 auto size = GetSizeNonOptSubfields();
1504 size += m_len.has_value() ? 1 : 0;
1505 size += m_fdCap.has_value() ? 2 : 0;
1506 size += m_opClass.has_value() ? 1 : 0;
1507 size += m_primaryCh.has_value() ? 1 : 0;
1508 size += m_apConfigSeqNum.has_value() ? 1 : 0;
1509 size += m_accessNetOpt.has_value() ? 1 : 0;
1510 size += m_chCntrFreqSeg1.has_value() ? 1 : 0;
1511 return size;
1512}
1513
1516{
1517 auto size = GetInformationFieldSize();
1518 // Optional elements
1519 size += m_rnr.has_value() ? m_rnr->GetSerializedSize() : 0;
1520 size += m_tim.has_value() ? m_tim->GetSerializedSize() : 0;
1521 return size;
1522}
1523
1526{
1527 return 2 /* FILS Discovery Frame Control */
1528 + 8 /* Timestamp */
1529 + 2 /* Beacon Interval */
1530 + m_ssid.length(); /* SSID */
1531}
1532
1533void
1535{
1536 m_len.reset(); // so that Length size is not included by GetInformationFieldSize()
1537 auto infoFieldSize = GetInformationFieldSize();
1538 auto nonOptSubfieldsSize = GetSizeNonOptSubfields();
1539 NS_ABORT_MSG_IF(infoFieldSize < nonOptSubfieldsSize, "Length subfield is less than 0");
1540 m_len = infoFieldSize - nonOptSubfieldsSize;
1541}
1542
1543void
1544FilsDiscHeader::Print(std::ostream& os) const
1545{
1546 os << "Control=" << m_frameCtl << ", "
1547 << "Time Stamp=" << m_timeStamp << ", "
1548 << "Beacon Interval=" << m_beaconInt << ", "
1549 << "SSID=" << m_ssid << ", ";
1550 if (m_len.has_value())
1551 {
1552 os << "Length=" << *m_len << ", ";
1553 }
1554 if (m_fdCap.has_value())
1555 {
1556 os << "FD Capability=" << *m_fdCap << ", ";
1557 }
1558 if (m_opClass.has_value())
1559 {
1560 os << "Operating Class=" << *m_opClass << ", ";
1561 }
1562 if (m_primaryCh.has_value())
1563 {
1564 os << "Primary Channel=" << *m_primaryCh << ", ";
1565 }
1567 {
1568 os << "AP-CSN=" << *m_apConfigSeqNum << ", ";
1569 }
1571 {
1572 os << "ANO=" << *m_accessNetOpt << ", ";
1573 }
1575 {
1576 os << "Channel Center Frequency Seg 1=" << *m_chCntrFreqSeg1 << ", ";
1577 }
1578 if (m_tim.has_value())
1579 {
1580 os << "Traffic Indicator Map=" << *m_tim;
1581 }
1582}
1583
1584void
1586{
1587 Buffer::Iterator i = start;
1589 i.WriteHtolsbU64(Simulator::Now().GetMicroSeconds()); // Time stamp
1591 i.Write(reinterpret_cast<const uint8_t*>(m_ssid.data()), m_ssid.length());
1592 if (m_len.has_value())
1593 {
1594 i.WriteU8(*m_len);
1595 }
1596 if (m_fdCap.has_value())
1597 {
1598 m_fdCap->Serialize(i);
1599 }
1600 NS_ASSERT(m_opClass.has_value() == m_primaryCh.has_value());
1601 if (m_opClass.has_value())
1602 {
1603 i.WriteU8(*m_opClass);
1604 }
1605 if (m_primaryCh.has_value())
1606 {
1607 i.WriteU8(*m_primaryCh);
1608 }
1610 {
1612 }
1614 {
1616 }
1618 {
1620 }
1621 i = m_rnr.has_value() ? m_rnr->Serialize(i) : i;
1622 i = m_tim.has_value() ? m_tim->Serialize(i) : i;
1623}
1624
1627{
1628 Buffer::Iterator i = start;
1629 auto nOctets = m_frameCtl.Deserialize(i);
1630 i.Next(nOctets);
1633 std::vector<uint8_t> ssid(m_frameCtl.m_ssidLen + 2);
1634 i.Read(ssid.data(), m_frameCtl.m_ssidLen + 1);
1635 ssid[m_frameCtl.m_ssidLen + 1] = 0;
1636 m_ssid = std::string(reinterpret_cast<char*>(ssid.data()));
1637 // Optional subfields
1639 {
1640 m_len = i.ReadU8();
1641 }
1643 {
1644 nOctets = m_fdCap->Deserialize(i);
1645 i.Next(nOctets);
1646 }
1648 {
1649 m_opClass = i.ReadU8();
1650 m_primaryCh = i.ReadU8();
1651 }
1653 {
1655 }
1657 {
1658 m_accessNetOpt = i.ReadU8();
1659 }
1661 {
1663 }
1664 // Optional elements
1665 m_rnr.emplace();
1666 auto tmp = i;
1667 i = m_rnr->DeserializeIfPresent(i);
1668 if (i.GetDistanceFrom(tmp) == 0)
1669 {
1670 m_rnr.reset();
1671 }
1672
1673 m_tim.emplace();
1674 tmp = i;
1675 i = m_tim->DeserializeIfPresent(i);
1676 if (i.GetDistanceFrom(tmp) == 0)
1677 {
1678 m_tim.reset();
1679 }
1680
1681 return i.GetDistanceFrom(start);
1682}
1683
1684std::ostream&
1685operator<<(std::ostream& os, const FilsDiscHeader::FilsDiscFrameControl& control)
1686{
1687 os << "ssidLen:" << control.m_ssidLen << " capPresenceInd:" << control.m_capPresenceInd
1688 << " shortSsidInd:" << control.m_shortSsidInd
1689 << " apCsnPresenceInd:" << control.m_apCsnPresenceInd
1690 << " anoPresenceInd:" << control.m_anoPresenceInd
1691 << " chCntrFreqSeg1PresenceInd:" << control.m_chCntrFreqSeg1PresenceInd
1692 << " primChPresenceInd:" << control.m_primChPresenceInd
1693 << " rsnInfoPresenceInd:" << control.m_rsnInfoPresenceInd
1694 << " lenPresenceInd:" << control.m_lenPresenceInd
1695 << " mdPresenceInd:" << control.m_mdPresenceInd;
1696 return os;
1697}
1698
1699void
1701{
1702 uint16_t val = m_ssidLen | ((m_capPresenceInd ? 1 : 0) << 5) | (m_shortSsidInd << 6) |
1703 ((m_apCsnPresenceInd ? 1 : 0) << 7) | ((m_anoPresenceInd ? 1 : 0) << 8) |
1704 ((m_chCntrFreqSeg1PresenceInd ? 1 : 0) << 9) |
1705 ((m_primChPresenceInd ? 1 : 0) << 10) | (m_rsnInfoPresenceInd << 11) |
1706 ((m_lenPresenceInd ? 1 : 0) << 12) | (m_mdPresenceInd << 13);
1707 start.WriteHtolsbU16(val);
1708}
1709
1712{
1713 auto val = start.ReadLsbtohU16();
1714
1715 m_ssidLen = val & 0x001f;
1716 m_capPresenceInd = ((val >> 5) & 0x0001) == 1;
1717 m_shortSsidInd = (val >> 6) & 0x0001;
1718 m_apCsnPresenceInd = ((val >> 7) & 0x0001) == 1;
1719 m_anoPresenceInd = ((val >> 8) & 0x0001) == 1;
1720 m_chCntrFreqSeg1PresenceInd = ((val >> 9) & 0x0001) == 1;
1721 m_primChPresenceInd = ((val >> 10) & 0x0001) == 1;
1722 m_rsnInfoPresenceInd = (val >> 11) & 0x0001;
1723 m_lenPresenceInd = ((val >> 12) & 0x0001) == 1;
1724 m_mdPresenceInd = (val >> 13) & 0x0001;
1725
1726 return 2;
1727}
1728
1729std::ostream&
1730operator<<(std::ostream& os, const FilsDiscHeader::FdCapability& capability)
1731{
1732 os << "ess:" << capability.m_ess << " privacy:" << capability.m_privacy
1733 << " channelWidth:" << capability.m_chWidth << " maxNss:" << capability.m_maxNss
1734 << " multiBssidInd:" << capability.m_multiBssidPresenceInd
1735 << " phyIdx:" << capability.m_phyIdx << " minRate:" << capability.m_minRate;
1736 return os;
1737}
1738
1739void
1741{
1742 uint16_t val = m_ess | (m_privacy << 1) | (m_chWidth << 2) | (m_maxNss << 5) |
1743 (m_multiBssidPresenceInd << 9) | (m_phyIdx << 10) | (m_minRate << 13);
1744 start.WriteHtolsbU16(val);
1745}
1746
1749{
1750 auto val = start.ReadLsbtohU16();
1751
1752 m_ess = val & 0x0001;
1753 m_privacy = (val >> 1) & 0x0001;
1754 m_chWidth = (val >> 2) & 0x0007;
1755 m_maxNss = (val >> 5) & 0x0007;
1756 m_multiBssidPresenceInd = (val >> 9) & 0x0001;
1757 m_phyIdx = (val >> 10) & 0x0007;
1758 m_minRate = (val >> 13) & 0x0007;
1759
1760 return 2;
1761}
1762
1763void
1765{
1766 m_chWidth = (width == MHz_u{20} || width == MHz_u{22}) ? 0
1767 : (width == MHz_u{40}) ? 1
1768 : (width == MHz_u{80}) ? 2
1769 : (width == MHz_u{160}) ? 3
1770 : 4;
1771}
1772
1773MHz_u
1775{
1776 switch (m_chWidth)
1777 {
1778 case 0:
1779 return m_phyIdx == 0 ? MHz_u{22} : MHz_u{20}; // PHY Index 0 indicates 802.11b
1780 case 1:
1781 return MHz_u{40};
1782 case 2:
1783 return MHz_u{80};
1784 case 3:
1785 return MHz_u{160};
1786 default:
1787 NS_ABORT_MSG("Reserved value: " << +m_chWidth);
1788 }
1789 return MHz_u{0};
1790}
1791
1792void
1794{
1795 NS_ABORT_MSG_IF(maxNss < 1, "NSS is equal to 0");
1796 maxNss--;
1797 // 4 is the maximum value for the Maximum Number of Spatial Streams subfield
1798 m_maxNss = std::min<uint8_t>(maxNss, 4);
1799}
1800
1801uint8_t
1803{
1804 return m_maxNss + 1;
1805}
1806
1807void
1809{
1810 switch (standard)
1811 {
1813 m_phyIdx = 0;
1814 break;
1817 m_phyIdx = 1;
1818 break;
1820 m_phyIdx = 2;
1821 break;
1823 m_phyIdx = 3;
1824 break;
1826 m_phyIdx = 4;
1827 break;
1829 m_phyIdx = 5;
1830 break;
1831 default:
1832 NS_ABORT_MSG("Unsupported standard: " << standard);
1833 }
1834}
1835
1838{
1839 switch (m_phyIdx)
1840 {
1841 case 0:
1842 return WIFI_STANDARD_80211b;
1843 case 1:
1845 "Invalid PHY band (" << band << ") with PHY index of 1");
1847 case 2:
1848 return WIFI_STANDARD_80211n;
1849 case 3:
1850 return WIFI_STANDARD_80211ac;
1851 case 4:
1852 return WIFI_STANDARD_80211ax;
1853 case 5:
1854 return WIFI_STANDARD_80211be;
1855 default:
1856 NS_ABORT_MSG("Invalid PHY index: " << m_phyIdx);
1857 }
1858
1860}
1861
1862} // 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.
The IEEE 802.11 GCR Group Address Element (Sec.
Mac48Address m_gcrGroupAddress
GCR Group Address field.
Protocol header serialization and deserialization.
Definition header.h:33
an EUI-48 address
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.
std::optional< Mac48Address > GetGcrGroupAddress() const
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.
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.
void SetGcrGroupAddress(const Mac48Address &address)
Set the GCR Group address.
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.
bool m_amsduSupport
Flag if A-MSDU is supported.
uint32_t GetSerializedSize() const override
std::optional< Mac48Address > m_gcrGroupAddress
GCR Group Address (optional)
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
bool 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.
void SetGcrGroupAddress(const Mac48Address &address)
Set the GCR Group address.
TypeId GetInstanceTypeId() const override
Get the most derived TypeId for this Object.
void SetBufferSize(uint16_t size)
Set buffer size.
std::optional< Mac48Address > m_gcrGroupAddress
GCR Group Address (optional)
void Print(std::ostream &os) const override
void SetStatusCode(StatusCode code)
Set the status code.
std::optional< Mac48Address > GetGcrGroupAddress() const
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.
std::optional< Mac48Address > GetGcrGroupAddress() const
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.
std::optional< Mac48Address > m_gcrGroupAddress
GCR Group Address (optional)
bool IsByOriginator() const
Check if the initiator bit in the DELBA is set.
uint16_t GetParameterSet() const
Return the raw parameter set.
void SetGcrGroupAddress(const Mac48Address &address)
Set the GCR Group address.
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:403
@ US
microsecond
Definition nstime.h:107
a unique identifier for an interface.
Definition type-id.h:49
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