ieee80211: add HT capability and operation management signaling - #1131
ieee80211: add HT capability and operation management signaling#1131mgonzalezlopezudc wants to merge 3 commits into
Conversation
Add a model-backed subset of the IEEE 802.11 HT Capabilities and HT Operation state to the MIB. Derive local capability limits from the authoritative mode set, preserve the standard Tx/Rx MCS representation, negotiate directional peer capabilities conservatively, and retain exact bitmap holes for equal Tx/Rx sets. Carry typed HT Capabilities and HT Operation elements in beacon, probe, association, and reassociation management frames. Serialize and deserialize the standard element layouts with subtype presence validation, malformed-element rejection, and concise protocol-printer output. Install peer HT state during detailed and simplified management flows. At the AP, reserve association IDs while a response is pending and commit the AID, station state, and peer capabilities only after the response is acknowledged. Preserve state across retries, clean up final failures, and downgrade an associated station after an acknowledged refusal when management-frame protection is not modeled. Add focused unit coverage for directional negotiation, unequal and undefined Tx MCS advertisements, non-contiguous MCS bitmaps, byte-level management element encoding, malformed inputs, and subtype policy. Add a detailed 802.11n association module test that verifies the request/response element matrix and peer-state installation.
| mib->bssStationData.isAssociated = true; | ||
| } | ||
| else if (stage == INITSTAGE_LINK_LAYER) { | ||
| else if (stage == INITSTAGE_LAST) { |
There was a problem hiding this comment.
🔴 Simplified wireless stations are no longer recognized as being on the same wireless network during setup, breaking automatic address and route assignment
The simplified station's network name and access-point link data are now recorded much later during startup (stage == INITSTAGE_LAST at src/inet/linklayer/ieee80211/mgmt/Ieee80211MgmtStaSimplified.cc:26) than when the network configurator groups wireless nodes, so such stations are no longer seen as sharing a wireless link with their access point.
Impact: Simulations using the simplified station management can get wrong IP addresses and routes, so traffic between the station and the rest of the network fails.
Init-stage ordering versus configurator wireless-link extraction
Previously the block ran at INITSTAGE_LINK_LAYER (94), which is before INITSTAGE_NETWORK_CONFIGURATION (101) where L3NetworkConfiguratorBase groups interfaces by getWirelessId() (src/inet/networklayer/configurator/base/L3NetworkConfiguratorBase.cc:470-520, called at lines 122/160/222/249). getWirelessId() first consults mibModule->bssData.ssid; the AP sets its own SSID at INITSTAGE_LOCAL (src/inet/linklayer/ieee80211/mgmt/Ieee80211MgmtApBase.cc:29) so the AP interface yields medium:ssid. With the new INITSTAGE_LAST, the STA's mib->bssData.ssid is still empty at configuration time, and Ieee80211MgmtStaSimplified has no ssid parameter and no agent submodule (src/inet/linklayer/ieee80211/mgmt/Ieee80211MgmtStaSimplified.ned), so the fallback path returns only medium. The STA and AP therefore end up in different wireless link groups.
Also apMib->bssAccessPointData.stations[...] = ASSOCIATED and mib->bssData.bssid are now installed only at the very last stage, after other modules may already have queried association state.
If the intent was only to guarantee that the AP mode set (and hence localHtCapabilities) is available, a safer approach is to keep the SSID/BSSID/association setup at INITSTAGE_LINK_LAYER and install only the HT peer state in a later stage.
Prompt for agents
Ieee80211MgmtStaSimplified::initialize moved its AP resolution block from INITSTAGE_LINK_LAYER to INITSTAGE_LAST so that the AP's mode-set-derived HT capabilities are already available. However, this delays setting mib->bssData.bssid, mib->bssData.ssid and apMib->bssAccessPointData.stations past INITSTAGE_NETWORK_CONFIGURATION, where L3NetworkConfiguratorBase::getWirelessId() reads mib->bssData.ssid to group interfaces into wireless links. Because Ieee80211MgmtStaSimplified has neither an 'ssid' parameter nor an agent submodule, the fallback yields only the medium name while the AP yields 'medium:ssid', so the STA and AP no longer share a wireless link and address/route assignment changes. Consider splitting the initialization: keep bssid/ssid/association-state installation at INITSTAGE_LINK_LAYER (or an earlier stage than network configuration) and install only the negotiated HT peer state in the later stage.
Was this helpful? React with 👍 or 👎 to provide feedback.
| const Ptr<Chunk> Ieee80211MgmtFrameSerializer::deserialize(MemoryInputStream& stream, const std::type_info& typeInfo) const | ||
| { | ||
| switch (0) { // TODO receive and dispatch on type_info parameter | ||
| int frameType = -1; |
There was a problem hiding this comment.
🔴 Deserialized management frames end up with an unset length, corrupting packet contents when frames are reconstructed from raw bytes
The new type-aware decoding path for management frames (deserialize(...) at src/inet/linklayer/ieee80211/mgmt/Ieee80211MgmtFrameSerializer.cc:460) replaces the framework routine that records how many bytes were consumed, so the rebuilt frame carries no valid length (and no cached raw bytes).
Impact: Any place that rebuilds an 802.11 management frame from raw bytes (emulation, capture replay, reinterpretation) gets a frame with a bogus length, leading to wrong packet offsets or errors.
Bypassed FieldsChunkSerializer bookkeeping
FieldsChunkSerializer::deserialize(stream, typeInfo) (src/inet/common/packet/serializer/FieldsChunkSerializer.cc:28-41) records the start position, calls the single-argument deserialize(stream), then sets fieldsChunk->setChunkLength(consumed), updates totalDeserializedLength, and fills the serialized-data cache. The new override in Ieee80211MgmtFrameSerializer does none of that: it constructs the frame and returns it directly.
Frames such as Ieee80211AssociationRequestFrame, Ieee80211AssociationResponseFrame, Ieee80211BeaconFrame have no chunkLength default in Ieee80211MgmtFrame.msg, so FieldsChunk::chunkLength stays b(-1) (src/inet/common/packet/chunk/FieldsChunk.cc:15-19); frames with defaults (e.g. Authentication B(6)) keep a fixed value that ignores any HT elements actually read. Chunk::convertChunk then uses result->getChunkLength() for region tags (src/inet/common/packet/chunk/Chunk.cc:136), and the consistency assertion at src/inet/common/packet/chunk/Chunk.cc:209 is compiled out by default (CHUNK_CHECK_IMPLEMENTATION_ENABLED is 0), so the problem is silent in normal builds.
A fix is to keep the framework bookkeeping, e.g. have the typed override measure the stream positions and call setChunkLength()/populate the serialized data exactly as the base class does, or restructure so the base implementation still wraps the typed dispatch.
Prompt for agents
Ieee80211MgmtFrameSerializer now overrides deserialize(MemoryInputStream&, const std::type_info&) directly, which bypasses FieldsChunkSerializer::deserialize(stream, typeInfo). That base implementation is responsible for computing the number of consumed bits, calling setChunkLength() on the resulting FieldsChunk, updating ChunkSerializer::totalDeserializedLength, and caching the original serialized bytes in the chunk. Without it, management frames created by deserialization carry either b(-1) or the stale msg-file default chunk length, which silently corrupts packet lengths/offsets (the consistency assert in Chunk::deserialize is compiled out by default). Restructure so the typed dispatch happens inside the framework's bookkeeping, e.g. record start/end stream positions in the override and apply the same setChunkLength/serialized-data handling as FieldsChunkSerializer.
Was this helpful? React with 👍 or 👎 to provide feedback.
| if (!mib->bssStationData.isAssociated || assocTimeoutMsg) | ||
| throw cRuntimeError("startReassociation: not associated or association currently in progress"); |
There was a problem hiding this comment.
🟡 Asking a station to re-associate while it is not currently associated now aborts the simulation instead of associating
The re-association request handler now refuses to run unless the station is already associated (throw cRuntimeError at src/inet/linklayer/ieee80211/mgmt/Ieee80211MgmtSta.cc:287), whereas the same request previously fell back to a normal association.
Impact: Setups or agents that issue a re-association request for an unassociated station now stop the simulation with an error instead of connecting.
Behavior change of the re-associate primitive
processReassociateCommand() previously delegated to processAssociateCommand() ("treat the same way as association"), so a Ieee80211Prim_ReassociateRequest worked in every state where association worked. It now calls startReassociation(), which throws when !mib->bssStationData.isAssociated. The bundled Ieee80211AgentSta never emits this primitive, but the primitive is part of the public management-agent interface (Ieee80211Primitives.msg) and custom agents rely on it. Consider falling back to startAssociation() when the station is not associated, rather than throwing.
Was this helpful? React with 👍 or 👎 to provide feedback.
Restore FieldsChunkSerializer bookkeeping for typed management frame deserialization so decoded chunks receive their consumed length and retain their serialized-data cache. Replace borrowed association-response packet pointers with deterministic sender-local transaction tags that survive fragmentation and RTS protection. Copy packet tags and correctly slice region tags when fragments are created, and commit or cancel pending association state only after authoritative exchange completion. Centralize association ID reservation, commit, cancellation, release, and cleanup in Ieee80211Mib using deterministic linear allocation. Mark the VHT-only ac mode profile as not advertising modeled HT operation. Add focused unit coverage for serializer length and cache preservation, bounded management-body decoding, transaction disposition and fragmentation propagation, association ID lifecycle, and HT mode-set gating. Validation: debug build; 5 focused unit tests; detailed HT association module test; lan80211ac Ping1 and DCF fragmentation fingerprints unchanged.
Restore simplified station BSS identity setup to the link-layer initialization stage so automatic network configuration sees the AP SSID, while keeping HT peer capability installation at the final stage after mode-set initialization. Add an AP-owned association-response timeout with per-station deadlines and transaction matching. Expired pending responses now release only uncommitted AID reservations and discard pending HT state without disturbing replacement transactions or committed reassociation IDs. Document the management serializer's exact-body stream contract and extend the HT element regression to cover vendor elements followed by trailing FCS-like bytes. Add deterministic unit and module coverage for timeout scheduling, AID reuse, stale transaction protection, simplified-station wireless identity during network configuration, and final-stage HT peer state. Tests: release and debug builds; 3 focused unit tests; 2 focused module tests.
Summary
This PR adds the model-backed IEEE 802.11 HT Capabilities and HT Operation management signaling that is currently missing from INET's infrastructure management exchange.
It deliberately implements a focused subset backed by existing PHY mode-set information and explicit BSS policy. It is not intended to be a complete Annex C HT MIB implementation.
What changed
Ieee80211ModeSet.Motivation
INET already models HT/VHT PHY mode sets and 802.11n MAC behavior, but its modeled management frames do not exchange the HT Capabilities and HT Operation elements required to describe that operation. Consequently, association state cannot retain the peer's advertised HT receive/transmit constraints or the BSS HT operating parameters.
This change connects the existing PHY authority to management signaling and stores a conservative, standards-aligned negotiated subset for later MAC/PHY use.
Validation
make -j$(nproc) MODE=releasemake -j$(nproc) MODE=debuginet_run_unit_tests -m release --no-build -f 'Ieee80211HtCapabilities_1|Ieee80211HtMgmtElements_1'inet_run_unit_tests -m debug --no-build -f 'Ieee80211HtCapabilities_1|Ieee80211HtMgmtElements_1'inet_run_module_tests -m release --no-build -f 'Ieee80211HtAssociation_1'inet_run_module_tests -m debug --no-build -f 'Ieee80211HtAssociation_1'examples/wireless/lan80211ac, configurationPing1showcases/wireless/txop, configurationGeneralAll listed checks pass. Existing fingerprint values were unchanged; no fingerprint CSV was updated.
Scope and follow-up