Skip to content

Commit 4aebf17

Browse files
Fix IEEE 802.11 guard interval mode handling
1 parent 16662c8 commit 4aebf17

17 files changed

Lines changed: 241 additions & 245 deletions

src/inet/linklayer/ieee80211/mac/rateselection/QosRateSelection.cc

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,8 @@ const IIeee80211Mode *QosRateSelection::computeResponseAckFrameMode(Packet *pack
7575
auto mode = getMode(packet, dataOrMgmtHeader);
7676
ASSERT(modeSet->containsMode(mode));
7777
if (!responseAckFrameMode) {
78-
if (modeSet->getIsMandatory(mode))
79-
return mode;
80-
else if (auto slowerMode = modeSet->getSlowerMandatoryMode(mode))
81-
return slowerMode;
78+
if (auto mandatoryMode = modeSet->getMandatoryModeAtOrBelow(mode))
79+
return mandatoryMode;
8280
else
8381
throw cRuntimeError("Mandatory mode not found");
8482
}
@@ -92,10 +90,8 @@ const IIeee80211Mode *QosRateSelection::computeResponseCtsFrameMode(Packet *pack
9290
auto mode = getMode(packet, rtsFrame);
9391
ASSERT(modeSet->containsMode(mode));
9492
if (!responseCtsFrameMode) {
95-
if (modeSet->getIsMandatory(mode))
96-
return mode;
97-
else if (auto slowerMode = modeSet->getSlowerMandatoryMode(mode))
98-
return slowerMode;
93+
if (auto mandatoryMode = modeSet->getMandatoryModeAtOrBelow(mode))
94+
return mandatoryMode;
9995
else
10096
throw cRuntimeError("Mandatory mode not found");
10197
}
@@ -248,4 +244,3 @@ void QosRateSelection::frameTransmitted(Packet *packet, const Ptr<const Ieee8021
248244

249245
} /* namespace ieee80211 */
250246
} /* namespace inet */
251-

src/inet/linklayer/ieee80211/mac/rateselection/QosRateSelection.ned

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ simple QosRateSelection extends SimpleModule
3131
double responseCtsFrameBitrate @unit(bps) = default(-1bps);
3232

3333
double dataFrameBitrate @unit(bps) = default(-1bps); // Fastest
34-
double dataFrameBandwidth @unit(Hz) = default(nan Hz); // Used only when dataFrameBitrate is specified
35-
int dataFrameNumSpatialStreams = default(-1); // Used only when dataFrameBitrate is specified
36-
double dataFrameGuardInterval @unit(s) = default(-1s); // Used only when dataFrameBitrate is specified
34+
double dataFrameBandwidth @unit(Hz) = default(nan Hz); // Explicit mode qualifier when dataFrameBitrate is specified
35+
int dataFrameNumSpatialStreams = default(-1); // Explicit mode qualifier when dataFrameBitrate is specified
36+
double dataFrameGuardInterval @unit(s) = default(-1s); // Explicit mode qualifier when dataFrameBitrate is specified
3737

3838
double mgmtFrameBitrate @unit(bps) = default(-1bps); // Fastest
3939
double controlFrameBitrate @unit(bps) = default(-1bps);

src/inet/linklayer/ieee80211/mac/rateselection/RateSelection.cc

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ const IIeee80211Mode *RateSelection::computeResponseAckFrameMode(Packet *packet,
8484
else {
8585
auto mode = getMode(packet, dataOrMgmtHeader);
8686
ASSERT(modeSet->containsMode(mode));
87-
return modeSet->getIsMandatory(mode) ? mode : modeSet->getSlowerMandatoryMode(mode); // TODO BSSBasicRateSet
87+
return modeSet->getMandatoryModeAtOrBelow(mode); // TODO BSSBasicRateSet
8888
}
8989
}
9090

@@ -95,7 +95,7 @@ const IIeee80211Mode *RateSelection::computeResponseCtsFrameMode(Packet *packet,
9595
else {
9696
auto mode = getMode(packet, rtsFrame);
9797
ASSERT(modeSet->containsMode(mode));
98-
return modeSet->getIsMandatory(mode) ? mode : modeSet->getSlowerMandatoryMode(mode); // TODO BSSBasicRateSet
98+
return modeSet->getMandatoryModeAtOrBelow(mode); // TODO BSSBasicRateSet
9999
}
100100
}
101101

@@ -170,4 +170,3 @@ void RateSelection::setFrameMode(Packet *packet, const Ptr<const Ieee80211MacHea
170170

171171
} // namespace ieee80211
172172
} // namespace inet
173-

src/inet/linklayer/ieee80211/mac/rateselection/RateSelection.ned

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ simple RateSelection extends SimpleModule like IRateSelection
2626
double responseCtsFrameBitrate @unit(bps) = default(-1bps);
2727

2828
double dataFrameBitrate @unit(bps) = default(-1bps); // Fastest
29-
double dataFrameBandwidth @unit(Hz) = default(nan Hz); // Used only when dataFrameBitrate is specified
30-
int dataFrameNumSpatialStreams = default(-1); // Used only when dataFrameBitrate is specified
31-
double dataFrameGuardInterval @unit(s) = default(-1s); // Used only when dataFrameBitrate is specified
29+
double dataFrameBandwidth @unit(Hz) = default(nan Hz); // Explicit mode qualifier when dataFrameBitrate is specified
30+
int dataFrameNumSpatialStreams = default(-1); // Explicit mode qualifier when dataFrameBitrate is specified
31+
double dataFrameGuardInterval @unit(s) = default(-1s); // Explicit mode qualifier when dataFrameBitrate is specified
3232

3333
double mgmtFrameBitrate @unit(bps) = default(-1bps); // Fastest
3434
double controlFrameBitrate @unit(bps) = default(-1bps);

src/inet/linklayer/ieee80211/mgmt/Ieee80211MgmtBase.cc

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,24 @@ void Ieee80211MgmtBase::receiveSignal(cComponent *source, simsignal_t signalID,
4545

4646
if (signalID == modesetChangedSignal) {
4747
modeSet = check_and_cast<physicallayer::Ieee80211ModeSet *>(obj);
48-
supportedRates.numRates = std::min(8, modeSet->getNumModes());
48+
for (int i = 0; i < 8; i++)
49+
supportedRates.rate[i] = 0;
4950
int rateIndex = 0;
50-
for (int i = 0; i < supportedRates.numRates; i++)
51-
if (modeSet->isMandatory(i))
52-
supportedRates.rate[rateIndex++] = modeSet->getMode(i)->getDataMode()->getNetBitrate().get<Mbps>();
51+
for (int i = 0; i < modeSet->getNumModes() && rateIndex < 8; i++) {
52+
if (!modeSet->isMandatory(i))
53+
continue;
54+
double rate = modeSet->getMode(i)->getDataMode()->getNetBitrate().get<Mbps>();
55+
bool alreadyStored = false;
56+
for (int j = 0; j < rateIndex; j++) {
57+
if (supportedRates.rate[j] == rate) {
58+
alreadyStored = true;
59+
break;
60+
}
61+
}
62+
if (!alreadyStored)
63+
supportedRates.rate[rateIndex++] = rate;
64+
}
65+
supportedRates.numRates = rateIndex;
5366
}
5467
}
5568

@@ -163,4 +176,3 @@ void Ieee80211MgmtBase::stop()
163176
} // namespace ieee80211
164177

165178
} // namespace inet
166-

src/inet/physicallayer/wireless/ieee80211/bitlevel/Ieee80211LayeredOfdmTransmitter.cc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ const ITransmission *Ieee80211LayeredOfdmTransmitter::createTransmission(const I
312312
// TODO: compute channel
313313
const simtime_t preambleDuration = mode->getPreambleLength();
314314
const simtime_t headerDuration = mode->getHeaderMode()->getDuration();
315-
const simtime_t dataDuration = mode->getDataMode()->getDuration(packet->getDataLength());
315+
const simtime_t dataDuration = mode->getDataDuration(packet->getDataLength());
316316
return new Ieee80211Transmission(transmitter, packet, startTime, endTime, preambleDuration, headerDuration, dataDuration, startPosition, endPosition, startOrientation, endOrientation, packetModel, bitModel, symbolModel, sampleModel, analogModel, mode, nullptr);
317317
}
318318

@@ -331,4 +331,3 @@ Ieee80211LayeredOfdmTransmitter::~Ieee80211LayeredOfdmTransmitter()
331331
} // namespace physicallayer
332332

333333
} // namespace inet
334-

src/inet/physicallayer/wireless/ieee80211/mode/IIeee80211Mode.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,12 @@ class INET_API IIeee80211DataMode : public cObject, public IPrintableObject
4242
virtual bps getGrossBitrate() const = 0;
4343
virtual b getPaddingLength(b dataLength) const = 0;
4444
virtual b getCompleteLength(b dataLength) const = 0;
45+
// Returns the raw duration of the encoded data symbol train. PPDU-format
46+
// rules may round this duration at the enclosing mode level.
4547
virtual const simtime_t getDuration(b dataLength) const = 0;
4648
virtual const simtime_t getSymbolInterval() const = 0;
49+
// Returns the guard interval used by the data symbols, or -1 when the PHY
50+
// has no meaningful guard interval (for example, non-OFDM modes).
4751
virtual const simtime_t getGuardInterval() const { return -1; }
4852
virtual const IModulation *getModulation() const = 0;
4953
virtual int getNumberOfSpatialStreams() const = 0;

src/inet/physicallayer/wireless/ieee80211/mode/Ieee80211ModeSet.cc

Lines changed: 34 additions & 190 deletions
Original file line numberDiff line numberDiff line change
@@ -30,185 +30,10 @@ std::vector<Ieee80211ModeSet::Entry> Ieee80211ModeSet::completeHtGuardIntervalVa
3030
return entries;
3131

3232
std::vector<Entry> completeEntries = entries;
33-
const Ieee80211Htmcs *legalMcsModes[] = {
34-
&Ieee80211HtmcsTable::htMcs0BW20MHz,
35-
&Ieee80211HtmcsTable::htMcs1BW20MHz,
36-
&Ieee80211HtmcsTable::htMcs2BW20MHz,
37-
&Ieee80211HtmcsTable::htMcs3BW20MHz,
38-
&Ieee80211HtmcsTable::htMcs4BW20MHz,
39-
&Ieee80211HtmcsTable::htMcs5BW20MHz,
40-
&Ieee80211HtmcsTable::htMcs6BW20MHz,
41-
&Ieee80211HtmcsTable::htMcs7BW20MHz,
42-
&Ieee80211HtmcsTable::htMcs8BW20MHz,
43-
&Ieee80211HtmcsTable::htMcs9BW20MHz,
44-
&Ieee80211HtmcsTable::htMcs10BW20MHz,
45-
&Ieee80211HtmcsTable::htMcs11BW20MHz,
46-
&Ieee80211HtmcsTable::htMcs12BW20MHz,
47-
&Ieee80211HtmcsTable::htMcs13BW20MHz,
48-
&Ieee80211HtmcsTable::htMcs14BW20MHz,
49-
&Ieee80211HtmcsTable::htMcs15BW20MHz,
50-
&Ieee80211HtmcsTable::htMcs16BW20MHz,
51-
&Ieee80211HtmcsTable::htMcs17BW20MHz,
52-
&Ieee80211HtmcsTable::htMcs18BW20MHz,
53-
&Ieee80211HtmcsTable::htMcs19BW20MHz,
54-
&Ieee80211HtmcsTable::htMcs20BW20MHz,
55-
&Ieee80211HtmcsTable::htMcs21BW20MHz,
56-
&Ieee80211HtmcsTable::htMcs22BW20MHz,
57-
&Ieee80211HtmcsTable::htMcs23BW20MHz,
58-
&Ieee80211HtmcsTable::htMcs24BW20MHz,
59-
&Ieee80211HtmcsTable::htMcs25BW20MHz,
60-
&Ieee80211HtmcsTable::htMcs26BW20MHz,
61-
&Ieee80211HtmcsTable::htMcs27BW20MHz,
62-
&Ieee80211HtmcsTable::htMcs28BW20MHz,
63-
&Ieee80211HtmcsTable::htMcs29BW20MHz,
64-
&Ieee80211HtmcsTable::htMcs30BW20MHz,
65-
&Ieee80211HtmcsTable::htMcs31BW20MHz,
66-
&Ieee80211HtmcsTable::htMcs33BW20MHz,
67-
&Ieee80211HtmcsTable::htMcs34BW20MHz,
68-
&Ieee80211HtmcsTable::htMcs35BW20MHz,
69-
&Ieee80211HtmcsTable::htMcs36BW20MHz,
70-
&Ieee80211HtmcsTable::htMcs37BW20MHz,
71-
&Ieee80211HtmcsTable::htMcs38BW20MHz,
72-
&Ieee80211HtmcsTable::htMcs39BW20MHz,
73-
&Ieee80211HtmcsTable::htMcs40BW20MHz,
74-
&Ieee80211HtmcsTable::htMcs41BW20MHz,
75-
&Ieee80211HtmcsTable::htMcs42BW20MHz,
76-
&Ieee80211HtmcsTable::htMcs43BW20MHz,
77-
&Ieee80211HtmcsTable::htMcs44BW20MHz,
78-
&Ieee80211HtmcsTable::htMcs45BW20MHz,
79-
&Ieee80211HtmcsTable::htMcs46BW20MHz,
80-
&Ieee80211HtmcsTable::htMcs47BW20MHz,
81-
&Ieee80211HtmcsTable::htMcs48BW20MHz,
82-
&Ieee80211HtmcsTable::htMcs49BW20MHz,
83-
&Ieee80211HtmcsTable::htMcs50BW20MHz,
84-
&Ieee80211HtmcsTable::htMcs51BW20MHz,
85-
&Ieee80211HtmcsTable::htMcs52BW20MHz,
86-
&Ieee80211HtmcsTable::htMcs53BW20MHz,
87-
&Ieee80211HtmcsTable::htMcs54BW20MHz,
88-
&Ieee80211HtmcsTable::htMcs55BW20MHz,
89-
&Ieee80211HtmcsTable::htMcs56BW20MHz,
90-
&Ieee80211HtmcsTable::htMcs57BW20MHz,
91-
&Ieee80211HtmcsTable::htMcs58BW20MHz,
92-
&Ieee80211HtmcsTable::htMcs59BW20MHz,
93-
&Ieee80211HtmcsTable::htMcs60BW20MHz,
94-
&Ieee80211HtmcsTable::htMcs61BW20MHz,
95-
&Ieee80211HtmcsTable::htMcs62BW20MHz,
96-
&Ieee80211HtmcsTable::htMcs63BW20MHz,
97-
&Ieee80211HtmcsTable::htMcs64BW20MHz,
98-
&Ieee80211HtmcsTable::htMcs65BW20MHz,
99-
&Ieee80211HtmcsTable::htMcs66BW20MHz,
100-
&Ieee80211HtmcsTable::htMcs67BW20MHz,
101-
&Ieee80211HtmcsTable::htMcs68BW20MHz,
102-
&Ieee80211HtmcsTable::htMcs69BW20MHz,
103-
&Ieee80211HtmcsTable::htMcs70BW20MHz,
104-
&Ieee80211HtmcsTable::htMcs71BW20MHz,
105-
&Ieee80211HtmcsTable::htMcs72BW20MHz,
106-
&Ieee80211HtmcsTable::htMcs73BW20MHz,
107-
&Ieee80211HtmcsTable::htMcs74BW20MHz,
108-
&Ieee80211HtmcsTable::htMcs75BW20MHz,
109-
&Ieee80211HtmcsTable::htMcs76BW20MHz,
110-
&Ieee80211HtmcsTable::htMcs0BW40MHz,
111-
&Ieee80211HtmcsTable::htMcs1BW40MHz,
112-
&Ieee80211HtmcsTable::htMcs2BW40MHz,
113-
&Ieee80211HtmcsTable::htMcs3BW40MHz,
114-
&Ieee80211HtmcsTable::htMcs4BW40MHz,
115-
&Ieee80211HtmcsTable::htMcs5BW40MHz,
116-
&Ieee80211HtmcsTable::htMcs6BW40MHz,
117-
&Ieee80211HtmcsTable::htMcs7BW40MHz,
118-
&Ieee80211HtmcsTable::htMcs8BW40MHz,
119-
&Ieee80211HtmcsTable::htMcs9BW40MHz,
120-
&Ieee80211HtmcsTable::htMcs10BW40MHz,
121-
&Ieee80211HtmcsTable::htMcs11BW40MHz,
122-
&Ieee80211HtmcsTable::htMcs12BW40MHz,
123-
&Ieee80211HtmcsTable::htMcs13BW40MHz,
124-
&Ieee80211HtmcsTable::htMcs14BW40MHz,
125-
&Ieee80211HtmcsTable::htMcs15BW40MHz,
126-
&Ieee80211HtmcsTable::htMcs16BW40MHz,
127-
&Ieee80211HtmcsTable::htMcs17BW40MHz,
128-
&Ieee80211HtmcsTable::htMcs18BW40MHz,
129-
&Ieee80211HtmcsTable::htMcs19BW40MHz,
130-
&Ieee80211HtmcsTable::htMcs20BW40MHz,
131-
&Ieee80211HtmcsTable::htMcs21BW40MHz,
132-
&Ieee80211HtmcsTable::htMcs22BW40MHz,
133-
&Ieee80211HtmcsTable::htMcs23BW40MHz,
134-
&Ieee80211HtmcsTable::htMcs24BW40MHz,
135-
&Ieee80211HtmcsTable::htMcs25BW40MHz,
136-
&Ieee80211HtmcsTable::htMcs26BW40MHz,
137-
&Ieee80211HtmcsTable::htMcs27BW40MHz,
138-
&Ieee80211HtmcsTable::htMcs28BW40MHz,
139-
&Ieee80211HtmcsTable::htMcs29BW40MHz,
140-
&Ieee80211HtmcsTable::htMcs30BW40MHz,
141-
&Ieee80211HtmcsTable::htMcs31BW40MHz,
142-
&Ieee80211HtmcsTable::htMcs32BW40MHz,
143-
&Ieee80211HtmcsTable::htMcs33BW40MHz,
144-
&Ieee80211HtmcsTable::htMcs34BW40MHz,
145-
&Ieee80211HtmcsTable::htMcs35BW40MHz,
146-
&Ieee80211HtmcsTable::htMcs36BW40MHz,
147-
&Ieee80211HtmcsTable::htMcs37BW40MHz,
148-
&Ieee80211HtmcsTable::htMcs38BW40MHz,
149-
&Ieee80211HtmcsTable::htMcs39BW40MHz,
150-
&Ieee80211HtmcsTable::htMcs40BW40MHz,
151-
&Ieee80211HtmcsTable::htMcs41BW40MHz,
152-
&Ieee80211HtmcsTable::htMcs42BW40MHz,
153-
&Ieee80211HtmcsTable::htMcs43BW40MHz,
154-
&Ieee80211HtmcsTable::htMcs44BW40MHz,
155-
&Ieee80211HtmcsTable::htMcs45BW40MHz,
156-
&Ieee80211HtmcsTable::htMcs46BW40MHz,
157-
&Ieee80211HtmcsTable::htMcs47BW40MHz,
158-
&Ieee80211HtmcsTable::htMcs48BW40MHz,
159-
&Ieee80211HtmcsTable::htMcs49BW40MHz,
160-
&Ieee80211HtmcsTable::htMcs50BW40MHz,
161-
&Ieee80211HtmcsTable::htMcs51BW40MHz,
162-
&Ieee80211HtmcsTable::htMcs52BW40MHz,
163-
&Ieee80211HtmcsTable::htMcs53BW40MHz,
164-
&Ieee80211HtmcsTable::htMcs54BW40MHz,
165-
&Ieee80211HtmcsTable::htMcs55BW40MHz,
166-
&Ieee80211HtmcsTable::htMcs56BW40MHz,
167-
&Ieee80211HtmcsTable::htMcs57BW40MHz,
168-
&Ieee80211HtmcsTable::htMcs58BW40MHz,
169-
&Ieee80211HtmcsTable::htMcs59BW40MHz,
170-
&Ieee80211HtmcsTable::htMcs60BW40MHz,
171-
&Ieee80211HtmcsTable::htMcs61BW40MHz,
172-
&Ieee80211HtmcsTable::htMcs62BW40MHz,
173-
&Ieee80211HtmcsTable::htMcs63BW40MHz,
174-
&Ieee80211HtmcsTable::htMcs64BW40MHz,
175-
&Ieee80211HtmcsTable::htMcs65BW40MHz,
176-
&Ieee80211HtmcsTable::htMcs66BW40MHz,
177-
&Ieee80211HtmcsTable::htMcs67BW40MHz,
178-
&Ieee80211HtmcsTable::htMcs68BW40MHz,
179-
&Ieee80211HtmcsTable::htMcs69BW40MHz,
180-
&Ieee80211HtmcsTable::htMcs70BW40MHz,
181-
&Ieee80211HtmcsTable::htMcs71BW40MHz,
182-
&Ieee80211HtmcsTable::htMcs72BW40MHz,
183-
&Ieee80211HtmcsTable::htMcs73BW40MHz,
184-
&Ieee80211HtmcsTable::htMcs74BW40MHz,
185-
&Ieee80211HtmcsTable::htMcs75BW40MHz,
186-
&Ieee80211HtmcsTable::htMcs76BW40MHz,
187-
};
188-
189-
// Preserve the historical catalog entries first. Add the missing legal
190-
// (bandwidth, MCS) tuples from Tables 19-27 through 19-41 in table order.
191-
for (auto mcsMode : legalMcsModes) {
192-
bool found = false;
193-
for (const auto& entry : completeEntries) {
194-
auto htMode = dynamic_cast<const Ieee80211HtMode *>(entry.mode);
195-
if (htMode != nullptr &&
196-
htMode->getDataMode()->getBandwidth() == mcsMode->getBandwidth() &&
197-
htMode->getDataMode()->getMcsIndex() == mcsMode->getMcsIndex())
198-
{
199-
found = true;
200-
break;
201-
}
202-
}
203-
if (!found)
204-
completeEntries.push_back({false, Ieee80211HtCompliantModes::getCompliantMode(
205-
mcsMode, Ieee80211HtMode::BAND_2_4GHZ,
206-
Ieee80211HtPreambleMode::HT_PREAMBLE_MIXED,
207-
Ieee80211HtModeBase::HT_GUARD_INTERVAL_SHORT)});
208-
}
209-
21033
// IEEE Std 802.11-2024, Table 19-6 defines the 800 ns and 400 ns GIs.
211-
// Add the alternate GI for every legal tuple above; short GI is optional.
34+
// Add only the alternate GI for each mode explicitly declared above;
35+
// declaration order, mandatory flags, and the historical catalog remain
36+
// authoritative for this operation mode.
21237
auto numberOfBaseEntries = completeEntries.size();
21338
for (size_t index = 0; index < numberOfBaseEntries; index++) {
21439
auto htMode = check_and_cast<const Ieee80211HtMode *>(completeEntries[index].mode);
@@ -789,24 +614,43 @@ const IIeee80211Mode *Ieee80211ModeSet::getFastestMandatoryMode() const
789614
return nullptr;
790615
}
791616

617+
const IIeee80211Mode *Ieee80211ModeSet::getMandatoryModeAtOrBelow(const IIeee80211Mode *mode) const
618+
{
619+
const auto bitrate = mode->getDataMode()->getNetBitrate();
620+
const IIeee80211Mode *result = nullptr;
621+
for (const auto& entry : entries) {
622+
const auto entryBitrate = entry.mode->getDataMode()->getNetBitrate();
623+
if (entry.isMandatory && entryBitrate <= bitrate &&
624+
(result == nullptr || entryBitrate > result->getDataMode()->getNetBitrate()))
625+
result = entry.mode;
626+
}
627+
return result;
628+
}
629+
792630
const IIeee80211Mode *Ieee80211ModeSet::getSlowerMandatoryMode(const IIeee80211Mode *mode) const
793631
{
794-
int index = findModeIndex(mode);
795-
if (index > 0)
796-
for (int i = index - 1; i >= 0; i--)
797-
if (entries[i].isMandatory)
798-
return entries[i].mode;
799-
return nullptr;
632+
const auto bitrate = mode->getDataMode()->getNetBitrate();
633+
const IIeee80211Mode *result = nullptr;
634+
for (const auto& entry : entries) {
635+
const auto entryBitrate = entry.mode->getDataMode()->getNetBitrate();
636+
if (entry.isMandatory && entryBitrate < bitrate &&
637+
(result == nullptr || entryBitrate > result->getDataMode()->getNetBitrate()))
638+
result = entry.mode;
639+
}
640+
return result;
800641
}
801642

802643
const IIeee80211Mode *Ieee80211ModeSet::getFasterMandatoryMode(const IIeee80211Mode *mode) const
803644
{
804-
int index = findModeIndex(mode);
805-
if (index >= 0)
806-
for (size_t i = index + 1; i < entries.size(); i++)
807-
if (entries[i].isMandatory)
808-
return entries[i].mode;
809-
return nullptr;
645+
const auto bitrate = mode->getDataMode()->getNetBitrate();
646+
const IIeee80211Mode *result = nullptr;
647+
for (const auto& entry : entries) {
648+
const auto entryBitrate = entry.mode->getDataMode()->getNetBitrate();
649+
if (entry.isMandatory && entryBitrate > bitrate &&
650+
(result == nullptr || entryBitrate < result->getDataMode()->getNetBitrate()))
651+
result = entry.mode;
652+
}
653+
return result;
810654
}
811655

812656
const Ieee80211ModeSet *Ieee80211ModeSet::findModeSet(const char *mode)

src/inet/physicallayer/wireless/ieee80211/mode/Ieee80211ModeSet.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ class INET_API Ieee80211ModeSet : public IPrintableObject, public cObject
6363
const IIeee80211Mode *getFasterMode(const IIeee80211Mode *mode) const;
6464
const IIeee80211Mode *getSlowestMandatoryMode() const;
6565
const IIeee80211Mode *getFastestMandatoryMode() const;
66+
const IIeee80211Mode *getMandatoryModeAtOrBelow(const IIeee80211Mode *mode) const;
6667
const IIeee80211Mode *getSlowerMandatoryMode(const IIeee80211Mode *mode) const;
6768
const IIeee80211Mode *getFasterMandatoryMode(const IIeee80211Mode *mode) const;
6869

@@ -85,4 +86,3 @@ class INET_API Ieee80211ModeSet : public IPrintableObject, public cObject
8586
} // namespace inet
8687

8788
#endif
88-

0 commit comments

Comments
 (0)