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 (uint16_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 (uint16_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 bool
211 HeRu::DoesOverlap (uint16_t bw, RuSpec ru, const std::vector<RuSpec> &v)
212 {
213  // A 2x996-tone RU spans 160 MHz, hence it overlaps with any other RU
214  if (bw == 160 && ru.ruType == RU_2x996_TONE && !v.empty ())
215  {
216  return true;
217  }
218 
219  SubcarrierGroup groups = GetSubcarrierGroup (bw, ru.ruType, ru.index);
220  for (auto& p : v)
221  {
222  if (ru.primary80MHz != p.primary80MHz)
223  {
224  // the two RUs are located in distinct 80MHz bands
225  continue;
226  }
227  if (DoesOverlap (bw, p, groups))
228  {
229  return true;
230  }
231  }
232  return false;
233 }
234 
235 bool
236 HeRu::DoesOverlap (uint16_t bw, RuSpec ru, const SubcarrierGroup &toneRanges)
237 {
238  for (const auto & range : toneRanges)
239  {
240  if (bw == 160 && ru.ruType == RU_2x996_TONE)
241  {
242  return true;
243  }
244 
245  SubcarrierGroup rangesRu = GetSubcarrierGroup (bw, ru.ruType, ru.index);
246  for (auto& r : rangesRu)
247  {
248  if (range.second >= r.first && r.second >= range.first)
249  {
250  return true;
251  }
252  }
253  }
254  return false;
255 }
256 
258 HeRu::FindOverlappingRu (uint16_t bw, RuSpec referenceRu, RuType searchedRuType)
259 {
260  RuSpec searchedRu;
261  searchedRu.ruType = searchedRuType;
262  std::size_t numRus = HeRu::GetNRus (bw, searchedRuType);
263 
264  std::size_t numRusPer80Mhz;
265  std::vector<bool> primary80MhzFlags;
266  if (bw == 160)
267  {
268  primary80MhzFlags.push_back (true);
269  primary80MhzFlags.push_back (false);
270  numRusPer80Mhz = numRus / 2;
271  }
272  else
273  {
274  primary80MhzFlags.push_back (referenceRu.primary80MHz);
275  numRusPer80Mhz = numRus;
276  }
277 
278  std::size_t index = 1;
279  for (const auto primary80Mhz : primary80MhzFlags)
280  {
281  searchedRu.primary80MHz = primary80Mhz;
282  for (std::size_t indexPer80Mhz = 1; indexPer80Mhz <= numRusPer80Mhz; ++indexPer80Mhz, ++index)
283  {
284  searchedRu.index = index;
285  if (DoesOverlap (bw, referenceRu, {searchedRu}))
286  {
287  return searchedRu;
288  }
289  }
290  }
291  NS_ABORT_MSG ("The searched RU type " << searchedRuType << " was not found for bw=" << bw << " and referenceRu=" << referenceRu);
292  return searchedRu;
293 }
294 
295 std::ostream& operator<< (std::ostream& os, const HeRu::RuType &ruType)
296 {
297  switch (ruType)
298  {
299  case HeRu::RU_26_TONE:
300  os << "26-tones";
301  break;
302  case HeRu::RU_52_TONE:
303  os << "52-tones";
304  break;
305  case HeRu::RU_106_TONE:
306  os << "106-tones";
307  break;
308  case HeRu::RU_242_TONE:
309  os << "242-tones";
310  break;
311  case HeRu::RU_484_TONE:
312  os << "484-tones";
313  break;
314  case HeRu::RU_996_TONE:
315  os << "996-tones";
316  break;
317  case HeRu::RU_2x996_TONE:
318  os << "2x996-tones";
319  break;
320  default:
321  NS_FATAL_ERROR ("Unknown RU type");
322  }
323  return os;
324 }
325 
326 std::ostream& operator<< (std::ostream& os, const HeRu::RuSpec &ru)
327 {
328  os << "RU{" << ru.ruType << "/" << ru.index << "/" << (ru.primary80MHz ? "primary80MHz" : "secondary80MHz") << "}";
329  return os;
330 }
331 
332 uint16_t
334 {
335  switch (ruType)
336  {
337  case RU_26_TONE:
338  return 2;
339  case RU_52_TONE:
340  return 4;
341  case RU_106_TONE:
342  return 8;
343  case RU_242_TONE:
344  return 20;
345  case RU_484_TONE:
346  return 40;
347  case RU_996_TONE:
348  return 80;
349  case RU_2x996_TONE:
350  return 160;
351  default:
352  NS_ABORT_MSG ("RU type " << ruType << " not found");
353  return 0;
354  }
355 }
356 
358 HeRu::GetRuType (uint16_t bandwidth)
359 {
360  switch (bandwidth)
361  {
362  case 2:
363  return RU_26_TONE;
364  case 4:
365  return RU_52_TONE;
366  case 8:
367  return RU_106_TONE;
368  case 20:
369  return RU_242_TONE;
370  case 40:
371  return RU_484_TONE;
372  case 80:
373  return RU_996_TONE;
374  case 160:
375  return RU_2x996_TONE;
376  default:
377  NS_ABORT_MSG (bandwidth << " MHz bandwidth not found");
378  return RU_242_TONE;
379  }
380 }
381 
382 } //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
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
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:137
static RuSpec FindOverlappingRu(uint16_t bw, RuSpec referenceRu, RuType searchedRuType)
Find the RU allocation of the given RU type overlapping the given reference RU allocation.
Definition: he-ru.cc:258
std::map< BwTonesPair, std::vector< SubcarrierGroup > > SubcarrierGroups
map (bandwidth, number of tones) pairs to the group of subcarrier ranges
Definition: he-ru.h:154
static uint16_t GetBandwidth(RuType ruType)
Get the approximate bandwidth occupied by a RU.
Definition: he-ru.cc:333
static const SubcarrierGroups m_heRuSubcarrierGroups
Definition: he-ru.h:157
RU Specification.
Definition: he-ru.h:64
static std::size_t GetNRus(uint16_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
static RuType GetRuType(uint16_t bandwidth)
Get the RU corresponding to the approximate bandwidth.
Definition: he-ru.cc:358
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(uint16_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_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