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{
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:
144 break;
145 case DELTS:
146 retval.qos = DELTS;
147 break;
148 case SCHEDULE:
149 retval.qos = SCHEDULE;
150 break;
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:
188 retval.publicAction = 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 {
200 retval.radioMeasurementAction = RADIO_MEASUREMENT_REQUEST;
201 break;
203 retval.radioMeasurementAction = RADIO_MEASUREMENT_REPORT;
204 break;
206 retval.radioMeasurementAction = LINK_MEASUREMENT_REQUEST;
207 break;
209 retval.radioMeasurementAction = LINK_MEASUREMENT_REPORT;
210 break;
212 retval.radioMeasurementAction = NEIGHBOR_REPORT_REQUEST;
213 break;
215 retval.radioMeasurementAction = NEIGHBOR_REPORT_RESPONSE;
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:
227 retval.selfProtectedAction = PEER_LINK_OPEN;
228 break;
230 retval.selfProtectedAction = PEER_LINK_CONFIRM;
231 break;
232 case PEER_LINK_CLOSE:
233 retval.selfProtectedAction = PEER_LINK_CLOSE;
234 break;
235 case GROUP_KEY_INFORM:
236 retval.selfProtectedAction = GROUP_KEY_INFORM;
237 break;
238 case GROUP_KEY_ACK:
239 retval.selfProtectedAction = 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 {
251 retval.meshAction = LINK_METRIC_REPORT;
252 break;
253 case PATH_SELECTION:
254 retval.meshAction = PATH_SELECTION;
255 break;
257 retval.meshAction = PORTAL_ANNOUNCEMENT;
258 break;
261 break;
263 retval.meshAction = MDA_SETUP_REQUEST;
264 break;
265 case MDA_SETUP_REPLY:
266 retval.meshAction = MDA_SETUP_REPLY;
267 break;
270 break;
272 retval.meshAction = MDAOP_ADVERTISEMENTS;
273 break;
275 retval.meshAction = MDAOP_SET_TEARDOWN;
276 break;
278 retval.meshAction = TBTT_ADJUSTMENT_REQUEST;
279 break;
281 retval.meshAction = TBTT_ADJUSTMENT_RESPONSE;
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
294 retval.multihopAction = PROXY_UPDATE;
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;
318 retval.dmgAction = DMG_HANDOVER_REQUEST;
319 break;
321 retval.dmgAction = DMG_HANDOVER_RESPONSE;
322 break;
323 case DMG_DTP_REQUEST:
324 retval.dmgAction = DMG_DTP_REQUEST;
325 break;
326 case DMG_DTP_RESPONSE:
327 retval.dmgAction = 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:
345 retval.dmgAction = DMG_RLS_RESPONSE;
346 break;
348 retval.dmgAction = DMG_RLS_ANNOUNCEMENT;
349 break;
350 case DMG_RLS_TEARDOWN:
351 retval.dmgAction = DMG_RLS_TEARDOWN;
352 break;
354 retval.dmgAction = DMG_RELAY_ACK_REQUEST;
355 break;
357 retval.dmgAction = DMG_RELAY_ACK_RESPONSE;
358 break;
359 case DMG_TPA_REQUEST:
360 retval.dmgAction = DMG_TPA_REQUEST;
361 break;
362 case DMG_TPA_RESPONSE:
363 retval.dmgAction = DMG_TPA_RESPONSE;
364 break;
365 case DMG_ROC_REQUEST:
366 retval.dmgAction = DMG_ROC_REQUEST;
367 break;
368 case DMG_ROC_RESPONSE:
369 retval.dmgAction = 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 {
381 retval.fstAction = FST_SETUP_REQUEST;
382 break;
384 retval.fstAction = FST_SETUP_RESPONSE;
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:
393 retval.fstAction = 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 {
408 retval.unprotectedDmgAction = UNPROTECTED_DMG_ANNOUNCE;
409 break;
411 retval.unprotectedDmgAction = UNPROTECTED_DMG_BRP;
412 break;
414 retval.unprotectedDmgAction = UNPROTECTED_MIMO_BF_SETUP;
415 break;
417 retval.unprotectedDmgAction = UNPROTECTED_MIMO_BF_POLL;
418 break;
420 retval.unprotectedDmgAction = UNPROTECTED_MIMO_BF_FEEDBACK;
421 break;
423 retval.unprotectedDmgAction = UNPROTECTED_MIMO_BF_SELECTION;
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;
456 retval.protectedEhtAction = PROTECTED_EHT_LINK_RECOMMENDATION;
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{
498 pkt->PeekHeader(actionHdr);
499 return {actionHdr.GetCategory(), actionHdr.GetAction()};
500}
501
502std::pair<WifiActionHeader::CategoryValue, WifiActionHeader::ActionValue>
504{
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;
777 i.WriteU8(m_dialogToken);
778 i.WriteHtolsbU16(GetParameterSet());
779 i.WriteHtolsbU16(m_timeoutValue);
780 i.WriteHtolsbU16(GetStartingSequenceControl());
782 {
785 i = gcrGroupAddr.Serialize(i);
786 }
787 if (m_bufferSize >= 1024)
788 {
791 i = addbaExt.Serialize(i);
792 }
793}
794
797{
798 Buffer::Iterator i = start;
799 m_dialogToken = i.ReadU8();
800 SetParameterSet(i.ReadLsbtohU16());
801 m_timeoutValue = i.ReadLsbtohU16();
802 SetStartingSequenceControl(i.ReadLsbtohU16());
803 m_gcrGroupAddress.reset();
805 auto tmp = i;
807 if (i.GetDistanceFrom(tmp) != 0)
808 {
809 m_gcrGroupAddress = gcrGroupAddr.m_gcrGroupAddress;
810 }
812 tmp = 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
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;
1003 i.WriteU8(m_dialogToken);
1004 i = m_code.Serialize(i);
1006 i.WriteHtolsbU16(m_timeoutValue);
1008 {
1011 i = gcrGroupAddr.Serialize(i);
1012 }
1013 if (m_bufferSize >= 1024)
1014 {
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);
1027 SetParameterSet(i.ReadLsbtohU16());
1028 m_timeoutValue = i.ReadLsbtohU16();
1029 m_gcrGroupAddress.reset();
1031 auto tmp = i;
1033 if (i.GetDistanceFrom(tmp) != 0)
1034 {
1035 m_gcrGroupAddress = gcrGroupAddr.m_gcrGroupAddress;
1036 }
1038 tmp = 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;
1209 i.WriteHtolsbU16(GetParameterSet());
1210 i.WriteHtolsbU16(m_reasonCode);
1212 {
1215 i = gcrGroupAddr.Serialize(i);
1216 }
1217}
1218
1221{
1222 Buffer::Iterator i = start;
1223 SetParameterSet(i.ReadLsbtohU16());
1224 m_reasonCode = i.ReadLsbtohU16();
1225 m_gcrGroupAddress.reset();
1227 auto tmp = 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 {
1411 m_emlControl.linkBitmap = i.ReadLsbtohU16();
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();
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()
1539 NS_ABORT_MSG_IF(infoFieldSize < nonOptSubfieldsSize, "Length subfield is less than 0");
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
1590 i.WriteHtolsbU16(m_beaconInt);
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 {
1611 i.WriteU8(*m_apConfigSeqNum);
1612 }
1614 {
1615 i.WriteU8(*m_accessNetOpt);
1616 }
1618 {
1619 i.WriteU8(*m_chCntrFreqSeg1);
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;
1630 i.Next(nOctets);
1631 m_timeStamp = i.ReadLsbtohU64();
1632 m_beaconInt = i.ReadLsbtohU16();
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 {
1654 m_apConfigSeqNum = i.ReadU8();
1655 }
1657 {
1658 m_accessNetOpt = i.ReadU8();
1659 }
1661 {
1662 m_chCntrFreqSeg1 = i.ReadU8();
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
uint32_t GetDistanceFrom(const Iterator &o) const
Definition buffer.cc:769
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 T & emplace(Args &&... args)
Construct the contained value in-place.
constexpr bool has_value() const
Check whether this object contains a value.
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:66
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: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 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
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
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
SelfProtectedActionValue selfProtectedAction
self protected