Skip to content

Commit b6a3e07

Browse files
802.11: align HT legacy response capabilities
1 parent 5209ca3 commit b6a3e07

8 files changed

Lines changed: 145 additions & 41 deletions

File tree

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ void QosRateSelection::initialize(int stage)
2323
ModeSetListener::initialize(stage);
2424
if (stage == INITSTAGE_LINK_LAYER) {
2525
dataOrMgmtRateControl = dynamic_cast<IRateControl *>(findModuleByPath(par("rateControlModule")));
26+
if (modeSet == nullptr)
27+
throw cRuntimeError("QosRateSelection module %s has no mode set at link-layer initialization", getFullPath().c_str());
2628
resolveConfiguredModes(modeSet);
2729
}
2830
}

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,13 @@ simple QosRateSelection extends SimpleModule
2626

2727
double multicastFrameBitrate @unit(bps) = default(-1bps);
2828

29+
// -1 selects the standard-derived automatic response. In a 2.4 GHz HT profile,
30+
// a configured HT bitrate is an upper bound mapped to the highest mandatory
31+
// non-HT rate at or below it; it does not select an exact HT ACK PPDU.
2932
double responseAckFrameBitrate @unit(bps) = default(-1bps);
33+
// -1 selects the standard-derived automatic response. In a 2.4 GHz HT profile,
34+
// a configured HT bitrate is an upper bound mapped to the highest mandatory
35+
// non-HT rate at or below it; it does not select an exact HT BlockAck PPDU.
3036
double responseBlockAckFrameBitrate @unit(bps) = default(-1bps);
3137
// -1 selects the standard-derived automatic response. A configured HT value is a deliberate
3238
// model override translated only to HT-mixed while preserving the resolved configured mode's
@@ -42,4 +48,3 @@ simple QosRateSelection extends SimpleModule
4248
double controlFrameBitrate @unit(bps) = default(-1bps);
4349
@display("i=block/cogwheel");
4450
}
45-

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ simple RateSelection extends SimpleModule like IRateSelection
2222

2323
double multicastFrameBitrate @unit(bps) = default(-1bps);
2424

25+
// -1 selects the standard-derived automatic response. In a 2.4 GHz HT profile,
26+
// a configured HT bitrate is an upper bound mapped to the highest mandatory
27+
// non-HT rate at or below it; it does not select an exact HT ACK PPDU.
2528
double responseAckFrameBitrate @unit(bps) = default(-1bps);
2629
// -1 selects the standard-derived automatic response. A configured HT value is a deliberate
2730
// model override translated only to HT-mixed while preserving the resolved configured mode's
@@ -37,4 +40,3 @@ simple RateSelection extends SimpleModule like IRateSelection
3740
double controlFrameBitrate @unit(bps) = default(-1bps);
3841
@display("i=block/cogwheel");
3942
}
40-

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

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -108,25 +108,28 @@ static std::vector<Ieee80211ModeSet::Entry> createHtSupportedEntries(Ieee80211Ht
108108
if (preambleFormat == Ieee80211HtPreambleMode::HT_PREAMBLE_GREENFIELD) {
109109
auto mixedEntries = createHtEntries(Ieee80211HtPreambleMode::HT_PREAMBLE_MIXED);
110110
result.insert(result.end(), mixedEntries.begin(), mixedEntries.end());
111-
// Supplement the Greenfield profile with the HT-mixed and mandatory
112-
// Clause 16/18 capabilities required by IEEE 802.11-2024 19.1.1 and
113-
// 19.1.4. The legacy mixed profile intentionally remains selectable-only
114-
// to preserve its established rate-selection and mode-membership contract.
115-
result.insert(result.end(), {
116-
{ true, &Ieee80211DsssCompliantModes::dsssMode1Mbps },
117-
{ true, &Ieee80211DsssCompliantModes::dsssMode2Mbps },
118-
{ true, &Ieee80211HrDsssCompliantModes::hrDsssMode5_5MbpsCckLongPreamble },
119-
{ true, &Ieee80211ErpOfdmCompliantModes::erpOfdmMode6Mbps },
120-
{ false, &Ieee80211ErpOfdmCompliantModes::erpOfdmMode9Mbps },
121-
{ true, &Ieee80211HrDsssCompliantModes::hrDsssMode11MbpsCckLongPreamble },
122-
{ true, &Ieee80211ErpOfdmCompliantModes::erpOfdmMode12Mbps },
123-
{ false, &Ieee80211ErpOfdmCompliantModes::erpOfdmMode18Mbps },
124-
{ true, &Ieee80211ErpOfdmCompliantModes::erpOfdmMode24Mbps },
125-
{ false, &Ieee80211ErpOfdmCompliantModes::erpOfdmMode36Mbps },
126-
{ false, &Ieee80211ErpOfdmCompliantModes::erpOfdmMode48Mbps },
127-
{ false, &Ieee80211ErpOfdmCompliantModes::erpOfdmMode54Mbps },
128-
});
129111
}
112+
// Every 2.4 GHz HT STA supports the mandatory Clause 16/18 modes, and a
113+
// Greenfield STA additionally supports HT-mixed PPDUs (IEEE 802.11-2024
114+
// 19.1.1 and 19.1.4). These are supplementary capabilities rather than
115+
// selectable operating modes, so they are kept out of createHtEntries().
116+
result.insert(result.end(), {
117+
{ true, &Ieee80211DsssCompliantModes::dsssMode1Mbps },
118+
{ true, &Ieee80211DsssCompliantModes::dsssMode2Mbps },
119+
{ true, &Ieee80211HrDsssCompliantModes::hrDsssMode2MbpsShortPreamble },
120+
{ true, &Ieee80211HrDsssCompliantModes::hrDsssMode5_5MbpsCckLongPreamble },
121+
{ true, &Ieee80211HrDsssCompliantModes::hrDsssMode5_5MbpsCckShortPreamble },
122+
{ true, &Ieee80211ErpOfdmCompliantModes::erpOfdmMode6Mbps },
123+
{ false, &Ieee80211ErpOfdmCompliantModes::erpOfdmMode9Mbps },
124+
{ true, &Ieee80211HrDsssCompliantModes::hrDsssMode11MbpsCckLongPreamble },
125+
{ true, &Ieee80211HrDsssCompliantModes::hrDsssMode11MbpsCckShortPreamble },
126+
{ true, &Ieee80211ErpOfdmCompliantModes::erpOfdmMode12Mbps },
127+
{ false, &Ieee80211ErpOfdmCompliantModes::erpOfdmMode18Mbps },
128+
{ true, &Ieee80211ErpOfdmCompliantModes::erpOfdmMode24Mbps },
129+
{ false, &Ieee80211ErpOfdmCompliantModes::erpOfdmMode36Mbps },
130+
{ false, &Ieee80211ErpOfdmCompliantModes::erpOfdmMode48Mbps },
131+
{ false, &Ieee80211ErpOfdmCompliantModes::erpOfdmMode54Mbps },
132+
});
130133
return result;
131134
}
132135

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,8 @@ class INET_API Ieee80211ModeSet : public IPrintableObject, public cObject
8282
// configured HT mode is a deliberate override translated only to HT-mixed.
8383
const IIeee80211Mode *getControlResponseMode(const IIeee80211Mode *mode, const IIeee80211Mode *configuredMode = nullptr) const;
8484
const IIeee80211Mode *getMandatoryControlResponseMode(const IIeee80211Mode *mode) const;
85-
// Greenfield HT modes are converted to non-HT responses; mixed-profile HT
86-
// modes retain the selected HT format. mandatory=false preserves the rate.
85+
// 2.4 GHz HT modes are converted to non-HT responses. With mandatory=false,
86+
// the input bitrate is used as a ceiling for selecting that non-HT mode.
8787
const IIeee80211Mode *getNonHtControlResponseMode(const IIeee80211Mode *mode, bool mandatory = true) const;
8888

8989
static const Ieee80211ModeSet *findModeSet(const char *mode);

tests/module/Ieee80211ConfiguredResponseRateSelection.test

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
%description:
2-
Checks through the public rate-selection API that Greenfield ACK/BlockAck responses use
3-
non-HT rates, mixed responses retain HT rates, and configured HT CTS rates use exact
4-
HT-mixed counterparts.
2+
Checks through the public rate-selection API that 2.4 GHz HT ACK/BlockAck responses use
3+
non-HT rates and configured HT CTS rates use exact HT-mixed counterparts.
54

65
%file: Test.cc
76
#include <cstring>
@@ -100,9 +99,9 @@ class ConfiguredResponseProbe : public cSimpleModule
10099

101100
auto basicBlockAckReq = makeShared<Ieee80211BasicBlockAckReq>();
102101
assertNonHtResponse("QoS Basic BlockAck", qosRateSelection->computeResponseBlockAckFrameMode(&packet, basicBlockAckReq));
103-
assertHtMixedResponse("Dynamic mixed QoS ACK", dynamicQosRateSelection->computeResponseAckFrameMode(&mixedPacket, nullptr));
102+
assertNonHtResponse("Dynamic mixed QoS ACK", dynamicQosRateSelection->computeResponseAckFrameMode(&mixedPacket, nullptr));
104103
assertHtMixedResponse("Dynamic mixed QoS CTS", dynamicQosRateSelection->computeResponseCtsFrameMode(&mixedPacket, nullptr));
105-
assertHtMixedResponse("Dynamic mixed QoS Basic BlockAck", dynamicQosRateSelection->computeResponseBlockAckFrameMode(&mixedPacket, basicBlockAckReq));
104+
assertNonHtResponse("Dynamic mixed QoS Basic BlockAck", dynamicQosRateSelection->computeResponseBlockAckFrameMode(&mixedPacket, basicBlockAckReq));
106105
auto optionalHtMode = Ieee80211HtCompliantModes::getCompliantMode(
107106
&Ieee80211HtmcsTable::htMcs8BW20MHz,
108107
Ieee80211HtMode::BAND_2_4GHZ,
@@ -130,9 +129,9 @@ class ConfiguredResponseProbe : public cSimpleModule
130129
ASSERT(qosRateSelection->computeMode(&dataPacket, dataHeader, nullptr) == mixedSourceMode);
131130
assertHtMixedResponse("Rebound DCF CTS mixed", dcfRateSelection->computeResponseCtsFrameMode(&mixedPacket, nullptr));
132131
assertHtMixedResponse("Rebound QoS CTS mixed", qosRateSelection->computeResponseCtsFrameMode(&mixedPacket, nullptr));
133-
assertHtMixedResponse("Rebound DCF ACK mixed", dcfRateSelection->computeResponseAckFrameMode(nullptr, nullptr));
134-
assertHtMixedResponse("Rebound QoS ACK mixed", qosRateSelection->computeResponseAckFrameMode(nullptr, nullptr));
135-
assertHtMixedResponse("Rebound QoS BlockAck mixed", qosRateSelection->computeResponseBlockAckFrameMode(nullptr, basicBlockAckReq));
132+
assertNonHtResponse("Rebound DCF ACK mixed", dcfRateSelection->computeResponseAckFrameMode(nullptr, nullptr));
133+
assertNonHtResponse("Rebound QoS ACK mixed", qosRateSelection->computeResponseAckFrameMode(nullptr, nullptr));
134+
assertNonHtResponse("Rebound QoS BlockAck mixed", qosRateSelection->computeResponseBlockAckFrameMode(nullptr, basicBlockAckReq));
136135
wlan->emit(modesetChangedSignal, const_cast<Ieee80211ModeSet *>(Ieee80211ModeSet::getModeSet("n(greenfield-2.4Ghz)")));
137136
ASSERT(dcfRateSelection->computeMode(&dataPacket, dataHeader) == sourceMode);
138137
ASSERT(qosRateSelection->computeMode(&dataPacket, dataHeader, nullptr) == sourceMode);
@@ -142,7 +141,7 @@ class ConfiguredResponseProbe : public cSimpleModule
142141
assertNonHtResponse("Rebound QoS ACK Greenfield", qosRateSelection->computeResponseAckFrameMode(nullptr, nullptr));
143142
assertNonHtResponse("Rebound QoS BlockAck Greenfield", qosRateSelection->computeResponseBlockAckFrameMode(nullptr, basicBlockAckReq));
144143

145-
std::cout << "Mixed ACK/Basic BlockAck remain HT while Greenfield responses use non-HT 6 Mbps; configured HT CTS uses the exact HT-mixed MCS override and requires an eliciting mode tag.\n";
144+
std::cout << "Mixed and Greenfield ACK/Basic BlockAck use non-HT 6 Mbps; configured HT CTS uses the exact HT-mixed MCS override and requires an eliciting mode tag.\n";
146145
}
147146
};
148147

@@ -204,4 +203,4 @@ sim-time-limit = 1s
204203
%extraargs: -c ConfiguredResponses
205204

206205
%contains: stdout
207-
Mixed ACK/Basic BlockAck remain HT while Greenfield responses use non-HT 6 Mbps; configured HT CTS uses the exact HT-mixed MCS override and requires an eliciting mode tag.
206+
Mixed and Greenfield ACK/Basic BlockAck use non-HT 6 Mbps; configured HT CTS uses the exact HT-mixed MCS override and requires an eliciting mode tag.
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
%description:
2+
QosRateSelection must reject reaching link-layer initialization without a mode set.
3+
4+
%file: Test.cc
5+
#include "inet/common/InitStages.h"
6+
#include "inet/linklayer/ieee80211/mac/rateselection/QosRateSelection.h"
7+
8+
using namespace inet;
9+
using namespace inet::ieee80211;
10+
11+
namespace QosRateSelectionNullModeSetInitialization {
12+
13+
class NullModeSetQosRateSelection : public QosRateSelection
14+
{
15+
protected:
16+
virtual void initialize(int stage) override
17+
{
18+
if (stage == INITSTAGE_LINK_LAYER)
19+
QosRateSelection::initialize(stage);
20+
}
21+
};
22+
23+
Define_Module(NullModeSetQosRateSelection);
24+
25+
} // namespace QosRateSelectionNullModeSetInitialization
26+
27+
%file: test.ned
28+
import inet.linklayer.ieee80211.mac.rateselection.QosRateSelection;
29+
30+
simple NullModeSetQosRateSelection extends QosRateSelection
31+
{
32+
parameters:
33+
@class(NullModeSetQosRateSelection);
34+
rateControlModule = "";
35+
}
36+
37+
network TestQosRateSelectionNullModeSetInitialization
38+
{
39+
submodules:
40+
rateSelection: NullModeSetQosRateSelection;
41+
}
42+
43+
%inifile: omnetpp.ini
44+
[General]
45+
network = TestQosRateSelectionNullModeSetInitialization
46+
ned-path = .;../../../../src;../../lib
47+
cmdenv-express-mode = true
48+
record-vector-results = false
49+
50+
%exitcode: 1
51+
52+
%contains-regex: stderr
53+
QosRateSelection module TestQosRateSelectionNullModeSetInitialization\.rateSelection has no mode set at link-layer initialization

tests/unit/Ieee80211HtGreenfield_1.test

Lines changed: 49 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
%description:
22
Checks that the 802.11n mixed and Greenfield mode profiles preserve distinct
3-
preamble formats and timing, retain strict membership and supplementary Greenfield control-response support, including legacy fallback rates. Also checks VHT cache identity.
3+
preamble formats and timing, retain strict membership, and support the legacy
4+
2.4 GHz HT capabilities used for non-HT control responses. Also checks VHT cache identity.
45

56
%includes:
67
#include <cstring>
78

89
#include "inet/common/packet/Packet.h"
10+
#include "inet/physicallayer/wireless/ieee80211/mode/Ieee80211DsssMode.h"
911
#include "inet/physicallayer/wireless/ieee80211/mode/Ieee80211DsssOfdmMode.h"
1012
#include "inet/physicallayer/wireless/ieee80211/mode/Ieee80211ErpOfdmMode.h"
13+
#include "inet/physicallayer/wireless/ieee80211/mode/Ieee80211HrDsssMode.h"
1114
#include "inet/physicallayer/wireless/ieee80211/mode/Ieee80211HtMode.h"
1215
#include "inet/physicallayer/wireless/ieee80211/mode/Ieee80211ModeSet.h"
1316
#include "inet/physicallayer/wireless/ieee80211/packetlevel/Ieee80211Transmitter.h"
@@ -94,10 +97,38 @@ ASSERT(mixedProfile->supportsMode(mixedMode));
9497
ASSERT(greenfieldProfile->supportsMode(greenfieldMode));
9598
ASSERT(greenfieldProfile->supportsMode(mixedMode));
9699
ASSERT(!mixedProfile->supportsMode(greenfieldMode));
97-
ASSERT(!mixedProfile->supportsMode(&Ieee80211ErpOfdmCompliantModes::erpOfdmMode6Mbps));
98-
ASSERT(!mixedProfile->containsMode(&Ieee80211ErpOfdmCompliantModes::erpOfdmMode6Mbps));
99-
ASSERT(greenfieldProfile->supportsMode(&Ieee80211ErpOfdmCompliantModes::erpOfdmMode6Mbps));
100-
ASSERT(mixedProfile->getNonHtControlResponseMode(mixedMode) == mixedMode);
100+
ASSERT(mixedProfile->getSifsTime() == SimTime(10, SIMTIME_US));
101+
ASSERT(greenfieldProfile->getSifsTime() == SimTime(10, SIMTIME_US));
102+
ASSERT(mixedProfile->getSlotTime() == SimTime(20, SIMTIME_US));
103+
ASSERT(greenfieldProfile->getSlotTime() == SimTime(20, SIMTIME_US));
104+
ASSERT(mixedProfile->getCwMin() == 15);
105+
ASSERT(greenfieldProfile->getCwMin() == 15);
106+
const IIeee80211Mode *mandatoryLegacyModes[] = {
107+
&Ieee80211DsssCompliantModes::dsssMode1Mbps,
108+
&Ieee80211DsssCompliantModes::dsssMode2Mbps,
109+
&Ieee80211HrDsssCompliantModes::hrDsssMode2MbpsShortPreamble,
110+
&Ieee80211HrDsssCompliantModes::hrDsssMode5_5MbpsCckLongPreamble,
111+
&Ieee80211HrDsssCompliantModes::hrDsssMode5_5MbpsCckShortPreamble,
112+
&Ieee80211ErpOfdmCompliantModes::erpOfdmMode6Mbps,
113+
&Ieee80211HrDsssCompliantModes::hrDsssMode11MbpsCckLongPreamble,
114+
&Ieee80211HrDsssCompliantModes::hrDsssMode11MbpsCckShortPreamble,
115+
&Ieee80211ErpOfdmCompliantModes::erpOfdmMode12Mbps,
116+
&Ieee80211ErpOfdmCompliantModes::erpOfdmMode24Mbps,
117+
};
118+
for (auto legacyMode : mandatoryLegacyModes) {
119+
ASSERT(mixedProfile->supportsMode(legacyMode));
120+
ASSERT(greenfieldProfile->supportsMode(legacyMode));
121+
ASSERT(!mixedProfile->containsMode(legacyMode));
122+
ASSERT(!greenfieldProfile->containsMode(legacyMode));
123+
}
124+
ASSERT(Ieee80211DsssCompliantModes::dsssMode1Mbps.getDataMode()->getBandwidth() == MHz(22));
125+
ASSERT(Ieee80211DsssCompliantModes::dsssMode2Mbps.getDataMode()->getBandwidth() == MHz(22));
126+
ASSERT(Ieee80211HrDsssCompliantModes::hrDsssMode2MbpsShortPreamble.getDataMode()->getBandwidth() == MHz(22));
127+
ASSERT(Ieee80211HrDsssCompliantModes::hrDsssMode5_5MbpsCckLongPreamble.getDataMode()->getBandwidth() == MHz(22));
128+
ASSERT(Ieee80211HrDsssCompliantModes::hrDsssMode5_5MbpsCckShortPreamble.getDataMode()->getBandwidth() == MHz(22));
129+
ASSERT(Ieee80211HrDsssCompliantModes::hrDsssMode11MbpsCckLongPreamble.getDataMode()->getBandwidth() == MHz(22));
130+
ASSERT(Ieee80211HrDsssCompliantModes::hrDsssMode11MbpsCckShortPreamble.getDataMode()->getBandwidth() == MHz(22));
131+
ASSERT(mixedProfile->getNonHtControlResponseMode(mixedMode) == &Ieee80211ErpOfdmCompliantModes::erpOfdmMode6Mbps);
101132
ASSERT(greenfieldProfile->getNonHtControlResponseMode(greenfieldMode) == &Ieee80211ErpOfdmCompliantModes::erpOfdmMode6Mbps);
102133
ASSERT(greenfieldProfile->getNonHtControlResponseMode(&Ieee80211ErpOfdmCompliantModes::erpOfdmMode9Mbps) == &Ieee80211ErpOfdmCompliantModes::erpOfdmMode6Mbps);
103134
ASSERT(mixedProfile->getControlResponseMode(mixedMode) == mixedMode);
@@ -146,9 +177,9 @@ ASSERT(configuredMixedResponse->getDataMode()->getMcsIndex() == greenfieldMcs15-
146177
ASSERT(configuredMixedResponse->getDataMode()->getBandwidth() == greenfieldMcs15->getDataMode()->getBandwidth());
147178
ASSERT(configuredMixedResponse->getDataMode()->getNumberOfSpatialStreams() == greenfieldMcs15->getDataMode()->getNumberOfSpatialStreams());
148179
ASSERT(configuredMixedResponse->getDataMode()->getGuardIntervalType() == greenfieldMcs15->getDataMode()->getGuardIntervalType());
149-
ASSERT(mixedProfile->getMandatoryControlResponseMode(mixedMcs7) == mixedMcs7);
150-
ASSERT(mixedProfile->getMandatoryControlResponseMode(mixedMcs15) == mixedMcs7);
151-
ASSERT(mixedProfile->getNonHtControlResponseMode(mixedMcs15, false) == mixedMcs15);
180+
ASSERT(mixedProfile->getMandatoryControlResponseMode(mixedMcs7) == &Ieee80211ErpOfdmCompliantModes::erpOfdmMode24Mbps);
181+
ASSERT(mixedProfile->getMandatoryControlResponseMode(mixedMcs15) == &Ieee80211ErpOfdmCompliantModes::erpOfdmMode24Mbps);
182+
ASSERT(mixedProfile->getNonHtControlResponseMode(mixedMcs15, false) == &Ieee80211ErpOfdmCompliantModes::erpOfdmMode24Mbps);
152183

153184
auto greenfieldMcs8Bw40 = Ieee80211HtCompliantModes::getCompliantMode(
154185
&Ieee80211HtmcsTable::htMcs8BW40MHz,
@@ -178,13 +209,22 @@ Packet supportedLegacyPacket("supportedLegacy");
178209
supportedLegacyPacket.addTag<Ieee80211ModeReq>()->setMode(&Ieee80211ErpOfdmCompliantModes::erpOfdmMode6Mbps);
179210
ASSERT(transmitter->getTestTransmissionMode(&supportedLegacyPacket) == &Ieee80211ErpOfdmCompliantModes::erpOfdmMode6Mbps);
180211
transmitter->setModeSet(mixedProfile);
212+
ASSERT(transmitter->getTestTransmissionMode(&supportedLegacyPacket) == &Ieee80211ErpOfdmCompliantModes::erpOfdmMode6Mbps);
181213
try {
182-
transmitter->getTestTransmissionMode(&supportedLegacyPacket);
214+
transmitter->setMode(&Ieee80211ErpOfdmCompliantModes::erpOfdmMode6Mbps);
183215
ASSERT(false);
184216
}
185217
catch (const cRuntimeError&) {
218+
ASSERT(transmitter->getTestMode() == mixedMode);
186219
}
187220
transmitter->setModeSet(greenfieldProfile);
221+
try {
222+
transmitter->setMode(&Ieee80211ErpOfdmCompliantModes::erpOfdmMode6Mbps);
223+
ASSERT(false);
224+
}
225+
catch (const cRuntimeError&) {
226+
ASSERT(transmitter->getTestMode() == greenfieldMode);
227+
}
188228
try {
189229
transmitter->setMode(mixedMode);
190230
ASSERT(false);

0 commit comments

Comments
 (0)