Skip to content

IEEE 802.11: add HT capability and operation signalling - #1154

Open
mgonzalezlopezudc wants to merge 31 commits into
inet-framework:masterfrom
mgonzalezlopezudc:cleanup/ht-cap-op-signalling-pr1144-v2
Open

IEEE 802.11: add HT capability and operation signalling#1154
mgonzalezlopezudc wants to merge 31 commits into
inet-framework:masterfrom
mgonzalezlopezudc:cleanup/ht-cap-op-signalling-pr1144-v2

Conversation

@mgonzalezlopezudc

@mgonzalezlopezudc mgonzalezlopezudc commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Dependency

Depends on #1166 (ethernet: preserve fragment FCS type when deserializing) at 353798aea4719c2823cc9da474e27c48eaabc87b.

PR #1166 is itself stacked on #1164. Until #1166 is merged, GitHub includes its 10 prerequisite commits in this PR’s comparison against master. The HT topic itself is the 29-commit range:

353798aea4719c2823cc9da474e27c48eaabc87b..bbc7e20ed7698bde82c603d1e4f49f340a43d9a7

Summary

This PR adds model-backed IEEE 802.11 HT Capabilities and HT Operation signalling and uses the negotiated state throughout discovery, association, channel validation, and rate selection.

It also:

  • completes the mixed HT mode catalogue and makes PHY timing references explicit;
  • encodes legacy operational rates and management fixed fields correctly;
  • derives advertised HT widths from the operational transmitter/receiver intersection;
  • carries HT state through Beacon, Probe, Association, and Reassociation exchanges;
  • restricts unicast rate selection to modes supported by negotiated peer state;
  • makes STA association, reassociation, teardown, and restart transitions explicit;
  • commits AP association state and AIDs only after the exact response transaction succeeds;
  • handles queue drops, retry exhaustion, RTS failure, fragmentation, and HCF internal collisions as terminal transaction outcomes;
  • exposes terminal frame-transmission outcomes through a signal and result recorders;
  • refreshes associated-peer HT state from accepted Beacons;
  • revalidates HT operation and negotiated peer state after runtime channel or band changes;
  • rejects malformed or contradictory peer HT advertisements without terminating the simulation.

This is the review-ready reconstruction of the work from #1144 as a linear, dependency-ordered 29-commit topic series.

Motivation

The previous model did not represent and negotiate HT capability and operation state end to end. In particular:

  • operational rate membership was inferred incompletely;
  • HT mode timing and channel-width authority were ambiguous;
  • internal radio channel indices could be confused with IEEE on-wire channel numbers;
  • unicast rate selection could choose an HT mode unsupported by the peer;
  • association state and AIDs could become effective before the corresponding response was acknowledged;
  • terminal queue and MAC failure paths could leave association transactions pending;
  • runtime channel changes could leave advertised and negotiated HT state stale;
  • malformed peer elements could abort the simulation or partially update cached state;
  • one-antenna radios could advertise unsupported multi-stream MCS values.

The implementation makes these authorities and transitions explicit while preserving legacy operation for peers without negotiated HT support.

Reading order

The 29 topic commits are ordered by dependency:

  1. PHY and wire-format foundations (C01–C05): timing authorities, operational rates, typed HT state, the complete mixed-mode catalogue, and operational PHY widths.
  2. Negotiation and STA behavior (C06–C14): local transaction metadata, detailed association transitions, HT discovery and association negotiation, peer-compatible rate selection, fixed-field byte order, channel validation, and lifecycle cleanup.
  3. Reliable AP completion (C15–C18): frame-transmission completion, compound-queue ownership, transactional AP responses, and EDCAF retry ownership.
  4. Robustness and observability (C19–C24): malformed peer handling, reassociation completion, antenna-stream limits, transmission-result signalling, Beacon-driven peer-state refresh, and AP restart cleanup.
  5. Runtime consistency and validation (C25–C29): resolution-independent timestamp coverage, dynamic channel and band revalidation, pending-association reconciliation, AP-side HT validation, and contradictory transmit-field rejection.

Tests and fingerprint updates travel with their causal commits.

Architectural surface

Contracts

  • Adds packet-PHY channel and HT-width provider contracts.
  • Publishes terminal MAC frame-transmission outcomes through frameTransmissionFinishedSignal.
  • Carries immutable FrameTransmissionDetails and FrameTransmissionStatus values to management and non-behavioral observers.
  • Keeps management transaction identity sender-local and removes it at the wireless packet-domain boundary.
  • Uses radio channel-change notifications to keep AP HT operation and peer state synchronized.

Packet representation

  • Adds typed HT Capabilities and HT Operation management elements.
  • Preserves Supported and Extended Supported Rate membership.
  • Encodes management fixed-width fields little-endian.
  • Validates Association ID marker bits and range.
  • Converts internal channel indices to and from IEEE channel numbers at the management boundary.
  • Safely rejects invalid HT channel tuples, unsupported Basic MCS sets, and contradictory transmit-MCS fields.
  • Extends coverage for the microsecond Beacon and Probe Response timestamp encoding supplied by the prerequisite stack.

State and ownership

  • The MIB owns local and per-peer HT capability, operation, association-ID, and station-membership state.
  • Detailed STA management owns pending association and reassociation transitions.
  • AP association state becomes effective only after the correlated response is acknowledged.
  • Runtime channel changes revalidate current and pending peer HT state.
  • Accepted Beacons refresh the authoritative associated-AP snapshot; invalid updates preserve the existing association and fall back safely.
  • Compound queues retain packet ownership while synchronously reporting drops.

Configuration and observability

  • Adds MIB parameters for the modeled HT A-MPDU exponent, secondary-channel offset, and protection mode.
  • Adds explicit MIB and radio module references where required.
  • Adds htNegotiationFailed diagnostics.
  • Adds frameAcked, frameRetryLimitReached, and frameDroppedBeforeTx statistics.

No changed topic source path is sealed. No new architecture or naming exception is required.

Validation

The topic was replayed and verified across eight upstream checkpoints while reusing one debug object tree. The final safe point is bbc7e20ed7698bde82c603d1e4f49f340a43d9a7.

Build commands:

make MODE=debug -j$(nproc) LN='cp -f'
make -C tests/unit/lib MODE=debug -j$(nproc)
make -C tests/module/lib MODE=debug -j$(nproc)

Result: PASS. The final incremental build completed without cleaning the object tree.

Focused unit tests:

UNIT_FILTER='Ieee80211HtModeSet_1|Ieee80211ResponseTimeout_1|Ieee80211TxopProcedure_1|Ieee80211SupportedRates_1|Ieee80211HtCapabilities_1|Ieee80211HtMgmtElements_1|Ieee80211MgmtProtocolPrinter_1|Ieee80211MgmtTransactionTag_1|Ieee80211MgmtStaPrimitiveDispatch_1|Ieee80211MgmtStaDiscovery_1|Ieee80211PeerModeSelection_1|Ieee80211MgmtFrameSerializer_1|Ieee80211Band_1|Ieee80211MgmtApTransaction_1|Ieee80211MibAssociationId_1|FieldsChunkSerializer_1|EthernetMacHeaderSerializer_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

Result: 17/17 PASS.

Focused module tests:

MODULE_FILTER='Ieee80211PacketDomainTagBoundary_1|Ieee80211MgmtStaDiscovery_1|Ieee80211MgmtStaDeauthentication_1|Ieee80211MgmtStaDisassociation_1|Ieee80211MgmtStaLifecycle_1|Ieee80211HtAssociation_1|Ieee80211MgmtApHcfQueueDrop_1|Ieee80211MgmtApHcfRtsTimeout_1|Ieee80211MgmtApQueueDrop_1|Ieee80211MgmtApReassociationSnapshot_1|Ieee80211MgmtApTimeout_1|Ieee80211MgmtApUnavailableChannel_1|Ieee80211MgmtStaSimplifiedInitialization_1|Ieee80211HcfInternalCollision_1|Ieee80211AgentStaReassociation_1|Ieee80211HtAntennaRateControl_1|Ieee80211FrameTransmissionStats_1|Ieee80211MgmtStaBeaconUpdate_1|Ieee80211MgmtApLifecycle_1|Ieee80211MgmtApChannelChange_1|Ieee80211MgmtApMalformedHtCap_1|EthernetFragmentFcsChecker_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

Result: 22/22 PASS.

Focused queueing test:

printf "run_opp_tests(test_folder='tests/queueing', filter='CompoundQueue_1', mode='debug', build=False)\nexit\n" |
  env INET_ROOT="$PWD" PATH="$PWD/bin:$PATH" opp_repl --load @opp -p inet

Result: 1/1 PASS.

The following reproduces the exact 37 fingerprint rows changed by this topic relative to PR #1166:

fingerprint_rows=$(mktemp)

git diff --unified=0 \
  353798aea4719c2823cc9da474e27c48eaabc87b..HEAD -- \
  tests/fingerprint/examples.csv \
  tests/fingerprint/showcases.csv \
  tests/fingerprint/tutorials.csv |
  sed -n '/^+++ /d; /^+/s/^+//p' > "$fingerprint_rows"

test "$(wc -l < "$fingerprint_rows")" -eq 37

(
  cd tests/fingerprint
  ./fingerprinttest \
    -d \
    -q \
    -m '.*' \
    -f tplx \
    -f '~tNl' \
    -f '~tND' \
    "$fingerprint_rows"
)

rm "$fingerprint_rows"

Result: 37/37 PASS.

Source and history checks:

git diff --check 353798aea4719c2823cc9da474e27c48eaabc87b..HEAD
doc/project/enforcement/check-source-seals.sh \
  --base 353798aea4719c2823cc9da474e27c48eaabc87b \
  --head HEAD
doc/project/enforcement/check-architecture.sh src/inet/linklayer/ieee80211
doc/project/enforcement/check-architecture.sh src/inet/physicallayer/wireless/ieee80211
doc/project/enforcement/check-commits.sh \
  353798aea4719c2823cc9da474e27c48eaabc87b..HEAD

The branch is linear with exactly 29 topic commits and no merge commits. Seal, architecture, whitespace, baseline-coupling, ordering, and rename checks pass.

The commit-message check has one known metadata finding: C26 (d0548c4433) has a 73-character subject, one character over the approximate 72-character limit.

Fingerprint updates

This topic updates 37 existing fingerprint rows relative to PR #1166:

  • 17 in tests/fingerprint/examples.csv;
  • 16 in tests/fingerprint/showcases.csv;
  • 4 in tests/fingerprint/tutorials.csv.

The updates remain in their causal commits:

  • C01 moves seven rows due to the corrected PHY timing authority;
  • C02 moves the remaining 30 rows due to operational-rate encoding;
  • C10 advances the TXOP row after negotiated peer-rate selection;
  • C11 advances the same 30 C02 rows to their final management-wire-byte fingerprints.

The staged rebase reproduced the expected timestamp transition exactly before the prerequisite baseline checkpoint and passed the combined oracle afterward. No additional repository baseline was introduced by the rebase.

Scope limits

The current packet PHY advertises operational HT20 only. HT40 catalogue, negotiation, selection, and channel validation are covered, but an end-to-end HT40 PHY exchange is outside this PR.

VHT capability negotiation is also outside the scope of this change.


Devin Review

@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 3 potential issues.

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

Devin Review

Comment thread src/inet/linklayer/ieee80211/mib/Ieee80211Mib.cc Outdated
Comment thread src/inet/linklayer/ieee80211/mgmt/Ieee80211MgmtSta.cc Outdated
Comment thread src/inet/linklayer/ieee80211/mgmt/Ieee80211MgmtSta.cc Outdated

@levy levy left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Please check these and let's discuss!

Comment thread src/inet/linklayer/ieee80211/mgmt/Ieee80211MgmtFrameSerializer.cc Outdated
}
// add indications
auto packet = const_cast<Packet *>(packetModel->getPacket());
// Packet-domain error models duplicate the transmitted packet, including

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hmm, I'm not saying this wrong or anything, but the Ieee80211LayeredOfdmReceiver class is only used in the bit level simulation model and it's not used at all in the packet level model.

So why is there no change related to this in the packet level simulation model? Is that already correct or not affected?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This clears all the tags attached to the transmitted packet to make sure the receiver only sees the actual transmitted packet, with the exception of the PacketProtocolTag. I think the receiver should not even see this one, but it's already common practice in INET as far as I remember.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

That is true, but it's suspicious to me that it's done here.

It's common practice on the sender side and this isn't that.

Comment thread src/inet/linklayer/ieee80211/mac/contract/IFrameTransmissionCallback.h Outdated

@levy levy left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I answered to each 3.

Comment thread src/inet/linklayer/ieee80211/mgmt/Ieee80211MgmtFrameSerializer.cc Outdated
}
// add indications
auto packet = const_cast<Packet *>(packetModel->getPacket());
// Packet-domain error models duplicate the transmitted packet, including

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

That is true, but it's suspicious to me that it's done here.

It's common practice on the sender side and this isn't that.

Comment thread src/inet/linklayer/ieee80211/mac/contract/IFrameTransmissionCallback.h Outdated
Mode-set timing must not depend on the entry that happens to sort first by bitrate. Store and validate an explicit reference mode and PHY family, and make timing and TXOP consumers use those authorities directly.

Correct HT and VHT receive-start delay to the standards-defined 24 microseconds so response timeout calculations use the intended PHY timing. Focused mode-set, response-timeout, and TXOP tests cover reordered modes, invalid references, PHY defaults, and control-response timing.

Record the seven directly affected debug WLAN trajectories in this commit. The corrected receive-start delay and explicit timing authority move the fragmentation, ad hoc QoS, 802.11ac ping, and TXOP event sequences; TXOP records the valid intermediate trajectory at this series boundary and advances again when negotiated peer-mode selection is introduced.
Management frame decoding and Supported Rates construction must preserve concrete frame subtype, basic-rate membership, and rates beyond the primary element.

Validate Supported and Extended Supported Rates, derive one explicit legacy operational set from eligible modes, and reject mode sets that cannot advertise a representable legacy rate. Focused serializer and mode-set tests cover malformed elements, primary/extended splitting, basic membership, timing, and empty-set rejection.

Record the 30 directly affected debug WLAN trajectories in this commit. Correct Supported and Extended Supported Rates content changes management-frame bytes, lengths, and downstream packet flow across the mapped infrastructure scenarios; their data-byte fingerprints advance again when fixed management fields become little-endian.
Introduce typed HT capability and operation state derived from the configured mode set, including exact MCS, channel-width, mandatory-rate, and short-guard-interval support. Make HT properties explicit in the mode interface, retain non-HT defaults in the base class, and serialize and print the corresponding management elements.
Populate the mixed 2.4 GHz HT mode set with every modeled MCS 0 through 31 across 20/40 MHz and long/short guard intervals. Keep only long-GI 20 MHz MCS 0 through 7 mandatory and verify the exact catalog and capability aggregation.
Distinguish channel widths described by the mode catalog from widths the configured packet PHY can actually transmit and receive. Publish a narrow PHY capability contract, intersect both directions in the MAC, and advertise only the operational widths and guard intervals through the MIB.
Introduce a typed management transaction tag, preserve it with packet and region semantics during fragmentation, and remove it at the layered PHY receive boundary. This keeps local completion correlation intact without leaking sender-local control state to the peer.
Preserve concrete association primitive types and model association and reassociation as correlated transactions with explicit pending state, subtype-aware confirmations, timer cleanup, and stale-response rejection. Restore the current AP channel when reassociation to a different AP fails without breaking the existing association.
Stations could not consistently recover HT state from serialized discovery frames or distinguish a genuinely legacy AP from malformed or incompatible HT signalling. Installing peer state from local or incomplete information would make association results and later rate selection unreliable.

Advertise typed HT capabilities in discovery and association exchanges, recover the primary channel from received HT Operation elements, and classify absent, valid, and invalid HT responses explicitly. Install negotiated peer state only when the correlated association or reassociation transaction succeeds, and preserve the current AP channel after a failed reassociation to another peer.

Focused unit and module tests cover serialized discovery, legacy fallback, invalid HT classification, missing channel metadata, peer-state visibility, and reassociation channel restoration.
IEEE 802.11 reserves the Basic HT-MCS Set in Association and Reassociation Responses, so interpreting those response bits made negotiated state depend on a field that must be transmitted as zero.

Preserve Basic HT-MCS bits only for Beacon and Probe Response HT Operation elements. Validate a selected BSS from its cached discovery advertisement before transmitting an association request, and combine that cached Basic HT-MCS Set with the correlated response capabilities when installing peer state.

Focused serializer and detailed-STA tests cover subtype-specific wire bits, discovery round trips, pre-transmission refusal, and successful negotiation from cached BSS state.
Individually addressed transmissions lacked an authoritative way to restrict configured, per-receiver, and rate-control candidates to modes supported by both the local catalog and negotiated peer state.

Add a deterministic peer-mode selector that intersects exact MCS, channel-width, HT Operation, and guard-interval state with local mode membership. Wire the MIB into DCF and HCF rate selection, preserve the existing master rate-control and per-receiver policies, and when negotiated HT is unavailable or invalid choose a mandatory legacy operational fallback that does not exceed the requested candidate rate.

Focused unit and module tests cover sparse MCS sets, 20/40 MHz operation, both guard intervals, local-mode membership, deterministic tie breaking, bounded legacy fallback including the MCS0 ACK/CTS path, and production DCF/HCF integration.

Advance the TXOP showcase baseline from the C01 timing-only trajectory to the directly caused negotiated-mode trajectory. Its packet types, lengths, and cross-node flow now match the approved final debug run.
IEEE 802.11 transmits fixed-width numeric management fields least-significant octet first, and successful Association/Reassociation Responses carry a marked 14-bit logical AID. The existing serializer used big-endian fields and exposed raw/unvalidated AIDs.

Encode and decode all modeled fixed numeric fields little-endian. Validate logical AID range/status semantics at the wire boundary and add/remove the 0xC000 marker without changing packet-domain IDs.

Exact independent byte-vector tests cover every modeled management subtype, AID boundaries, malformed markers, unsuccessful responses, and existing rates/HT element integration.

Advance the 30 management-frame data-byte fingerprints introduced with the corrected rate elements to their approved final values. The packet types, lengths, and cross-node flow remain unchanged from C02; only the serialized fixed fields and successful-response AID marker move the ~tND ingredient.
HT Operation carries standards channel numbers, while packet-level radios use internal zero-based channel indices. Treating the two as interchangeable made 2.4 GHz advertisements off by one and allowed impossible HT40 primary/secondary combinations.

Add explicit bidirectional band mappings and a current-channel provider, keep the PHY band synchronized with channel changes, and convert HT Operation fields only at management boundaries. Move AP channel tracking into the common management base at this boundary, preserve the detailed AP legacy channel view through delegation, and expose the radio module on the simplified AP so both variants initialize independently. Make primary-channel availability explicit in the MIB, require received HT state to match the packet channel, and reject illegal AP HT40 tuples during initialization.

Focused band, discovery, association-path, and mapped AP initialization checks cover channel-number conversion, missing/mismatched metadata, duplicate subscription prevention, and valid and invalid 2.4 GHz HT40 combinations.
Detailed STA management used untracked scan timers and several independent teardown paths. Deauthentication and disassociation also consulted the wrong address field or cleared state before preserving the pending transaction context.

Track and cancel every scan timer, centralize current-association cleanup, and make peer-initiated termination preserve unrelated pending work while completing same-peer work deterministically. Clear peer HT state on all relevant teardown and stop paths, and reset discovery-test association state between exchanges.

Focused module tests cover current, pending, foreign, cached, and uncached peers together with stop/start cycles and outstanding scan, authentication, association, and beacon timers.
A Disassociate primitive for one peer unconditionally canceled any pending association or reassociation, even when that transaction belonged to a different AP.

Scope cancellation to the request's PeerSTAAddress. Preserve unrelated pending transactions while still canceling same-target work, for both initial association and reassociation.

Extend the focused disassociation module test through current, target, and foreign peers, including late-response behavior after a same-target cancellation.
Management needs terminal delivery outcomes while the coordination function still owns the transmitted frame. Existing frame-sequence signals expose internal sequencing and do not provide one typed, ownership-safe contract across DCF and HCF.

Add a synchronous non-retaining transmission callback discovered through the management gate. Report acknowledged and retry-limit outcomes for locally originated management frames from DCF and HCF, including RTS-protected and internal-collision terminal paths.

This commit establishes and compiles the callback plumbing; policy consumers and focused end-to-end outcome coverage follow with the AP transaction commit.
A compound queue removes an overflow-selected packet from its child queue before emitting the drop. That removal releases ownership, so the subsequent drop path can observe a packet no longer owned by the compound module.

Retake the selected packet after removal and before drop processing. Also keep the streaming push API publicly accessible through PacketQueueBase as required by its queue interface.

Focused AP queue-drop integration coverage follows in C17, where the dropped management packet is inspected synchronously.
AP association state must become effective only after the exact response transaction reaches a terminal MAC outcome. Frame-sequence inference, eager AID publication, and uncorrelated queue drops could commit or tear down the wrong peer state.

Reserve and commit AIDs transactionally, tag each response, snapshot negotiated HT state, and complete it on acknowledged, retry-limit, RTS-timeout, or pre-transmission-drop callbacks. Coalesce duplicate requests, clear pending state before synchronous notifications, preserve same-AP reassociation semantics, convert HT channels through the radio band, and keep simplified management restart-safe.

Focused unit and module coverage spans AID reservation, correlation, DCF/HCF queue drops, HCF RTS timeout, reassociation snapshots, unavailable channels, simplified initialization, and an RTS-protected end-to-end HT association.
Use the retry counters of the EDCAF that actually lost an HCF internal collision, including management frames scheduled outside AC_BE. Verify AC_VO retry ownership and the resulting terminal management callback with a focused module test.
Malformed HT Capabilities or HT Operation elements in Beacon, Probe Response, Association Response, and Reassociation Response frames were passed to strict conversion helpers. Missing reception-channel metadata, unmappable primary channels, and inconsistent channel-width/secondary-offset tuples could therefore abort the simulation or leave a partially refreshed AP cache. The STA could also accept a 40 MHz operation whose secondary channel did not exist.

Treat these elements as peer input at the STA management boundary. Validate a complete candidate AP record before committing it, reject invalid discovery frames without refreshing the associated AP's beacon timeout, and translate response validation failures into the existing successful legacy fallback with one htNegotiationFailed notification.

Accept 20 MHz operation only without a secondary channel. Accept 40 MHz operation only with an above or below offset whose complete channel pair is supported by the received band. Legacy STAs continue to ignore HT elements.

Add focused unit and module coverage for all four response and discovery frame types, cache preservation, beacon deadlines, legal and invalid channel pairs, unmappable primary channels, and legacy STA behavior. Serialized-byte parsing and 5 GHz standards-channel mapping remain unchanged.
Reassociation failures could restart scanning even when management retained the current AP, causing scan setup to destroy a valid association. Successful handovers also reported every completion as an old-AP reassociation and left prevAP stale.

Base retry decisions on the management-owned MIB association state, so scanning resumes only after association loss. Commit the confirmed target before completion callbacks and classify old/new AP notifications from prevAP.

Add focused dispatch and module coverage for retained and lost association failures, same- and different-AP success, and completion ordering.
The MIB previously copied every HT MCS from the configured mode set, so a one-antenna radio advertised multi-stream modes. Once rate control advanced beyond MCS 7, peer negotiation could select a mode that the transmitter rejected because its spatial-stream count exceeded the antenna count.

Pass the radio's operational stream limit into HT capability construction and restrict the receive bitmap, equal transmit map, and Basic MCS set to locally processable modes.
The 1-to-1 typed callback IFrameTransmissionCallback coupled Ieee80211Mac
directly to a single management peer (Ieee80211MgmtAp), preventing
non-behavioral observers (result filters, statistics, trace visualizers)
from observing terminal transmission outcomes (acknowledged, retry-limit
exhaustion, queue drop before transmission).

Replace the callback interface with frameTransmissionFinishedSignal carrying
a stack-allocated FrameTransmissionDetails object (FrameTransmissionStatus).
Register result filters for each terminal outcome and declare OMNeT++
statistics frameAcked, frameRetryLimitReached, and frameDroppedBeforeTx on
Ieee80211Mac. In Ieee80211MgmtAp, subscribe to the signal on the paired MAC
during initialization and dispatch the status to association transaction
management without keeping a 1-to-1 callback binding.

Update affected DCF and HCF coordination paths and all management unit/module
tests, and add focused module test coverage verifying that result filters
and statistic recorders accurately track each terminal transmission status.
Ieee80211MgmtSta::storeAPInfo previously refreshed only the cached AP
record in apList upon receiving a Beacon, leaving the authoritative
associated-AP snapshot (assocAP) and MIB peer HT state unrefreshed.
Dynamic updates in an associated AP's subsequent Beacon advertisements
(such as operating channel width, secondary channel offset, short guard
interval, or supported MCS restrictions) did not propagate to peer HT
state, allowing unicast rate selection to retain obsolete constraints.

Update storeAPInfo so an accepted Beacon from the currently associated AP
refreshes assocAP and revalidates advertised HT capabilities and
operation against local capabilities. When the refreshed advertisement is
usable, update the MIB peer HT state. When the refreshed advertisement is
legacy or unusable (unsupported Basic MCS set or no bidirectionally valid
common mode), preserve the existing association while removing peer HT
state so rate selection falls back to legacy operational modes. Ensure
Probe Responses from the associated AP only refresh rxPower and do not
alter authoritative associated-AP state.

Add focused module test coverage in Ieee80211MgmtStaBeaconUpdate_1.test
verifying dynamic 40 MHz to 20 MHz, Short GI, and MCS demotions,
association preservation on legacy and unusable updates, beacon interval
updates, malformed beacon rejection, and probe response immunity.
Ieee80211MgmtAp::stop previously cleared staList and called
mib->clearAssociationIds(), but clearAssociationIds left
bssAccessPointData.stations populated. Consequently, after an AP shutdown
and restart, stale station membership records remained in the MIB. In
addition, nextAssociationTransactionId was not reset on stop.

Update Ieee80211Mib::clearAssociationIds to clear bssAccessPointData.stations
alongside association IDs, reservations, and peer HT state, and reset
nextAssociationTransactionId in Ieee80211MgmtAp::stop.

Add unit test verification in Ieee80211MibAssociationId_1.test and a
lifecycle module test in Ieee80211MgmtApLifecycle_1.test verifying that an AP
shutdown completely clears station records, and that upon restart a former
station is rejected with deauthentication until it authenticates and
associates again.
Ieee80211MgmtFrameSerializer previously serialized the 8-byte Timestamp field
for Beacon and Probe Response frames using simTime().raw(), coupling the wire
encoding to the internal simulation time resolution. IEEE 802.11 specifies
that the Timestamp field represents the value of the TSF timer in microseconds.

Update both Beacon and Probe Response serialization branches to use
simTime().inUnit(SIMTIME_US). Extend Ieee80211MgmtFrameSerializer_1.test with
non-zero simulation times and postrun executions under nanosecond and
microsecond resolutions to verify wire bytes are resolution-independent.
…tion

Ieee80211Mib::setPrimaryChannel previously updated the primary channel
without revalidating against the active IIeee80211Band, and the 40 MHz HT
primary and secondary channel configuration was validated only once during
AP initialization at INITSTAGE_LAST. If an AP dynamically changed channel or
band via radioChannelChanged notifications to an unsupported frequency or an
invalid secondary offset, the advertised HT Operation and negotiated peer state
became inconsistent or invalid.

Emit radioChannelChangedSignal on dynamic radio band changes in Ieee80211Radio.
In Ieee80211Mib::setPrimaryChannel, revalidate the primary channel against the
active band before committing, rejecting invalid channels with cRuntimeError.
When a configured 40 MHz secondary channel offset is unsupported on the new
channel or band, fall back dynamically to 20 MHz BSS operation while preserving
the configured offset policy (IEEE Std 802.11-2024, 11.15.2 and 11.15.3.1),
restoring 40 MHz operation when moving back to a capable channel.
Re-negotiate all existing peer HT states against the updated HT operation and
bump peer generation numbers to keep advertised frame elements and rate
selection consistent.

Add module test Ieee80211MgmtApChannelChange_1.test verifying dynamic 20 MHz
fallback, 40 MHz restoration, invalid channel rejection, and dynamic band
revalidation.
When an association or reassociation request arrives, Ieee80211MgmtAp
snapshots the active HT Operation to populate the response frame.
If the AP's radio channel or band changes dynamically before the
terminal acknowledgment arrives, Ieee80211Mib::setPrimaryChannel
updates already-associated peer states, but the pending transaction
snapshot in StaInfo remained unchanged. Acknowledging the queued
response subsequently installed the stale snapshot, reverting the
peer's primary channel and HT operation back to the pre-switch state
and desynchronizing it from the current BSS.

Reconcile pending association transactions with runtime channel
changes at completion in Ieee80211MgmtAp::frameTransmissionFinished
by validating and deriving the committed HT Operation from the current
MIB state (mib->getHtOperation()) and verifying that the peer still
supports the current Basic HT-MCS set. The transmitted response frame
elements remain preserved as originally advertised to the station.
Ieee80211MgmtAp passed peer-provided HT Capabilities elements directly
to makeHtCapabilities, whose validation throws cRuntimeError when field
values are out of bounds (such as maxAmpduLengthExponent outside 0..3).
This terminated the simulation instead of handling the malformed frame.

Move decodeHtCapabilities into Ieee80211HtMgmtElements.h so that both
STA and AP management paths share safe conversion logic. In AP
association and reassociation request handlers, catch malformed HT
capabilities, log an EV_WARN, and transmit an association or
reassociation response refused with status code SC_UNSUP_CAP and
AID 0 without reserving an association ID. Pursuant to IEEE Std
802.11-2024 clause 11.3.5.5(n), an acknowledged reassociation refusal
clears any pre-existing association.
When peer advertisements bypass byte-stream serialization, makeHtCapabilities only checked the A-MPDU length exponent and accepted contradictory transmit capability fields. In simulation, peer advertisements could install invalid negotiated HT state with undefined Tx MCS sets that still advertise spatial streams or unequal modulation, equal Tx/Rx MCS sets that advertise non-zero spatial stream counts or unequal modulation, or unequal Tx/Rx MCS sets with an invalid spatial stream count.

Validate the HT Tx MCS set fields in makeHtCapabilities to match the rules enforced during wire serialization and deserialization in Ieee80211MgmtFrameSerializer. When invalid fields are encountered, throw cRuntimeError so that callers using decodeHtCapabilities safely reject or ignore the malformed advertisement.
When macModule points outside the conventional mac child slot, the AP misses frame transmission completion notifications and association responses remain pending after acknowledgment. Resolve the configured module path when subscribing so completion reaches the AP.
@mgonzalezlopezudc
mgonzalezlopezudc force-pushed the cleanup/ht-cap-op-signalling-pr1144-v2 branch from 5b13d7a to ff10a94 Compare September 8, 2026 08:03
Comment thread src/inet/common/Simsignals.cc Outdated
simsignal_t linkBrokenSignal = cComponent::registerSignal("linkBroken");

simsignal_t modesetChangedSignal = cComponent::registerSignal("modesetChanged");
simsignal_t frameTransmissionFinishedSignal = cComponent::registerSignal("frameTransmissionFinished");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We already have a transmissionEndedSignal, how is this different? I assume it is different but then it should have a more specific name because it's hard to distinguish.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done

* Reports HT channel widths that an IEEE 802.11 PHY component can actually
* operate, independently of the modes described by its mode catalog.
*/
class INET_API IIeee80211HtChannelWidthProvider

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'm not sure about this interface. First, are we sure we want to have a separate interface for answering the channel width support question? What if there will be future questions for the receiver/transmitter related to HT? Are we going to have a separate interface for each one?

Maybe the name is not right, because it should be more generic like capabilities... I don't know, it just feels wrong. We should discuss.

}
// add indications
auto packet = const_cast<Packet *>(packetModel->getPacket());
// Packet-domain error models duplicate the transmitted packet, including

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

But should packet-domain error models really produce a packet which carries the tags from original transmitted packet? Or should we rather strip the packets there? It feels a bit late here.

All error model callers should do the same?

The notification includes frames dropped before transmission, so outcome describes its meaning more accurately than finished. Its emitter, consumer and details payload are specific to IEEE 802.11.

Replace the global frameTransmissionFinishedSignal with Ieee80211Mac::frameTransmissionOutcomeSignal and rename the registered signal and aggregate statistic to frameTransmissionOutcome. Update subscriptions and recorder sources, and verify the aggregate count alongside the status filters.

Validation: debug build and all five focused module tests passed (frame transmission statistics, DCF/HCF queue drops, HCF RTS timeout and HT association).
/**
* Provides the current IEEE 802.11 channel of a packet-level PHY component.
*/
class INET_API IIeee80211ChannelProvider

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is this yet another interface that needs to be added due to the duality of receiver/transmitter?
Or is this just transmitter? Why don't we simply add the method there?

levy added a commit that referenced this pull request Sep 8, 2026
The branch was force-updated and rebased since this morning's audit:
5aa31bc became 5b13d7a, 21 commits became 32, and the merge base
moved. PASS with 3 findings.

The eleven added commits make the change better, not merely bigger. One
of them removes a coupling the earlier head introduced: the 1-to-1
IFrameTransmissionCallback that tied Ieee80211Mac to a single management
peer becomes a signal with a details object, because the callback kept
result filters, statistics and visualizers from seeing terminal
transmission outcomes. That is AR-OBS-SIGNALS arrived at from the inside.
The interface summary is smaller than the earlier head's despite eleven
more commits: 2 removed against 4, 4 changed against 5.

Two ethernet commits now lead the series, each with its own unit test,
ahead of the 802.11 work that needs them -- PR-SPLIT-UPSTREAM in a second
subsystem.

F-1 survived the rewrite and is still the one that matters: no WHATSNEW,
at 32 commits and 112 files, for a change that removes two symbols and
re-signs three. It is the same gap as pr-1155.md F-2, a different
subsystem and a different author on the same day, which says the rule is
not visible enough rather than that two authors were careless. The change
summary already computes the exact list a T3 check would need.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
levy added a commit that referenced this pull request Sep 8, 2026
The branch was force-updated again: 5b13d7a became ff10a94. This
one is a pure rebase. The merge base, the commit count, the diffstat and
all 32 subjects are unchanged, and every commit has an identical
git patch-id.

So the findings are carried forward rather than re-derived, and the report
says so. The change summary confirms it from the other side: regenerated
against the new head it differs by two lines, the head hash and the
extraction time.

The report now records the patch-id comparison in its method section. A
rebase that changes no patch-id changes no finding, and comparing the two
sorted patch-id sets is what lets a re-audit say that honestly instead of
either re-reading 32 commits or quietly assuming.

Only two hashes moved in the report: the head, and the commit that carries
the one over-long subject.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
levy added a commit that referenced this pull request Sep 8, 2026
Three audits in a row reported a subject two or three characters over the
limit in the same numbered list as a missing release note and a sealed
path edited without permission. A reader who learns the numbers mean
nothing skims all of them.

Two faults, and the first was mine. PR-MSG-SUBJECT says "below about 72"
and check-commits.sh implemented that as a hard > 72 -- a gate stricter
than the rule it enforces, which is exactly the drift the rule documents
warn about. The rule now states both numbers and why: aim for 72, where
git log --oneline still fits an 80-column terminal once the hash is
counted, and fail above 80, where the subject stops fitting on its own.
Between them nothing is gained by arguing. The length is a proxy for
PR-SPLIT-ONE-CHANGE, and at 73 characters that proxy says nothing.

The second fault is that reports had one severity. Findings now carry
three -- Blocking, Finding, Note -- defined in audit/README.md. Only the
first two are numbered; a note goes in an unnumbered Notes section, and
the verdict counts findings rather than notes. The gate follows the same
split: it prints VIOLATION for what fails it and note: for what is
advisory, and only a VIOLATION sets the exit status.

Applied to the three reports that carried the old shape. #1154 and #1122
each drop from three findings to two and a note; #1155 drops from five to
four, and its ten over-long subjects become one note.

Co-Authored-By: Claude Opus 5 (1M context) <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.

2 participants