Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions doc/project/evidence/model/wifi/pr1343-comparison-method.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Parent-to-commit protocol comparisons

> **Kind:** procedure · **Status:** current · **Seal:** none · **Owns:** — · **Stands on:** [test rules](../../../rule/testing.md), [protocol authoring](../../../../../tests/protocol/lib/AUTHORING.md)

Each comparison record checks one implementation commit against its first parent. The after revision is the commit that adds the selected protocol fixture. The before revision is that commit's parent. The same fixture inputs and successful assertions apply to both revisions.

The parent lacks the new fixture. The comparison therefore copies the fixture and its listed test components into the parent worktree. It copies no production file. A parent failure must reach the intended protocol assertion. A compilation failure, initialization error, or unavailable observation point does not establish the stated repair.

## Resolve the two revisions

Each record names its fixture and implementation subject. Use the fixture path to locate the fix in the current history:

```sh
fixture_path=tests/protocol/wifi/common/WifiBlockAckDuplicateAddba.test
fix_commit="$(git log --diff-filter=A --format=%H -- "$fixture_path")"
before_commit="$(git rev-parse "$fix_commit^1")"
```

Replace `fixture_path` with the path from the selected record. The current series adds each fixture once. The lifecycle commit adds both the BAR and inactivity fixtures; either path selects that same commit.

## Prepare identical test inputs

1. Create separate worktrees at `before_commit` and `fix_commit`.
2. Copy the record's listed fixture inputs from `fix_commit` into the parent worktree.
3. Preserve the parent production source and its existing test framework.
4. Source `.envrc` from each worktree root.
5. Run `make makefiles` in each worktree.
6. Run `make MODE=debug -j12` in each worktree.
7. Run the record's filtered protocol command in each worktree.

The after worktree supplies the listed paths without another copy. Original topology, PHY configuration, and protocol framework files remain part of each revision. The before and after builds must match their respective production inputs. The protocol runner builds test executables; it does not replace the INET library build.

## Read the result

Each fixture retains its ordinary PASS expectation. A failed protocol assertion on the parent remains FAIL. A control can pass while another run in the same file fails. The report therefore separates test files from simulation runs and records each control.

All recorded protocol runs use debug mode, configuration `General`, and `seed-set = 0`. Each fixture supplies its run selection and observation windows. The fixtures use the INET Basic compatibility profile. Their guides explain the stimulus and standards limits.

## Identify the executed inputs

Each record pins the before and after source revisions used by the recorded executions. Those hashes identify the actual runs. A later rewrite of documentation can change commit IDs. The rewrite must preserve both compared production inputs and all fixture inputs before it reuses the recorded result.

The production tree hashes identify the tracked `src/` contents independently of commit metadata. Check the current pair with this command:

```sh
git rev-parse "$before_commit:src" "$fix_commit:src"
```

Both values must equal the record's production tree hashes. Fixture identity requires a separate check of every listed input. A source tree match alone does not establish fixture identity or execute a test.

The four pairs were executed during the protocol fold. Local evidence resides under `/tmp/pr1343-fold-20261020/`. The parent output directories contain the failed assertions and controls that pass. The after logs contain the successful fixture verdicts at the selected fix. `verification.json` maps those logs to the executed revisions. These local artifacts are outside Git.

This record revision reuses those executions. It does not claim another simulation campaign. Per-commit source and fixture comparisons establish that the documentation rewrite preserves the recorded inputs. The published fixtures and commands permit another execution.

## Standards corpus

The guides preserve the standard references for their own scenarios. The original retrieval used a rebuilt corpus. Its lint output reports 14 heading ambiguities elsewhere in the document, plus other extraction diagnostics. The cited entries resolved to distinct canonical nodes. Table 9-36 also received direct PDF inspection to confirm its reserved value and table alignment.

The checked outgoing references for 11.5.4, 10.3.2.14.3, 11.3.5.5, Table 9-466, and Table 9-467 all resolve. The receiver-cache table and reassociation cross-reference resolve. These checks do not establish a clean verdict for the complete corpus. Local retrieval records and lint output reside under `audit/pr1343-compliant-scenarios-20261020/` outside Git.
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# BAR without an agreement: parent-to-commit comparison

> **Kind:** report · **Status:** snapshot 2026-10-20 · **Seal:** none · **Owns:** — · **Stands on:** [comparison method](../pr1343-comparison-method.md), [test guide](blockack-bar-without-agreement.md)

The orphan-BAR run fails before the lifecycle fix and passes after that fix. The established-agreement control passes on both revisions. This record covers only `WifiBlockAckBarWithoutAgreement.test`. The inactivity fixture has its own [comparison record](blockack-inactivity-comparison.md).

## Compared revisions

The selected commit has the subject `ieee80211: fix: preserve Block Ack setup and teardown boundaries`. It adds [WifiBlockAckBarWithoutAgreement.test](../../../../../../tests/protocol/wifi/common/WifiBlockAckBarWithoutAgreement.test) and [WifiBlockAckInactivity.test](../../../../../../tests/protocol/wifi/common/WifiBlockAckInactivity.test). Either fixture identifies the same fix in the comparison method.

| Role | Executed source revision | Production tree (`src/`) |
| --- | --- | --- |
| Before: parent of the lifecycle fix | `6c90fe0b9b85f199d867ab08bd42097b3437530e` | `3d134699aca48ba038d9dec3a8b947c32b754c2d` |
| After: lifecycle fix | `d58fe2b72590a195fa69f4c128fddcbb2a7269d8` | `d6fb238177e86a61b28a45ab040d5d9c5a3cf3b8` |

These hashes pin the recorded executions. A documentation rewrite can change current commit IDs without a production or fixture change. Both compared input sets retain their executed contents.

## Results

| Run | Before the commit | After the commit |
| --- | --- | --- |
| 0: no agreement | FAIL: no required DELBA within 20 ms | PASS: recipient-role DELBA has the correct peer and TID |
| 1: established agreement | PASS: Basic Block Ack reaches the controlled peer; no DELBA appears | PASS: the same assertions succeed |

One file contains two simulation runs. The parent failure reaches the orphan-BAR deadline assertion. The after revision passes both runs. Ordinary PASS expectations remain unchanged in both revisions.

## BAR recovery

Before this commit, the recipient does not start the required recovery when a valid BAR arrives without an agreement. After this commit, HCF requests recipient-role DELBA without a recipient agreement allocation. The test requires the correct receiver, TID, and Initiator value.

The stimulus sends a crafted Basic BAR through production Tx and the radio. Run 0 selects TID 5 without an agreement. Run 1 establishes TID 6 through real ADDBA before the BAR. Its controlled peer consumes the Basic Block Ack after production Rx validation. It takes ownership before frame deletion. The recipient response paths remain unchanged by the fixture.

## Reproduce and inspect

Copy these four inputs from the fix into its parent worktree:

- `tests/protocol/wifi/common/WifiBlockAckBarWithoutAgreement.test`.
- `tests/protocol/wifi/BlockAckLifecycleTestSupport.h`.
- `tests/protocol/wifi/ned/BlockAckLifecycleHcf.ned`.
- `tests/protocol/wifi/ini/_blockackLifecycle.ini`.

Run this selector on both debug builds:

```sh
inet_run_protocol_tests -p inet -m debug -w '^tests/protocol/wifi$' \
-f '/WifiBlockAckBarWithoutAgreement\.test$' --no-concurrent
```

The parent output is `06-942a7e2780-parent-output/WifiBlockAckBarWithoutAgreement.out`. The after log is `06-942a7e2780-protocol.log`. That after selector also repeats other fixtures. Only the BAR fixture verdict belongs to this comparison.

## Limits

The fixture supplies the absent agreement directly. It does not reproduce earlier agreement teardown and lost DELBA attempts. Its crafted sender bypasses ordinary EDCA channel access. Basic BAR uses a reserved current-standard type value. The guide explains the legitimate recovery condition and these fixture limits.
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
# BAR without a Block Ack agreement

> **Kind:** reference · **Status:** current · **Seal:** none · **Owns:** — · **Stands on:** [test source](../../../../../../tests/protocol/wifi/common/WifiBlockAckBarWithoutAgreement.test), [comparison record](blockack-bar-without-agreement-comparison.md)

A recipient without the selected Block Ack agreement must send recipient-role DELBA after it receives the test BAR. A separate control establishes an agreement and requires a Basic Block Ack response. Together, the runs distinguish recovery from normal response behavior.

The test checks INET's Basic compatibility profile. It does not establish support for every Block Ack format or current-standard conformance for the Basic format.

## Can compliant stations reach this situation?

Yes, after a real agreement becomes inconsistent across the two stations because a teardown frame is lost. The stations need not disagree about the rules. They can temporarily have different information about the agreement.

Hypothetical compliant scenario: the recipient's management entity requests teardown of an active agreement. The recipient removes its local agreement and transmits DELBA. Every DELBA attempt fails to reach the originator because of medium loss. The originator retains its local agreement and later transmits a BAR. The recipient must then recover from the absent-agreement condition.

```mermaid
sequenceDiagram
participant O as Compliant originator
participant M as Wireless medium
participant R as Compliant recipient
Note over O,R: Earlier valid agreement exists at both stations
R->>R: Local management requests teardown
R->>M: DELBA attempts
M->>M: DELBA frames do not reach originator
Note over O: Local agreement remains active
O->>R: BAR under retained local agreement
R->>O: Recipient-role DELBA recovery
```

[IEEE Std 802.11-2024, 11.5.3.2](../../../../../../standards/80211ax-2024.pdf#page=2565) permits management to initiate teardown through DELBA. [11.5.4](../../../../../../standards/80211ax-2024.pdf#page=2566) specifies DELBA when a recipient receives BAR without an active agreement. The hypothetical loss sequence explains how that receive condition can arise without peer misconduct.

The current fixture starts directly from the absent-agreement state. It does not establish the earlier agreement and lose its DELBA. Its result proves the recovery response for the supplied state, not the complete practical sequence above.

There is also a wire-format limit. This fixture sends a Basic BAR with BAR Type 0, which [Table 9-36](../../../../../../standards/80211ax-2024.pdf#page=719) reserves in IEEE 802.11-2024. The controlled sender also bypasses normal channel access. The current BAR stimulus therefore does not satisfy a strict requirement for fully compliant nodes and frames.

For that requirement, use a permitted BAR variant after real setup and real DELBA loss. Retain the recipient-role recovery assertion. The [profile limits](#profile-limits) distinguish this required follow-up from the current compatibility regression.

## Two runs with different initial state

Both runs use real association, production transmission, and the wireless medium. At `1.1 s`, a controlled station sends one crafted Basic BAR to the AP. The request identifies the selected traffic identifier (TID), sequence 0, and fragment 0.

| Run | State before the crafted BAR | Required AP response |
| --- | --- | --- |
| 0 | No agreement for station `sta1` and TID 5 | Recipient-role DELBA for that station and TID |
| 1 | Real ADDBA establishes an agreement for `sta1` and TID 6 | Basic Block Ack for that station and TID |

Run 0 starts application traffic after the simulation's time limit. Run 1 supplies a short traffic batch before the crafted BAR. Read-only queries check the required agreement state at both endpoints before transmission. The control must establish its agreement before the response assertion can test normal behavior.

```mermaid
sequenceDiagram
participant S as Controlled station
participant A as Production AP
alt Run 0 - no agreement for TID 5
S->>A: Basic BAR for TID 5
A->>A: Detect absent recipient agreement
A-->>S: DELBA for TID 5, Initiator false
else Run 1 - agreement for TID 6
Note over S,A: Application traffic establishes agreement through ADDBA
S->>A: Basic BAR for TID 6
A-->>S: Basic Block Ack for TID 6
S->>S: Validate and consume control response
Note over A: No DELBA during the control window
end
```

The sequence diagram shows distinct runs, not two BAR exchanges within one run. The AP uses production receive and response paths in both cases.

## Assertions and observation windows

Run 0 first requires the AP to receive a Basic BAR from `sta1` for TID 5. The next assertion requires a transmitted DELBA within 20 ms of that reception. DELBA must identify the station and TID. Its Initiator field must be false because the AP ends its recipient role. A query also requires no recipient agreement when DELBA enters transmission.

Run 1 observes the crafted BAR at station transmission. It requires a Basic Block Ack within 20 ms. The response must identify the station and TID 6. The controlled peer must then receive and validate that response through the radio. A concurrent guard prohibits AP DELBA transmission for 20 ms after the BAR transmission.

The no-agreement run observes DELBA transmission at the AP. It does not separately assert DELBA reception or its ACK. The control observes both response transmission and reception. These are different evidence boundaries.

## Why the sender is a controlled peer

The [shared support](../../../../../../tests/protocol/wifi/BlockAckLifecycleTestSupport.h) submits the crafted BAR to production Tx. Tx supplies transmitter addresses and FCS and retains its own frame copy. The fixture deletes its original after submission. Production MAC, radio, and AP receive processing remain active.

The crafted BAR does not create a normal originator exchange context at the sender. The test MAC therefore consumes the control's Basic Block Ack after production Rx validation. It does not submit that response to an idle HCF that never requested it.

```mermaid
flowchart LR
F["Test constructs BAR"] --> T["Production Tx and radio"]
T --> R["Production AP receive path"]
R --> H["Production agreement decision"]
H --> W["Production AP transmission"]
W --> P["Controlled peer radio and Rx"]
P --> C["Test consumes Basic Block Ack in control run"]
```

This boundary makes the sender an explicit test component. It leaves the recipient decision under test in production code.

## Recorded result and failure interpretation

The [comparison record](blockack-bar-without-agreement-comparison.md) compares the lifecycle fix with its parent. The parent sends no required DELBA during the observation window. The same run passes after the fix. The established-agreement control passes on both revisions.

If neither run receives a response, first check association, radio reception, and the stimulus. A failure in the control does not isolate absent-agreement recovery. If only run 0 misses DELBA after confirmed BAR reception, the failure reaches the intended recovery obligation.

## Run and scope

From the INET root, use the normal OMNeT++ and INET environment setup. Run the fixture:

```sh
inet_run_protocol_tests -p inet -m debug -w '^tests/protocol/wifi$' \
-f '/WifiBlockAckBarWithoutAgreement\.test$' --no-concurrent
```

The file runs scenarios 0 and 1. Both `wifi_block_ack_orphan_bar` and `wifi_block_ack_known_bar` must report PASS. The file also rejects a protocol FAIL line.

The tests use seed 0 and disable inactivity expiration. They do not test absent-agreement DATA, malformed BAR, response bitmap accuracy, or another Block Ack format. The agreement query checks state at its observation point; it does not observe every possible temporary allocation.

## Profile limits

The shared configuration selects HT stations and `blockAckVariant = "basic"`. This is INET's historical compatibility profile. [IEEE Std 802.11-2024, Table 9-36](../../../../../../standards/80211ax-2024.pdf#page=719) reserves BAR Type 0. INET's Basic BAR uses that value. A run that ends before a BAR appears does not establish conformance for every encoded field.

The fixtures inspect typed frame objects and selected state transitions. They do not check every encoded field or every channel-access requirement. A frame that crosses the simulated radio is not automatically a complete wire-conformance check.

[HCF](../../../../../../src/inet/linklayer/ieee80211/mac/coordinationfunction/Hcf.cc) rejects Compressed Block Ack selection during initialization at this stage. A permitted variant requires further implementation support. A configuration change alone cannot supply that support.

## Standards evidence

These references use IEEE Std 802.11-2024, corpus ID `ieee80211-2024`. Physical pages refer to the local file `standards/80211ax-2024.pdf`. Its filename does not identify an ax amendment.

| Subject | Clause, table, or figure | Physical PDF pages | Canonical node ID |
| --- | --- | --- | --- |
| BAR variant encoding | Table 9-36 | 719–720 | `ieee80211-2024:table:9-36` |
| Final-transfer teardown | 10.25.4 | 2056 | `ieee80211-2024:clause:10.25.4` |
| Management-initiated teardown | 11.5.3.2 | 2565 | `ieee80211-2024:clause:11.5.3.2` |
| Inactivity and absent-agreement recovery | 11.5.4 | 2566 | `ieee80211-2024:clause:11.5.4` |

The [shared procedure](../pr1343-comparison-method.md#standards-corpus) records the corpus checks, extraction limits, and local retrieval artifacts.
Loading
Loading