A Discrete-Event Network Simulator
API
eht-operation.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2022
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Sharan Naribole <sharan.naribole@gmail.com>
18  */
19 
20 #include "eht-operation.h"
21 
22 #include <ns3/assert.h>
23 
24 #include <algorithm>
25 
26 namespace ns3
27 {
28 
29 void
30 EhtOperation::Print(std::ostream& os) const
31 {
32  os << "EHT Operation=" << +m_params.opInfoPresent << "|" << +m_params.disabledSubchBmPresent
33  << "|" << +m_params.defaultPeDur << "|" << +m_params.grpBuIndLimit << "|"
34  << +m_params.grpBuExp << "|[";
35  for (const auto& maxRxNss : m_mcsNssSet.maxRxNss)
36  {
37  os << +maxRxNss << "|";
38  }
39  os << "]|[";
40  for (const auto& maxTxNss : m_mcsNssSet.maxTxNss)
41  {
42  os << +maxTxNss << "|";
43  }
44  os << "]";
45  if (m_opInfo.has_value())
46  {
47  os << "|" << +m_opInfo->control.channelWidth << "|" << +m_opInfo->ccfs0 << "|"
48  << +m_opInfo->ccfs1;
49  if (m_opInfo->disabledSubchBm.has_value())
50  {
51  os << "|" << m_opInfo->disabledSubchBm.value();
52  }
53  }
54 }
55 
56 void
58 {
59  uint8_t val = opInfoPresent | (disabledSubchBmPresent << 1) | (defaultPeDur << 2) |
60  (grpBuIndLimit << 3) | (grpBuExp << 4);
61  start.WriteU8(val);
62 }
63 
64 uint16_t
66 {
67  auto params = start.ReadU8();
68  opInfoPresent = params & 0x01;
69  disabledSubchBmPresent = (params >> 1) & 0x01;
70  defaultPeDur = (params >> 2) & 0x01;
71  grpBuIndLimit = (params >> 3) & 0x01;
72  grpBuExp = (params >> 4) & 0x03;
74 }
75 
83 void
84 SetMaxNss(std::vector<uint8_t>& vec, uint8_t maxNss, uint8_t mcsStart, uint8_t mcsEnd)
85 {
86  NS_ASSERT(mcsStart <= mcsEnd);
87  NS_ASSERT((mcsStart >= 0) && (mcsEnd <= WIFI_EHT_MAX_MCS_INDEX));
88  NS_ASSERT((maxNss >= 1) && (maxNss <= WIFI_EHT_MAX_NSS_CONFIGURABLE));
89  for (auto index = mcsStart; index <= mcsEnd; index++)
90  {
91  vec[index] = maxNss;
92  }
93 }
94 
102 uint32_t
103 GetMaxNss(const std::vector<uint8_t>& vec, uint8_t mcsStart, uint8_t mcsEnd)
104 {
105  NS_ASSERT(mcsStart <= mcsEnd);
106  NS_ASSERT((mcsStart >= 0) && (mcsEnd <= WIFI_EHT_MAX_MCS_INDEX));
107  auto minMaxNss = WIFI_EHT_MAX_NSS_CONFIGURABLE;
108  for (auto index = mcsStart; index <= mcsEnd; index++)
109  {
110  if (vec[index] < minMaxNss)
111  {
112  minMaxNss = vec[index];
113  }
114  }
115  return minMaxNss;
116 }
117 
118 void
120 {
121  uint32_t val = GetMaxNss(maxRxNss, 0, 7) | (GetMaxNss(maxTxNss, 0, 7) << 4) |
122  (GetMaxNss(maxRxNss, 8, 9) << 8) | (GetMaxNss(maxTxNss, 8, 9) << 12) |
123  (GetMaxNss(maxRxNss, 10, 11) << 16) | (GetMaxNss(maxTxNss, 10, 11) << 20) |
124  (GetMaxNss(maxRxNss, 12, 13) << 24) | (GetMaxNss(maxTxNss, 12, 13) << 28);
125  start.WriteHtolsbU32(val);
126 }
127 
128 uint16_t
130 {
131  auto subfield = start.ReadLsbtohU32();
132  auto rxNssMcs0_7 = subfield & 0xf; // Max Rx NSS MCS 0-7
133  SetMaxNss(maxRxNss, rxNssMcs0_7, 0, 7);
134  auto txNssMcs0_7 = (subfield >> 4) & 0xf; // Max Tx NSS MCS 0-7
135  SetMaxNss(maxTxNss, txNssMcs0_7, 0, 7);
136  auto rxNssMcs8_9 = (subfield >> 8) & 0xf; // Max Rx NSS MCS 8-9
137  SetMaxNss(maxRxNss, rxNssMcs8_9, 8, 9);
138  auto txNssMcs8_9 = (subfield >> 12) & 0xf; // Max Tx NSS MCS 8-9
139  SetMaxNss(maxTxNss, txNssMcs8_9, 8, 9);
140  auto rxNssMcs10_11 = (subfield >> 16) & 0xf; // Max Rx NSS MCS 10-11
141  SetMaxNss(maxRxNss, rxNssMcs10_11, 10, 11);
142  auto txNssMcs10_11 = (subfield >> 20) & 0xf; // Max Tx NSS MCS 10-11
143  SetMaxNss(maxTxNss, txNssMcs10_11, 10, 11);
144  auto rxNssMcs12_13 = (subfield >> 24) & 0xf; // Max Rx NSS MCS 12-13
145  SetMaxNss(maxRxNss, rxNssMcs12_13, 12, 13);
146  auto txNssMcs12_13 = (subfield >> 28) & 0xf; // Max Tx NSS MCS 12-13
147  SetMaxNss(maxTxNss, txNssMcs12_13, 12, 13);
149 }
150 
151 void
153 {
154  start.WriteU8(control.channelWidth); // Control
155  start.WriteU8(ccfs0); // CCFS 0
156  start.WriteU8(ccfs1); // CCFS 1
157  if (disabledSubchBm.has_value())
158  {
159  start.WriteU16(disabledSubchBm.value());
160  }
161 }
162 
163 uint16_t
165 {
166  auto i = start;
167  uint16_t count = 0;
168  auto controlSubfield = i.ReadU8();
169  count++;
170  control.channelWidth = controlSubfield & 0x7;
171  ccfs0 = i.ReadU8();
172  count++;
173  ccfs1 = i.ReadU8();
174  count++;
176  "Incorrect EHT Operation Info deserialize");
177  if (!disabledSubchBmPresent)
178  {
179  return count;
180  }
181  disabledSubchBm = i.ReadU16();
182  count += 2;
184  "Incorrect EHT Operation Info deserialize");
185  return count;
186 }
187 
189 {
192 }
193 
196 {
197  return IE_EXTENSION;
198 }
199 
202 {
203  return IE_EXT_EHT_OPERATION;
204 }
205 
206 uint16_t
208 {
209  // IEEE 802.11be D2.0 9.4.2.311
210  auto ret =
212  if (!m_params.opInfoPresent)
213  {
214  return ret;
215  }
218  {
219  return ret;
220  }
222 }
223 
224 void
225 EhtOperation::SetMaxRxNss(uint8_t maxNss, uint8_t mcsStart, uint8_t mcsEnd)
226 {
227  NS_ASSERT(mcsStart <= mcsEnd);
228  NS_ASSERT((mcsStart >= 0) && (mcsEnd <= WIFI_EHT_MAX_MCS_INDEX));
229  NS_ASSERT((maxNss >= 1) && (maxNss <= WIFI_EHT_MAX_NSS_CONFIGURABLE));
230  SetMaxNss(m_mcsNssSet.maxRxNss, maxNss, mcsStart, mcsEnd);
231 }
232 
233 void
234 EhtOperation::SetMaxTxNss(uint8_t maxNss, uint8_t mcsStart, uint8_t mcsEnd)
235 {
236  NS_ASSERT(mcsStart <= mcsEnd);
237  NS_ASSERT((mcsStart >= 0) && (mcsEnd <= WIFI_EHT_MAX_MCS_INDEX));
238  NS_ASSERT((maxNss >= 1) && (maxNss <= WIFI_EHT_MAX_NSS_CONFIGURABLE));
239  SetMaxNss(m_mcsNssSet.maxTxNss, maxNss, mcsStart, mcsEnd);
240 }
241 
242 void
244 {
248  "Incorrect setting of EHT Operation Information Present bit");
249 
250  if (!m_params.opInfoPresent)
251  { // EHT Operation Information Present not set
252  return;
253  }
254 
255  auto disabledSubchBmPresent = m_params.disabledSubchBmPresent > 0;
256  NS_ASSERT_MSG(disabledSubchBmPresent == m_opInfo->disabledSubchBm.has_value(),
257  "Incorrect setting of Disabled Subchannel Bitmap Present bit");
258  m_opInfo->Serialize(start);
259 }
260 
261 uint16_t
263 {
264  auto i = start;
265  i.Next(m_params.Deserialize(i));
266  i.Next(m_mcsNssSet.Deserialize(i));
267  uint16_t count = i.GetDistanceFrom(start);
268 
269  if (!m_params.opInfoPresent)
270  {
271  NS_ASSERT_MSG(count == length, "Unexpected EHT Operation size");
272  }
273 
274  if (m_params.opInfoPresent > 0)
275  {
276  auto disabledSubchBmPresent = m_params.disabledSubchBmPresent > 0;
277  m_opInfo = EhtOpInfo();
278  i.Next(m_opInfo->Deserialize(i, disabledSubchBmPresent));
279  count = i.GetDistanceFrom(start);
280  }
281 
282  NS_ABORT_MSG_IF(count != length,
283  "EHT Operation Length (" << +length
284  << ") differs "
285  "from actual number of bytes read ("
286  << +count << ")");
287  return length;
288 }
289 } // namespace ns3
iterator in a Buffer instance
Definition: buffer.h:100
void SetMaxTxNss(uint8_t maxNss, uint8_t mcsStart, uint8_t mcsEnd)
Set the max Tx NSS for input MCS index range.
void SetMaxRxNss(uint8_t maxNss, uint8_t mcsStart, uint8_t mcsEnd)
Set the max Rx NSS for input MCS index range.
EhtOpParams m_params
EHT Operation Parameters.
EhtBasicMcsNssSet m_mcsNssSet
Basic EHT-MCS and NSS set.
uint16_t DeserializeInformationField(Buffer::Iterator start, uint16_t length) override
Deserialize information (i.e., the body of the IE, not including the Element ID and length octets)
WifiInformationElementId ElementIdExt() const override
Get the wifi information element ID extension.
void Print(std::ostream &os) const override
Generate human-readable form of IE.
WifiInformationElementId ElementId() const override
Get the wifi information element ID.
uint16_t GetInformationFieldSize() const override
Length of serialized information (i.e., the length of the body of the IE, not including the Element I...
std::optional< EhtOpInfo > m_opInfo
EHT Operation Information.
void SerializeInformationField(Buffer::Iterator start) const override
Serialize information (i.e., the body of the IE, not including the Element ID and length octets)
#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_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
Every class exported by the ns3 library is enclosed in the ns3 namespace.
constexpr uint16_t WIFI_EHT_OP_INFO_BASIC_SIZE_B
IEEE 802.11be D2.0 Figure 9-1002c.
Definition: eht-operation.h:36
constexpr uint16_t WIFI_EHT_DISABLED_SUBCH_BM_SIZE_B
IEEE 802.11be D2.0 Figure 9-1002c.
Definition: eht-operation.h:38
constexpr uint8_t WIFI_DEFAULT_EHT_MAX_NSS
Default max Tx/Rx NSS.
Definition: eht-operation.h:42
constexpr uint8_t WIFI_EHT_MAX_MCS_INDEX
IEEE 802.11be D2.0 Figure 9-1002ai.
Definition: eht-operation.h:32
constexpr uint8_t WIFI_IE_ELEMENT_ID_EXT_SIZE
Size in bytes of the Element ID Extension field (IEEE 802.11-2020 9.4.2.1 General)
constexpr uint16_t WIFI_EHT_BASIC_MCS_NSS_SET_SIZE_B
IEEE 802.11be D2.0 Figure 9-1002ai.
Definition: eht-operation.h:40
void SetMaxNss(std::vector< uint8_t > &vec, uint8_t maxNss, uint8_t mcsStart, uint8_t mcsEnd)
set the max Tx/Rx NSS for input MCS index range
constexpr uint8_t WIFI_EHT_MAX_NSS_CONFIGURABLE
Max NSS configurable, 802.11be D2.0 Table 9-401m.
Definition: eht-operation.h:44
constexpr uint16_t WIFI_EHT_OP_PARAMS_SIZE_B
IEEE 802.11be D2.0 Figure 9-1002b.
Definition: eht-operation.h:34
uint8_t WifiInformationElementId
This type is used to represent an Information Element ID.
uint32_t GetMaxNss(const std::vector< uint8_t > &vec, uint8_t mcsStart, uint8_t mcsEnd)
Get the max Tx/Rx NSS for input MCS index range.
params
Fit Fluctuating Two Ray model to the 3GPP TR 38.901 using the Anderson-Darling goodness-of-fit ##.
void Serialize(Buffer::Iterator &start) const
Serialize the Basic EHT-MCS and NSS Set subfield.
std::vector< uint8_t > maxRxNss
Max Rx NSS per MCS.
std::vector< uint8_t > maxTxNss
Max Tx NSS per MCS.
uint16_t Deserialize(Buffer::Iterator start)
Deserialize the Basic EHT-MCS and NSS Set subfield.
EHT Operation Information subfield IEEE 802.11be D2.0 Figure 9-1002c.
void Serialize(Buffer::Iterator &start) const
Serialize the EHT Operation Information subfield.
uint16_t Deserialize(Buffer::Iterator start, bool disabledSubchBmPresent)
Deserialize the EHT Operation Information subfield.
uint8_t defaultPeDur
EHT Default PE Duration.
Definition: eht-operation.h:79
void Serialize(Buffer::Iterator &start) const
Serialize the EHT Operation Parameters subfield.
uint8_t grpBuExp
Group Addressed BU Indication Exponent.
Definition: eht-operation.h:83
uint16_t Deserialize(Buffer::Iterator start)
Deserialize the EHT Operation Parameters subfield.
uint8_t opInfoPresent
EHT Operation Information Present.
Definition: eht-operation.h:75
uint8_t disabledSubchBmPresent
Disabled Subchannel Bitmap Present.
Definition: eht-operation.h:77
uint8_t grpBuIndLimit
Group Addressed BU Indication Limit.
Definition: eht-operation.h:81
#define IE_EXTENSION
#define IE_EXT_EHT_OPERATION