Skip to content

Commit c1d40fe

Browse files
Ieee80211: fix HT40 medium sensing during reception, band-aware secondary idle check, and rate reconfiguration
- Rx: require receptionState == IDLE in HT40 primaryPhysicallyIdle calculation to prevent transmitting during in-progress frame reception - Hcf: apply DIFS in 2.4 GHz and PIFS in 5 GHz for secondary channel idle verification per IEEE Std 802.11-2024 clause 11.15.9 item b - Ieee80211Radio: restrict publishModeSet so bitrate-only reconfigurations do not reset receiver state or emit spurious listening signals
1 parent a83ec65 commit c1d40fe

3 files changed

Lines changed: 9 additions & 7 deletions

File tree

src/inet/linklayer/ieee80211/mac/Rx.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ void Rx::recomputeMediumFree()
159159
{
160160
bool oldMediumFree = mediumFree;
161161
// note: the duration of mode switching (rx-to-tx or tx-to-rx) should also count as busy
162-
bool primaryPhysicallyIdle = ht40Cca ? !primaryCcaBusy : receptionState == IRadio::RECEPTION_STATE_IDLE;
162+
bool primaryPhysicallyIdle = (receptionState == IRadio::RECEPTION_STATE_IDLE) && (!ht40Cca || !primaryCcaBusy);
163163
mediumFree = primaryPhysicallyIdle && transmissionState == IRadio::TRANSMISSION_STATE_UNDEFINED && !endNavTimer->isScheduled();
164164
if (mediumFree != oldMediumFree) {
165165
for (auto contention : contentions)

src/inet/linklayer/ieee80211/mac/coordinationfunction/Hcf.cc

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -206,10 +206,12 @@ bool Hcf::shouldRestartHt40ChannelAccess(Edcaf *edcaf)
206206
mode->getDataMode()->getBandwidth() != MHz(40))
207207
return false;
208208
// IEEE Std 802.11-2024, 11.15.9 item b):
209-
// If the secondary channel was busy during DIFS before channel access,
210-
// invoke the backoff procedure with the current CW[AC].
211-
simtime_t difs = modeSet->getSifsTime() + 2 * modeSet->getSlotTime();
212-
return !rx->isSecondaryChannelIdleFor(difs);
209+
// Secondary channel must be idle during an interval of DIFS for the 2.4 GHz band
210+
// and PIFS for the 5 GHz band immediately preceding the expiration of the backoff counter.
211+
// If the secondary channel was busy during this interval, invoke the backoff procedure with the current CW[AC].
212+
bool is24GHz = modeSet != nullptr && strstr(modeSet->getName(), "2.4Ghz") != nullptr;
213+
simtime_t requiredIdle = modeSet->getSifsTime() + (is24GHz ? 2 : 1) * modeSet->getSlotTime();
214+
return !rx->isSecondaryChannelIdleFor(requiredIdle);
213215
}
214216

215217
void Hcf::channelGranted(IChannelAccess *channelAccess)
@@ -226,7 +228,7 @@ void Hcf::channelGranted(IChannelAccess *channelAccess)
226228
emit(edcaCollisionDetectedSignal, (unsigned long)internallyCollidedEdcafs.size());
227229
}
228230
if (shouldRestartHt40ChannelAccess(edcaf)) {
229-
EV_INFO << "Secondary channel was busy during DIFS before channel access for HT40 transmission, restarting backoff.\n";
231+
EV_INFO << "Secondary channel was busy during required interval before channel access for HT40 transmission, restarting backoff.\n";
230232
edcaf->restartChannelAccess(this);
231233
return;
232234
}

src/inet/physicallayer/wireless/ieee80211/packetlevel/Ieee80211Radio.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ void Ieee80211Radio::handleUpperCommand(cMessage *message)
169169
throw cRuntimeError("HT 40 MHz operation requires a secondary channel offset of above or below");
170170

171171
bool publishModeSet = targetModeSet != this->modeSet || targetBand != this->band ||
172-
!std::isnan(newBandwidth.get()) || !std::isnan(newBitrate.get()) || *requestedOpMode;
172+
*requestedOpMode;
173173

174174
if (targetChannelNumber != -1 &&
175175
(currentChannel == nullptr || targetBand != this->band || targetChannelNumber != currentChannel->getChannelNumber() ||

0 commit comments

Comments
 (0)