Skip to content

Commit 67145b7

Browse files
fix(ieee80211): answer valid compressed block ack requests
Remove the recipient-side peer capability assumption from compressed Block Ack response selection. An addressed, syntactically valid one-TID compressed BlockAckReq must receive a compressed BlockAck after SIFS, including the all-zero response when no matching partial state exists, as required by IEEE 802.11-2024 sections 9.3.1.7.2 and 10.25.6.5. Keep the originator-side capability assumption as the explicit opt-in for selecting compressed BlockAckReq frames until per-peer HT capability management is modeled. Continue rejecting nonzero fragment numbers and suppressing immediate responses for unaccepted or delayed agreements. Update the focused unit and runtime coverage to verify null-state responses, malformed fragment rejection, agreement-policy gates, and asymmetric endpoint configuration.
1 parent c862050 commit 67145b7

5 files changed

Lines changed: 19 additions & 26 deletions

File tree

src/inet/linklayer/ieee80211/mac/recipient/RecipientQosAckPolicy.cc

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,8 @@ Define_Module(RecipientQosAckPolicy);
1818
void RecipientQosAckPolicy::initialize(int stage)
1919
{
2020
ModeSetListener::initialize(stage);
21-
if (stage == INITSTAGE_LOCAL) {
21+
if (stage == INITSTAGE_LOCAL)
2222
rateSelection = check_and_cast<IQosRateSelection *>(getModuleByPath(par("rateSelectionModule")));
23-
assumePeerSupportsCompressedBlockAck = par("assumePeerSupportsCompressedBlockAck");
24-
}
2523
}
2624

2725
simtime_t RecipientQosAckPolicy::computeBlockAckDuration(Packet *packet, const Ptr<const Ieee80211BlockAckReq>& blockAckReq) const
@@ -70,17 +68,16 @@ bool RecipientQosAckPolicy::isBlockAckNeeded(const Ptr<const Ieee80211BlockAckRe
7068
// frame have been discarded from the transmit buffer due to expiry of their lifetime limit.
7169
}
7270
else if (auto compressedBlockAckReq = dynamicPtrCast<const Ieee80211CompressedBlockAckReq>(blockAckReq))
73-
return isCompressedBlockAckNeeded(compressedBlockAckReq, agreement, assumePeerSupportsCompressedBlockAck);
71+
return isCompressedBlockAckNeeded(compressedBlockAckReq, agreement);
7472
else
7573
throw cRuntimeError("Unsupported BlockAckReq");
7674
}
7775

78-
bool RecipientQosAckPolicy::isCompressedBlockAckNeeded(const Ptr<const Ieee80211CompressedBlockAckReq>& blockAckReq, RecipientBlockAckAgreement *agreement, bool assumePeerSupportsCompressedBlockAck)
76+
bool RecipientQosAckPolicy::isCompressedBlockAckNeeded(const Ptr<const Ieee80211CompressedBlockAckReq>& blockAckReq, RecipientBlockAckAgreement *agreement)
7977
{
80-
// IEEE Std 802.11-2024, 9.3.1.7.2 and 10.25.6.5. Both endpoint policies
81-
// must carry the explicit peer-capability assumption because this baseline
82-
// does not model negotiated peer HT capability.
83-
if (!assumePeerSupportsCompressedBlockAck || blockAckReq->getFragmentNumber() != 0)
78+
// IEEE Std 802.11-2024, 9.3.1.7.2 and 10.25.6.5: an addressed, syntactically
79+
// valid Compressed BlockAckReq elicits a Compressed BlockAck, including a null response.
80+
if (blockAckReq->getFragmentNumber() != 0)
8481
return false;
8582
// A missing partial state still elicits the mandatory null compressed BA.
8683
return agreement == nullptr || (agreement->getIsAddbaResponseSent() && !agreement->getIsDelayedBlockAckPolicySupported());

src/inet/linklayer/ieee80211/mac/recipient/RecipientQosAckPolicy.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,12 @@ class INET_API RecipientQosAckPolicy : public ModeSetListener, public IRecipient
2020
{
2121
protected:
2222
IQosRateSelection *rateSelection = nullptr;
23-
bool assumePeerSupportsCompressedBlockAck = false;
2423

2524
protected:
2625
virtual int numInitStages() const override { return NUM_INIT_STAGES; }
2726
virtual void initialize(int stage) override;
2827

29-
static bool isCompressedBlockAckNeeded(const Ptr<const Ieee80211CompressedBlockAckReq>& blockAckReq, RecipientBlockAckAgreement *agreement, bool assumePeerSupportsCompressedBlockAck);
28+
static bool isCompressedBlockAckNeeded(const Ptr<const Ieee80211CompressedBlockAckReq>& blockAckReq, RecipientBlockAckAgreement *agreement);
3029
simtime_t computeBlockAckDuration(Packet *packet, const Ptr<const Ieee80211BlockAckReq>& blockAckReq) const;
3130
simtime_t computeAckDuration(Packet *packet, const Ptr<const Ieee80211DataOrMgmtHeader>& dataOrMgmtHeader) const;
3231

src/inet/linklayer/ieee80211/mac/recipient/RecipientQosAckPolicy.ned

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,5 @@ simple RecipientQosAckPolicy extends SimpleModule like IRecipientQosAckPolicy
1818
parameters:
1919
@class(RecipientQosAckPolicy);
2020
string rateSelectionModule;
21-
// Set only for an HT-or-later local STA when peer capability management establishes that the peer supports Compressed Block Ack.
22-
// This explicit assumption is needed because peer HT capabilities are not represented by the baseline agreement contract.
23-
bool assumePeerSupportsCompressedBlockAck = default(false);
2421
@display("i=block/control");
2522
}

tests/module/Ieee80211CompressedBlockAckRuntime.test

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ abstract = false
2222
sim-time-limit = 1.05s
2323

2424
**.opMode = "n(mixed-2.4Ghz)"
25-
# Baseline capability management is absent, so both endpoint policies explicitly
26-
# opt in to compressed Block Ack; the production default remains false.
27-
**.assumePeerSupportsCompressedBlockAck = true
25+
# The originator explicitly opts in based on its peer-capability assumption;
26+
# the recipient requires no additional station-wide capability setting.
27+
**.originatorAckPolicy.assumePeerSupportsCompressedBlockAck = true
2828
**.cmdenv-log-level = info
2929

3030
%contains: stdout

tests/unit/Ieee80211CompressedBlockAck_1.test

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,9 @@ class TestOriginatorQosAckPolicy : public OriginatorQosAckPolicy
4343
class TestRecipientQosAckPolicy : public RecipientQosAckPolicy
4444
{
4545
public:
46-
static bool isCompressedResponseNeeded(const Ptr<const Ieee80211CompressedBlockAckReq>& request, RecipientBlockAckAgreement *agreement, bool enabled)
46+
static bool isCompressedResponseNeeded(const Ptr<const Ieee80211CompressedBlockAckReq>& request, RecipientBlockAckAgreement *agreement)
4747
{
48-
return isCompressedBlockAckNeeded(request, agreement, enabled);
48+
return isCompressedBlockAckNeeded(request, agreement);
4949
}
5050
};
5151

@@ -235,18 +235,18 @@ static Packet *makeOutstandingQosFrame(MacAddress receiverAddress, Tid tid, Frag
235235

236236
{
237237
auto request = makeCompressedBlockAckReq();
238-
ASSERT(!TestRecipientQosAckPolicy::isCompressedResponseNeeded(request, nullptr, false));
239-
ASSERT(TestRecipientQosAckPolicy::isCompressedResponseNeeded(request, nullptr, true));
238+
ASSERT(TestRecipientQosAckPolicy::isCompressedResponseNeeded(request, nullptr));
240239
request->setFragmentNumber(1);
241-
ASSERT(!TestRecipientQosAckPolicy::isCompressedResponseNeeded(request, nullptr, true));
240+
ASSERT(!TestRecipientQosAckPolicy::isCompressedResponseNeeded(request, nullptr));
242241
request->setFragmentNumber(0);
243242
RecipientBlockAckAgreement delayedAgreement(MacAddress("11:22:33:44:55:66"), 5, SequenceNumberCyclic(100), 64, SIMTIME_ZERO);
243+
ASSERT(!TestRecipientQosAckPolicy::isCompressedResponseNeeded(request, &delayedAgreement));
244244
delayedAgreement.addbaResposneSent();
245245
delayedAgreement.setIsDelayedBlockAckPolicySupported(true);
246-
ASSERT(!TestRecipientQosAckPolicy::isCompressedResponseNeeded(request, &delayedAgreement, true));
246+
ASSERT(!TestRecipientQosAckPolicy::isCompressedResponseNeeded(request, &delayedAgreement));
247247
delayedAgreement.setIsDelayedBlockAckPolicySupported(false);
248-
ASSERT(TestRecipientQosAckPolicy::isCompressedResponseNeeded(request, &delayedAgreement, true));
249-
EV << "Recipient capability, fragment, and agreement-policy gates passed.\n";
248+
ASSERT(TestRecipientQosAckPolicy::isCompressedResponseNeeded(request, &delayedAgreement));
249+
EV << "Recipient fragment and agreement-policy gates passed.\n";
250250
}
251251

252252
{
@@ -346,7 +346,7 @@ Established agreement produces the expected 64-bit bitmap.
346346
Compressed bitmap preserves leading receive-window holes.
347347
Compressed bitmap wraps from sequence 4095 to 0.
348348
Compressed bitmap preserves leading holes across sequence wrap.
349-
Recipient capability, fragment, and agreement-policy gates passed.
349+
Recipient fragment and agreement-policy gates passed.
350350
Originator capability, agreement, and fragmentation gates passed.
351351
Legacy Basic BAR and BA remain byte-exact.
352352
Accepted delayed agreement is retained for Basic BAR fallback.

0 commit comments

Comments
 (0)