A Discrete-Event Network Simulator
API
he-ru.cc
Go to the documentation of this file.
1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2018
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: Stefano Avallone <stavallo@unina.it>
19  */
20 
21 #include "he-ru.h"
22 #include "ns3/abort.h"
23 
24 namespace ns3 {
25 
27 {
28  // RUs in a 20 MHz HE PPDU (Table 28-6)
29  { {20, HeRu::RU_26_TONE}, { /* 1 */ {{-121, -96}},
30  /* 2 */ {{-95, -70}},
31  /* 3 */ {{-68, -43}},
32  /* 4 */ {{-42, -17}},
33  /* 5 */ {{-16, -4}, {4, 16}},
34  /* 6 */ {{17, 42}},
35  /* 7 */ {{43, 68}},
36  /* 8 */ {{70, 95}},
37  /* 9 */ {{96, 121}} } },
38  { {20, HeRu::RU_52_TONE}, { /* 1 */ {{-121, -70}},
39  /* 2 */ {{-68, -17}},
40  /* 3 */ {{17, 68}},
41  /* 4 */ {{70, 121}} } },
42  { {20, HeRu::RU_106_TONE}, { /* 1 */ {{-122, -17}},
43  /* 2 */ {{17, 122}} } },
44  { {20, HeRu::RU_242_TONE}, { /* 1 */ {{-122, -2}, {2, 122}} } },
45  // RUs in a 40 MHz HE PPDU (Table 28-7)
46  { {40, HeRu::RU_26_TONE}, { /* 1 */ {{-243, -218}},
47  /* 2 */ {{-217, -192}},
48  /* 3 */ {{-189, -164}},
49  /* 4 */ {{-163, -138}},
50  /* 5 */ {{-136, -111}},
51  /* 6 */ {{-109, -84}},
52  /* 7 */ {{-83, -58}},
53  /* 8 */ {{-55, -30}},
54  /* 9 */ {{-29, -4}},
55  /* 10 */ {{4, 29}},
56  /* 11 */ {{30, 55}},
57  /* 12 */ {{58, 83}},
58  /* 13 */ {{84, 109}},
59  /* 14 */ {{111, 136}},
60  /* 15 */ {{138, 163}},
61  /* 16 */ {{164, 189}},
62  /* 17 */ {{192, 217}},
63  /* 18 */ {{218, 243}} } },
64  { {40, HeRu::RU_52_TONE}, { /* 1 */ {{-243, -192}},
65  /* 2 */ {{-189, -138}},
66  /* 3 */ {{-109, -58}},
67  /* 4 */ {{-55, -4}},
68  /* 5 */ {{4, 55}},
69  /* 6 */ {{58, 109}},
70  /* 7 */ {{138, 189}},
71  /* 8 */ {{192, 243}} } },
72  { {40, HeRu::RU_106_TONE}, { /* 1 */ {{-243, -138}},
73  /* 2 */ {{-109, -4}},
74  /* 3 */ {{4, 109}},
75  /* 4 */ {{138, 243}} } },
76  { {40, HeRu::RU_242_TONE}, { /* 1 */ {{-244, -3}},
77  /* 2 */ {{3, 244}} } },
78  { {40, HeRu::RU_484_TONE}, { /* 1 */ {{-244, -3}, {3, 244}} } },
79  // RUs in an 80 MHz HE PPDU (Table 28-8)
80  { {80, HeRu::RU_26_TONE}, { /* 1 */ {{-499, -474}},
81  /* 2 */ {{-473, -448}},
82  /* 3 */ {{-445, -420}},
83  /* 4 */ {{-419, -394}},
84  /* 5 */ {{-392, -367}},
85  /* 6 */ {{-365, -340}},
86  /* 7 */ {{-339, -314}},
87  /* 8 */ {{-311, -286}},
88  /* 9 */ {{-285, -260}},
89  /* 10 */ {{-257, -232}},
90  /* 11 */ {{-231, -206}},
91  /* 12 */ {{-203, -178}},
92  /* 13 */ {{-177, -152}},
93  /* 14 */ {{-150, -125}},
94  /* 15 */ {{-123, -98}},
95  /* 16 */ {{-97, -72}},
96  /* 17 */ {{-69, -44}},
97  /* 18 */ {{-43, -18}},
98  /* 19 */ {{-16, -4}, {4, 16}},
99  /* 20 */ {{18, 43}},
100  /* 21 */ {{44, 69}},
101  /* 22 */ {{72, 97}},
102  /* 23 */ {{98, 123}},
103  /* 24 */ {{125, 150}},
104  /* 25 */ {{152, 177}},
105  /* 26 */ {{178, 203}},
106  /* 27 */ {{206, 231}},
107  /* 28 */ {{232, 257}},
108  /* 29 */ {{260, 285}},
109  /* 30 */ {{286, 311}},
110  /* 31 */ {{314, 339}},
111  /* 32 */ {{340, 365}},
112  /* 33 */ {{367, 392}},
113  /* 34 */ {{394, 419}},
114  /* 35 */ {{420, 445}},
115  /* 36 */ {{448, 473}},
116  /* 37 */ {{474, 499}} } },
117  { {80, HeRu::RU_52_TONE}, { /* 1 */ {{-499, -448}},
118  /* 2 */ {{-445, -394}},
119  /* 3 */ {{-365, -314}},
120  /* 4 */ {{-311, -260}},
121  /* 5 */ {{-257, -206}},
122  /* 6 */ {{-203, -152}},
123  /* 7 */ {{-123, -72}},
124  /* 8 */ {{-69, -18}},
125  /* 9 */ {{18, 69}},
126  /* 10 */ {{72, 123}},
127  /* 11 */ {{152, 203}},
128  /* 12 */ {{206, 257}},
129  /* 13 */ {{260, 311}},
130  /* 14 */ {{314, 365}},
131  /* 15 */ {{394, 445}},
132  /* 16 */ {{448, 499}} } },
133  { {80, HeRu::RU_106_TONE}, { /* 1 */ {{-499, -394}},
134  /* 2 */ {{-365, -260}},
135  /* 3 */ {{-257, -152}},
136  /* 4 */ {{-123, -18}},
137  /* 5 */ {{18, 123}},
138  /* 6 */ {{152, 257}},
139  /* 7 */ {{260, 365}},
140  /* 8 */ {{394, 499}} } },
141  { {80, HeRu::RU_242_TONE}, { /* 1 */ {{-500, -259}},
142  /* 2 */ {{-258, -17}},
143  /* 3 */ {{17, 258}},
144  /* 4 */ {{259, 500}} } },
145  { {80, HeRu::RU_484_TONE}, { /* 1 */ {{-500, -17}},
146  /* 2 */ {{17, 500}} } },
147  { {80, HeRu::RU_996_TONE}, { /* 1 */ {{-500, -3}, {3, 500}} } }
148 };
149 
150 
151 std::size_t
152 HeRu::GetNRus (uint8_t bw, RuType ruType)
153 {
154  if (bw == 160 && ruType == RU_2x996_TONE)
155  {
156  return 1;
157  }
158 
159  // if the bandwidth is 160MHz, search for the number of RUs available
160  // in 80MHz and double the result.
161  auto it = m_heRuSubcarrierGroups.find ({(bw == 160 ? 80 : bw), ruType});
162 
163  if (it == m_heRuSubcarrierGroups.end ())
164  {
165  return 0;
166  }
167 
168  return (bw == 160 ? 2 : 1) * it->second.size ();
169 }
170 
172 HeRu::GetSubcarrierGroup (uint8_t bw, RuType ruType, std::size_t index)
173 {
174  if (ruType == HeRu::RU_2x996_TONE) //handle special case of RU covering 160 MHz channel
175  {
176  NS_ABORT_MSG_IF (bw != 160, "2x996 tone RU can only be used on 160 MHz band");
177  return {{-1012, -3}, {3, 1012}};
178  }
179 
180  // Determine the shift to apply to tone indices for 160 MHz channel (i.e. -1012 to 1012), since
181  // m_heRuSubcarrierGroups contains indices for primary 80 MHz subchannel (i.e. from -500 to 500).
182  // The index is used to that aim.
183  std::size_t indexInPrimary80MHz = index;
184  std::size_t numRus = GetNRus (bw, ruType);
185  int16_t shift = (bw == 160) ? -512 : 0;
186  if (bw == 160 && index > (numRus / 2))
187  {
188  // The provided index is that of the secondary 80 MHz subchannel
189  indexInPrimary80MHz = index - (numRus / 2);
190  shift = 512;
191  }
192 
193  auto it = m_heRuSubcarrierGroups.find ({(bw == 160 ? 80 : bw), ruType});
194 
195  NS_ABORT_MSG_IF (it == m_heRuSubcarrierGroups.end (), "RU not found");
196  NS_ABORT_MSG_IF (!indexInPrimary80MHz || indexInPrimary80MHz > it->second.size (), "RU index not available");
197 
198  SubcarrierGroup group = it->second.at (indexInPrimary80MHz - 1);
199  if (bw == 160)
200  {
201  for (auto & range : group)
202  {
203  range.first += shift;
204  range.second += shift;
205  }
206  }
207  return group;
208 }
209 
210 #ifdef NOTYET
211 // Currently unused methods planned for ns-3.34; causing
212 // problems with API scanning (see issue #308)
213 bool
214 HeRu::DoesOverlap (uint8_t bw, RuSpec ru, const std::vector<RuSpec> &v)
215 {
216  // A 2x996-tone RU spans 160 MHz, hence it overlaps with any other RU
217  if (bw == 160 && ru.ruType == RU_2x996_TONE && !v.empty ())
218  {
219  return true;
220  }
221 
222  SubcarrierGroup groups = GetSubcarrierGroup (bw, ru.ruType, ru.index);
223  for (auto& p : v)
224  {
225  if (ru.primary80MHz != p.primary80MHz)
226  {
227  // the two RUs are located in distinct 80MHz bands
228  continue;
229  }
230  if (DoesOverlap (bw, p, groups))
231  {
232  return true;
233  }
234  }
235  return false;
236 }
237 
238 bool
239 HeRu::DoesOverlap (uint8_t bw, RuSpec ru, const SubcarrierGroup &toneRanges)
240 {
241  for (const auto & range : toneRanges)
242  {
243  if (bw == 160 && ru.ruType == RU_2x996_TONE)
244  {
245  return true;
246  }
247 
248  SubcarrierGroup rangesRu = GetSubcarrierGroup (bw, ru.ruType, ru.index);
249  for (auto& r : rangesRu)
250  {
251  if (range.second >= r.first && r.second >= range.first)
252  {
253  return true;
254  }
255  }
256  }
257  return false;
258 }
259 #endif
260 
261 std::ostream& operator<< (std::ostream& os, const HeRu::RuType &ruType)
262 {
263  switch (ruType)
264  {
265  case HeRu::RU_26_TONE:
266  os << "26-tones";
267  break;
268  case HeRu::RU_52_TONE:
269  os << "52-tones";
270  break;
271  case HeRu::RU_106_TONE:
272  os << "106-tones";
273  break;
274  case HeRu::RU_242_TONE:
275  os << "242-tones";
276  break;
277  case HeRu::RU_484_TONE:
278  os << "484-tones";
279  break;
280  case HeRu::RU_996_TONE:
281  os << "996-tones";
282  break;
283  case HeRu::RU_2x996_TONE:
284  os << "2x996-tones";
285  break;
286  default:
287  NS_FATAL_ERROR ("Unknown RU type");
288  }
289  return os;
290 }
291 
292 std::ostream& operator<< (std::ostream& os, const HeRu::RuSpec &ru)
293 {
294  os << "RU{" << ru.ruType << "/" << ru.index << "/" << (ru.primary80MHz ? "primary80MHz" : "secondary80MHz") << "}";
295  return os;
296 }
297 
298 uint16_t
300 {
301  switch (ruType)
302  {
303  case RU_26_TONE:
304  return 2;
305  case RU_52_TONE:
306  return 4;
307  case RU_106_TONE:
308  return 8;
309  case RU_242_TONE:
310  return 20;
311  case RU_484_TONE:
312  return 40;
313  case RU_996_TONE:
314  return 80;
315  case RU_2x996_TONE:
316  return 160;
317  default:
318  NS_ABORT_MSG ("RU type " << ruType << " not found");
319  return 0;
320  }
321 }
322 
324 HeRu::GetEqualSizedRusForStations (uint16_t bandwidth, std::size_t& nStations)
325 {
326  RuType ruType;
327  uint8_t nRusAssigned = 0;
328 
329  // iterate over all the available RU types
330  for (auto& ru : m_heRuSubcarrierGroups)
331  {
332  if (ru.first.first == bandwidth && ru.second.size () <= nStations)
333  {
334  ruType = ru.first.second;
335  nRusAssigned = ru.second.size ();
336  break;
337  }
338  else if (bandwidth == 160 && ru.first.first == 80 && (2 * ru.second.size () <= nStations))
339  {
340  ruType = ru.first.second;
341  nRusAssigned = 2 * ru.second.size ();
342  break;
343  }
344  }
345  if (nRusAssigned == 0)
346  {
347  NS_ABORT_IF (bandwidth != 160 || nStations != 1);
348  nRusAssigned = 1;
349  ruType = RU_2x996_TONE;
350  }
351 
352  nStations = nRusAssigned;
353  return ruType;
354 }
355 
356 } //namespace ns3
RuType ruType
RU type.
Definition: he-ru.h:67
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
bool primary80MHz
true if the RU is allocated in the primary 80MHz channel
Definition: he-ru.h:66
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
std::map< BwTonesPair, std::vector< SubcarrierGroup > > SubcarrierGroups
map (bandwidth, number of tones) pairs to the group of subcarrier ranges
Definition: he-ru.h:151
static uint16_t GetBandwidth(RuType ruType)
Get the approximate bandwidth occupied by a RU.
Definition: he-ru.cc:299
static const SubcarrierGroups m_heRuSubcarrierGroups
Definition: he-ru.h:154
RU Specification.
Definition: he-ru.h:64
static RuType GetEqualSizedRusForStations(uint16_t bandwidth, std::size_t &nStations)
Given the channel bandwidth and the number of stations candidate for being assigned an RU...
Definition: he-ru.cc:324
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.
RuType
The different HE Resource Unit (RU) types.
Definition: he-ru.h:41
static SubcarrierGroup GetSubcarrierGroup(uint8_t bw, RuType ruType, std::size_t index)
Get the subcarrier group of the RU having the given index among all the RUs of the given type (number...
Definition: he-ru.cc:172
#define NS_ABORT_IF(cond)
Abnormal program termination if a condition is true.
Definition: abort.h:77
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
std::size_t index
index (starting at 1)
Definition: he-ru.h:68
static std::size_t GetNRus(uint8_t bw, RuType ruType)
Get the number of distinct RUs of the given type (number of tones) available in a HE PPDU of the give...
Definition: he-ru.cc:152