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 
374 bool
376 {
378 }
379 
380 bool
382 {
383  return (m_preamble == WIFI_PREAMBLE_HE_TB);
384 }
385 
387 WifiTxVector::GetRu (uint16_t staId) const
388 {
389  NS_ABORT_MSG_IF (!IsMu (), "RU only available for MU");
390  NS_ABORT_MSG_IF (staId > 2048, "STA-ID should be correctly set for HE MU");
391  return m_muUserInfos.at (staId).ru;
392 }
393 
394 void
395 WifiTxVector::SetRu (HeRu::RuSpec ru, uint16_t staId)
396 {
397  NS_ABORT_MSG_IF (!IsMu (), "RU only available for MU");
398  NS_ABORT_MSG_IF (staId > 2048, "STA-ID should be correctly set for HE MU");
399  m_muUserInfos[staId].ru = ru;
400 }
401 
403 WifiTxVector::GetHeMuUserInfo (uint16_t staId) const
404 {
405  NS_ABORT_MSG_IF (!IsMu (), "HE MU user info only available for MU");
406  return m_muUserInfos.at (staId);
407 }
408 
409 void
410 WifiTxVector::SetHeMuUserInfo (uint16_t staId, HeMuUserInfo userInfo)
411 {
412  NS_ABORT_MSG_IF (!IsMu (), "HE MU user info only available for MU");
413  NS_ABORT_MSG_IF (staId > 2048, "STA-ID should be correctly set for HE MU");
414  NS_ABORT_MSG_IF (userInfo.mcs.GetModulationClass () != WIFI_MOD_CLASS_HE, "Only HE modes authorized for HE MU");
415  m_muUserInfos[staId] = userInfo;
416  m_modeInitialized = true;
417 }
418 
421 {
422  NS_ABORT_MSG_IF (!IsMu (), "HE MU user info map only available for MU");
423  return m_muUserInfos;
424 }
425 
428 {
429  NS_ABORT_MSG_IF (!IsMu (), "HE MU user info map only available for MU");
430  return m_muUserInfos;
431 }
432 
433 std::pair<std::size_t, std::size_t>
435 {
436  NS_ABORT_MSG_IF (m_preamble != WIFI_PREAMBLE_HE_MU, "HE-SIG-B content channels only available for HE MU");
437  //MU-MIMO is not handled for now, i.e. one station per RU
438 
439  if (m_channelWidth == 20)
440  {
441  return std::make_pair (m_muUserInfos.size (), 0); //all RUs are in HE-SIG-B content channel 1
442  }
443 
444  HeRu::SubcarrierGroup toneRangesContentChannel1, toneRangesContentChannel2;
445  // See section 27.3.10.8.3 of IEEE 802.11ax draft 4.0 for tone ranges per HE-SIG-B content channel
446  switch (m_channelWidth)
447  {
448  case 40:
449  toneRangesContentChannel1.push_back (std::make_pair (-244, -3));
450  toneRangesContentChannel2.push_back (std::make_pair (3, 244));
451  break;
452  case 80:
453  toneRangesContentChannel1.push_back (std::make_pair (-500, -259));
454  toneRangesContentChannel2.push_back (std::make_pair (-258, -17));
455  toneRangesContentChannel1.push_back (std::make_pair (-16, -4)); //first part of center carrier (in HE-SIG-B content channel 1)
456  toneRangesContentChannel1.push_back (std::make_pair (4, 16)); //second part of center carrier (in HE-SIG-B content channel 1)
457  toneRangesContentChannel1.push_back (std::make_pair (17, 258));
458  toneRangesContentChannel2.push_back (std::make_pair (259, 500));
459  break;
460  case 160:
461  toneRangesContentChannel1.push_back (std::make_pair (-1012, -771));
462  toneRangesContentChannel2.push_back (std::make_pair (-770, -529));
463  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)
464  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)
465  toneRangesContentChannel1.push_back (std::make_pair (-495, -254));
466  toneRangesContentChannel2.push_back (std::make_pair (-253, -12));
467  toneRangesContentChannel1.push_back (std::make_pair (12, 253));
468  toneRangesContentChannel2.push_back (std::make_pair (254, 495));
469  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)
470  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)
471  toneRangesContentChannel1.push_back (std::make_pair (529, 770));
472  toneRangesContentChannel2.push_back (std::make_pair (771, 1012));
473  break;
474  default:
475  NS_ABORT_MSG ("Unknown channel width: " << m_channelWidth);
476  }
477 
478  std::size_t numRusContentChannel1 = 0;
479  std::size_t numRusContentChannel2 = 0;
480  for (auto & userInfo : m_muUserInfos)
481  {
482  HeRu::RuSpec ru = userInfo.second.ru;
483  if (!ru.IsPhyIndexSet ())
484  {
485  // this method can be called when calculating the TX duration of a frame
486  // and at that time the RU PHY index may have not been set yet
487  ru.SetPhyIndex (m_channelWidth, 0);
488  }
489  if (HeRu::DoesOverlap (m_channelWidth, ru, toneRangesContentChannel1))
490  {
491  numRusContentChannel1++;
492  }
493  if (HeRu::DoesOverlap (m_channelWidth, ru, toneRangesContentChannel2))
494  {
495  numRusContentChannel2++;
496  }
497  }
498  return std::make_pair (numRusContentChannel1, numRusContentChannel2);
499 }
500 
501 std::ostream & operator << ( std::ostream &os, const WifiTxVector &v)
502 {
503  if (!v.IsValid ())
504  {
505  os << "TXVECTOR not valid";
506  return os;
507  }
508  os << "txpwrlvl: " << +v.GetTxPowerLevel ()
509  << " preamble: " << v.GetPreambleType ()
510  << " channel width: " << v.GetChannelWidth ()
511  << " GI: " << v.GetGuardInterval ()
512  << " NTx: " << +v.GetNTx ()
513  << " Ness: " << +v.GetNess ()
514  << " MPDU aggregation: " << v.IsAggregation ()
515  << " STBC: " << v.IsStbc ()
516  << " FEC coding: " << (v.IsLdpc () ? "LDPC" : "BCC");
518  {
519  os << " BSS color: " << +v.GetBssColor ();
520  }
522  {
523  os << " Length: " << v.GetLength ();
524  }
525  if (v.IsMu ())
526  {
528  os << " num User Infos: " << userInfoMap.size ();
529  for (auto & ui : userInfoMap)
530  {
531  os << ", {STA-ID: " << ui.first
532  << ", " << ui.second.ru
533  << ", MCS: " << ui.second.mcs
534  << ", Nss: " << +ui.second.nss << "}";
535  }
536  }
537  else
538  {
539  os << " mode: " << v.GetMode ()
540  << " Nss: " << +v.GetNss ();
541  }
542  return os;
543 }
544 
545 } //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
RU Specification.
Definition: he-ru.h:67
#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:47
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:352
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
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:137
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.
void SetGuardInterval(uint16_t guardInterval)
Sets the guard interval duration (in nanoseconds)
void SetPhyIndex(uint16_t bw, uint8_t p20Index)
Set the RU PHY index.
Definition: he-ru.cc:188
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:159
std::string GetUniqueName(void) const
Definition: wifi-mode.cc:122
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.
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.
bool IsDlMu(void) const
Return true if this TX vector is used for a downlink multi-user transmission.
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.
bool IsUlMu(void) const
Return true if this TX vector is used for an uplink multi-user transmission.
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 a const reference to the map HE MU user-specific transmission information indexed by STA-ID...
bool IsPhyIndexSet(void) const
Return true if the RU PHY index has been set, false otherwise.
Definition: he-ru.cc:206
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