Skip to content

IEEE 802.11: support HT and VHT guard intervals, atomic mode-set switching, and rate selection - #1145

Open
mgonzalezlopezudc wants to merge 12 commits into
inet-framework:masterfrom
mgonzalezlopezudc:cleanup/fix-ht-gi
Open

IEEE 802.11: support HT and VHT guard intervals, atomic mode-set switching, and rate selection#1145
mgonzalezlopezudc wants to merge 12 commits into
inet-framework:masterfrom
mgonzalezlopezudc:cleanup/fix-ht-gi

Conversation

@mgonzalezlopezudc

@mgonzalezlopezudc mgonzalezlopezudc commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

Overview and Motivation

Correct IEEE 802.11 HT and VHT guard-interval timing and mode selection, keep configured fixed and mandatory modes synchronized across runtime physical-layer mode-set transitions with fail-fast consumer updates, constrain group-addressed transmissions to mandatory legacy rates in mixed HT mode, and harden management frame serialization/deserialization against oversized SSIDs and malformed response AIDs.

Summary of Changes

  1. Whitespace Isolation (PR-SPLIT-WHITESPACE):

    • Pre-emptively strip redundant blank lines from touched IEEE 802.11 sources so subsequent functional changes carry no incidental formatting diffs.
  2. PHY Timing, MCS Definitions, and Mode Cache Keys:

    • Require every data mode to state its modeled guard interval (getDataGuardInterval()), preserving -1s for PHYs without one (IIeee80211Mode).
    • Correct table definitions for HT MCS 32 (1 spatial stream, BPSK), MCS 73 (stream 3 16-QAM at 40 MHz), and MCS 76 (stream 4 16-QAM at 20 MHz) per IEEE Std 802.11-2024.
    • Decouple HT/VHT SIGNAL field symbol duration from data GI, maintaining 4 µs symbol timing for signal fields (Table 19-6 and Table 21-5).
    • Round mixed-format HT and VHT short-GI data airtime up to 4 µs symbol boundaries (Eq. 19-90 and Eq. 21-109) while leaving greenfield short-GI data airtimes unpadded (Eq. 19-92).
    • Qualify mode cache keys in Ieee80211HtMode and Ieee80211VhtMode with band mode and preamble format, preventing cache aliasing across frequency bands and rejecting unsupported VHT greenfield requests before lookup.
  3. Mode Lookup, Catalog Completion, and Rate Stepping:

    • Complete Ieee80211ModeSet for "n(mixed-2.4Ghz)" with short and long guard-interval variants.
    • Add guard-interval qualified lookups in findMode and getMode.
    • Add findCompatibleMode for exact PHY parameter matching across mode sets (treating negative guard intervals as wildcards for non-OFDM modes).
    • Enforce strict rate stepping monotonicity across adjacent rates in getSlowerMode, getFasterMode, getSlowerMandatoryMode, and getFasterMandatoryMode.
    • Add getMandatoryModeAtOrBelow to locate the highest-bitrate mandatory mode at or below a requested transmission rate.
  4. MAC Rate Selection Configuration and Group-Addressed Fallback:

    • Add dataFrameGuardInterval parameter to RateSelection and QosRateSelection ("long", "short", or "unspecified"), enabling explicit short-GI qualification for fixed data rates.
    • Use getMandatoryModeAtOrBelow in computeResponseAckFrameMode and computeResponseCtsFrameMode so mandatory response modes can match the triggering frame's bitrate without stepping down unnecessarily.
    • Constrain Beacon and multicast frame transmission to mandatory legacy operational modes when an advertised basic legacy rate set is non-empty, preventing mandatory HT MCS rates from rendering discovery frames invisible to legacy stations in mixed BSSs.
  5. Dynamic Mode-Set Synchronization and Fail-Fast Consumer Updates:

    • Apply typed consumers synchronously (transmitter, receiver, MAC HT capabilities, advertised rates, channel access, and rate selectors) before publishing modesetChangedSignal on runtime mode-set transitions (setModeSet and setModeSetAndMode).
    • Subscribe Ieee80211Mac to modesetChangedSignal at INITSTAGE_LINK_LAYER and rebuild configured fixed mode pointers and mandatory mode references in RateSelection and QosRateSelection, invalidating receiver caches and clearing stale rate history.
    • Validate compatible or explicitly selected transmitter modes, reject reentrant transitions, and treat consumer or observer failures as fatal simulation errors (cRuntimeError).
  6. Management Wire Codec Hardening:

    • Enforce IEEE Std 802.11-2024 Clause 9.4.2.2 SSID length bounds (0 to 32 octets) during both serialization and deserialization across Beacon, Probe Request, Probe Response, Association Request, and Reassociation Request frames.
    • Tolerate out-of-range or non-zero malformed AIDs in association and reassociation response byte streams during deserialization by marking the frame incorrect and substituting zero instead of throwing cRuntimeError, preserving parsing of status codes and trailing elements.

Series Reading Order

The 12 commits are linear on top of upstream master:

  1. db566892b7ieee80211: remove redundant blank lines
    Removes redundant blank lines across affected IEEE 802.11 source files to isolate whitespace cleanup from subsequent functional edits (PR-SPLIT-WHITESPACE).
  2. 7df7971e85ieee80211: require explicit data-mode guard interval queries
    Exposes getDataGuardInterval() in IIeee80211Mode across PHY mode classes, preserving -1s sentinel for PHYs without guard intervals; documents migration guide.
  3. abc2e3e9a8ieee80211: correct HT MCS 32, 73 and 76 definitions
    Corrects spatial stream count and modulation for optional HT MCS entries 32 (1 stream BPSK), 73 (stream 3 16-QAM at 40 MHz), and 76 (stream 4 16-QAM at 20 MHz).
  4. 6b9cf9177cieee80211: distinguish band and preamble in mode caches
    Qualifies HT and VHT mode cache keys by band mode and preamble format to prevent cache aliasing, and rejects unsupported VHT greenfield requests before lookup.
  5. bc01713da4ieee80211: correct HT/VHT PPDU timing
    Keeps SIGNAL field symbol duration at 4 µs independent of data GI, rounds mixed HT/VHT data airtime to 4 µs symbol boundaries, and aligns transmitter PPDU phase calculations.
  6. 04a96e2057ieee80211: complete guard-interval mode lookup
    Completes mixed 2.4 GHz HT mode set with short-GI variants, adds GI-qualified lookups, enforces strict rate stepping monotonicity, adds findCompatibleMode and getMandatoryModeAtOrBelow, and adds Ieee80211HtGuardInterval_1.test.
  7. b98f44e130ieee80211: qualify fixed data rates by guard interval
    Adds dataFrameGuardInterval parameter to RateSelection and QosRateSelection ("long", "short", or "unspecified") to qualify fixed bitrate lookups.
  8. 036a54bfa7ieee80211: select mandatory response rates by bitrate
    Uses getMandatoryModeAtOrBelow in RateSelection ACK/CTS response mode selection so mandatory response rates match the triggering frame's bitrate when possible.
  9. 9039d75807ieee80211: use legacy basic rates for group-addressed frames
    Constrains group-addressed frames to mandatory legacy operational rates when basic rates are present, adds Ieee80211MixedHtDiscovery_1.test, and updates lan80211ac Ping1 plus 12 legacy configuration fingerprints with causal provenance.
  10. 385e01373aieee80211: apply mode-set consumers before notification
    Synchronously updates transmitter, receiver, MAC HT capabilities, rates, channel access, and rate selectors before publishing modesetChangedSignal; enforces fail-fast error handling; adds Ieee80211ModeSetTransition_1.test and Ieee80211ModeSetFailure_1.test.
  11. d400a5a2f5ieee80211: enforce SSID element length bounds
    Enforces 0..32 octet bounds on SSID serialization and deserialization across management frames; adds tests in Ieee80211SupportedRates_1.test.
  12. e4e39e24c4ieee80211: mark malformed response AIDs incorrect
    Handles malformed wire AIDs in (re)association responses by marking the frame incorrect and substituting zero instead of throwing cRuntimeError; adds tests in Ieee80211MgmtFrameSerializer_1.test.

Architectural Surface

Contracts and Interfaces:

  • IIeee80211Mode: Added getDataGuardInterval() requirement.
  • IIeee80211ModeSetListener: Synchronous participant callback interface for coordinated mode-set switching.
  • Ieee80211Radio / Ieee80211Transmitter: Added setModeSetAndMode(const Ieee80211ModeSet *, const IIeee80211Mode *) with membership verification and typed consumer pre-notification phase.
    Configuration Surface:
  • RateSelection.ned & QosRateSelection.ned: Added string dataFrameGuardInterval = default("unspecified"); ("long", "short", or "unspecified").
    Signals and Observability:
  • Registered modesetChangedSignal on Ieee80211Radio, emitted on mode-set changes and subscribed by Ieee80211Mac.
    Wire Representation and Parsing:
  • Enforced 0..32 octet length bounds for SSID elements on wire encode/decode.
  • Non-throwing AID handling for malformed association and reassociation response frames.
    Documentation and Migration Guide:
  • Updated WHATSNEW and doc/src/migration-guide/index.rst covering getDataGuardInterval(), mode-set lookup changes, and listener interface migration.
    Sealing and Audit Exceptions:
  • All modified files reside under src/inet/linklayer/ieee80211 and src/inet/physicallayer/wireless/ieee80211. All touched paths are unsealed.
  • No new architectural deviations (AV-*) or naming deviations (NV-*) introduced.

Baselines

Updated 13 test configurations across tests/fingerprint/examples.csv, tests/fingerprint/showcases.csv, tests/fingerprint/tutorials.csv, and tests/fingerprint/store.json (carried in commit 9 9039d75807 per PR-SPLIT-BASELINE):

  1. /examples/wireless/lan80211ac/ Ping1 run 0 (100s):

    • In tests/fingerprint/examples.csv: updated from bb14-f903/tplx;538b-6566/~tNl to 8180-0d11/tplx;a5d5-2820/~tNl.
    • In tests/fingerprint/store.json: synchronized matching entries; the stale ~tNl entry (1108-9845) now matches the verified run.
    • Causal attribution: The AP forwards the broadcast ARP request at the mandatory legacy rate of 24 Mbps instead of the configured VHT rate per IEEE Std 802.11-2024 Clause 10.6.5.4. At event 41, t=0.006500862657, airtime changes from 72 µs to 44 µs (transmission-end event moves 28 µs earlier). Restoring only the prior group-rate selection with an interposed helper reproduces the original fingerprints over the full 100s run, proving the rate-selection correction accounts for the movement.
  2. 12 Legacy Configurations Configured for 54 Mbps:

    • Updated run 0 fingerprints across:
      • examples/manetrouting/multiradio: SingleRadio and MultiRadio
      • showcases/general/pcaprecording: PcapRecording
      • showcases/visualizer/canvas/statistic: PacketErrorRate
      • showcases/visualizer/canvas/submoduleinfo: MACStates and PacketCounts
      • showcases/wireless/analogmodel: Distance
      • showcases/wireless/power: General
      • showcases/wireless/qos: NonQos and Qos
      • tutorials/configurator: Step9 and Step10C
    • Causal attribution: The same basic-rate restriction applies to group-addressed traffic in legacy networks configured for 54 Mbps. The configured 54 Mbps rate previously bypassed the basic-rate restriction; selecting mandatory 24 Mbps instead changes airtime and subsequent event trajectories (e.g., in PacketCounts, event 11 at 0.01 s switches from 54 Mbps to 24 Mbps).
    • Causal verification: Bypassing only selectGroupAddressedMode's restriction restores all 12 original baselines while retaining the other changes. These 12 CSV rows and their 34 matching JSON fingerprints retain their existing simulation limits and non-graphical ingredients.

Verification Evidence

  1. Compilation:
    make -j$(nproc) MODE=debug && make -j$(nproc) MODE=release
    Both debug (libINET_dbg.so) and release (libINET.so) build cleanly without errors.

  2. Mechanical Project Gates:

    • doc/project/enforcement/check-commits.sh upstream/master..HEAD (PASS, 12/12 clean commits)
    • doc/project/enforcement/check-source-seals.sh --base upstream/master (PASS, all touched files unsealed)
    • doc/project/enforcement/check-architecture.sh src/inet/linklayer/ieee80211 (PASS)
    • doc/project/enforcement/check-architecture.sh src/inet/physicallayer/wireless/ieee80211 (PASS)
    • doc/project/enforcement/check-naming.sh --base upstream/master (PASS, 0 new declarations in changed NED/MSG files)
    • git diff --check upstream/master..HEAD (PASS, clean formatting)
  3. Direct Unit Tests (4/4 PASS):

    UNIT_FILTER='Ieee80211HtGuardInterval_1|Ieee80211PeerModeSelection_1|Ieee80211SupportedRates_1|Ieee80211MgmtFrameSerializer_1'
    printf "run_opp_tests(test_folder='tests/unit', filter='$UNIT_FILTER', mode='debug', build=False)\nexit\n" |
      env INET_ROOT="$PWD" PATH="$PWD/bin:$PATH" opp_repl --load @opp -p inet
    • Ieee80211HtGuardInterval_1.test: PASS
    • Ieee80211PeerModeSelection_1.test: PASS
    • Ieee80211SupportedRates_1.test: PASS
    • Ieee80211MgmtFrameSerializer_1.test: PASS
  4. Direct Module Tests (3/3 PASS):

    MODULE_FILTER='Ieee80211MixedHtDiscovery_1|Ieee80211ModeSetFailure_1|Ieee80211ModeSetTransition_1'
    printf "run_opp_tests(test_folder='tests/module', filter='$MODULE_FILTER', mode='debug', build=False)\nexit\n" |
      env INET_ROOT="$PWD" PATH="$PWD/bin:$PATH" opp_repl --load @opp -p inet
    • Ieee80211MixedHtDiscovery_1.test: PASS
    • Ieee80211ModeSetFailure_1.test: PASS
    • Ieee80211ModeSetTransition_1.test: PASS
  5. Fingerprint Regression Tests (PASS):

    • Debug mode (lan80211ac.*Ping1):
      ( cd tests/fingerprint && env INET_ROOT="$PWD/../.." PATH="$PWD/../../bin:$PATH" ./fingerprinttest -d -m 'lan80211ac.*Ping1' )
      Result: Ran 1 test in 47.694s OK
    • Release mode (12 updated legacy configurations, excluding unmaintained graphical tyf fingerprints per INET testing policy):
      ( cd tests/fingerprint && env INET_ROOT="$PWD/../.." PATH="$PWD/../../bin:$PATH" ./fingerprinttest -F tyf -m 'multiradio|pcaprecording|statistic|submoduleinfo|analogmodel|power|qos|configurator' )
      Result: Ran 56 tests in 35.822s OK

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 2 potential issues.

3 flags not posted on this PR by your GitHub settings — view them in Devin Review. (Configure)

Devin Review

Comment thread src/inet/physicallayer/wireless/ieee80211/packetlevel/Ieee80211Radio.cc Outdated
Comment thread src/inet/linklayer/ieee80211/mgmt/Ieee80211MgmtStaSimplified.cc
Remove redundant blank lines from the affected IEEE 802.11 sources so
subsequent functional changes contain no incidental whitespace cleanup.
Rate selection needs to distinguish modes with the same bitrate and
different guard intervals. Require every data mode to state its modeled
interval, preserving the negative sentinel for PHYs without one.

Document the new requirement for external data-mode implementations.
The optional HT table entries encode the wrong stream count or modulation.
Use one BPSK stream for MCS 32, 16-QAM on stream 4 for MCS 76 at 20 MHz,
and 16-QAM on stream 3 for MCS 73 at 40 MHz.
Band and preamble format affect mode behavior but were absent from cache
identity, allowing a request to reuse a mode with different properties.
Include both in the HT and VHT keys and reject unsupported VHT greenfield
requests before cache lookup. Cover rejection before and after a mixed
format request.
Short GI applies to data symbols, while signal fields retain long-GI
timing. Round mixed HT and VHT data airtime to long-symbol boundaries;
retain raw short-GI timing for HT greenfield.

Expose consistent PPDU phase durations and use them in both transmitter
paths so the phases sum to the modeled frame duration. Add the independent
VHT timing assertions; catalog-based HT assertions follow with lookup.
Equal-rate catalog entries can differ in GI and do not form distinct
steps for rate adaptation. Qualify bitrate lookups by GI, retain stable
equal-rate ordering, and find adjacent rates by bitrate.

Provide complete PHY-tuple compatibility lookup and mandatory-at-or-below
selection for consumers. Cover catalog traversal, peer fallback, compatible
lookup and timing across the HT/VHT catalogs; document lookup migration.
A fixed bitrate alone can select the wrong guard interval. Apply the
configured dataFrameGuardInterval to interface-wide and per-receiver data
mode lookup in both rate selectors. Negative values retain unspecified-GI
selection; explicit values must match the modeled PHY interval.
A response may use a mandatory mode at the same bitrate even when the
request mode itself is not mandatory. Select the highest mandatory bitrate
at or below the request instead of stepping strictly to a lower rate.
@mgonzalezlopezudc

Copy link
Copy Markdown
Contributor Author

@levy the bug Devin is signaling is a false positive. I confirmed it with Devin itself. Here's Devin response:

You're correct, and I withdraw my earlier claim. The trace confirms it:

  • Dcf::transmitFrame() calls rateSelection->computeMode(...) then setFrameMode(...) on every transmission (src/inet/linklayer/ieee80211/mac/coordinationfunction/Dcf.cc:190-191).
  • Hcf::transmitFrame() does the same (src/inet/linklayer/ieee80211/mac/coordinationfunction/Hcf.cc:713-714).
  • computeMode selects afresh and never reads Ieee80211ModeReq (src/inet/linklayer/ieee80211/mac/rateselection/RateSelection.cc:189-195); getMode (src/inet/linklayer/ieee80211/mac/rateselection/RateSelection.cc:97-106) is the only reader of that tag, and it's not on the transmit path.
  • setFrameMode uses addTagIfAbsent<Ieee80211ModeReq>()->setMode(mode) (src/inet/linklayer/ieee80211/mac/rateselection/RateSelection.cc:202), which overwrites the existing tag.

So the stale tag is unconditionally recomputed and overwritten before each (re)transmission. My asserted failure chain — computeMode reusing the old tag → transmitter rejection → abort — is broken at the first link. The finding is a false positive for ef97937b88, and queue-wide invalidation / request-provenance tracking is not justified by this report.

The one caveat you raised stands: a mode switch after a frame is already handed to Tx is a separate timing question this static trace doesn't cover.

Mixed HT catalogs place mandatory HT MCS entries above legacy rates, so the fastest mandatory mode makes Beacons invisible to legacy stations. Constrain both rate selectors to mandatory legacy operational modes when the advertised basic legacy set is nonempty, preserving eligible configured rates.

Add passive-discovery coverage for legacy stations associating with mixed HT DCF and HCF access points.

Update the lan80211ac Ping1/run 0/100s fingerprints in examples.csv from
bb14-f903/tplx;538b-6566/~tNl to 8180-0d11/tplx;a5d5-2820/~tNl, and
synchronize the matching JSON store entries. The JSON ~tNl entry was
already stale (1108-9845); it now matches the same verified run.

This change makes the AP forward the broadcast ARP request at the
mandatory legacy rate of 24 Mbps instead of the configured VHT rate.
At event 41, t=0.006500862657, its airtime changes from 72 us to 44 us;
the transmission-end event moves 28 us earlier. IEEE 802.11-2024,
10.6.5.4 requires a non-HT basic rate for this group-addressed frame
when the basic legacy rate set is nonempty.

Causal verification: restoring only the previous group-rate decision
with an interposed selectGroupAddressedMode that returns requestedMode
reproduces both original fingerprints over the full 100s run, while
keeping the GI and duration fixes active. Thus this rate-selection
correction, rather than the GI timing changes, accounts for the new
fingerprints. The normal debug run passes the updated CSV expectations.

The same basic-rate restriction changes group-addressed traffic in
legacy networks configured for 54 Mbps. Update run 0 fingerprints for:
- examples/manetrouting/multiradio: SingleRadio and MultiRadio;
- showcases/general/pcaprecording: PcapRecording;
- showcases/visualizer/canvas/statistic: PacketErrorRate;
- showcases/visualizer/canvas/submoduleinfo: MACStates and PacketCounts;
- showcases/wireless/analogmodel: Distance;
- showcases/wireless/power: General;
- showcases/wireless/qos: NonQos and Qos;
- tutorials/configurator: Step9 and Step10C.

These 12 CSV rows and their 34 matching JSON fingerprints retain their
existing simulation limits and non-graphical ingredients. The configured
54 Mbps rate previously bypassed the basic-rate restriction; selecting
24 Mbps instead changes airtime and the subsequent event trajectory.
In PacketCounts, the first changed group-rate decision is event 11 at
0.01 s, where the requested 54 Mbps mode becomes 24 Mbps.

Causal verification at the final series tip reproduces all 12 changed
fingerprints. Bypassing only selectGroupAddressedMode's restriction
restores all 12 original baselines while retaining the other changes.
The ordinary debug runs pass all 12 updated CSV expectations. This
extends the same group-addressed basic-rate correction documented above
for Ping1 to the affected legacy configurations.
Runtime catalog changes must refresh the transmitter, receiver, MAC HT
capabilities, advertised rates, channel access and rate-selection state
before observers see the new mode set. Apply typed consumers once before
publishing notification and rebuild configured modes from their qualifiers.

Validate compatible or explicitly selected transmitter modes and reject
reentrant transitions. Consumer and observer failures are fatal simulation
errors; these setters do not offer rollback or continuation after failure.

Cover successful transitions, peer state, advertisements, fixed-rate
failures and notification failures through both setters. Document the
listener interface inherited by external subclasses.
SSID elements contain at most 32 octets. Use shared wire helpers to reject
overlength values and truncated input consistently across management frame
types. Cover zero, one, 32 and 33 octets and truncated payloads.
Invalid wire AIDs in association and reassociation responses should mark
the frame incorrect while allowing parsing to finish. Substitute zero and
preserve status, rates, trailing elements and stream position.

Cover missing markers, out-of-range successful AIDs and nonzero AIDs in
unsuccessful responses for both frame types.
levy added a commit that referenced this pull request Sep 11, 2026
PASS with 4 findings and 3 notes. 13 commits, 56 files, +3260/-309 on
current master. The most ambitious change of this workstream: IEEE-cited
corrections to the HT and VHT timing tables, guard interval as a
first-class parameter, and a transactional mode-set change whose listener
contract carries a rollback closure. 2352 of the 3260 added lines are
tests, and the last four commits each say the regression fails before the
fix.

F-1 blocks the merge. Commit 3 corrects HT MCS 32, 73 and 76 and the
HT/VHT symbol timing, and rounds short-GI airtimes to the 4 us boundary.
That moves the trajectory of any n or ac simulation. Two fingerprint rows
run those modes, the branch touches no baseline, and no message mentions
a fingerprint. A small exposure is exactly the case where the run gets
skipped.

F-2 is new: master is at 15 interface violations, this head at 16.
IIeee80211DataMode gains getGuardInterval() { return -1; }, a default
body in a flat interface that seven data modes inherit directly and only
three override. The value is right for the other four; the place is not.
Four one-line overrides make each mode state its own answer.

F-4: this branch and #1175 carry two versions of one commit, differing by
three lines. This one is 14 hours newer and drops
getConfiguredSecondaryChannelOffset() -- the member #1175's own note
questioned as called only from tests. The question looks answered; both
versions being open is what remains.

Recorded against the tool rather than the branch: the summary reports
four getMode and findMode removals where the truth is four signatures
extended by one defaulted parameter. The pairing that would catch it is
skipped when two overloads of a name change at once.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant