A Discrete-Event Network Simulator
API
eht-operation.cc
Go to the documentation of this file.
1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2022
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  * Author: Sharan Naribole <sharan.naribole@gmail.com>
19  */
20 
21 #include "eht-operation.h"
22 
23 #include <ns3/assert.h>
24 
25 #include <algorithm>
26 
27 namespace ns3
28 {
29 
30 void
32 {
33  uint8_t val = opInfoPresent | (disabledSubchBmPresent << 1) | (defaultPeDur << 2) |
34  (grpBuIndLimit << 3) | (grpBuExp << 4);
35  start.WriteU8(val);
36 }
37 
38 uint16_t
40 {
41  auto params = start.ReadU8();
42  opInfoPresent = params & 0x01;
43  disabledSubchBmPresent = (params >> 1) & 0x01;
44  defaultPeDur = (params >> 2) & 0x01;
45  grpBuIndLimit = (params >> 3) & 0x01;
46  grpBuExp = (params >> 4) & 0x03;
48 }
49 
57 void
58 SetMaxNss(std::vector<uint8_t>& vec, uint8_t maxNss, uint8_t mcsStart, uint8_t mcsEnd)
59 {
60  NS_ASSERT(mcsStart <= mcsEnd);
61  NS_ASSERT((mcsStart >= 0) && (mcsEnd <= WIFI_EHT_MAX_MCS_INDEX));
62  NS_ASSERT((maxNss >= 1) && (maxNss <= WIFI_EHT_MAX_NSS_CONFIGURABLE));
63  for (auto index = mcsStart; index <= mcsEnd; index++)
64  {
65  vec[index] = maxNss;
66  }
67 }
68 
76 uint32_t
77 GetMaxNss(const std::vector<uint8_t>& vec, uint8_t mcsStart, uint8_t mcsEnd)
78 {
79  NS_ASSERT(mcsStart <= mcsEnd);
80  NS_ASSERT((mcsStart >= 0) && (mcsEnd <= WIFI_EHT_MAX_MCS_INDEX));
81  auto minMaxNss = WIFI_EHT_MAX_NSS_CONFIGURABLE;
82  for (auto index = mcsStart; index <= mcsEnd; index++)
83  {
84  if (vec[index] < minMaxNss)
85  {
86  minMaxNss = vec[index];
87  }
88  }
89  return minMaxNss;
90 }
91 
92 void
94 {
95  uint32_t val = GetMaxNss(maxRxNss, 0, 7) | (GetMaxNss(maxTxNss, 0, 7) << 4) |
96  (GetMaxNss(maxRxNss, 8, 9) << 8) | (GetMaxNss(maxTxNss, 8, 9) << 12) |
97  (GetMaxNss(maxRxNss, 10, 11) << 16) | (GetMaxNss(maxTxNss, 10, 11) << 20) |
98  (GetMaxNss(maxRxNss, 12, 13) << 24) | (GetMaxNss(maxTxNss, 12, 13) << 28);
99  start.WriteHtolsbU32(val);
100 }
101 
102 uint16_t
104 {
105  auto subfield = start.ReadLsbtohU32();
106  auto rxNssMcs0_7 = subfield & 0xf; // Max Rx NSS MCS 0-7
107  SetMaxNss(maxRxNss, rxNssMcs0_7, 0, 7);
108  auto txNssMcs0_7 = (subfield >> 4) & 0xf; // Max Tx NSS MCS 0-7
109  SetMaxNss(maxTxNss, txNssMcs0_7, 0, 7);
110  auto rxNssMcs8_9 = (subfield >> 8) & 0xf; // Max Rx NSS MCS 8-9
111  SetMaxNss(maxRxNss, rxNssMcs8_9, 8, 9);
112  auto txNssMcs8_9 = (subfield >> 12) & 0xf; // Max Tx NSS MCS 8-9
113  SetMaxNss(maxTxNss, txNssMcs8_9, 8, 9);
114  auto rxNssMcs10_11 = (subfield >> 16) & 0xf; // Max Rx NSS MCS 10-11
115  SetMaxNss(maxRxNss, rxNssMcs10_11, 10, 11);
116  auto txNssMcs10_11 = (subfield >> 20) & 0xf; // Max Tx NSS MCS 10-11
117  SetMaxNss(maxTxNss, txNssMcs10_11, 10, 11);
118  auto rxNssMcs12_13 = (subfield >> 24) & 0xf; // Max Rx NSS MCS 12-13
119  SetMaxNss(maxRxNss, rxNssMcs12_13, 12, 13);
120  auto txNssMcs12_13 = (subfield >> 28) & 0xf; // Max Tx NSS MCS 12-13
121  SetMaxNss(maxTxNss, txNssMcs12_13, 12, 13);
123 }
124 
125 void
127 {
128  start.WriteU8(control.channelWidth); // Control
129  start.WriteU8(ccfs0); // CCFS 0
130  start.WriteU8(ccfs1); // CCFS 1
131  if (disabledSubchBm.has_value())
132  {
133  start.WriteU16(disabledSubchBm.value());
134  }
135 }
136 
137 uint16_t
139 {
140  auto i = start;
141  uint16_t count = 0;
142  auto controlSubfield = i.ReadU8();
143  count++;
144  control.channelWidth = controlSubfield & 0x7;
145  ccfs0 = i.ReadU8();
146  count++;
147  ccfs1 = i.ReadU8();
148  count++;
150  "Incorrect EHT Operation Info deserialize");
151  if (!disabledSubchBmPresent)
152  {
153  return count;
154  }
155  disabledSubchBm = i.ReadU16();
156  count += 2;
158  "Incorrect EHT Operation Info deserialize");
159  return count;
160 }
161 
163 {
166 }
167 
170 {
171  return IE_EXTENSION;
172 }
173 
176 {
177  return IE_EXT_EHT_OPERATION;
178 }
179 
180 uint16_t
182 {
183  // IEEE 802.11be D2.0 9.4.2.311
184  auto ret =
186  if (!m_params.opInfoPresent)
187  {
188  return ret;
189  }
192  {
193  return ret;
194  }
196 }
197 
198 void
199 EhtOperation::SetMaxRxNss(uint8_t maxNss, uint8_t mcsStart, uint8_t mcsEnd)
200 {
201  NS_ASSERT(mcsStart <= mcsEnd);
202  NS_ASSERT((mcsStart >= 0) && (mcsEnd <= WIFI_EHT_MAX_MCS_INDEX));
203  NS_ASSERT((maxNss >= 1) && (maxNss <= WIFI_EHT_MAX_NSS_CONFIGURABLE));
204  SetMaxNss(m_mcsNssSet.maxRxNss, maxNss, mcsStart, mcsEnd);
205 }
206 
207 void
208 EhtOperation::SetMaxTxNss(uint8_t maxNss, uint8_t mcsStart, uint8_t mcsEnd)
209 {
210  NS_ASSERT(mcsStart <= mcsEnd);
211  NS_ASSERT((mcsStart >= 0) && (mcsEnd <= WIFI_EHT_MAX_MCS_INDEX));
212  NS_ASSERT((maxNss >= 1) && (maxNss <= WIFI_EHT_MAX_NSS_CONFIGURABLE));
213  SetMaxNss(m_mcsNssSet.maxTxNss, maxNss, mcsStart, mcsEnd);
214 }
215 
216 void
218 {
222  "Incorrect setting of EHT Operation Information Present bit");
223 
224  if (!m_params.opInfoPresent)
225  { // EHT Operation Information Present not set
226  return;
227  }
228 
229  auto disabledSubchBmPresent = m_params.disabledSubchBmPresent > 0;
230  NS_ASSERT_MSG(disabledSubchBmPresent == m_opInfo->disabledSubchBm.has_value(),
231  "Incorrect setting of Disabled Subchannel Bitmap Present bit");
232  m_opInfo->Serialize(start);
233 }
234 
235 uint16_t
237 {
238  auto i = start;
239  i.Next(m_params.Deserialize(i));
240  i.Next(m_mcsNssSet.Deserialize(i));
241  uint16_t count = i.GetDistanceFrom(start);
242 
243  if (!m_params.opInfoPresent)
244  {
245  NS_ASSERT_MSG(count == length, "Unexpected EHT Operation size");
246  }
247 
248  if (m_params.opInfoPresent > 0)
249  {
250  auto disabledSubchBmPresent = m_params.disabledSubchBmPresent > 0;
251  m_opInfo = EhtOpInfo();
252  i.Next(m_opInfo->Deserialize(i, disabledSubchBmPresent));
253  count = i.GetDistanceFrom(start);
254  }
255 
256  NS_ABORT_MSG_IF(count != length,
257  "EHT Operation Length (" << +length
258  << ") differs "
259  "from actual number of bytes read ("
260  << +count << ")");
261  return length;
262 }
263 
264 std::ostream&
265 operator<<(std::ostream& os, const EhtOperation& ehtOperation)
266 {
267  os << +ehtOperation.m_params.opInfoPresent << "|"
268  << +ehtOperation.m_params.disabledSubchBmPresent << "|"
269  << +ehtOperation.m_params.defaultPeDur << "|" << +ehtOperation.m_params.grpBuIndLimit << "|"
270  << +ehtOperation.m_params.grpBuExp << "|[";
271  for (const auto& maxRxNss : ehtOperation.m_mcsNssSet.maxRxNss)
272  {
273  os << +maxRxNss << "|";
274  }
275  os << "]|[";
276  for (const auto& maxTxNss : ehtOperation.m_mcsNssSet.maxTxNss)
277  {
278  os << +maxTxNss << "|";
279  }
280  os << "]";
281  if (ehtOperation.m_opInfo.has_value())
282  {
283  os << "|" << +ehtOperation.m_opInfo->control.channelWidth << "|"
284  << +ehtOperation.m_opInfo->ccfs0 << "|" << +ehtOperation.m_opInfo->ccfs1;
285  if (ehtOperation.m_opInfo->disabledSubchBm.has_value())
286  {
287  os << "|" << ehtOperation.m_opInfo->disabledSubchBm.value();
288  }
289  }
290  return os;
291 }
292 
293 } // namespace ns3
iterator in a Buffer instance
Definition: buffer.h:100
EHT Operation Information Element.
Definition: eht-operation.h:67
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.
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:37
constexpr uint16_t WIFI_EHT_DISABLED_SUBCH_BM_SIZE_B
IEEE 802.11be D2.0 Figure 9-1002c.
Definition: eht-operation.h:39
constexpr uint8_t WIFI_DEFAULT_EHT_MAX_NSS
Default max Tx/Rx NSS.
Definition: eht-operation.h:43
constexpr uint8_t WIFI_EHT_MAX_MCS_INDEX
IEEE 802.11be D2.0 Figure 9-1002ai.
Definition: eht-operation.h:33
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:41
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:45
constexpr uint16_t WIFI_EHT_OP_PARAMS_SIZE_B
IEEE 802.11be D2.0 Figure 9-1002b.
Definition: eht-operation.h:35
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:129
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:80
void Serialize(Buffer::Iterator &start) const
Serialize the EHT Operation Parameters subfield.
uint8_t grpBuExp
Group Addressed BU Indication Exponent.
Definition: eht-operation.h:84
uint16_t Deserialize(Buffer::Iterator start)
Deserialize the EHT Operation Parameters subfield.
uint8_t opInfoPresent
EHT Operation Information Present.
Definition: eht-operation.h:76
uint8_t disabledSubchBmPresent
Disabled Subchannel Bitmap Present.
Definition: eht-operation.h:78
uint8_t grpBuIndLimit
Group Addressed BU Indication Limit.
Definition: eht-operation.h:82
#define IE_EXTENSION
#define IE_EXT_EHT_OPERATION