A Discrete-Event Network Simulator
API
reduced-neighbor-report.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2021 Universita' degli Studi di Napoli Federico II
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Stefano Avallone <stavallo@unina.it>
18  */
19 
21 
23 
24 #include "ns3/abort.h"
25 #include "ns3/address-utils.h"
26 
27 #include <iterator>
28 
29 namespace ns3
30 {
31 
33 {
34 }
35 
38 {
40 }
41 
42 std::size_t
44 {
45  return m_nbrApInfoFields.size();
46 }
47 
48 void
50 {
51  m_nbrApInfoFields.emplace_back();
52 }
53 
54 void
57 {
58  NS_ASSERT(nbrApInfoId < m_nbrApInfoFields.size());
59 
60  uint8_t operatingClass = 0;
61  uint8_t channelNumber = channel.GetNumber();
62 
63  // Information taken from Table E-4 of 802.11-2020
64  switch (channel.GetPhyBand())
65  {
67  if (channel.GetWidth() == 20)
68  {
69  operatingClass = 81;
70  }
71  else if (channel.GetWidth() == 40)
72  {
73  operatingClass = 83;
74  }
75  break;
76  case WIFI_PHY_BAND_5GHZ:
77  if (channel.GetWidth() == 20)
78  {
79  if (channelNumber == 36 || channelNumber == 40 || channelNumber == 44 ||
80  channelNumber == 48)
81  {
82  operatingClass = 115;
83  }
84  else if (channelNumber == 52 || channelNumber == 56 || channelNumber == 60 ||
85  channelNumber == 64)
86  {
87  operatingClass = 118;
88  }
89  else if (channelNumber == 100 || channelNumber == 104 || channelNumber == 108 ||
90  channelNumber == 112 || channelNumber == 116 || channelNumber == 120 ||
91  channelNumber == 124 || channelNumber == 128 || channelNumber == 132 ||
92  channelNumber == 136 || channelNumber == 140 || channelNumber == 144)
93  {
94  operatingClass = 121;
95  }
96  else if (channelNumber == 149 || channelNumber == 153 || channelNumber == 157 ||
97  channelNumber == 161 || channelNumber == 165 || channelNumber == 169 ||
98  channelNumber == 173 || channelNumber == 177 || channelNumber == 181)
99  {
100  operatingClass = 125;
101  }
102  }
103  else if (channel.GetWidth() == 40)
104  {
105  if (channelNumber == 38 || channelNumber == 46)
106  {
107  operatingClass = 116;
108  }
109  else if (channelNumber == 54 || channelNumber == 62)
110  {
111  operatingClass = 119;
112  }
113  else if (channelNumber == 102 || channelNumber == 110 || channelNumber == 118 ||
114  channelNumber == 126 || channelNumber == 134 || channelNumber == 142)
115  {
116  operatingClass = 122;
117  }
118  else if (channelNumber == 151 || channelNumber == 159 || channelNumber == 167 ||
119  channelNumber == 175)
120  {
121  operatingClass = 126;
122  }
123  }
124  else if (channel.GetWidth() == 80)
125  {
126  if (channelNumber == 42 || channelNumber == 58 || channelNumber == 106 ||
127  channelNumber == 122 || channelNumber == 138 || channelNumber == 155 ||
128  channelNumber == 171)
129  {
130  operatingClass = 128;
131  }
132  }
133  else if (channel.GetWidth() == 160)
134  {
135  if (channelNumber == 50 || channelNumber == 114 || channelNumber == 163)
136  {
137  operatingClass = 129;
138  }
139  }
140  break;
141  case WIFI_PHY_BAND_6GHZ:
142  if (channel.GetWidth() == 20)
143  {
144  operatingClass = 131;
145  }
146  else if (channel.GetWidth() == 40)
147  {
148  operatingClass = 132;
149  }
150  else if (channel.GetWidth() == 80)
151  {
152  operatingClass = 133;
153  }
154  else if (channel.GetWidth() == 160)
155  {
156  operatingClass = 134;
157  }
158  break;
160  default:
161  NS_ABORT_MSG("The provided channel has an unspecified PHY band");
162  break;
163  }
164 
165  NS_ABORT_MSG_IF(operatingClass == 0,
166  "Operating class not found for channel number "
167  << channelNumber << " width " << channel.GetWidth() << " MHz "
168  << "band " << channel.GetPhyBand());
169 
170  // find the primary channel number
171  uint16_t startingFreq = 0;
172 
173  switch (channel.GetPhyBand())
174  {
176  startingFreq = 2407;
177  break;
178  case WIFI_PHY_BAND_5GHZ:
179  startingFreq = 5000;
180  break;
181  case WIFI_PHY_BAND_6GHZ:
182  startingFreq = 5950;
183  break;
185  default:
186  NS_ABORT_MSG("The provided channel has an unspecified PHY band");
187  break;
188  }
189 
190  uint8_t primaryChannelNumber =
191  (channel.GetPrimaryChannelCenterFrequency(20) - startingFreq) / 5;
192 
193  m_nbrApInfoFields.at(nbrApInfoId).operatingClass = operatingClass;
194  m_nbrApInfoFields.at(nbrApInfoId).channelNumber = primaryChannelNumber;
195 }
196 
198 ReducedNeighborReport::GetOperatingChannel(std::size_t nbrApInfoId) const
199 {
200  NS_ASSERT(nbrApInfoId < m_nbrApInfoFields.size());
201 
203  uint16_t width = 0;
204 
205  switch (m_nbrApInfoFields.at(nbrApInfoId).operatingClass)
206  {
207  case 81:
208  band = WIFI_PHY_BAND_2_4GHZ;
209  width = 20;
210  break;
211  case 83:
212  band = WIFI_PHY_BAND_2_4GHZ;
213  width = 40;
214  break;
215  case 115:
216  case 118:
217  case 121:
218  case 125:
219  band = WIFI_PHY_BAND_5GHZ;
220  width = 20;
221  break;
222  case 116:
223  case 119:
224  case 122:
225  case 126:
226  band = WIFI_PHY_BAND_5GHZ;
227  width = 40;
228  break;
229  case 128:
230  band = WIFI_PHY_BAND_5GHZ;
231  width = 80;
232  break;
233  case 129:
234  band = WIFI_PHY_BAND_5GHZ;
235  width = 160;
236  break;
237  case 131:
238  band = WIFI_PHY_BAND_6GHZ;
239  width = 20;
240  break;
241  case 132:
242  band = WIFI_PHY_BAND_6GHZ;
243  width = 40;
244  break;
245  case 133:
246  band = WIFI_PHY_BAND_6GHZ;
247  width = 80;
248  break;
249  case 134:
250  band = WIFI_PHY_BAND_6GHZ;
251  width = 160;
252  break;
253  default:
254  break;
255  }
256 
257  NS_ABORT_IF(band == WIFI_PHY_BAND_UNSPECIFIED || width == 0);
258 
259  uint16_t startingFreq = 0;
260 
261  switch (band)
262  {
264  startingFreq = 2407;
265  break;
266  case WIFI_PHY_BAND_5GHZ:
267  startingFreq = 5000;
268  break;
269  case WIFI_PHY_BAND_6GHZ:
270  startingFreq = 5950;
271  break;
273  default:
274  NS_ABORT_MSG("Unspecified band");
275  break;
276  }
277 
278  uint8_t primaryChannelNumber = m_nbrApInfoFields.at(nbrApInfoId).channelNumber;
279  uint16_t primaryChannelCenterFrequency = startingFreq + primaryChannelNumber * 5;
280 
281  uint8_t channelNumber = 0;
282  uint16_t frequency = 0;
283 
285  {
286  if (std::get<2>(channel) == width && std::get<3>(channel) == WIFI_PHY_OFDM_CHANNEL &&
287  std::get<4>(channel) == band &&
288  primaryChannelCenterFrequency > std::get<1>(channel) - width / 2 &&
289  primaryChannelCenterFrequency < std::get<1>(channel) + width / 2)
290  {
291  // the center frequency of the primary channel falls into the frequency
292  // range of this channel
293  bool found = false;
294 
295  if (band != WIFI_PHY_BAND_2_4GHZ)
296  {
297  found = true;
298  }
299  else
300  {
301  // frequency channels overlap in the 2.4 GHz band, hence we have to check
302  // that the given primary channel center frequency can be the center frequency
303  // of the primary20 channel of the channel under consideration
304  switch (width)
305  {
306  case 20:
307  if (std::get<1>(channel) == primaryChannelCenterFrequency)
308  {
309  found = true;
310  }
311  break;
312  case 40:
313  if (std::get<1>(channel) == primaryChannelCenterFrequency + 10 ||
314  std::get<1>(channel) == primaryChannelCenterFrequency - 10)
315  {
316  found = true;
317  }
318  break;
319  default:
320  NS_ABORT_MSG("No channel of width " << width << " MHz in the 2.4 GHz band");
321  }
322  }
323 
324  if (found)
325  {
326  channelNumber = std::get<0>(channel);
327  frequency = std::get<1>(channel);
328  break;
329  }
330  }
331  }
332 
333  NS_ABORT_IF(channelNumber == 0 || frequency == 0);
334 
336  channel.Set(channelNumber, frequency, width, WIFI_STANDARD_UNSPECIFIED, band);
337 
338  uint16_t channelLowestFreq = frequency - width / 2;
339  uint16_t primaryChannelLowestFreq = primaryChannelCenterFrequency - 10;
340  channel.SetPrimary20Index((primaryChannelLowestFreq - channelLowestFreq) / 20);
341 
342  return channel;
343 }
344 
345 std::size_t
347 {
348  NS_ASSERT(nbrApInfoId < m_nbrApInfoFields.size());
349  return m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.size();
350 }
351 
352 void
354 {
355  NS_ASSERT(nbrApInfoId < m_nbrApInfoFields.size());
356  m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.emplace_back();
357 }
358 
359 void
361 {
362  NS_ASSERT(nbrApInfoId < m_nbrApInfoFields.size());
363 
364  uint8_t length = 0; // reserved value
365 
366  auto it = std::next(m_nbrApInfoFields.begin(), nbrApInfoId);
367 
368  if (it->hasBssid && !it->hasShortSsid && !it->hasBssParams && !it->has20MHzPsd &&
369  !it->hasMldParams)
370  {
371  length = 7;
372  }
373  else if (it->hasBssid && it->hasShortSsid && it->hasBssParams && it->has20MHzPsd &&
374  it->hasMldParams)
375  {
376  length = 16;
377  }
378  else
379  {
380  NS_ABORT_MSG("Unsupported TBTT Information field contents");
381  }
382 
383  // set the TBTT Information Length field
384  it->tbttInfoHdr.tbttInfoLength = length;
385 }
386 
387 void
389 {
390  NS_ASSERT(nbrApInfoId < m_nbrApInfoFields.size());
391 
392  auto it = std::next(m_nbrApInfoFields.begin(), nbrApInfoId);
393 
394  switch (it->tbttInfoHdr.tbttInfoLength)
395  {
396  case 7:
397  it->hasBssid = true;
398  it->hasShortSsid = false;
399  it->hasBssParams = false;
400  it->has20MHzPsd = false;
401  it->hasMldParams = false;
402  break;
403  case 16:
404  it->hasBssid = true;
405  it->hasShortSsid = true;
406  it->hasBssParams = true;
407  it->has20MHzPsd = true;
408  it->hasMldParams = true;
409  break;
410  default:
411  NS_ABORT_MSG(
412  "Unsupported TBTT Information Length value: " << it->tbttInfoHdr.tbttInfoLength);
413  }
414 }
415 
416 void
417 ReducedNeighborReport::SetBssid(std::size_t nbrApInfoId, std::size_t index, Mac48Address bssid)
418 {
419  NS_ASSERT(nbrApInfoId < m_nbrApInfoFields.size());
420  NS_ASSERT(index < m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.size());
421 
422  m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.at(index).bssid = bssid;
423 
424  m_nbrApInfoFields.at(nbrApInfoId).hasBssid = true;
425 }
426 
427 bool
428 ReducedNeighborReport::HasBssid(std::size_t nbrApInfoId) const
429 {
430  NS_ASSERT(nbrApInfoId < m_nbrApInfoFields.size());
431 
432  return m_nbrApInfoFields.at(nbrApInfoId).hasBssid;
433 }
434 
436 ReducedNeighborReport::GetBssid(std::size_t nbrApInfoId, std::size_t index) const
437 {
438  NS_ASSERT(HasBssid(nbrApInfoId));
439  NS_ASSERT(index < m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.size());
440 
441  return m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.at(index).bssid;
442 }
443 
444 void
445 ReducedNeighborReport::SetShortSsid(std::size_t nbrApInfoId, std::size_t index, uint32_t shortSsid)
446 {
447  NS_ASSERT(nbrApInfoId < m_nbrApInfoFields.size());
448  NS_ASSERT(index < m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.size());
449 
450  m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.at(index).shortSsid = shortSsid;
451 
452  m_nbrApInfoFields.at(nbrApInfoId).hasShortSsid = true;
453 }
454 
455 bool
456 ReducedNeighborReport::HasShortSsid(std::size_t nbrApInfoId) const
457 {
458  NS_ASSERT(nbrApInfoId < m_nbrApInfoFields.size());
459 
460  return m_nbrApInfoFields.at(nbrApInfoId).hasShortSsid;
461 }
462 
463 uint32_t
464 ReducedNeighborReport::GetShortSsid(std::size_t nbrApInfoId, std::size_t index) const
465 {
466  NS_ASSERT(HasShortSsid(nbrApInfoId));
467  NS_ASSERT(index < m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.size());
468 
469  return m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.at(index).shortSsid;
470 }
471 
472 void
474  std::size_t index,
475  uint8_t bssParameters)
476 {
477  NS_ASSERT(nbrApInfoId < m_nbrApInfoFields.size());
478  NS_ASSERT(index < m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.size());
479 
480  m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.at(index).bssParameters = bssParameters;
481 
482  m_nbrApInfoFields.at(nbrApInfoId).hasBssParams = true;
483 }
484 
485 bool
486 ReducedNeighborReport::HasBssParameters(std::size_t nbrApInfoId) const
487 {
488  NS_ASSERT(nbrApInfoId < m_nbrApInfoFields.size());
489 
490  return m_nbrApInfoFields.at(nbrApInfoId).hasBssParams;
491 }
492 
493 uint8_t
494 ReducedNeighborReport::GetBssParameters(std::size_t nbrApInfoId, std::size_t index) const
495 {
496  NS_ASSERT(HasBssParameters(nbrApInfoId));
497  NS_ASSERT(index < m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.size());
498 
499  return m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.at(index).bssParameters;
500 }
501 
502 void
503 ReducedNeighborReport::SetPsd20MHz(std::size_t nbrApInfoId, std::size_t index, uint8_t psd20MHz)
504 {
505  NS_ASSERT(nbrApInfoId < m_nbrApInfoFields.size());
506  NS_ASSERT(index < m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.size());
507 
508  m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.at(index).psd20MHz = psd20MHz;
509 
510  m_nbrApInfoFields.at(nbrApInfoId).has20MHzPsd = true;
511 }
512 
513 bool
514 ReducedNeighborReport::HasPsd20MHz(std::size_t nbrApInfoId) const
515 {
516  NS_ASSERT(nbrApInfoId < m_nbrApInfoFields.size());
517 
518  return m_nbrApInfoFields.at(nbrApInfoId).has20MHzPsd;
519 }
520 
521 uint8_t
522 ReducedNeighborReport::GetPsd20MHz(std::size_t nbrApInfoId, std::size_t index) const
523 {
524  NS_ASSERT(HasPsd20MHz(nbrApInfoId));
525  NS_ASSERT(index < m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.size());
526 
527  return m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.at(index).psd20MHz;
528 }
529 
530 void
532  std::size_t index,
533  uint8_t mldId,
534  uint8_t linkId,
535  uint8_t changeCount)
536 {
537  NS_ASSERT(nbrApInfoId < m_nbrApInfoFields.size());
538  NS_ASSERT(index < m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.size());
539 
540  auto it = std::next(m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.begin(), index);
541  it->mldParameters.mldId = mldId;
542  it->mldParameters.linkId = (linkId & 0x0f);
543  it->mldParameters.bssParamsChangeCount = changeCount;
544 
545  m_nbrApInfoFields.at(nbrApInfoId).hasMldParams = true;
546 }
547 
548 bool
549 ReducedNeighborReport::HasMldParameters(std::size_t nbrApInfoId) const
550 {
551  NS_ASSERT(nbrApInfoId < m_nbrApInfoFields.size());
552 
553  return m_nbrApInfoFields.at(nbrApInfoId).hasMldParams;
554 }
555 
556 uint8_t
557 ReducedNeighborReport::GetMldId(std::size_t nbrApInfoId, std::size_t index) const
558 {
559  NS_ASSERT(HasMldParameters(nbrApInfoId));
560  NS_ASSERT(index < m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.size());
561 
562  return m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.at(index).mldParameters.mldId;
563 }
564 
565 uint8_t
566 ReducedNeighborReport::GetLinkId(std::size_t nbrApInfoId, std::size_t index) const
567 {
568  NS_ASSERT(HasMldParameters(nbrApInfoId));
569  NS_ASSERT(index < m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.size());
570 
571  return m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.at(index).mldParameters.linkId &
572  0x0f;
573 }
574 
575 void
577 {
578  NS_ASSERT(nbrApInfoId < m_nbrApInfoFields.size());
579  NS_ASSERT(!m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.empty());
580 
581  // set the TBTT Information Count field
582  m_nbrApInfoFields.at(nbrApInfoId).tbttInfoHdr.tbttInfoCount =
583  m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.size() - 1;
584 }
585 
586 uint8_t
588 {
589  NS_ASSERT(nbrApInfoId < m_nbrApInfoFields.size());
590 
591  return 1 + m_nbrApInfoFields.at(nbrApInfoId).tbttInfoHdr.tbttInfoCount;
592 }
593 
594 uint16_t
596 {
597  uint16_t size = 0;
598 
599  for (const auto& neighborApInfo : m_nbrApInfoFields)
600  {
601  size += 4;
602 
603  size += 1 * neighborApInfo.tbttInformationSet.size();
604 
605  if (neighborApInfo.hasBssid)
606  {
607  size += 6 * neighborApInfo.tbttInformationSet.size();
608  }
609  if (neighborApInfo.hasShortSsid)
610  {
611  size += 4 * neighborApInfo.tbttInformationSet.size();
612  }
613  if (neighborApInfo.hasBssParams)
614  {
615  size += 1 * neighborApInfo.tbttInformationSet.size();
616  }
617  if (neighborApInfo.has20MHzPsd)
618  {
619  size += 1 * neighborApInfo.tbttInformationSet.size();
620  }
621  if (neighborApInfo.hasMldParams)
622  {
623  size += 3 * neighborApInfo.tbttInformationSet.size();
624  }
625  }
626 
627  return size;
628 }
629 
630 void
632 {
633  for (std::size_t id = 0; id < m_nbrApInfoFields.size(); ++id)
634  {
637  }
638 
639  for (auto& neighborApInfo : m_nbrApInfoFields)
640  {
641  // serialize the TBTT Information Header
642  uint16_t tbttInfoHdr = 0;
643  tbttInfoHdr |= neighborApInfo.tbttInfoHdr.type;
644  tbttInfoHdr |= (neighborApInfo.tbttInfoHdr.filtered << 2);
645  tbttInfoHdr |= (neighborApInfo.tbttInfoHdr.tbttInfoCount << 4);
646  tbttInfoHdr |= (neighborApInfo.tbttInfoHdr.tbttInfoLength << 8);
647  start.WriteHtolsbU16(tbttInfoHdr);
648 
649  start.WriteU8(neighborApInfo.operatingClass);
650  start.WriteU8(neighborApInfo.channelNumber);
651 
652  for (const auto& tbttInformation : neighborApInfo.tbttInformationSet)
653  {
654  start.WriteU8(tbttInformation.neighborApTbttOffset);
655 
656  if (neighborApInfo.hasBssid)
657  {
658  WriteTo(start, tbttInformation.bssid);
659  }
660  if (neighborApInfo.hasShortSsid)
661  {
662  start.WriteHtolsbU32(tbttInformation.shortSsid);
663  }
664  if (neighborApInfo.hasBssParams)
665  {
666  start.WriteU8(tbttInformation.bssParameters);
667  }
668  if (neighborApInfo.has20MHzPsd)
669  {
670  start.WriteU8(tbttInformation.psd20MHz);
671  }
672  if (neighborApInfo.hasMldParams)
673  {
674  start.WriteU8(tbttInformation.mldParameters.mldId);
675  uint16_t other = 0;
676  other |= (tbttInformation.mldParameters.linkId & 0x0f);
677  other |= (tbttInformation.mldParameters.bssParamsChangeCount << 4);
678  start.WriteHtolsbU16(other);
679  }
680  }
681  }
682 }
683 
684 uint16_t
686 {
688  uint16_t count = 0;
689 
690  while (count < length)
691  {
693 
694  auto tbttInfoHdr = i.ReadLsbtohU16();
695  m_nbrApInfoFields.back().tbttInfoHdr.type = tbttInfoHdr & 0x0003;
696  m_nbrApInfoFields.back().tbttInfoHdr.filtered = (tbttInfoHdr >> 2) & 0x0001;
697  m_nbrApInfoFields.back().tbttInfoHdr.tbttInfoCount = (tbttInfoHdr >> 4) & 0x000f;
698  m_nbrApInfoFields.back().tbttInfoHdr.tbttInfoLength = (tbttInfoHdr >> 8) & 0x00ff;
699 
700  m_nbrApInfoFields.back().operatingClass = i.ReadU8();
701  m_nbrApInfoFields.back().channelNumber = i.ReadU8();
702  count += 4;
703 
704  std::size_t neighborId = m_nbrApInfoFields.size() - 1;
705  ReadTbttInformationLength(neighborId);
706 
707  for (uint8_t j = 0; j < ReadTbttInformationCount(neighborId); j++)
708  {
709  AddTbttInformationField(neighborId);
710 
711  m_nbrApInfoFields.back().tbttInformationSet.back().neighborApTbttOffset = i.ReadU8();
712  count++;
713 
714  if (m_nbrApInfoFields.back().hasBssid)
715  {
716  ReadFrom(i, m_nbrApInfoFields.back().tbttInformationSet.back().bssid);
717  count += 6;
718  }
719  if (m_nbrApInfoFields.back().hasShortSsid)
720  {
721  m_nbrApInfoFields.back().tbttInformationSet.back().shortSsid = i.ReadLsbtohU32();
722  count += 4;
723  }
724  if (m_nbrApInfoFields.back().hasBssParams)
725  {
726  m_nbrApInfoFields.back().tbttInformationSet.back().bssParameters = i.ReadU8();
727  count += 1;
728  }
729  if (m_nbrApInfoFields.back().has20MHzPsd)
730  {
731  m_nbrApInfoFields.back().tbttInformationSet.back().psd20MHz = i.ReadU8();
732  count += 1;
733  }
734  if (m_nbrApInfoFields.back().hasMldParams)
735  {
736  m_nbrApInfoFields.back().tbttInformationSet.back().mldParameters.mldId = i.ReadU8();
737  uint16_t other = i.ReadLsbtohU16();
738  count += 3;
739  m_nbrApInfoFields.back().tbttInformationSet.back().mldParameters.linkId =
740  other & 0x000f;
741  m_nbrApInfoFields.back()
742  .tbttInformationSet.back()
743  .mldParameters.bssParamsChangeCount = (other >> 4) & 0x00ff;
744  }
745  }
746  }
747 
748  return count;
749 }
750 
751 } // namespace ns3
iterator in a Buffer instance
Definition: buffer.h:100
uint8_t ReadU8()
Definition: buffer.h:1027
uint16_t ReadLsbtohU16()
Definition: buffer.cc:1064
uint32_t ReadLsbtohU32()
Definition: buffer.cc:1076
an EUI-48 address
Definition: mac48-address.h:46
void WriteTbttInformationLength(std::size_t nbrApInfoId) const
Set the TBTT Information Length field of the given Neighbor AP Information field based on the xxxPres...
Mac48Address GetBssid(std::size_t nbrApInfoId, std::size_t index) const
Get the BSSID field (must be present) in the i-th TBTT Information field of the given Neighbor AP Inf...
std::vector< NeighborApInformation > m_nbrApInfoFields
one or more Neighbor AP Information fields
void SerializeInformationField(Buffer::Iterator start) const override
Serialize information (i.e., the body of the IE, not including the Element ID and length octets)
bool HasShortSsid(std::size_t nbrApInfoId) const
Return true if the Short SSID field is present in all the TBTT Information fields of the given Neighb...
std::size_t GetNNbrApInfoFields() const
Get the number of Neighbor AP Information fields.
void WriteTbttInformationCount(std::size_t nbrApInfoId) const
Set the TBTT Information Count field of the given Neighbor AP Information field based on the size of ...
bool HasBssid(std::size_t nbrApInfoId) const
Return true if the BSSID field is present in all the TBTT Information fields of the given Neighbor AP...
uint8_t ReadTbttInformationCount(std::size_t nbrApInfoId) const
Get the TBTT Information Count field of the given Neighbor AP Information field.
void SetMldParameters(std::size_t nbrApInfoId, std::size_t index, uint8_t mldId, uint8_t linkId, uint8_t changeSequence)
Set the MLD Parameters subfield of the i-th TBTT Information field of the given Neighbor AP Informati...
void SetShortSsid(std::size_t nbrApInfoId, std::size_t index, uint32_t shortSsid)
Set the Short SSID field of the i-th TBTT Information field of the given Neighbor AP Information fiel...
uint32_t GetShortSsid(std::size_t nbrApInfoId, std::size_t index) const
Get the Short SSID field (must be present) in the i-th TBTT Information field of the given Neighbor A...
void SetBssid(std::size_t nbrApInfoId, std::size_t index, Mac48Address bssid)
Set the BSSID field of the i-th TBTT Information field of the given Neighbor AP Information field.
std::size_t GetNTbttInformationFields(std::size_t nbrApInfoId) const
Get the number of TBTT Information fields included in the TBTT Information Set field of the given Nei...
uint8_t GetLinkId(std::size_t nbrApInfoId, std::size_t index) const
Get the Link ID value in the MLD Parameters subfield (must be present) in the i-th TBTT Information f...
uint8_t GetMldId(std::size_t nbrApInfoId, std::size_t index) const
Get the MLD ID value in the MLD Parameters subfield (must be present) in the i-th TBTT Information fi...
void SetPsd20MHz(std::size_t nbrApInfoId, std::size_t index, uint8_t psd20MHz)
Set the 20 MHz PSD field of the i-th TBTT Information field of the given Neighbor AP Information fiel...
WifiInformationElementId ElementId() const override
Get the wifi information element ID.
void AddNbrApInfoField()
Add a Neighbor AP Information field.
WifiPhyOperatingChannel GetOperatingChannel(std::size_t nbrApInfoId) const
Get the operating channel coded into the Operating Class and the Channel Number fields of the given N...
void SetBssParameters(std::size_t nbrApInfoId, std::size_t index, uint8_t bssParameters)
Set the BSS Parameters field of the i-th TBTT Information field of the given Neighbor AP Information ...
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)
uint8_t GetPsd20MHz(std::size_t nbrApInfoId, std::size_t index) const
Get the 20 MHz PSD field (must be present) in the i-th TBTT Information field of the given Neighbor A...
bool HasMldParameters(std::size_t nbrApInfoId) const
Return true if the MLD Parameters subfield is present in all the TBTT Information fields of the given...
void AddTbttInformationField(std::size_t nbrApInfoId)
Add a TBTT Information fields to the TBTT Information Set field of the given Neighbor AP Information ...
void ReadTbttInformationLength(std::size_t nbrApInfoId)
Use the TBTT Information Length field of the given Neighbor AP Information field to set the xxxPresen...
bool HasBssParameters(std::size_t nbrApInfoId) const
Return true if the BSS Parameters field is present in all the TBTT Information fields of the given Ne...
uint16_t GetInformationFieldSize() const override
Length of serialized information (i.e., the length of the body of the IE, not including the Element I...
void SetOperatingChannel(std::size_t nbrApInfoId, const WifiPhyOperatingChannel &channel)
Set the Operating Class and the Channel Number fields of the given Neighbor AP Information field base...
bool HasPsd20MHz(std::size_t nbrApInfoId) const
Return true if the 20 MHz PSD field is present in all the TBTT Information fields of the given Neighb...
uint8_t GetBssParameters(std::size_t nbrApInfoId, std::size_t index) const
Get the BSS Parameters field (must be present) in the i-th TBTT Information field of the given Neighb...
Class that keeps track of all information about the current PHY operating channel.
static const std::set< FrequencyChannelInfo > m_frequencyChannels
Available frequency channels.
#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_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:49
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
#define NS_ABORT_IF(cond)
Abnormal program termination if a condition is true.
Definition: abort.h:76
WifiPhyBand
Identifies the PHY band.
Definition: wifi-phy-band.h:33
@ WIFI_STANDARD_UNSPECIFIED
@ WIFI_PHY_OFDM_CHANNEL
@ WIFI_PHY_BAND_6GHZ
The 6 GHz band.
Definition: wifi-phy-band.h:39
@ WIFI_PHY_BAND_UNSPECIFIED
Unspecified.
Definition: wifi-phy-band.h:43
@ WIFI_PHY_BAND_2_4GHZ
The 2.4 GHz band.
Definition: wifi-phy-band.h:35
@ WIFI_PHY_BAND_5GHZ
The 5 GHz band.
Definition: wifi-phy-band.h:37
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void WriteTo(Buffer::Iterator &i, Ipv4Address ad)
Write an Ipv4Address to a Buffer.
uint8_t WifiInformationElementId
This type is used to represent an Information Element ID.
void ReadFrom(Buffer::Iterator &i, Ipv4Address &ad)
Read an Ipv4Address from a Buffer.
channel
Definition: third.py:88
#define IE_REDUCED_NEIGHBOR_REPORT