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