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 * 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
29namespace ns3
30{
31
33{
34}
35
38{
40}
41
42std::size_t
44{
45 return m_nbrApInfoFields.size();
46}
47
48void
50{
51 m_nbrApInfoFields.emplace_back();
52}
53
54void
56 const WifiPhyOperatingChannel& channel)
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;
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;
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;
179 startingFreq = 5000;
180 break;
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
198ReducedNeighborReport::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:
209 width = 20;
210 break;
211 case 83:
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;
267 startingFreq = 5000;
268 break;
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
284 for (const auto& channel : WifiPhyOperatingChannel::m_frequencyChannels)
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
345std::size_t
347{
348 NS_ASSERT(nbrApInfoId < m_nbrApInfoFields.size());
349 return m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.size();
350}
351
352void
354{
355 NS_ASSERT(nbrApInfoId < m_nbrApInfoFields.size());
356 m_nbrApInfoFields.at(nbrApInfoId).tbttInformationSet.emplace_back();
357}
358
359void
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
387void
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:
412 "Unsupported TBTT Information Length value: " << it->tbttInfoHdr.tbttInfoLength);
413 }
414}
415
416void
417ReducedNeighborReport::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
427bool
428ReducedNeighborReport::HasBssid(std::size_t nbrApInfoId) const
429{
430 NS_ASSERT(nbrApInfoId < m_nbrApInfoFields.size());
431
432 return m_nbrApInfoFields.at(nbrApInfoId).hasBssid;
433}
434
436ReducedNeighborReport::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
444void
445ReducedNeighborReport::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
455bool
456ReducedNeighborReport::HasShortSsid(std::size_t nbrApInfoId) const
457{
458 NS_ASSERT(nbrApInfoId < m_nbrApInfoFields.size());
459
460 return m_nbrApInfoFields.at(nbrApInfoId).hasShortSsid;
461}
462
464ReducedNeighborReport::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
472void
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
485bool
486ReducedNeighborReport::HasBssParameters(std::size_t nbrApInfoId) const
487{
488 NS_ASSERT(nbrApInfoId < m_nbrApInfoFields.size());
489
490 return m_nbrApInfoFields.at(nbrApInfoId).hasBssParams;
491}
492
493uint8_t
494ReducedNeighborReport::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
502void
503ReducedNeighborReport::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
513bool
514ReducedNeighborReport::HasPsd20MHz(std::size_t nbrApInfoId) const
515{
516 NS_ASSERT(nbrApInfoId < m_nbrApInfoFields.size());
517
518 return m_nbrApInfoFields.at(nbrApInfoId).has20MHzPsd;
519}
520
521uint8_t
522ReducedNeighborReport::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
530void
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
548bool
549ReducedNeighborReport::HasMldParameters(std::size_t nbrApInfoId) const
550{
551 NS_ASSERT(nbrApInfoId < m_nbrApInfoFields.size());
552
553 return m_nbrApInfoFields.at(nbrApInfoId).hasMldParams;
554}
555
556uint8_t
557ReducedNeighborReport::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
565uint8_t
566ReducedNeighborReport::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
575void
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
586uint8_t
588{
589 NS_ASSERT(nbrApInfoId < m_nbrApInfoFields.size());
590
591 return 1 + m_nbrApInfoFields.at(nbrApInfoId).tbttInfoHdr.tbttInfoCount;
592}
593
594uint16_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
630void
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
684uint16_t
686{
687 Buffer::Iterator i = start;
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.
#define IE_REDUCED_NEIGHBOR_REPORT