A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
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 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Stefano Avallone <stavallo@unina.it>
7 */
8
10
12#include "wifi-utils.h"
13
14#include "ns3/abort.h"
15#include "ns3/address-utils.h"
16
17#include <iterator>
18
19namespace ns3
20{
21
25
31
32std::size_t
37
38void
43
44void
46 const WifiPhyOperatingChannel& channel)
47{
48 NS_ASSERT(nbrApInfoId < m_nbrApInfoFields.size());
49
50 uint8_t operatingClass = 0;
51 uint8_t channelNumber = channel.GetNumber();
52
53 // Information taken from Table E-4 of 802.11-2020
54 switch (channel.GetPhyBand())
55 {
57 if (channel.GetWidth() == MHz_u{20})
58 {
59 operatingClass = 81;
60 }
61 else if (channel.GetWidth() == MHz_u{40})
62 {
63 operatingClass = 83;
64 }
65 break;
67 if (channel.GetWidth() == MHz_u{20})
68 {
69 if (channelNumber == 36 || channelNumber == 40 || channelNumber == 44 ||
70 channelNumber == 48)
71 {
72 operatingClass = 115;
73 }
74 else if (channelNumber == 52 || channelNumber == 56 || channelNumber == 60 ||
75 channelNumber == 64)
76 {
77 operatingClass = 118;
78 }
79 else if (channelNumber == 100 || channelNumber == 104 || channelNumber == 108 ||
80 channelNumber == 112 || channelNumber == 116 || channelNumber == 120 ||
81 channelNumber == 124 || channelNumber == 128 || channelNumber == 132 ||
82 channelNumber == 136 || channelNumber == 140 || channelNumber == 144)
83 {
84 operatingClass = 121;
85 }
86 else if (channelNumber == 149 || channelNumber == 153 || channelNumber == 157 ||
87 channelNumber == 161 || channelNumber == 165 || channelNumber == 169 ||
88 channelNumber == 173 || channelNumber == 177 || channelNumber == 181)
89 {
90 operatingClass = 125;
91 }
92 }
93 else if (channel.GetWidth() == MHz_u{40})
94 {
95 if (channelNumber == 38 || channelNumber == 46)
96 {
97 operatingClass = 116;
98 }
99 else if (channelNumber == 54 || channelNumber == 62)
100 {
101 operatingClass = 119;
102 }
103 else if (channelNumber == 102 || channelNumber == 110 || channelNumber == 118 ||
104 channelNumber == 126 || channelNumber == 134 || channelNumber == 142)
105 {
106 operatingClass = 122;
107 }
108 else if (channelNumber == 151 || channelNumber == 159 || channelNumber == 167 ||
109 channelNumber == 175)
110 {
111 operatingClass = 126;
112 }
113 }
114 else if (channel.GetWidth() == MHz_u{80})
115 {
116 if (channelNumber == 42 || channelNumber == 58 || channelNumber == 106 ||
117 channelNumber == 122 || channelNumber == 138 || channelNumber == 155 ||
118 channelNumber == 171)
119 {
120 operatingClass = 128;
121 }
122 }
123 else if (channel.GetWidth() == MHz_u{160})
124 {
125 if (channelNumber == 50 || channelNumber == 114 || channelNumber == 163)
126 {
127 operatingClass = 129;
128 }
129 }
130 break;
132 if (channel.GetWidth() == MHz_u{20})
133 {
134 operatingClass = 131;
135 }
136 else if (channel.GetWidth() == MHz_u{40})
137 {
138 operatingClass = 132;
139 }
140 else if (channel.GetWidth() == MHz_u{80})
141 {
142 operatingClass = 133;
143 }
144 else if (channel.GetWidth() == MHz_u{160})
145 {
146 operatingClass = 134;
147 }
148 else if (channel.GetWidth() == MHz_u{320})
149 {
150 operatingClass = 137;
151 }
152 break;
154 default:
155 NS_ABORT_MSG("The provided channel has an unspecified PHY band");
156 break;
157 }
158
159 NS_ABORT_MSG_IF(operatingClass == 0,
160 "Operating class not found for channel number "
161 << +channelNumber << " width " << channel.GetWidth() << " MHz "
162 << "band " << channel.GetPhyBand());
163
164 // find the primary channel number
165 MHz_u startingFreq{0};
166
167 switch (channel.GetPhyBand())
168 {
170 startingFreq = MHz_u{2407};
171 break;
173 startingFreq = MHz_u{5000};
174 break;
176 startingFreq = MHz_u{5950};
177 break;
179 default:
180 NS_ABORT_MSG("The provided channel has an unspecified PHY band");
181 break;
182 }
183
184 uint8_t primaryChannelNumber =
185 (channel.GetPrimaryChannelCenterFrequency(MHz_u{20}) - startingFreq) / MHz_u{5};
186
187 m_nbrApInfoFields.at(nbrApInfoId).operatingClass = operatingClass;
188 m_nbrApInfoFields.at(nbrApInfoId).channelNumber = primaryChannelNumber;
189}
190
192ReducedNeighborReport::GetOperatingChannel(std::size_t nbrApInfoId) const
193{
194 NS_ASSERT(nbrApInfoId < m_nbrApInfoFields.size());
195
197 MHz_u width{0};
198
199 switch (m_nbrApInfoFields.at(nbrApInfoId).operatingClass)
200 {
201 case 81:
203 width = MHz_u{20};
204 break;
205 case 83:
207 width = MHz_u{40};
208 break;
209 case 115:
210 case 118:
211 case 121:
212 case 125:
213 band = WIFI_PHY_BAND_5GHZ;
214 width = MHz_u{20};
215 break;
216 case 116:
217 case 119:
218 case 122:
219 case 126:
220 band = WIFI_PHY_BAND_5GHZ;
221 width = MHz_u{40};
222 break;
223 case 128:
224 band = WIFI_PHY_BAND_5GHZ;
225 width = MHz_u{80};
226 break;
227 case 129:
228 band = WIFI_PHY_BAND_5GHZ;
229 width = MHz_u{160};
230 break;
231 case 131:
232 band = WIFI_PHY_BAND_6GHZ;
233 width = MHz_u{20};
234 break;
235 case 132:
236 band = WIFI_PHY_BAND_6GHZ;
237 width = MHz_u{40};
238 break;
239 case 133:
240 band = WIFI_PHY_BAND_6GHZ;
241 width = MHz_u{80};
242 break;
243 case 134:
244 band = WIFI_PHY_BAND_6GHZ;
245 width = MHz_u{160};
246 break;
247 case 137:
248 band = WIFI_PHY_BAND_6GHZ;
249 width = MHz_u{320};
250 break;
251 default:
252 break;
253 }
254
255 NS_ABORT_IF(band == WIFI_PHY_BAND_UNSPECIFIED || width == MHz_u{0});
256
257 MHz_u startingFreq{0};
258
259 switch (band)
260 {
262 startingFreq = MHz_u{2407};
263 break;
265 startingFreq = MHz_u{5000};
266 break;
268 startingFreq = MHz_u{5950};
269 break;
271 default:
272 NS_ABORT_MSG("Unspecified band");
273 break;
274 }
275
276 uint8_t primaryChannelNumber = m_nbrApInfoFields.at(nbrApInfoId).channelNumber;
277 auto primaryChannelCenterFrequency = startingFreq + primaryChannelNumber * MHz_u{5};
278
279 uint8_t channelNumber = 0;
280 MHz_u frequency{0};
281
282 for (const auto& channel : WifiPhyOperatingChannel::m_frequencyChannels)
283 {
284 if (channel.width == width && channel.type == FrequencyChannelType::OFDM &&
285 channel.band == band &&
286 primaryChannelCenterFrequency > (channel.frequency - (width / 2)) &&
287 primaryChannelCenterFrequency < (channel.frequency + (width / 2)))
288 {
289 // the center frequency of the primary channel falls into the frequency
290 // range of this channel
291 bool found = false;
292
293 if (band != WIFI_PHY_BAND_2_4GHZ)
294 {
295 found = true;
296 }
297 else
298 {
299 // frequency channels overlap in the 2.4 GHz band, hence we have to check
300 // that the given primary channel center frequency can be the center frequency
301 // of the primary20 channel of the channel under consideration
302 switch (static_cast<uint16_t>(width))
303 {
304 case 20:
305 if (channel.frequency == primaryChannelCenterFrequency)
306 {
307 found = true;
308 }
309 break;
310 case 40:
311 if ((channel.frequency == primaryChannelCenterFrequency + MHz_u{10}) ||
312 (channel.frequency == primaryChannelCenterFrequency - MHz_u{10}))
313 {
314 found = true;
315 }
316 break;
317 default:
318 NS_ABORT_MSG("No channel of width " << width << " MHz in the 2.4 GHz band");
319 }
320 }
321
322 if (found)
323 {
324 channelNumber = channel.number;
325 frequency = channel.frequency;
326 break;
327 }
328 }
329 }
330
331 NS_ABORT_IF(channelNumber == 0 || frequency == MHz_u{0});
332
334 channel.Set({{channelNumber, frequency, width, band}}, WIFI_STANDARD_UNSPECIFIED);
335
336 const auto channelLowestFreq = frequency - width / 2;
337 const auto primaryChannelLowestFreq = primaryChannelCenterFrequency - MHz_u{10};
338 channel.SetPrimary20Index(Count20MHzSubchannels(channelLowestFreq, primaryChannelLowestFreq));
339
340 return channel;
341}
342
343std::size_t
345{
346 NS_ASSERT(nbrApInfoId < m_nbrApInfoFields.size());
347 return m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.size();
348}
349
350void
352{
353 NS_ASSERT(nbrApInfoId < m_nbrApInfoFields.size());
354 m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.emplace_back();
355}
356
357void
359{
360 NS_ASSERT(nbrApInfoId < m_nbrApInfoFields.size());
361
362 uint8_t length = 0; // reserved value
363
364 auto it = std::next(m_nbrApInfoFields.begin(), nbrApInfoId);
365
366 if (it->hasBssid && !it->hasShortSsid && !it->hasBssParams && !it->has20MHzPsd &&
367 !it->hasMldParams)
368 {
369 length = 7;
370 }
371 else if (it->hasBssid && it->hasShortSsid && it->hasBssParams && it->has20MHzPsd &&
372 it->hasMldParams)
373 {
374 length = 16;
375 }
376 else
377 {
378 NS_ABORT_MSG("Unsupported TBTT Information field contents");
379 }
380
381 // set the TBTT Information Length field
382 it->tbttInfoHdr.tbttInfoLength = length;
383}
384
385void
387{
388 NS_ASSERT(nbrApInfoId < m_nbrApInfoFields.size());
389
390 auto it = std::next(m_nbrApInfoFields.begin(), nbrApInfoId);
391
392 switch (it->tbttInfoHdr.tbttInfoLength)
393 {
394 case 7:
395 it->hasBssid = true;
396 it->hasShortSsid = false;
397 it->hasBssParams = false;
398 it->has20MHzPsd = false;
399 it->hasMldParams = false;
400 break;
401 case 16:
402 it->hasBssid = true;
403 it->hasShortSsid = true;
404 it->hasBssParams = true;
405 it->has20MHzPsd = true;
406 it->hasMldParams = true;
407 break;
408 default:
410 "Unsupported TBTT Information Length value: " << it->tbttInfoHdr.tbttInfoLength);
411 }
412}
413
414void
415ReducedNeighborReport::SetBssid(std::size_t nbrApInfoId, std::size_t index, Mac48Address bssid)
416{
417 NS_ASSERT(nbrApInfoId < m_nbrApInfoFields.size());
418 NS_ASSERT(index < m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.size());
419
420 m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.at(index).bssid = bssid;
421
422 m_nbrApInfoFields.at(nbrApInfoId).hasBssid = true;
423}
424
425bool
426ReducedNeighborReport::HasBssid(std::size_t nbrApInfoId) const
427{
428 NS_ASSERT(nbrApInfoId < m_nbrApInfoFields.size());
429
430 return m_nbrApInfoFields.at(nbrApInfoId).hasBssid;
431}
432
434ReducedNeighborReport::GetBssid(std::size_t nbrApInfoId, std::size_t index) const
435{
436 NS_ASSERT(HasBssid(nbrApInfoId));
437 NS_ASSERT(index < m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.size());
438
439 return m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.at(index).bssid;
440}
441
442void
443ReducedNeighborReport::SetShortSsid(std::size_t nbrApInfoId, std::size_t index, uint32_t shortSsid)
444{
445 NS_ASSERT(nbrApInfoId < m_nbrApInfoFields.size());
446 NS_ASSERT(index < m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.size());
447
448 m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.at(index).shortSsid = shortSsid;
449
450 m_nbrApInfoFields.at(nbrApInfoId).hasShortSsid = true;
451}
452
453bool
454ReducedNeighborReport::HasShortSsid(std::size_t nbrApInfoId) const
455{
456 NS_ASSERT(nbrApInfoId < m_nbrApInfoFields.size());
457
458 return m_nbrApInfoFields.at(nbrApInfoId).hasShortSsid;
459}
460
462ReducedNeighborReport::GetShortSsid(std::size_t nbrApInfoId, std::size_t index) const
463{
464 NS_ASSERT(HasShortSsid(nbrApInfoId));
465 NS_ASSERT(index < m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.size());
466
467 return m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.at(index).shortSsid;
468}
469
470void
472 std::size_t index,
473 uint8_t bssParameters)
474{
475 NS_ASSERT(nbrApInfoId < m_nbrApInfoFields.size());
476 NS_ASSERT(index < m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.size());
477
478 m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.at(index).bssParameters = bssParameters;
479
480 m_nbrApInfoFields.at(nbrApInfoId).hasBssParams = true;
481}
482
483bool
484ReducedNeighborReport::HasBssParameters(std::size_t nbrApInfoId) const
485{
486 NS_ASSERT(nbrApInfoId < m_nbrApInfoFields.size());
487
488 return m_nbrApInfoFields.at(nbrApInfoId).hasBssParams;
489}
490
491uint8_t
492ReducedNeighborReport::GetBssParameters(std::size_t nbrApInfoId, std::size_t index) const
493{
494 NS_ASSERT(HasBssParameters(nbrApInfoId));
495 NS_ASSERT(index < m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.size());
496
497 return m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.at(index).bssParameters;
498}
499
500void
501ReducedNeighborReport::SetPsd20MHz(std::size_t nbrApInfoId, std::size_t index, uint8_t psd20MHz)
502{
503 NS_ASSERT(nbrApInfoId < m_nbrApInfoFields.size());
504 NS_ASSERT(index < m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.size());
505
506 m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.at(index).psd20MHz = psd20MHz;
507
508 m_nbrApInfoFields.at(nbrApInfoId).has20MHzPsd = true;
509}
510
511bool
512ReducedNeighborReport::HasPsd20MHz(std::size_t nbrApInfoId) const
513{
514 NS_ASSERT(nbrApInfoId < m_nbrApInfoFields.size());
515
516 return m_nbrApInfoFields.at(nbrApInfoId).has20MHzPsd;
517}
518
519uint8_t
520ReducedNeighborReport::GetPsd20MHz(std::size_t nbrApInfoId, std::size_t index) const
521{
522 NS_ASSERT(HasPsd20MHz(nbrApInfoId));
523 NS_ASSERT(index < m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.size());
524
525 return m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.at(index).psd20MHz;
526}
527
528void
530 std::size_t index,
531 const MldParameters& mldParams)
532{
533 NS_ASSERT(nbrApInfoId < m_nbrApInfoFields.size());
534 NS_ASSERT(index < m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.size());
535
536 auto it = std::next(m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.begin(), index);
537 it->mldParameters = mldParams;
538
539 m_nbrApInfoFields.at(nbrApInfoId).hasMldParams = true;
540}
541
542bool
543ReducedNeighborReport::HasMldParameters(std::size_t nbrApInfoId) const
544{
545 NS_ASSERT(nbrApInfoId < m_nbrApInfoFields.size());
546
547 return m_nbrApInfoFields.at(nbrApInfoId).hasMldParams;
548}
549
551ReducedNeighborReport::GetMldParameters(std::size_t nbrApInfoId, std::size_t index) const
552{
553 NS_ASSERT(HasMldParameters(nbrApInfoId));
554 NS_ASSERT(index < m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.size());
555
556 return m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.at(index).mldParameters;
557}
558
559void
561{
562 NS_ASSERT(nbrApInfoId < m_nbrApInfoFields.size());
563 NS_ASSERT(!m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.empty());
564
565 // set the TBTT Information Count field
566 m_nbrApInfoFields.at(nbrApInfoId).tbttInfoHdr.tbttInfoCount =
567 m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.size() - 1;
568}
569
570uint8_t
572{
573 NS_ASSERT(nbrApInfoId < m_nbrApInfoFields.size());
574
575 return 1 + m_nbrApInfoFields.at(nbrApInfoId).tbttInfoHdr.tbttInfoCount;
576}
577
578uint16_t
580{
581 uint16_t size = 0;
582
583 for (const auto& neighborApInfo : m_nbrApInfoFields)
584 {
585 size += 4;
586
587 size += 1 * neighborApInfo.tbttInformationSet.size();
588
589 if (neighborApInfo.hasBssid)
590 {
591 size += 6 * neighborApInfo.tbttInformationSet.size();
592 }
593 if (neighborApInfo.hasShortSsid)
594 {
595 size += 4 * neighborApInfo.tbttInformationSet.size();
596 }
597 if (neighborApInfo.hasBssParams)
598 {
599 size += 1 * neighborApInfo.tbttInformationSet.size();
600 }
601 if (neighborApInfo.has20MHzPsd)
602 {
603 size += 1 * neighborApInfo.tbttInformationSet.size();
604 }
605 if (neighborApInfo.hasMldParams)
606 {
607 size += 3 * neighborApInfo.tbttInformationSet.size();
608 }
609 }
610
611 return size;
612}
613
614void
616{
617 for (std::size_t id = 0; id < m_nbrApInfoFields.size(); ++id)
618 {
621 }
622
623 for (auto& neighborApInfo : m_nbrApInfoFields)
624 {
625 // serialize the TBTT Information Header
626 uint16_t tbttInfoHdr = 0;
627 tbttInfoHdr |= neighborApInfo.tbttInfoHdr.type;
628 tbttInfoHdr |= (neighborApInfo.tbttInfoHdr.filtered << 2);
629 tbttInfoHdr |= (neighborApInfo.tbttInfoHdr.tbttInfoCount << 4);
630 tbttInfoHdr |= (neighborApInfo.tbttInfoHdr.tbttInfoLength << 8);
631 start.WriteHtolsbU16(tbttInfoHdr);
632
633 start.WriteU8(neighborApInfo.operatingClass);
634 start.WriteU8(neighborApInfo.channelNumber);
635
636 for (const auto& tbttInformation : neighborApInfo.tbttInformationSet)
637 {
638 start.WriteU8(tbttInformation.neighborApTbttOffset);
639
640 if (neighborApInfo.hasBssid)
641 {
642 WriteTo(start, tbttInformation.bssid);
643 }
644 if (neighborApInfo.hasShortSsid)
645 {
646 start.WriteHtolsbU32(tbttInformation.shortSsid);
647 }
648 if (neighborApInfo.hasBssParams)
649 {
650 start.WriteU8(tbttInformation.bssParameters);
651 }
652 if (neighborApInfo.has20MHzPsd)
653 {
654 start.WriteU8(tbttInformation.psd20MHz);
655 }
656 if (neighborApInfo.hasMldParams)
657 {
658 start.WriteU8(tbttInformation.mldParameters.apMldId);
659 uint16_t other = 0;
660 other |= (tbttInformation.mldParameters.linkId & 0x0f);
661 other |= (tbttInformation.mldParameters.bssParamsChangeCount << 4);
662 other |= (tbttInformation.mldParameters.allUpdates << 12);
663 other |= (tbttInformation.mldParameters.disabledLink << 13);
664 start.WriteHtolsbU16(other);
665 }
666 }
667 }
668}
669
670uint16_t
672{
673 Buffer::Iterator i = start;
674 uint16_t count = 0;
675
676 while (count < length)
677 {
679
680 auto tbttInfoHdr = i.ReadLsbtohU16();
681 m_nbrApInfoFields.back().tbttInfoHdr.type = tbttInfoHdr & 0x0003;
682 m_nbrApInfoFields.back().tbttInfoHdr.filtered = (tbttInfoHdr >> 2) & 0x0001;
683 m_nbrApInfoFields.back().tbttInfoHdr.tbttInfoCount = (tbttInfoHdr >> 4) & 0x000f;
684 m_nbrApInfoFields.back().tbttInfoHdr.tbttInfoLength = (tbttInfoHdr >> 8) & 0x00ff;
685
686 m_nbrApInfoFields.back().operatingClass = i.ReadU8();
687 m_nbrApInfoFields.back().channelNumber = i.ReadU8();
688 count += 4;
689
690 std::size_t neighborId = m_nbrApInfoFields.size() - 1;
691 ReadTbttInformationLength(neighborId);
692
693 for (uint8_t j = 0; j < ReadTbttInformationCount(neighborId); j++)
694 {
695 AddTbttInformationField(neighborId);
696
697 m_nbrApInfoFields.back().tbttInformationSet.back().neighborApTbttOffset = i.ReadU8();
698 count++;
699
700 if (m_nbrApInfoFields.back().hasBssid)
701 {
702 ReadFrom(i, m_nbrApInfoFields.back().tbttInformationSet.back().bssid);
703 count += 6;
704 }
705 if (m_nbrApInfoFields.back().hasShortSsid)
706 {
707 m_nbrApInfoFields.back().tbttInformationSet.back().shortSsid = i.ReadLsbtohU32();
708 count += 4;
709 }
710 if (m_nbrApInfoFields.back().hasBssParams)
711 {
712 m_nbrApInfoFields.back().tbttInformationSet.back().bssParameters = i.ReadU8();
713 count += 1;
714 }
715 if (m_nbrApInfoFields.back().has20MHzPsd)
716 {
717 m_nbrApInfoFields.back().tbttInformationSet.back().psd20MHz = i.ReadU8();
718 count += 1;
719 }
720 if (m_nbrApInfoFields.back().hasMldParams)
721 {
722 auto& mldParams = m_nbrApInfoFields.back().tbttInformationSet.back().mldParameters;
723 mldParams.apMldId = i.ReadU8();
724 uint16_t other = i.ReadLsbtohU16();
725 count += 3;
726 mldParams.linkId = other & 0x000f;
727 mldParams.bssParamsChangeCount = (other >> 4) & 0x00ff;
728 mldParams.allUpdates = (other >> 12) & 0x01;
729 mldParams.disabledLink = (other >> 13) & 0x01;
730 }
731 }
732 }
733
734 return count;
735}
736
737void
738ReducedNeighborReport::Print(std::ostream& os) const
739{
740 os << "Reduced Neighbor Report=[";
741 for (const auto& neighborApInfo : m_nbrApInfoFields)
742 {
743 os << "{Operating Class: " << +neighborApInfo.operatingClass
744 << ", Channel Number: " << +neighborApInfo.channelNumber
745 << ", TBTT Information Count: " << +neighborApInfo.tbttInfoHdr.tbttInfoCount
746 << ", TBTT Information Length: " << +neighborApInfo.tbttInfoHdr.tbttInfoLength << "}, ";
747 }
748 os << "]";
749}
750
751} // namespace ns3
iterator in a Buffer instance
Definition buffer.h:89
uint16_t ReadLsbtohU16()
Definition buffer.cc:1053
uint32_t ReadLsbtohU32()
Definition buffer.cc:1065
an EUI-48 address
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 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...
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.
const MldParameters & GetMldParameters(std::size_t nbrApInfoId, std::size_t index) const
Get the MLD Parameters subfield (must be present) in the i-th TBTT Information field of the given Nei...
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 ...
void SetMldParameters(std::size_t nbrApInfoId, std::size_t index, const MldParameters &mldParams)
Set the MLD Parameters subfield of the i-th TBTT Information field of the given Neighbor AP Informati...
void Print(std::ostream &os) const override
Generate human-readable form of IE.
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:55
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition abort.h:38
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition abort.h:97
#define NS_ABORT_IF(cond)
Abnormal program termination if a condition is true.
Definition abort.h:65
WifiPhyBand
Identifies the PHY band.
@ WIFI_STANDARD_UNSPECIFIED
@ WIFI_PHY_BAND_6GHZ
The 6 GHz band.
@ WIFI_PHY_BAND_UNSPECIFIED
Unspecified.
@ WIFI_PHY_BAND_2_4GHZ
The 2.4 GHz band.
@ WIFI_PHY_BAND_5GHZ
The 5 GHz band.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
double MHz_u
MHz weak type.
Definition wifi-units.h:31
std::size_t Count20MHzSubchannels(MHz_u channelWidth)
Return the number of 20 MHz subchannels covering the channel width.
Definition wifi-utils.h:138
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.
#define IE_REDUCED_NEIGHBOR_REPORT