fix(802.11): complete HT guard interval support - #1135
Conversation
| auto bitrate = dataMode->getNetBitrate(); | ||
| auto htMode = dynamic_cast<const Ieee80211HtMode *>(mode); | ||
| bool guardIntervalMatches = guardInterval < SIMTIME_ZERO || | ||
| (htMode != nullptr && htMode->getDataMode()->getGuardInterval() == guardInterval); | ||
| if (minBitrate <= bitrate && bitrate <= maxBitrate && | ||
| (std::isnan(bandwidth.get()) || dataMode->getBandwidth() == bandwidth) && | ||
| (numSpatialStreams == -1 || dataMode->getNumberOfSpatialStreams() == numSpatialStreams)) | ||
| (numSpatialStreams == -1 || dataMode->getNumberOfSpatialStreams() == numSpatialStreams) && | ||
| guardIntervalMatches) |
There was a problem hiding this comment.
🟡 Asking for a specific guard interval outside 802.11n aborts the simulation with a misleading error
A requested guard interval is only ever accepted for 802.11n transmission modes (dynamic_cast<const Ieee80211HtMode *> at src/inet/physicallayer/wireless/ieee80211/mode/Ieee80211ModeSet.cc:706-708), so a network using any other operating mode always finds no usable mode and stops with an "Unknown bitrate" message that never mentions the guard interval.
Impact: Users who configure a guard interval on an 802.11a/g/ac network get an immediate simulation abort with a confusing error about the bitrate instead of a clear message.
Mechanism: HT-only guard-interval predicate combined with the getMode() error path
findMode() builds guardIntervalMatches as guardInterval < SIMTIME_ZERO || (htMode != nullptr && ...). For 802.11ac the entries are Ieee80211VhtMode objects (src/inet/physicallayer/wireless/ieee80211/mode/Ieee80211VhtMode.h:244), which are unrelated to Ieee80211HtMode, even though VHT data modes do carry a guard interval type (src/inet/physicallayer/wireless/ieee80211/mode/Ieee80211VhtMode.h:49). Therefore every entry is rejected and getMode() throws "Unknown bitrate: %g in operation mode: '%s'" (src/inet/physicallayer/wireless/ieee80211/mode/Ieee80211ModeSet.cc:720-726), which is the path taken from RateSelection::initialize() (src/inet/linklayer/ieee80211/mac/rateselection/RateSelection.cc:35) and QosRateSelection::initialize() (src/inet/linklayer/ieee80211/mac/rateselection/QosRateSelection.cc:29) whenever dataFrameGuardInterval is set.
Prompt for agents
In Ieee80211ModeSet::findMode() the new guardInterval filter only matches modes that dynamic_cast to Ieee80211HtMode. Any other mode family (OFDM/ERP/VHT) can never satisfy a non-negative guardInterval request, so getMode() throws "Unknown bitrate" with no hint that the guard interval was the reason. Consider either (a) exposing a guard interval accessor on the data-mode interface (or handling Ieee80211VhtDataMode too) so VHT modes can be matched by guard interval, and/or (b) making the failure diagnosable, e.g. including the requested guard interval in the getMode() error text so users can tell why the lookup failed.
Was this helpful? React with 👍 or 👎 to provide feedback.
- Reused derived HT guard-interval timing instead of raw constants. - Corrected contiguous HT/VHT preamble, header, and data phase accounting, eliminating negative data durations. - Made rate-control ladder steps strictly change bitrate. - Preserved exact GI/bandwidth/NSS modes through transmitter configuration. - Added generic HT/VHT GI-qualified lookup with clearer diagnostics. - Documented that rate qualifiers require a fixed bitrate. - Expanded Ieee80211HtGuardInterval_1.test with timing, lookup, transmitter, ladder, and VHT regressions. The catalog duplication/O(n²) observation was left for a separate maintainability refactor because changing catalog construction could alter legacy equal-bitrate lookup ordering.
2dd9375 to
4aebf17
Compare
Use 3.6 us raw VHT data symbols for short guard intervals and round the aggregate data duration to a 4 us boundary according to IEEE 802.11-2024. Keep VHT signaling intervals and rates independent of the data guard interval. Add an exact PHY compatibility lookup for mode-set transitions. Preserve bitrate, bandwidth, spatial-stream count, and modeled guard-interval presence, and reject incompatible transitions before mutating transmitter state. Document radio command precedence and rate-selection guard-interval qualifiers. Extend the focused IEEE 802.11 guard-interval test with VHT rounding boundaries, signaling checks, compatible and rejected mode-set transitions, and atomic state preservation. Validated with the debug build, the filtered Ieee80211HtGuardInterval_1 unit test, and the lan80211ac Ping1 fingerprint.
This commit addresses all reviewer flags and info items from the PR review, adding documentation and fixing one backward compatibility issue. FLAGS RESOLVED: - MCS table corrections (MCS76 BW20, MCS73 BW40, MCS32 BW40): Verified all three changes against IEEE 802.11-2024 standard tables. All are deliberate standards-compliance corrections with added inline documentation. - Mode-set switching backward compatibility: Fixed findCompatibleMode to handle GI=-1 (unconstrained guard interval) cases, restoring ability to transition between HT and legacy modes that was broken by strict GI matching. - VHT short-GI rounding: Verified rounding behavior against IEEE 802.11-2024 Eq. (21-109). The rounding up to long-GI symbol boundary is required by the standard, correcting the previous raw short-GI symbol train implementation. INFO ITEMS DOCUMENTED: - Mgmt supported-rates rebuild: Added comment explaining the bug fix for stale entry handling and its impact on SupportedRates element contents. - Equal-bitrate HT mode selection: Added warning about fragile invariant dependency on declaration order and stable_sort behavior. - getMandatoryModeAtOrBelow behavior: Added comment explaining equal-bitrate selection logic and functional equivalence despite different mode object returns. - Radio configure opMode precedence: Added comment documenting contract change where modeSet now takes precedence over opMode when both are present. TECHNICAL CHANGES: - Ieee80211ModeSet::findCompatibleMode: Modified GI matching logic to treat GI=-1 as unconstrained, matching any candidate GI while requiring exact match when both GIs are >= 0. This preserves legacy/HT mode transitions. - Added comprehensive inline comments with standard references and behavioral explanations for all modified code paths. All changes verified against IEEE 802.11-2024 standard and compiled successfully in debug mode. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Summary
dataFrameGuardIntervalin both DCF and HCF rate selectionRoot cause
INET represented both HT guard intervals when calculating bitrate, but the predefined mode set exposed only one GI for each tuple, rate selection could not qualify a lookup by GI, and HT data duration always used the 4.0 us long-GI symbol interval.
Implementation
The HT catalog now contains 306 modes: 153 legal bandwidth/MCS tuples, each with long and short GI. Only the mandatory long-GI 20 MHz MCS 0-7 entries remain mandatory.
HT Data uses 4.0 us or 3.6 us symbols as selected. HT-SIG remains on 4.0 us symbols, and HT-mixed short-GI data airtime follows IEEE 802.11-2024 Equation 19-90 by rounding to a 4 us boundary using exact simulation-time ticks. HT-greenfield retains raw 3.6 us data symbols.
Validation
git diff --check: PASSKnown limitations
Peer short-GI capability negotiation and serialization of the HT-SIG Short GI bit remain outside this patch; both are pre-existing model limitations.