A Discrete-Event Network Simulator
API
wifi-tx-vector.cc
Go to the documentation of this file.
1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2010 CTTC
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: Nicola Baldo <nbaldo@cttc.es>
19  * Ghada Badawy <gbadawy@gmail.com>
20  */
21 
22 #include "wifi-tx-vector.h"
23 #include "ns3/abort.h"
24 
25 namespace ns3 {
26 
28  : m_preamble (WIFI_PREAMBLE_LONG),
29  m_channelWidth (20),
30  m_guardInterval (800),
31  m_nTx (1),
32  m_nss (1),
33  m_ness (0),
34  m_aggregation (false),
35  m_stbc (false),
36  m_ldpc (false),
37  m_bssColor (0),
38  m_length (0),
39  m_modeInitialized (false)
40 {
41 }
42 
44  uint8_t powerLevel,
45  WifiPreamble preamble,
46  uint16_t guardInterval,
47  uint8_t nTx,
48  uint8_t nss,
49  uint8_t ness,
50  uint16_t channelWidth,
51  bool aggregation,
52  bool stbc,
53  bool ldpc,
54  uint8_t bssColor,
55  uint16_t length)
56  : m_mode (mode),
57  m_txPowerLevel (powerLevel),
58  m_preamble (preamble),
59  m_channelWidth (channelWidth),
60  m_guardInterval (guardInterval),
61  m_nTx (nTx),
62  m_nss (nss),
63  m_ness (ness),
64  m_aggregation (aggregation),
65  m_stbc (stbc),
66  m_ldpc (ldpc),
67  m_bssColor (bssColor),
68  m_length (length),
69  m_modeInitialized (true)
70 {
71 }
72 
74  : m_mode (txVector.m_mode),
75  m_txPowerLevel (txVector.m_txPowerLevel),
76  m_preamble (txVector.m_preamble),
77  m_channelWidth (txVector.m_channelWidth),
78  m_guardInterval (txVector.m_guardInterval),
79  m_nTx (txVector.m_nTx),
80  m_nss (txVector.m_nss),
81  m_ness (txVector.m_ness),
82  m_aggregation (txVector.m_aggregation),
83  m_stbc (txVector.m_stbc),
84  m_ldpc (txVector.m_ldpc),
85  m_bssColor (txVector.m_bssColor),
86  m_length (txVector.m_length),
87  m_modeInitialized (txVector.m_modeInitialized)
88 {
89  m_muUserInfos.clear ();
90  if (!txVector.m_muUserInfos.empty ()) //avoids crashing for loop
91  {
92  for (auto & info : txVector.m_muUserInfos)
93  {
94  m_muUserInfos.insert (std::make_pair (info.first, info.second));
95  }
96  }
97 }
98 
100 {
101  m_muUserInfos.clear ();
102 }
103 
104 bool
106 {
107  return m_modeInitialized;
108 }
109 
110 WifiMode
111 WifiTxVector::GetMode (uint16_t staId) const
112 {
113  if (!m_modeInitialized)
114  {
115  NS_FATAL_ERROR ("WifiTxVector mode must be set before using");
116  }
117  if (IsMu ())
118  {
119  NS_ABORT_MSG_IF (staId > 2048, "STA-ID should be correctly set for HE MU (" << staId << ")");
120  NS_ASSERT (m_muUserInfos.find (staId) != m_muUserInfos.end ());
121  return m_muUserInfos.at (staId).mcs;
122  }
123  return m_mode;
124 }
125 
128 {
129  NS_ABORT_MSG_IF (!m_modeInitialized, "WifiTxVector mode must be set before using");
130 
131  if (IsMu ())
132  {
133  NS_ASSERT (!m_muUserInfos.empty ());
134  // all the modes belong to the same modulation class
135  return m_muUserInfos.begin ()->second.mcs.GetModulationClass ();
136  }
137  return m_mode.GetModulationClass ();
138 }
139 
140 uint8_t
142 {
143  return m_txPowerLevel;
144 }
145 
148 {
149  return m_preamble;
150 }
151 
152 uint16_t
154 {
155  return m_channelWidth;
156 }
157 
158 uint16_t
160 {
161  return m_guardInterval;
162 }
163 
164 uint8_t
166 {
167  return m_nTx;
168 }
169 
170 uint8_t
171 WifiTxVector::GetNss (uint16_t staId) const
172 {
173  if (IsMu ())
174  {
175  NS_ABORT_MSG_IF (staId > 2048, "STA-ID should be correctly set for HE MU (" << staId << ")");
176  NS_ASSERT (m_muUserInfos.find (staId) != m_muUserInfos.end ());
177  return m_muUserInfos.at (staId).nss;
178  }
179  return m_nss;
180 }
181 
182 uint8_t
184 {
185  uint8_t nss = 0;
186  if (IsMu ())
187  {
188  for (const auto & info : m_muUserInfos)
189  {
190  nss = (nss < info.second.nss) ? info.second.nss : nss;
191  }
192  }
193  else
194  {
195  nss = m_nss;
196  }
197  return nss;
198 }
199 
200 uint8_t
202 {
203  return m_ness;
204 }
205 
206 bool
208 {
209  return m_aggregation;
210 }
211 
212 bool
214 {
215  return m_stbc;
216 }
217 
218 bool
220 {
221  return m_ldpc;
222 }
223 
224 void
226 {
227  m_mode = mode;
228  m_modeInitialized = true;
229 }
230 
231 void
232 WifiTxVector::SetMode (WifiMode mode, uint16_t staId)
233 {
234  NS_ABORT_MSG_IF (!IsMu (), "Not an HE MU transmission");
235  NS_ABORT_MSG_IF (staId > 2048, "STA-ID should be correctly set for HE MU");
236  m_muUserInfos[staId].mcs = mode;
237  m_modeInitialized = true;
238 }
239 
240 void
241 WifiTxVector::SetTxPowerLevel (uint8_t powerlevel)
242 {
243  m_txPowerLevel = powerlevel;
244 }
245 
246 void
248 {
249  m_preamble = preamble;
250 }
251 
252 void
253 WifiTxVector::SetChannelWidth (uint16_t channelWidth)
254 {
255  m_channelWidth = channelWidth;
256 }
257 
258 void
259 WifiTxVector::SetGuardInterval (uint16_t guardInterval)
260 {
261  m_guardInterval = guardInterval;
262 }
263 
264 void
265 WifiTxVector::SetNTx (uint8_t nTx)
266 {
267  m_nTx = nTx;
268 }
269 
270 void
271 WifiTxVector::SetNss (uint8_t nss)
272 {
273  m_nss = nss;
274 }
275 
276 void
277 WifiTxVector::SetNss (uint8_t nss, uint16_t staId)
278 {
279  NS_ABORT_MSG_IF (!IsMu (), "Not an HE MU transmission");
280  NS_ABORT_MSG_IF (staId > 2048, "STA-ID should be correctly set for HE MU");
281  m_muUserInfos[staId].nss = nss;
282 }
283 
284 void
285 WifiTxVector::SetNess (uint8_t ness)
286 {
287  m_ness = ness;
288 }
289 
290 void
292 {
293  m_aggregation = aggregation;
294 }
295 
296 void
298 {
299  m_stbc = stbc;
300 }
301 
302 void
304 {
305  m_ldpc = ldpc;
306 }
307 
308 void
310 {
311  m_bssColor = color;
312 }
313 
314 uint8_t
316 {
317  return m_bssColor;
318 }
319 
320 void
321 WifiTxVector::SetLength (uint16_t length)
322 {
323  m_length = length;
324 }
325 
326 uint16_t
328 {
329  return m_length;
330 }
331 
332 bool
334 {
335  if (!GetModeInitialized ())
336  {
337  return false;
338  }
339  std::string modeName = m_mode.GetUniqueName ();
340  if (m_channelWidth == 20)
341  {
342  if (m_nss != 3 && m_nss != 6)
343  {
344  return (modeName != "VhtMcs9");
345  }
346  }
347  else if (m_channelWidth == 80)
348  {
349  if (m_nss == 3 || m_nss == 7)
350  {
351  return (modeName != "VhtMcs6");
352  }
353  else if (m_nss == 6)
354  {
355  return (modeName != "VhtMcs9");
356  }
357  }
358  else if (m_channelWidth == 160)
359  {
360  if (m_nss == 3)
361  {
362  return (modeName != "VhtMcs9");
363  }
364  }
365  return true;
366 }
367 
368 bool
369 WifiTxVector::IsMu (void) const
370 {
372 }
373 
375 WifiTxVector::GetRu (uint16_t staId) const
376 {
377  NS_ABORT_MSG_IF (!IsMu (), "RU only available for MU");
378  NS_ABORT_MSG_IF (staId > 2048, "STA-ID should be correctly set for HE MU");
379  return m_muUserInfos.at (staId).ru;
380 }
381 
382 void
383 WifiTxVector::SetRu (HeRu::RuSpec ru, uint16_t staId)
384 {
385  NS_ABORT_MSG_IF (!IsMu (), "RU only available for MU");
386  NS_ABORT_MSG_IF (staId > 2048, "STA-ID should be correctly set for HE MU");
387  m_muUserInfos[staId].ru = ru;
388 }
389 
391 WifiTxVector::GetHeMuUserInfo (uint16_t staId) const
392 {
393  NS_ABORT_MSG_IF (!IsMu (), "HE MU user info only available for MU");
394  return m_muUserInfos.at (staId);
395 }
396 
397 void
398 WifiTxVector::SetHeMuUserInfo (uint16_t staId, HeMuUserInfo userInfo)
399 {
400  NS_ABORT_MSG_IF (!IsMu (), "HE MU user info only available for MU");
401  NS_ABORT_MSG_IF (staId > 2048, "STA-ID should be correctly set for HE MU");
402  NS_ABORT_MSG_IF (userInfo.mcs.GetModulationClass () != WIFI_MOD_CLASS_HE, "Only HE modes authorized for HE MU");
403  m_muUserInfos[staId] = userInfo;
404  m_modeInitialized = true;
405 }
406 
409 {
410  NS_ABORT_MSG_IF (!IsMu (), "HE MU user info map only available for MU");
411  return m_muUserInfos;
412 }
413 
414 std::pair<std::size_t, std::size_t>
416 {
417  NS_ABORT_MSG_IF (m_preamble != WIFI_PREAMBLE_HE_MU, "HE-SIG-B content channels only available for HE MU");
418  //MU-MIMO is not handled for now, i.e. one station per RU
419 
420  if (m_channelWidth == 20)
421  {
422  return std::make_pair (m_muUserInfos.size (), 0); //all RUs are in HE-SIG-B content channel 1
423  }
424 
425  HeRu::SubcarrierGroup toneRangesContentChannel1, toneRangesContentChannel2;
426  // See section 27.3.10.8.3 of IEEE 802.11ax draft 4.0 for tone ranges per HE-SIG-B content channel
427  switch (m_channelWidth)
428  {
429  case 40:
430  toneRangesContentChannel1.push_back (std::make_pair (-244, -3));
431  toneRangesContentChannel2.push_back (std::make_pair (3, 244));
432  break;
433  case 80:
434  toneRangesContentChannel1.push_back (std::make_pair (-500, -259));
435  toneRangesContentChannel2.push_back (std::make_pair (-258, -17));
436  toneRangesContentChannel1.push_back (std::make_pair (-16, -4)); //first part of center carrier (in HE-SIG-B content channel 1)
437  toneRangesContentChannel1.push_back (std::make_pair (4, 16)); //second part of center carrier (in HE-SIG-B content channel 1)
438  toneRangesContentChannel1.push_back (std::make_pair (17, 258));
439  toneRangesContentChannel2.push_back (std::make_pair (259, 500));
440  break;
441  case 160:
442  toneRangesContentChannel1.push_back (std::make_pair (-1012, -771));
443  toneRangesContentChannel2.push_back (std::make_pair (-770, -529));
444  toneRangesContentChannel1.push_back (std::make_pair (-528, -516)); //first part of center carrier of lower 80 MHz band (in HE-SIG-B content channel 1)
445  toneRangesContentChannel1.push_back (std::make_pair (-508, -496)); //second part of center carrier of lower 80 MHz band (in HE-SIG-B content channel 1)
446  toneRangesContentChannel1.push_back (std::make_pair (-495, -254));
447  toneRangesContentChannel2.push_back (std::make_pair (-253, -12));
448  toneRangesContentChannel1.push_back (std::make_pair (12, 253));
449  toneRangesContentChannel2.push_back (std::make_pair (254, 495));
450  toneRangesContentChannel2.push_back (std::make_pair (496, 508)); //first part of center carrier of upper 80 MHz band (in HE-SIG-B content channel 2)
451  toneRangesContentChannel2.push_back (std::make_pair (516, 528)); //second part of center carrier of upper 80 MHz band (in HE-SIG-B content channel 2)
452  toneRangesContentChannel1.push_back (std::make_pair (529, 770));
453  toneRangesContentChannel2.push_back (std::make_pair (771, 1012));
454  break;
455  default:
456  NS_ABORT_MSG ("Unknown channel width: " << m_channelWidth);
457  }
458 
459  std::size_t numRusContentChannel1 = 0;
460  std::size_t numRusContentChannel2 = 0;
461  for (auto & userInfo : m_muUserInfos)
462  {
463  HeRu::RuSpec ru = userInfo.second.ru;
464  if (HeRu::DoesOverlap (m_channelWidth, ru, toneRangesContentChannel1))
465  {
466  numRusContentChannel1++;
467  }
468  if (HeRu::DoesOverlap (m_channelWidth, ru, toneRangesContentChannel2))
469  {
470  numRusContentChannel2++;
471  }
472  }
473  return std::make_pair (numRusContentChannel1, numRusContentChannel2);
474 }
475 
476 std::ostream & operator << ( std::ostream &os, const WifiTxVector &v)
477 {
478  if (!v.IsValid ())
479  {
480  os << "TXVECTOR not valid";
481  return os;
482  }
483  os << "txpwrlvl: " << +v.GetTxPowerLevel ()
484  << " preamble: " << v.GetPreambleType ()
485  << " channel width: " << v.GetChannelWidth ()
486  << " GI: " << v.GetGuardInterval ()
487  << " NTx: " << +v.GetNTx ()
488  << " Ness: " << +v.GetNess ()
489  << " MPDU aggregation: " << v.IsAggregation ()
490  << " STBC: " << v.IsStbc ()
491  << " FEC coding: " << (v.IsLdpc () ? "LDPC" : "BCC");
493  {
494  os << " BSS color: " << +v.GetBssColor ();
495  }
497  {
498  os << " Length: " << v.GetLength ();
499  }
500  if (v.IsMu ())
501  {
503  os << " num User Infos: " << userInfoMap.size ();
504  for (auto & ui : userInfoMap)
505  {
506  os << ", {STA-ID: " << ui.first
507  << ", " << ui.second.ru
508  << ", MCS: " << ui.second.mcs
509  << ", Nss: " << +ui.second.nss << "}";
510  }
511  }
512  else
513  {
514  os << " mode: " << v.GetMode ()
515  << " Nss: " << +v.GetNss ();
516  }
517  return os;
518 }
519 
520 } //namespace ns3
uint16_t m_channelWidth
channel width in MHz
WifiModulationClass
This enumeration defines the modulation classes per (Table 10-6 "Modulation classes"; IEEE 802...
uint8_t GetNssMax(void) const
bool IsAggregation(void) const
Checks whether the PSDU contains A-MPDU.
uint8_t m_nTx
number of TX antennas
std::vector< SubcarrierRange > SubcarrierGroup
a vector of subcarrier ranges defining a subcarrier group
Definition: he-ru.h:56
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:50
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
void SetChannelWidth(uint16_t channelWidth)
Sets the selected channelWidth (in MHz)
bool m_ldpc
LDPC FEC coding if true, BCC otherwise.
void SetBssColor(uint8_t color)
Set the BSS color.
std::map< uint16_t, HeMuUserInfo > HeMuUserInfoMap
map of HE MU specific user info paramters indexed by STA-ID
WifiModulationClass GetModulationClass(void) const
Get the modulation class specified by this TXVECTOR.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
void SetStbc(bool stbc)
Sets if STBC is being used.
bool IsStbc(void) const
Check if STBC is used or not.
bool GetModeInitialized(void) const
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
uint8_t GetNess(void) const
bool IsMu(void) const
Return true if this TX vector is used for a multi-user transmission.
uint16_t GetGuardInterval(void) const
uint8_t GetNss(uint16_t staId=SU_STA_ID) const
If this TX vector is associated with an SU PPDU, return the number of spatial streams.
void SetLdpc(bool ldpc)
Sets if LDPC FEC coding is being used.
HeMuUserInfo GetHeMuUserInfo(uint16_t staId) const
Get the HE MU user-specific transmission information for the given STA-ID.
represent a single transmission modeA WifiMode is implemented by a single integer which is used to lo...
Definition: wifi-mode.h:68
static bool DoesOverlap(uint16_t bw, RuSpec ru, const std::vector< RuSpec > &v)
Check whether the given RU overlaps with the given set of RUs.
Definition: he-ru.cc:211
WifiMode mcs
MCS.
bool IsLdpc(void) const
Check if LDPC FEC coding is used or not.
uint8_t m_nss
number of spatial streams
HeRu::RuSpec GetRu(uint16_t staId) const
Get the RU specification for the STA-ID.
WifiMode GetMode(uint16_t staId=SU_STA_ID) const
If this TX vector is associated with an SU PPDU, return the selected payload transmission mode...
WifiPreamble GetPreambleType(void) const
WifiPreamble
The type of preamble to be used by an IEEE 802.11 transmission.
uint8_t m_bssColor
BSS color.
bool IsValid(void) const
The standard disallows certain combinations of WifiMode, number of spatial streams, and channel widths.
RU Specification.
Definition: he-ru.h:64
void SetGuardInterval(uint16_t guardInterval)
Sets the guard interval duration (in nanoseconds)
uint16_t m_guardInterval
guard interval duration in nanoseconds
uint8_t GetNTx(void) const
std::pair< std::size_t, std::size_t > GetNumRusPerHeSigBContentChannel(void) const
Get the number of RUs per HE-SIG-B content channel.
WifiModulationClass GetModulationClass() const
Definition: wifi-mode.cc:147
std::string GetUniqueName(void) const
Definition: wifi-mode.cc:110
void SetHeMuUserInfo(uint16_t staId, HeMuUserInfo userInfo)
Set the HE MU user-specific transmission information for the given STA-ID.
void SetNss(uint8_t nss)
Sets the number of Nss.
bool m_modeInitialized
Internal initialization flag.
std::ostream & operator<<(std::ostream &os, const Angles &a)
print a struct Angles to output
Definition: angles.cc:42
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void SetAggregation(bool aggregation)
Sets if PSDU contains A-MPDU.
void SetPreambleType(WifiPreamble preamble)
Sets the preamble type.
void SetTxPowerLevel(uint8_t powerlevel)
Sets the selected transmission power level.
void SetNTx(uint8_t nTx)
Sets the number of TX antennas.
bool m_aggregation
Flag whether the PSDU contains A-MPDU.
bool m_stbc
STBC used or not.
void SetMode(WifiMode mode)
Sets the selected payload transmission mode.
uint16_t m_length
LENGTH field of the L-SIG.
uint16_t GetLength(void) const
Get the LENGTH field of the L-SIG.
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
uint8_t GetBssColor(void) const
Get the BSS color.
void SetNess(uint8_t ness)
Sets the Ness number.
HeMuUserInfoMap m_muUserInfos
HE MU specific per-user information indexed by station ID (STA-ID) corresponding to the 11 LSBs of th...
uint8_t GetTxPowerLevel(void) const
uint16_t GetChannelWidth(void) const
uint8_t m_ness
number of spatial streams in beamforming
void SetLength(uint16_t length)
Set the LENGTH field of the L-SIG.
const HeMuUserInfoMap & GetHeMuUserInfoMap(void) const
Get the map HE MU user-specific transmission information indexed by STA-ID.
void SetRu(HeRu::RuSpec ru, uint16_t staId)
Set the RU specification for the STA-ID.
HE MU specific user transmission parameters.
uint8_t m_txPowerLevel
The TXPWR_LEVEL parameter in Table 15-4.
WifiMode m_mode
The DATARATE parameter in Table 15-4.
WifiPreamble m_preamble
preamble