wifi: Add unit test to check ChannelAccessManager attributes
This commit is contained in:
@@ -18,22 +18,37 @@
|
||||
*/
|
||||
|
||||
#include "ns3/adhoc-wifi-mac.h"
|
||||
#include "ns3/ap-wifi-mac.h"
|
||||
#include "ns3/channel-access-manager.h"
|
||||
#include "ns3/config.h"
|
||||
#include "ns3/frame-exchange-manager.h"
|
||||
#include "ns3/interference-helper.h"
|
||||
#include "ns3/mgt-action-headers.h"
|
||||
#include "ns3/mobility-helper.h"
|
||||
#include "ns3/multi-model-spectrum-channel.h"
|
||||
#include "ns3/packet-socket-client.h"
|
||||
#include "ns3/packet-socket-helper.h"
|
||||
#include "ns3/packet-socket-server.h"
|
||||
#include "ns3/pointer.h"
|
||||
#include "ns3/qos-txop.h"
|
||||
#include "ns3/rng-seed-manager.h"
|
||||
#include "ns3/simulator.h"
|
||||
#include "ns3/spectrum-wifi-helper.h"
|
||||
#include "ns3/spectrum-wifi-phy.h"
|
||||
#include "ns3/sta-wifi-mac.h"
|
||||
#include "ns3/string.h"
|
||||
#include "ns3/test.h"
|
||||
#include "ns3/wifi-net-device.h"
|
||||
#include "ns3/wifi-spectrum-phy-interface.h"
|
||||
|
||||
#include <iomanip>
|
||||
#include <list>
|
||||
#include <numeric>
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE("WifiChannelAccessManagerTest");
|
||||
|
||||
template <typename TxopType>
|
||||
class ChannelAccessManagerTest;
|
||||
|
||||
@@ -1529,6 +1544,481 @@ LargestIdlePrimaryChannelTest::DoRun()
|
||||
Simulator::Destroy();
|
||||
}
|
||||
|
||||
/**
|
||||
* \ingroup wifi-test
|
||||
* \ingroup tests
|
||||
*
|
||||
* \brief Test the GenerateBackoffIfTxopWithoutTx and ProactiveBackoff attributes of the
|
||||
* ChannelAccessManager. The backoff values generated by the VO AC of the AP are checked.
|
||||
*
|
||||
* The GenerateBackoffIfTxopWithoutTx test checks the generation of backoff values when the
|
||||
* attribute is set to true. A QoS data frame is queued at the AP but the queue is blocked so
|
||||
* 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 │ └───┘ └───┘
|
||||
* └─────┘
|
||||
*
|
||||
* The ProactiveBackoff test checks the generation of backoff values when the attribute is set
|
||||
* to true. A noise is generated to trigger the generation of a new backoff value, provided
|
||||
* that the backoff counter is zero.
|
||||
*
|
||||
*
|
||||
* Backoff Backoff Backoff Backoff
|
||||
* value #0 value #1 value #2 value #3
|
||||
* | | ┌─────┐ | |
|
||||
* | | ┌───┐ │Assoc│ | |
|
||||
* | | │ACK│ │Resp │ |SIFS| noise | AIFS+backoff | noise |
|
||||
* ─────────────┬─────┬┴───┴──┴─────┴┬───┬──────────────────────────────────────────────────
|
||||
* │Assoc│ │ACK│
|
||||
* │ Req │ └───┘
|
||||
* └─────┘
|
||||
*/
|
||||
class BackoffGenerationTest : public TestCase
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Tested attributes
|
||||
*/
|
||||
enum TestType : uint8_t
|
||||
{
|
||||
GEN_BACKOFF_IF_TXOP_NO_TX = 0,
|
||||
PROACTIVE_BACKOFF
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \param type the test type
|
||||
*/
|
||||
BackoffGenerationTest(TestType type);
|
||||
|
||||
private:
|
||||
void DoSetup() override;
|
||||
void DoRun() override;
|
||||
|
||||
/**
|
||||
* Callback invoked when a FEM passes PSDUs to the PHY.
|
||||
*
|
||||
* \param psduMap the PSDU map
|
||||
* \param txVector the TX vector
|
||||
* \param txPowerW the tx power in Watts
|
||||
*/
|
||||
void Transmit(WifiConstPsduMap psduMap, WifiTxVector txVector, double txPowerW);
|
||||
|
||||
/**
|
||||
* Callback invoked when a new backoff value is generated by the given AC on the station.
|
||||
*
|
||||
* \param ac the AC index
|
||||
* \param backoff the generated backoff value
|
||||
* \param linkId the ID of the link for which the backoff value has been generated
|
||||
*/
|
||||
void BackoffGenerated(AcIndex ac, uint32_t backoff, uint8_t linkId);
|
||||
|
||||
/**
|
||||
* Indicate that a new backoff value has not been generated as expected.
|
||||
*/
|
||||
void MissedBackoff();
|
||||
|
||||
/**
|
||||
* Generate interference to make CCA busy.
|
||||
*/
|
||||
void GenerateInterference();
|
||||
|
||||
Ptr<ApWifiMac> m_apMac; ///< AP wifi MAC
|
||||
Ptr<StaWifiMac> m_staMac; ///< MAC of the non-AP STA
|
||||
bool m_generateBackoffIfTxopWithoutTx; ///< whether the GenerateBackoffIfTxopWithoutTx
|
||||
///< attribute is set to true
|
||||
bool m_proactiveBackoff; ///< whether the ProactiveBackoff attribute is set to true
|
||||
static constexpr uint8_t m_tid{6}; ///< TID of generated packet
|
||||
std::size_t m_nGenBackoff{0}; ///< number of generated backoff values
|
||||
std::size_t m_nExpectedGenBackoff{0}; ///< expected total number of generated backoff values
|
||||
EventId m_nextBackoffGen; ///< timer elapsing when next backoff value is expected
|
||||
///< to be generated
|
||||
Time m_assocReqStartTxTime{0}; ///< Association Request start TX time
|
||||
Time m_assocReqPpduHdrDuration{0}; ///< Association Request PPDU header TX duration
|
||||
std::size_t m_nAcks{0}; ///< number of transmitted Ack frames
|
||||
const Time m_interferenceDuration{MicroSeconds(10)}; ///< interference duration
|
||||
Ptr<PacketSocketClient> m_client; ///< client to be installed on the AP after association
|
||||
};
|
||||
|
||||
BackoffGenerationTest::BackoffGenerationTest(TestType type)
|
||||
: TestCase("Check attributes impacting the generation of backoff values"),
|
||||
m_generateBackoffIfTxopWithoutTx(type == GEN_BACKOFF_IF_TXOP_NO_TX),
|
||||
m_proactiveBackoff(type == PROACTIVE_BACKOFF)
|
||||
{
|
||||
if (m_proactiveBackoff)
|
||||
{
|
||||
m_nExpectedGenBackoff = 4;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BackoffGenerationTest::DoSetup()
|
||||
{
|
||||
RngSeedManager::SetSeed(1);
|
||||
RngSeedManager::SetRun(1);
|
||||
int64_t streamNumber = 10;
|
||||
|
||||
Config::SetDefault("ns3::ChannelAccessManager::GenerateBackoffIfTxopWithoutTx",
|
||||
BooleanValue(m_generateBackoffIfTxopWithoutTx));
|
||||
Config::SetDefault("ns3::ChannelAccessManager::ProactiveBackoff",
|
||||
BooleanValue(m_proactiveBackoff));
|
||||
|
||||
auto apNode = CreateObject<Node>();
|
||||
auto staNode = CreateObject<Node>();
|
||||
|
||||
WifiHelper wifi;
|
||||
wifi.SetStandard(WIFI_STANDARD_80211be);
|
||||
wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager",
|
||||
"DataMode",
|
||||
StringValue("EhtMcs0"),
|
||||
"ControlMode",
|
||||
StringValue("HtMcs0"));
|
||||
|
||||
// MLDs are configured with three links
|
||||
SpectrumWifiPhyHelper phyHelper;
|
||||
phyHelper.SetPcapDataLinkType(WifiPhyHelper::DLT_IEEE802_11_RADIO);
|
||||
phyHelper.Set("ChannelSettings", StringValue("{36, 0, BAND_5GHZ, 0}"));
|
||||
phyHelper.AddChannel(CreateObject<MultiModelSpectrumChannel>());
|
||||
|
||||
WifiMacHelper mac;
|
||||
mac.SetType("ns3::ApWifiMac",
|
||||
"Ssid",
|
||||
SsidValue(Ssid("ns-3-ssid")),
|
||||
"BeaconGeneration",
|
||||
BooleanValue(true));
|
||||
|
||||
auto apDevice = DynamicCast<WifiNetDevice>(wifi.Install(phyHelper, mac, apNode).Get(0));
|
||||
|
||||
mac.SetType("ns3::StaWifiMac",
|
||||
"Ssid",
|
||||
SsidValue(Ssid("ns-3-ssid")),
|
||||
"ActiveProbing",
|
||||
BooleanValue(false));
|
||||
|
||||
auto staDevice = DynamicCast<WifiNetDevice>(wifi.Install(phyHelper, mac, staNode).Get(0));
|
||||
|
||||
m_apMac = DynamicCast<ApWifiMac>(apDevice->GetMac());
|
||||
m_staMac = DynamicCast<StaWifiMac>(staDevice->GetMac());
|
||||
|
||||
// Trace PSDUs passed to the PHY
|
||||
apDevice->GetPhy(SINGLE_LINK_OP_ID)
|
||||
->TraceConnectWithoutContext("PhyTxPsduBegin",
|
||||
MakeCallback(&BackoffGenerationTest::Transmit, this));
|
||||
staDevice->GetPhy(SINGLE_LINK_OP_ID)
|
||||
->TraceConnectWithoutContext("PhyTxPsduBegin",
|
||||
MakeCallback(&BackoffGenerationTest::Transmit, this));
|
||||
|
||||
// Trace backoff generation
|
||||
m_apMac->GetQosTxop(AC_VO)->TraceConnectWithoutContext(
|
||||
"BackoffTrace",
|
||||
MakeCallback(&BackoffGenerationTest::BackoffGenerated, this).Bind(AC_VO));
|
||||
|
||||
// Assign fixed streams to random variables in use
|
||||
streamNumber += WifiHelper::AssignStreams(NetDeviceContainer(apDevice), streamNumber);
|
||||
streamNumber += WifiHelper::AssignStreams(NetDeviceContainer(staDevice), streamNumber);
|
||||
|
||||
Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
|
||||
positionAlloc->Add(Vector(0.0, 0.0, 0.0));
|
||||
positionAlloc->Add(Vector(1.0, 0.0, 0.0));
|
||||
|
||||
MobilityHelper mobility;
|
||||
mobility.SetPositionAllocator(positionAlloc);
|
||||
mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
|
||||
mobility.Install(apNode);
|
||||
mobility.Install(staNode);
|
||||
|
||||
// // install packet socket on all nodes
|
||||
PacketSocketHelper packetSocket;
|
||||
packetSocket.Install(apNode);
|
||||
packetSocket.Install(staNode);
|
||||
|
||||
// install a packet socket server on the non-AP station
|
||||
PacketSocketAddress srvAddr;
|
||||
srvAddr.SetSingleDevice(staDevice->GetIfIndex());
|
||||
srvAddr.SetProtocol(1);
|
||||
|
||||
auto server = CreateObject<PacketSocketServer>();
|
||||
server->SetLocal(srvAddr);
|
||||
server->SetStartTime(Seconds(0));
|
||||
server->SetStopTime(Seconds(1));
|
||||
staNode->AddApplication(server);
|
||||
|
||||
// Prepare a packet socket client that generates one packet at the AP. This client will be
|
||||
// installed as soon as association is completed
|
||||
PacketSocketAddress remoteAddr;
|
||||
remoteAddr.SetSingleDevice(apDevice->GetIfIndex());
|
||||
remoteAddr.SetPhysicalAddress(staDevice->GetAddress());
|
||||
remoteAddr.SetProtocol(1);
|
||||
|
||||
m_client = CreateObject<PacketSocketClient>();
|
||||
m_client->SetAttribute("PacketSize", UintegerValue(1000));
|
||||
m_client->SetAttribute("MaxPackets", UintegerValue(1));
|
||||
m_client->SetAttribute("Interval", TimeValue(Time{0}));
|
||||
m_client->SetAttribute("Priority", UintegerValue(m_tid)); // AC VO
|
||||
m_client->SetRemote(remoteAddr);
|
||||
m_client->SetStartTime(Seconds(0));
|
||||
m_client->SetStopTime(Seconds(1));
|
||||
|
||||
// Block VO queue so that the AP does not send QoS data frames
|
||||
m_apMac->GetMacQueueScheduler()->BlockQueues(WifiQueueBlockedReason::TID_NOT_MAPPED,
|
||||
AC_VO,
|
||||
{WIFI_QOSDATA_QUEUE},
|
||||
m_staMac->GetAddress(),
|
||||
m_apMac->GetAddress(),
|
||||
{m_tid},
|
||||
{SINGLE_LINK_OP_ID});
|
||||
}
|
||||
|
||||
void
|
||||
BackoffGenerationTest::DoRun()
|
||||
{
|
||||
Simulator::Stop(Seconds(1));
|
||||
Simulator::Run();
|
||||
|
||||
NS_TEST_EXPECT_MSG_EQ(m_nExpectedGenBackoff,
|
||||
m_nGenBackoff,
|
||||
"Unexpected total number of generated backoff values");
|
||||
|
||||
Simulator::Destroy();
|
||||
}
|
||||
|
||||
void
|
||||
BackoffGenerationTest::Transmit(WifiConstPsduMap psduMap, WifiTxVector txVector, double txPowerW)
|
||||
{
|
||||
auto txDuration =
|
||||
WifiPhy::CalculateTxDuration(psduMap,
|
||||
txVector,
|
||||
m_apMac->GetWifiPhy(SINGLE_LINK_OP_ID)->GetPhyBand());
|
||||
|
||||
for (const auto& [aid, psdu] : psduMap)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << std::setprecision(10) << psdu->GetHeader(0).GetTypeString();
|
||||
if (psdu->GetHeader(0).IsAction())
|
||||
{
|
||||
ss << " ";
|
||||
WifiActionHeader actionHdr;
|
||||
psdu->GetPayload(0)->PeekHeader(actionHdr);
|
||||
actionHdr.Print(ss);
|
||||
}
|
||||
ss << " #MPDUs " << psdu->GetNMpdus() << " duration/ID " << psdu->GetHeader(0).GetDuration()
|
||||
<< " RA = " << psdu->GetAddr1() << " TA = " << psdu->GetAddr2()
|
||||
<< " ADDR3 = " << psdu->GetHeader(0).GetAddr3()
|
||||
<< " ToDS = " << psdu->GetHeader(0).IsToDs()
|
||||
<< " FromDS = " << psdu->GetHeader(0).IsFromDs();
|
||||
if (psdu->GetHeader(0).IsAssocReq())
|
||||
{
|
||||
m_assocReqStartTxTime = Simulator::Now();
|
||||
m_assocReqPpduHdrDuration = WifiPhy::CalculatePhyPreambleAndHeaderDuration(txVector);
|
||||
}
|
||||
else if (psdu->GetHeader(0).IsAck())
|
||||
{
|
||||
m_nAcks++;
|
||||
if (m_nAcks == 2)
|
||||
{
|
||||
// generate a packet destined to the non-AP station (this packet is held because
|
||||
// the queue is blocked) as soon as association is completed
|
||||
Simulator::Schedule(txDuration,
|
||||
&Node::AddApplication,
|
||||
m_apMac->GetDevice()->GetNode(),
|
||||
m_client);
|
||||
}
|
||||
}
|
||||
else if (psdu->GetHeader(0).IsQosData())
|
||||
{
|
||||
ss << " seqNo = {";
|
||||
for (auto& mpdu : *PeekPointer(psdu))
|
||||
{
|
||||
ss << mpdu->GetHeader().GetSequenceNumber() << ",";
|
||||
}
|
||||
ss << "} TID = " << +psdu->GetHeader(0).GetQosTid();
|
||||
|
||||
// after sending the QoS data frame, we expect one more backoff value to be generated
|
||||
// (at the end of the TXOP)
|
||||
m_nExpectedGenBackoff = m_nGenBackoff + 1;
|
||||
}
|
||||
NS_LOG_INFO(ss.str());
|
||||
}
|
||||
NS_LOG_INFO("TX duration = " << txDuration.As(Time::MS) << " TXVECTOR = " << txVector << "\n");
|
||||
}
|
||||
|
||||
void
|
||||
BackoffGenerationTest::BackoffGenerated(AcIndex ac, uint32_t backoff, uint8_t linkId)
|
||||
{
|
||||
NS_LOG_INFO("Backoff value " << backoff << " generated by AP on link " << +linkId << " for "
|
||||
<< ac << "\n");
|
||||
|
||||
// number of backoff values to generate when the GenerateBackoffIfTxopWithoutTx attribute is
|
||||
// set to true (can be any value >= 3)
|
||||
const std::size_t nValues = 5;
|
||||
|
||||
switch (m_nGenBackoff)
|
||||
{
|
||||
case 0:
|
||||
NS_TEST_EXPECT_MSG_EQ(Simulator::Now().IsZero(),
|
||||
true,
|
||||
"First backoff value should be generated at initialization time");
|
||||
m_nGenBackoff++;
|
||||
return;
|
||||
case 1:
|
||||
if (m_generateBackoffIfTxopWithoutTx)
|
||||
{
|
||||
NS_TEST_EXPECT_MSG_EQ(m_apMac->IsAssociated(m_staMac->GetAddress()).has_value(),
|
||||
true,
|
||||
"Second backoff value should be generated after association");
|
||||
}
|
||||
if (m_proactiveBackoff)
|
||||
{
|
||||
NS_TEST_ASSERT_MSG_GT(
|
||||
Simulator::Now(),
|
||||
m_assocReqStartTxTime,
|
||||
"Second backoff value should be generated after AssocReq TX start time");
|
||||
NS_TEST_EXPECT_MSG_LT(Simulator::Now(),
|
||||
m_assocReqStartTxTime + m_assocReqPpduHdrDuration,
|
||||
"Second backoff value should be generated right after AssocReq "
|
||||
"PPDU payload starts");
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (m_proactiveBackoff)
|
||||
{
|
||||
NS_TEST_EXPECT_MSG_EQ(m_apMac->IsAssociated(m_staMac->GetAddress()).has_value(),
|
||||
true,
|
||||
"Third backoff value should be generated after association");
|
||||
// after a SIFS:
|
||||
Simulator::Schedule(m_apMac->GetWifiPhy(linkId)->GetSifs(), [=, this]() {
|
||||
// generate interference (lasting 10 us)
|
||||
GenerateInterference();
|
||||
|
||||
if (backoff == 0)
|
||||
{
|
||||
// backoff value is 0, thus a new backoff value is generated due to the
|
||||
// interference
|
||||
NS_TEST_EXPECT_MSG_EQ(m_nGenBackoff,
|
||||
4,
|
||||
"Unexpected number of generated backoff values");
|
||||
}
|
||||
else
|
||||
{
|
||||
// interference does not cause the generation of a new backoff value because
|
||||
// the backoff counter is non-zero.
|
||||
// At the end of the interference:
|
||||
Simulator::Schedule(m_interferenceDuration, [=, this]() {
|
||||
auto voEdcaf = m_apMac->GetQosTxop(AC_VO);
|
||||
// update backoff (backoff info is only updated when some event occurs)
|
||||
m_apMac->GetChannelAccessManager(linkId)->NeedBackoffUponAccess(voEdcaf,
|
||||
true,
|
||||
true);
|
||||
auto delay =
|
||||
m_apMac->GetChannelAccessManager(linkId)->GetBackoffEndFor(voEdcaf) -
|
||||
Simulator::Now() + NanoSeconds(1);
|
||||
|
||||
// right after the backoff counts down to zero:
|
||||
Simulator::Schedule(delay, [=, this]() {
|
||||
// check that the number of generated backoff values is still 3
|
||||
NS_TEST_EXPECT_MSG_EQ(m_nGenBackoff,
|
||||
3,
|
||||
"Unexpected number of generated backoff values");
|
||||
GenerateInterference();
|
||||
// check that a new backoff value is generated due to the interference
|
||||
NS_TEST_EXPECT_MSG_EQ(m_nGenBackoff,
|
||||
4,
|
||||
"Unexpected number of generated backoff values");
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
break;
|
||||
case nValues:
|
||||
// Unblock VO queue so that the AP can send QoS data frames
|
||||
m_apMac->GetMacQueueScheduler()->UnblockQueues(WifiQueueBlockedReason::TID_NOT_MAPPED,
|
||||
AC_VO,
|
||||
{WIFI_QOSDATA_QUEUE},
|
||||
m_staMac->GetAddress(),
|
||||
m_apMac->GetAddress(),
|
||||
{m_tid},
|
||||
{SINGLE_LINK_OP_ID});
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_generateBackoffIfTxopWithoutTx)
|
||||
{
|
||||
Time delay; // expected time until the generation of the next backoff value
|
||||
const auto offset =
|
||||
NanoSeconds(1); // offset between expected time and the time when check is made
|
||||
|
||||
if (m_nGenBackoff == 1)
|
||||
{
|
||||
// we have to wait an AIFS before invoking backoff
|
||||
delay = m_apMac->GetWifiPhy(linkId)->GetSifs() +
|
||||
m_apMac->GetQosTxop(AC_VO)->GetAifsn(linkId) *
|
||||
m_apMac->GetWifiPhy(linkId)->GetSlot();
|
||||
}
|
||||
else if (m_nGenBackoff <= nValues)
|
||||
{
|
||||
NS_TEST_EXPECT_MSG_EQ(m_nextBackoffGen.IsPending(),
|
||||
true,
|
||||
"Expected a timer to be running");
|
||||
NS_TEST_EXPECT_MSG_EQ(Simulator::GetDelayLeft(m_nextBackoffGen),
|
||||
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)
|
||||
{
|
||||
// add the time corresponding to the generated number of slots
|
||||
delay += backoff * m_apMac->GetWifiPhy(linkId)->GetSlot();
|
||||
|
||||
m_nextBackoffGen =
|
||||
Simulator::Schedule(delay + offset, &BackoffGenerationTest::MissedBackoff, this);
|
||||
}
|
||||
}
|
||||
|
||||
m_nGenBackoff++;
|
||||
}
|
||||
|
||||
void
|
||||
BackoffGenerationTest::MissedBackoff()
|
||||
{
|
||||
NS_TEST_EXPECT_MSG_EQ(true,
|
||||
false,
|
||||
"Expected a new backoff value to be generated at time "
|
||||
<< Simulator::Now().As(Time::S));
|
||||
}
|
||||
|
||||
void
|
||||
BackoffGenerationTest::GenerateInterference()
|
||||
{
|
||||
NS_LOG_FUNCTION(this);
|
||||
auto phy = DynamicCast<SpectrumWifiPhy>(m_apMac->GetWifiPhy(SINGLE_LINK_OP_ID));
|
||||
auto psd = Create<SpectrumValue>(phy->GetCurrentInterface()->GetRxSpectrumModel());
|
||||
*psd = DbmToW(20) / 80e6; // PSD spread across 80 MHz to generate some noise
|
||||
|
||||
auto spectrumSignalParams = Create<SpectrumSignalParameters>();
|
||||
spectrumSignalParams->duration = m_interferenceDuration;
|
||||
spectrumSignalParams->txPhy = phy->GetCurrentInterface();
|
||||
spectrumSignalParams->txAntenna = phy->GetAntenna();
|
||||
spectrumSignalParams->psd = psd;
|
||||
|
||||
phy->StartRx(spectrumSignalParams, phy->GetCurrentInterface());
|
||||
}
|
||||
|
||||
/**
|
||||
* \ingroup wifi-test
|
||||
* \ingroup tests
|
||||
@@ -1585,6 +2075,10 @@ ChannelAccessManagerTestSuite::ChannelAccessManagerTestSuite()
|
||||
: TestSuite("wifi-channel-access-manager", Type::UNIT)
|
||||
{
|
||||
AddTestCase(new LargestIdlePrimaryChannelTest, TestCase::Duration::QUICK);
|
||||
AddTestCase(new BackoffGenerationTest(BackoffGenerationTest::GEN_BACKOFF_IF_TXOP_NO_TX),
|
||||
TestCase::Duration::QUICK);
|
||||
AddTestCase(new BackoffGenerationTest(BackoffGenerationTest::PROACTIVE_BACKOFF),
|
||||
TestCase::Duration::QUICK);
|
||||
}
|
||||
|
||||
static ChannelAccessManagerTestSuite g_camTestSuite;
|
||||
|
||||
Reference in New Issue
Block a user