wifi: Fix EDCA immediate channel access

...when channel access is requested at a slot boundary.
This commit is contained in:
Stefano Avallone
2025-08-20 16:25:02 +02:00
parent d8feca9156
commit 7cd1a70131
25 changed files with 29 additions and 33 deletions

View File

@@ -17,6 +17,7 @@
#include "ns3/log.h"
#include "ns3/simulator.h"
#include <cmath>
#include <sstream>
#undef NS_LOG_APPEND_CONTEXT
@@ -591,13 +592,13 @@ ChannelAccessManager::RequestAccess(Ptr<Txop> txop)
*/
Time accessGrantStart = GetAccessGrantStart() + (txop->GetAifsn(m_linkId) * GetSlot());
if (txop->IsQosTxop() && txop->GetBackoffStart(m_linkId) > accessGrantStart)
if (const auto diff = txop->GetBackoffStart(m_linkId) - accessGrantStart;
txop->IsQosTxop() && diff.IsStrictlyPositive())
{
// The backoff start time reported by the EDCAF is more recent than the last
// time the medium was busy plus an AIFS, hence we need to align it to the
// next slot boundary.
Time diff = txop->GetBackoffStart(m_linkId) - accessGrantStart;
uint32_t nIntSlots = (diff / GetSlot()).GetHigh() + 1;
// The backoff start time reported by the EDCAF is more recent than the last time the medium
// was busy plus an AIFS, hence we need to align it to the next slot boundary.
const auto div = diff / GetSlot();
const uint32_t nIntSlots = div.GetHigh() + (div.GetLow() > 0 ? 1 : 0);
txop->UpdateBackoffSlotsNow(0, accessGrantStart + (nIntSlots * GetSlot()), m_linkId);
}

View File

@@ -1746,15 +1746,15 @@ LargestIdlePrimaryChannelTest::DoRun()
* that the frame is not transmitted. A backoff value is kept being generated as long as the
* frame is kept in the queue.
*
* Backoff Last
* Backoff Backoff Backoff value #3, backoff
* value #0 value #1 value #2 unblock queue value
* | ┌─────┐ | | | ┌─────┐ ┌────┐ |
* | ┌───┐ │Assoc│ | |Decrement| |Decrement| |Decrement│ADDBA│ │QoS │ |
* | │ACK│ │Resp │ |AIFS| backoff |slot| backoff |slot| backoff │ Req │. .│data│ |
* ──┬─────┬┴───┴──┴─────┴┬───┬────────────────────────────────────────────┴─────┴───┴────┴┬───┬──
* │Assoc│ │ACK│ │ACK│
* │ Req │ └───┘ └───┘
* Backoff Last
* Backoff Backoff Backoff value #3, backoff
* value #0 value #1 value #2 unblock queue value
* | ┌─────┐ | | | ┌─────┐ ┌────┐ |
* | ┌───┐ │Assoc│ | | Decrement | Decrement | Decrement │ADDBA│ │QoS │ |
* | │ACK│ │Resp │ |AIFS| backoff | backoff | backoff │ Req │. .│data│ |
* ──┬─────┬┴───┴──┴─────┴┬───┬────────────────────────────────────────┴─────┴───┴────┴┬───┬──
* │Assoc│ │ACK│ │ACK│
* │ Req │ └───┘ └───┘
* └─────┘
*
* The ProactiveBackoff test checks the generation of backoff values when the attribute is set
@@ -2164,10 +2164,6 @@ BackoffGenerationTest::BackoffGenerated(AcIndex ac, uint32_t backoff, uint8_t li
offset,
"Backoff value generated too early");
m_nextBackoffGen.Cancel();
// we get here when the backoff expired but no transmission occurred, thus we have
// generated a new backoff value and we will start decrementing the counter in a slot
delay = m_apMac->GetWifiPhy(linkId)->GetSlot();
}
if (m_nGenBackoff < nValues)

View File

@@ -155,8 +155,8 @@ WifiUseAvailBwTest::Transmit(uint8_t bss,
client->SetAttribute("Interval", TimeValue(MicroSeconds(0)));
client->SetRemote(m_sockets[0]);
m_apDevices.Get(0)->GetNode()->AddApplication(client);
client->SetStartTime(Seconds(0)); // start now
client->SetStopTime(Seconds(1)); // stop in a second
client->SetStartTime(TimeStep(1)); // start shortly after the start of PPDU in BSS 1
client->SetStopTime(Seconds(1)); // stop in a second
client->Initialize();
// after 1us (to allow for propagation delay), the largest idle primary
@@ -470,20 +470,18 @@ WifiDynamicBwOpTestSuite::WifiDynamicBwOpTestSuite()
AddTestCase(
new WifiUseAvailBwTest({"{50, 160, BAND_5GHZ, 5}", "{42, 80, BAND_5GHZ, 2}"}, MHz_u{80}),
TestCase::Duration::QUICK);
// clang-format off
/**
* ───────────────────────────── primary 160 ─────────────────────────────
* primary20
* ┌────────┬────────┬────────┬────────┬───────┬────────┬────────┬────────┌────────┬────────┬────────┬────────┬───────┬────────┬────────┬────────┐
* BSS 0 │ 1 │ 5 │ 9 │ 13 17 │ 21 │ 25 │ 29 │ 33 │ 37 │ 41 │ 45 49 │ 53 │ 57 │ 61
* └────────┴────────┴────────┴────────┴───────┴────────┴────────┴────────└────────┴────────┴────────┴────────┴───────┴────────┴────────┴────────┘
* ────────────── primary 160 ──────────────
* primary20
* ┌────┬────┬────┬────┬────┬────┬────┬────┬────────┬────┬────┬────────┬────────┐
* BSS 0 │ 1 │ 5 │ 9 │ 13 │ 17 │ 21 │ 25 │ 29 │ 33 │ 37 │ 41 │ 45 │ 49 │ 53 │ 57 │ 61
* └────┴────┴────┴────┴────┴────┴────┴────┴────────┴────┴────┴────────┴────────┘
*
* ┌────────┬────────┬────────┬────────┬───────┬────────┬────────┬────────┐
* BSS 1 │ 1 │ 5 │ 9 │ 13 17 │ 21 │ 25 │ 29
* └────────┴────────┴────────┴────────┴───────┴────────┴────────┴────────┘
* primary20
* ┌────┬────┬────┬────┬────┬────┬────┬────┐
* BSS 1 │ 1 │ 5 │ 9 │ 13 │ 17 │ 21 │ 25 │ 29
* └────┴────┴────┴────┴────┴────┴────┴────┘
* primary20
*/
// clang-format on
AddTestCase(
new WifiUseAvailBwTest({"{31, 320, BAND_6GHZ, 10}", "{15, 160, BAND_6GHZ, 7}"}, 160),
TestCase::Duration::QUICK);