9#include "ns3/adhoc-wifi-mac.h" 
   10#include "ns3/ap-wifi-mac.h" 
   11#include "ns3/channel-access-manager.h" 
   12#include "ns3/config.h" 
   13#include "ns3/frame-exchange-manager.h" 
   14#include "ns3/interference-helper.h" 
   15#include "ns3/mgt-action-headers.h" 
   16#include "ns3/mobility-helper.h" 
   17#include "ns3/multi-model-spectrum-channel.h" 
   18#include "ns3/packet-socket-client.h" 
   19#include "ns3/packet-socket-helper.h" 
   20#include "ns3/packet-socket-server.h" 
   21#include "ns3/pointer.h" 
   22#include "ns3/qos-txop.h" 
   23#include "ns3/rng-seed-manager.h" 
   24#include "ns3/simulator.h" 
   25#include "ns3/spectrum-wifi-helper.h" 
   26#include "ns3/spectrum-wifi-phy.h" 
   27#include "ns3/sta-wifi-mac.h" 
   28#include "ns3/string.h" 
   30#include "ns3/wifi-net-device.h" 
   31#include "ns3/wifi-spectrum-phy-interface.h" 
   41template <
typename TxopType>
 
   50template <
typename TxopType>
 
   67    void QueueTx(uint64_t txTime, uint64_t expectedGrantTime);
 
 
  181template <
typename TxopType>
 
  205        dcf->NotifyChannelAccessed(0);
 
 
  218        m_test->NotifyChannelSwitching();
 
 
 
  231template <
typename TxopType>
 
  269                   uint64_t eifsNoDifsNoSifs,
 
  309    void AddRxOkEvt(uint64_t at, uint64_t duration);
 
  322    void AddRxErrorEvt(uint64_t at, uint64_t duration, uint64_t timeUntilError);
 
  334    void AddTxEvt(uint64_t at, uint64_t duration);
 
  369                                        uint64_t expectedGrantTime,
 
  381                                           uint64_t expectedGrantTime,
 
  391                         uint64_t expectedGrantTime,
 
 
  443template <
typename TxopType>
 
  447    m_expectedGrants.emplace_back(txTime, expectedGrantTime);
 
 
  450template <
typename TxopType>
 
  457template <
typename TxopType>
 
  462    TxopType::DoDispose();
 
 
  465template <
typename TxopType>
 
  470    m_test->NotifyAccessGranted(m_i);
 
 
  473template <
typename TxopType>
 
  477    m_test->GenerateBackoff(m_i);
 
 
  480template <
typename TxopType>
 
  484    return !m_expectedGrants.empty();
 
 
  487template <
typename TxopType>
 
  493template <
typename TxopType>
 
  499template <
typename TxopType>
 
  505template <
typename TxopType>
 
  511    if (!state->m_expectedGrants.empty())
 
  513        std::pair<uint64_t, uint64_t> expected = state->m_expectedGrants.front();
 
  514        state->m_expectedGrants.pop_front();
 
  517                              "Expected access grant is now");
 
  518        m_ChannelAccessManager->NotifyTxStartNow(
MicroSeconds(expected.first));
 
  519        m_ChannelAccessManager->NotifyAckTimeoutStartNow(
 
 
  524template <
typename TxopType>
 
  530                        m_ChannelAccessManager,
 
 
  534template <
typename TxopType>
 
  540                          "Have expected internal collisions");
 
  541    if (!state->m_expectedInternalCollision.empty())
 
  547                              MicroSeconds(expected.at),
 
  548                              "Expected internal collision time is now");
 
  549        state->StartBackoffNow(expected.nSlots, 0);
 
 
  553template <typename TxopType>
 
  559    if (!state->m_expectedBackoff.empty())
 
  564                              MicroSeconds(expected.at),
 
  565                              "Expected backoff is now");
 
  566        state->StartBackoffNow(expected.nSlots, 0);
 
 
  570template <typename TxopType>
 
  574    for (
auto& state : m_txop)
 
  576        if (!state->m_expectedGrants.empty())
 
  578            std::pair<uint64_t, uint64_t> expected = state->m_expectedGrants.front();
 
  579            state->m_expectedGrants.pop_front();
 
  582                                  "Expected grant is now");
 
 
  588template <
typename TxopType>
 
  601template <typename TxopType>
 
  608    backoff.nSlots = nSlots;
 
 
  612template <typename TxopType>
 
  622template <
typename TxopType>
 
  629template <
typename TxopType>
 
  633                                              uint64_t eifsNoDifsNoSifs,
 
  639    m_ChannelAccessManager->SetupFrameExchangeManager(m_feManager);
 
  640    m_ChannelAccessManager->SetSlot(
MicroSeconds(slotTime));
 
  642    m_ChannelAccessManager->SetEifsNoDifs(
MicroSeconds(eifsNoDifsNoSifs + sifs));
 
  643    m_ackTimeoutValue = ackTimeoutValue;
 
  653    m_ChannelAccessManager->SetupPhyListener(m_phy);
 
 
  656template <
typename TxopType>
 
  661    m_txop.push_back(txop);
 
  662    m_ChannelAccessManager->Add(txop);
 
  667    mac->SetWifiPhys({
nullptr});
 
  668    txop->SetWifiMac(mac);
 
  669    txop->SetAifsn(aifsn);
 
 
  672template <
typename TxopType>
 
  678    m_ChannelAccessManager->RemovePhyListener(m_phy);
 
  680    m_ChannelAccessManager->Dispose();
 
  681    m_ChannelAccessManager = 
nullptr;
 
  682    m_feManager = 
nullptr;
 
  684    for (
auto i = m_txop.begin(); i != m_txop.end(); i++)
 
  690                              "Have no internal collisions");
 
 
  700template <
typename TxopType>
 
  706                        m_ChannelAccessManager,
 
  710                        m_ChannelAccessManager);
 
 
  713template <
typename TxopType>
 
  719                        m_ChannelAccessManager,
 
 
  723template <
typename TxopType>
 
  729                        m_ChannelAccessManager,
 
  733                        m_ChannelAccessManager,
 
 
  750template <
typename TxopType>
 
  754                                                  uint64_t timeUntilError)
 
  758                        m_ChannelAccessManager,
 
  762                        m_ChannelAccessManager,
 
  779                        m_ChannelAccessManager,
 
  782                        std::vector<Time>{});
 
 
  785template <
typename TxopType>
 
  791                        m_ChannelAccessManager,
 
 
  795template <
typename TxopType>
 
  801                        m_ChannelAccessManager,
 
 
  805template <
typename TxopType>
 
  811                        m_ChannelAccessManager);
 
 
  814template <
typename TxopType>
 
  818                                                     uint64_t expectedGrantTime,
 
  821    AddAccessRequestWithSuccessfulAck(at, txTime, expectedGrantTime, 0, from);
 
 
  824template <
typename TxopType>
 
  828                                                                   uint64_t expectedGrantTime,
 
 
  839template <
typename TxopType>
 
  843                                                                      uint64_t expectedGrantTime,
 
  854    AddAckTimeoutReset(expectedGrantTime + txTime + ackDelay);
 
 
  857template <
typename TxopType>
 
  860                                                    uint64_t expectedGrantTime,
 
  864    state->QueueTx(txTime, expectedGrantTime);
 
  865    if (m_ChannelAccessManager->NeedBackoffUponAccess(state, hadFramesToTransmit, 
true))
 
  867        state->GenerateBackoff(0);
 
  869    m_ChannelAccessManager->RequestAccess(state);
 
 
  872template <
typename TxopType>
 
  878    const auto chWidth = m_phy->GetChannelWidth();
 
  879    std::vector<Time> per20MhzDurations(chWidth == 20 ? 0 : chWidth / 20, 
Seconds(0));
 
  882                        m_ChannelAccessManager,
 
 
  888template <
typename TxopType>
 
  894                        m_ChannelAccessManager,
 
 
  899template <
typename TxopType>
 
  905                        m_ChannelAccessManager,
 
 
  909template <
typename TxopType>
 
  916    m_ChannelAccessManager->SetAttribute(
"ResetBackoffThreshold",
 
  921                        m_ChannelAccessManager,
 
  925        auto txop = m_txop[from];
 
  927        m_ChannelAccessManager->SetupPhyListener(m_phy);
 
  928        if (duration > threshold)
 
  931            if (m_ChannelAccessManager->NeedBackoffUponAccess(txop, hadFramesToTransmit, 
true))
 
  933                txop->GenerateBackoff(0);
 
  935            m_ChannelAccessManager->RequestAccess(txop);
 
 
  940template <
typename TxopType>
 
  948        newPhy->SetOperatingChannel(m_phy->GetOperatingChannel());
 
  951        m_ChannelAccessManager->SetupPhyListener(newPhy);
 
  955            m_ChannelAccessManager->RemovePhyListener(newPhy);
 
  957            m_ChannelAccessManager->SetupPhyListener(m_phy);
 
 
  976    AddAccessRequest(1, 1, 5, 0);
 
  977    AddAccessRequest(8, 2, 12, 0);
 
  988    AddAccessRequest(1, 1, 5, 0);
 
  989    AddRxInsideSifsEvt(7, 10);
 
  991    AddAccessRequest(14, 2, 18, 0);
 
 1005    StartTest(4, 6, 10);
 
 1009    AddAccessRequest(30, 2, 118, 0);
 
 1010    ExpectBackoff(30, 4, 0); 
 
 1019    StartTest(4, 6, 10);
 
 1022    AddAccessRequest(30, 2, 70, 0);
 
 1023    ExpectBackoff(30, 0, 0); 
 
 1032    StartTest(4, 6, 10);
 
 1036    AddAccessRequest(30, 2, 110, 0);
 
 1037    ExpectBackoff(30, 0, 0); 
 
 1045    StartTest(4, 6, 10);
 
 1048    AddAccessRequest(62, 2, 72, 0);
 
 1056    StartTest(4, 6, 10);
 
 1059    AddAccessRequest(70, 2, 80, 0);
 
 1068    StartTest(4, 6, 10);
 
 1070    AddRxErrorEvt(20, 40);
 
 1071    AddAccessRequest(30, 2, 102, 0);
 
 1072    ExpectBackoff(30, 4, 0); 
 
 1082    StartTest(4, 6, 10);
 
 1084    AddRxErrorEvt(20, 40);
 
 1085    AddAccessRequest(70, 2, 86, 0);
 
 1094    StartTest(4, 6, 10);
 
 1096    AddRxErrorEvt(20, 40, 20); 
 
 1097    ExpectBusy(41, 
true);      
 
 1098    ExpectBusy(59, 
true);
 
 1099    ExpectBusy(61, 
false);
 
 1108    StartTest(4, 6, 10);
 
 1110    AddRxErrorEvt(20, 40);
 
 1111    AddAccessRequest(30, 2, 101, 0);
 
 1112    ExpectBackoff(30, 4, 0); 
 
 1125    StartTest(4, 6, 10);
 
 1129    AddAccessRequest(30, 10, 78, 0);
 
 1130    ExpectBackoff(30, 2, 0); 
 
 1131    AddAccessRequest(40, 2, 110, 1);
 
 1132    ExpectBackoff(40, 0, 1);           
 
 1133    ExpectInternalCollision(78, 1, 1); 
 
 1143    StartTest(4, 6, 10);
 
 1146    AddAccessRequestWithAckTimeout(20, 20, 34, 1);
 
 1147    AddAccessRequest(64, 10, 80, 0);
 
 1159    StartTest(4, 6, 10);
 
 1162    AddAccessRequestWithSuccessfulAck(20, 20, 34, 2, 1);
 
 1163    AddAccessRequest(55, 10, 62, 0);
 
 1170    StartTest(4, 6, 10);
 
 1172    AddAccessRequest(20, 20, 34, 0);
 
 1174    AddAccessRequest(61, 10, 80, 0);
 
 1175    ExpectBackoff(61, 1, 0); 
 
 1181    StartTest(4, 6, 10);
 
 1184    AddNavStart(60, 15);
 
 1187    AddAccessRequest(30, 10, 93, 0);
 
 1188    ExpectBackoff(30, 2, 0); 
 
 1194    StartTest(4, 6, 10);
 
 1197    AddNavStart(60, 15);
 
 1200    AddAccessRequest(30, 10, 91, 0);
 
 1201    ExpectBackoff(30, 2, 0); 
 
 1207    StartTest(4, 6, 10);
 
 1210    AddAccessRequest(80, 10, 94, 0);
 
 1213    StartTest(4, 6, 10);
 
 1217    AddAccessRequest(30, 50, 108, 0);
 
 1218    ExpectBackoff(30, 3, 0); 
 
 1226    StartTest(1, 3, 10);
 
 1228    AddSwitchingEvt(0, 20);
 
 1229    AddAccessRequest(21, 1, 25, 0);
 
 1237    StartTest(1, 3, 10);
 
 1239    AddSwitchingEvt(20, 20);
 
 1240    AddCcaBusyEvt(30, 20);
 
 1241    ExpectBackoff(45, 2, 0); 
 
 1242    AddAccessRequest(45, 1, 56, 0);
 
 1249    StartTest(1, 3, 10);
 
 1251    AddRxStartEvt(20, 40);
 
 1252    AddSwitchingEvt(30, 20);
 
 1253    AddAccessRequest(51, 1, 55, 0);
 
 1260    StartTest(1, 3, 10);
 
 1262    AddCcaBusyEvt(20, 40);
 
 1263    AddSwitchingEvt(30, 20);
 
 1264    AddAccessRequest(51, 1, 55, 0);
 
 1271    StartTest(1, 3, 10);
 
 1273    AddNavStart(20, 40);
 
 1274    AddSwitchingEvt(30, 20);
 
 1275    AddAccessRequest(51, 1, 55, 0);
 
 1283    StartTest(1, 3, 10);
 
 1285    AddAccessRequestWithAckTimeout(20, 20, 24, 0);
 
 1286    AddAccessRequest(49, 1, 54, 0);
 
 1287    AddSwitchingEvt(54, 5);
 
 1288    AddAccessRequest(60, 1, 64, 0);
 
 1296    StartTest(4, 6, 10);
 
 1299    AddAccessRequest(30, 2, 80, 0);
 
 1300    ExpectBackoff(30, 4, 0); 
 
 1301    AddSwitchingEvt(80, 20);
 
 1302    AddAccessRequest(101, 2, 111, 0);
 
 
 1320    StartTest(4, 6, 10, 20, 
MHz_u{40});
 
 1324    AddAccessRequest(52, 20, 60, 0);
 
 1334    StartTest(4, 6, 10, 20, 
MHz_u{80});
 
 1338    AddAccessRequest(58, 20, 60, 0);
 
 1348    StartTest(4, 6, 10, 20, 
MHz_u{80});
 
 1352    AddAccessRequest(62, 20, 64, 0);
 
 1363    StartTest(4, 6, 10, 20, 
MHz_u{160});
 
 1365    AddRxErrorEvt(20, 30);
 
 1367    AddAccessRequest(55, 20, 76, 0);
 
 1378    StartTest(4, 6, 10, 20, 
MHz_u{160});
 
 1380    AddRxErrorEvt(20, 30);
 
 1382    AddAccessRequest(70, 20, 76, 0);
 
 1393    StartTest(4, 6, 10, 20, 
MHz_u{160});
 
 1395    AddRxErrorEvt(20, 30);
 
 1397    AddAccessRequest(82, 20, 84, 0);
 
 1408    StartTest(4, 6, 10, 20, 
MHz_u{320});
 
 1410    AddRxErrorEvt(20, 30);
 
 1412    AddAccessRequest(55, 20, 76, 0);
 
 1423    StartTest(4, 6, 10, 20, 
MHz_u{320});
 
 1425    AddRxErrorEvt(20, 30);
 
 1427    AddAccessRequest(70, 20, 76, 0);
 
 1438    StartTest(4, 6, 10, 20, 
MHz_u{320});
 
 1440    AddRxErrorEvt(20, 30);
 
 1442    AddAccessRequest(82, 20, 84, 0);
 
 1453    StartTest(4, 6, 10, 20, 
MHz_u{320});
 
 1455    AddRxErrorEvt(20, 30);
 
 1457    AddAccessRequest(82, 20, 84, 0);
 
 1466    StartTest(4, 6, 10);
 
 1469    AddAccessRequest(30, 20, 76, 0);
 
 1470    ExpectBackoff(30, 4, 0);
 
 1479    StartTest(4, 6, 10);
 
 1484    AddAccessRequest(30, 20, 107, 0);
 
 1485    ExpectBackoff(30, 3, 0);
 
 1494    StartTest(4, 6, 10);
 
 1497    AddAccessRequest(30, 20, 81, 0);
 
 1498    ExpectBackoff(30, 3, 0);
 
 1499    AddPhyDisconnectEvt(61, 10, 0, 0);
 
 1508    StartTest(4, 6, 10);
 
 1511    AddAccessRequest(30, 20, 89, 0);
 
 1512    ExpectBackoff(30, 3, 0);
 
 1513    AddPhyDisconnectEvt(61, 10, 20, 0);
 
 1523    StartTest(4, 6, 10);
 
 1526    AddAccessRequest(30, 20, 76, 0);
 
 1527    ExpectBackoff(30, 4, 0);
 
 1528    AddPhyReconnectEvt(61, 10);
 
 
 1551    void DoRun() 
override;
 
 
 1566    : 
TestCase(
"Check calculation of the largest idle primary channel")
 
 
 1607    const auto idleWidth = (busyChannel == WifiChannelListType::WIFI_CHANLIST_PRIMARY)
 
 1609                               : ((1 << (busyChannel - 1)) * 
MHz_u{20});
 
 1611    Time checkTime1 = start + ccaBusyStartDelay + ccaBusyDuration / 2;
 
 1613        Time interval1 = (ccaBusyStartDelay + ccaBusyDuration) / 2;
 
 1616                              "Incorrect width of the idle channel in an interval " 
 1617                                  << 
"ending within CCA_BUSY (channel width: " << chWidth
 
 1618                                  << 
" MHz, busy channel: " << busyChannel << 
")");
 
 1624    Time checkTime2 = start + ccaBusyStartDelay + ccaBusyDuration + ccaBusyRxInterval / 2;
 
 1626        Time interval2 = (ccaBusyDuration + ccaBusyRxInterval) / 2;
 
 1629                              "Incorrect width of the idle channel in an interval " 
 1630                                  << 
"starting within CCA_BUSY (channel width: " << chWidth
 
 1631                                  << 
" MHz, busy channel: " << busyChannel << 
")");
 
 1643    Time checkTime3 = start + ccaBusyStartDelay + ccaBusyDuration + ccaBusyRxInterval + rxDuration;
 
 1645        Time interval3 = ccaBusyDuration / 2 + ccaBusyRxInterval;
 
 1646        Time end3 = checkTime3 - rxDuration;
 
 1649                              "Incorrect width of the idle channel in an interval " 
 1650                                  << 
"preceding RX start and overlapping CCA_BUSY " 
 1651                                  << 
"(channel width: " << chWidth
 
 1652                                  << 
" MHz, busy channel: " << busyChannel << 
")");
 
 1657    const Time& checkTime4 = checkTime3;
 
 1659        const Time& interval4 = ccaBusyRxInterval;
 
 1660        Time end4 = checkTime4 - rxDuration;
 
 1663                              "Incorrect width of the idle channel in the interval " 
 1664                                  << 
"following CCA_BUSY and preceding RX start (channel " 
 1665                                  << 
"width: " << chWidth << 
" MHz, busy channel: " << busyChannel
 
 1672    Time checkTime5 = checkTime4 + interval5;
 
 1676                              "Incorrect width of the idle channel in an interval " 
 1677                                  << 
"following RX end (channel width: " << chWidth
 
 1678                                  << 
" MHz, busy channel: " << busyChannel << 
")");
 
 1682    const Time& checkTime6 = checkTime5;
 
 1684        Time interval6 = interval5 + rxDuration / 2;
 
 1687                              "Incorrect width of the idle channel in an interval " 
 1688                                  << 
"overlapping RX (channel width: " << chWidth
 
 1689                                  << 
" MHz, busy channel: " << busyChannel << 
")");
 
 
 1698    uint8_t channel = 0;
 
 1699    std::list<WifiChannelListType> busyChannels;
 
 1705        for (
const auto busyChannel : busyChannels)
 
 1718                m_phy->SetOperatingChannel(
 
 1725                RunOne(chWidth, busyChannel);
 
 
 1798    void DoRun() 
override;
 
 
 1846    : 
TestCase(
"Check attributes impacting the generation of backoff values"),
 
 1847      m_generateBackoffIfTxopWithoutTx(type == GEN_BACKOFF_IF_TXOP_NO_TX),
 
 1848      m_proactiveBackoff(type == PROACTIVE_BACKOFF)
 
 
 1861    int64_t streamNumber = 10;
 
 1873    wifi.SetRemoteStationManager(
"ns3::ConstantRateWifiManager",
 
 1882    phyHelper.
Set(
"ChannelSettings", 
StringValue(
"{36, 0, BAND_5GHZ, 0}"));
 
 1886    mac.SetType(
"ns3::ApWifiMac",
 
 1894    mac.SetType(
"ns3::StaWifiMac",
 
 1907        ->TraceConnectWithoutContext(
"PhyTxPsduBegin",
 
 1910        ->TraceConnectWithoutContext(
"PhyTxPsduBegin",
 
 1914    m_apMac->GetQosTxop(
AC_VO)->TraceConnectWithoutContext(
 
 1923    positionAlloc->Add(Vector(0.0, 0.0, 0.0));
 
 1924    positionAlloc->Add(Vector(1.0, 0.0, 0.0));
 
 1927    mobility.SetPositionAllocator(positionAlloc);
 
 1928    mobility.SetMobilityModel(
"ns3::ConstantPositionMobilityModel");
 
 1929    mobility.Install(apNode);
 
 1930    mobility.Install(staNode);
 
 1935    packetSocket.
Install(staNode);
 
 1943    server->SetLocal(srvAddr);
 
 1944    server->SetStartTime(
Seconds(0));
 
 1945    server->SetStopTime(
Seconds(1));
 
 1946    staNode->AddApplication(server);
 
 1965    m_apMac->GetMacQueueScheduler()->BlockQueues(WifiQueueBlockedReason::TID_NOT_MAPPED,
 
 1971                                                 {SINGLE_LINK_OP_ID});
 
 
 1982                          "Unexpected total number of generated backoff values");
 
 
 1995    for (
const auto& [aid, psdu] : psduMap)
 
 1997        std::stringstream ss;
 
 1998        ss << std::setprecision(10) << psdu->GetHeader(0).GetTypeString();
 
 1999        if (psdu->GetHeader(0).IsAction())
 
 2003            psdu->GetPayload(0)->PeekHeader(actionHdr);
 
 2004            actionHdr.
Print(ss);
 
 2006        ss << 
" #MPDUs " << psdu->GetNMpdus() << 
" duration/ID " << psdu->GetHeader(0).GetDuration()
 
 2007           << 
" RA = " << psdu->GetAddr1() << 
" TA = " << psdu->GetAddr2()
 
 2008           << 
" ADDR3 = " << psdu->GetHeader(0).GetAddr3()
 
 2009           << 
" ToDS = " << psdu->GetHeader(0).IsToDs()
 
 2010           << 
" FromDS = " << psdu->GetHeader(0).IsFromDs();
 
 2011        if (psdu->GetHeader(0).IsAssocReq())
 
 2016        else if (psdu->GetHeader(0).IsAck())
 
 2025                                    m_apMac->GetDevice()->GetNode(),
 
 2029        else if (psdu->GetHeader(0).IsQosData())
 
 2034                ss << mpdu->GetHeader().GetSequenceNumber() << 
",";
 
 2036            ss << 
"} TID = " << +psdu->GetHeader(0).GetQosTid();
 
 2044    NS_LOG_INFO(
"TX duration = " << txDuration.As(
Time::MS) << 
"  TXVECTOR = " << txVector << 
"\n");
 
 
 2050    NS_LOG_INFO(
"Backoff value " << backoff << 
" generated by AP on link " << +linkId << 
" for " 
 2055    const std::size_t nValues = 5;
 
 2062                              "First backoff value should be generated at initialization time");
 
 2070                                  "Second backoff value should be generated after association");
 
 2077                "Second backoff value should be generated after AssocReq TX start time");
 
 2080                                  "Second backoff value should be generated right after AssocReq " 
 2081                                  "PPDU payload starts");
 
 2089                                  "Third backoff value should be generated after association");
 
 2093                GenerateInterference();
 
 2099                    NS_TEST_EXPECT_MSG_EQ(m_nGenBackoff,
 
 2101                                          "Unexpected number of generated backoff values");
 
 2108                    Simulator::Schedule(m_interferenceDuration, [=, this]() {
 
 2109                        auto voEdcaf = m_apMac->GetQosTxop(AC_VO);
 
 2111                        m_apMac->GetChannelAccessManager(linkId)->NeedBackoffUponAccess(voEdcaf,
 
 2115                            m_apMac->GetChannelAccessManager(linkId)->GetBackoffEndFor(voEdcaf) -
 
 2116                            Simulator::Now() + NanoSeconds(1);
 
 2119                        Simulator::Schedule(delay, [=, this]() {
 
 2121                            NS_TEST_EXPECT_MSG_EQ(m_nGenBackoff,
 
 2123                                                  "Unexpected number of generated backoff values");
 
 2124                            GenerateInterference();
 
 2126                            NS_TEST_EXPECT_MSG_EQ(m_nGenBackoff,
 
 2128                                                  "Unexpected number of generated backoff values");
 
 2137        m_apMac->GetMacQueueScheduler()->UnblockQueues(WifiQueueBlockedReason::TID_NOT_MAPPED,
 
 2140                                                       m_staMac->GetAddress(),
 
 2141                                                       m_apMac->GetAddress(),
 
 2147    if (m_generateBackoffIfTxopWithoutTx)
 
 2153        if (m_nGenBackoff == 1)
 
 2156            delay = m_apMac->GetWifiPhy(linkId)->GetSifs() +
 
 2157                    m_apMac->GetQosTxop(
AC_VO)->GetAifsn(linkId) *
 
 2158                        m_apMac->GetWifiPhy(linkId)->GetSlot();
 
 2160        else if (m_nGenBackoff <= nValues)
 
 2164                                  "Expected a timer to be running");
 
 2167                                  "Backoff value generated too early");
 
 2168            m_nextBackoffGen.Cancel();
 
 2172            delay = m_apMac->GetWifiPhy(linkId)->GetSlot();
 
 2175        if (m_nGenBackoff < nValues)
 
 2178            delay += backoff * m_apMac->GetWifiPhy(linkId)->GetSlot();
 
 
 2193                          "Expected a new backoff value to be generated at time " 
 
 2207    spectrumSignalParams->txPhy = phy->GetCurrentInterface();
 
 2208    spectrumSignalParams->txAntenna = phy->GetAntenna();
 
 2209    spectrumSignalParams->psd = psd;
 
 2211    phy->StartRx(spectrumSignalParams, phy->GetCurrentInterface());
 
 
 2271                TestCase::Duration::QUICK);
 
 2273                TestCase::Duration::QUICK);
 
 
static ChannelAccessManagerTestSuite g_camTestSuite
static TxopTestSuite g_dcfTestSuite
static QosTxopTestSuite g_edcaTestSuite
Test the GenerateBackoffIfTxopWithoutTx and ProactiveBackoff attributes of the ChannelAccessManager.
void Transmit(WifiConstPsduMap psduMap, WifiTxVector txVector, double txPowerW)
Callback invoked when a FEM passes PSDUs to the PHY.
Ptr< StaWifiMac > m_staMac
MAC of the non-AP STA.
Ptr< ApWifiMac > m_apMac
AP wifi MAC.
std::size_t m_nGenBackoff
number of generated backoff values
void GenerateInterference()
Generate interference to make CCA busy.
Time m_assocReqStartTxTime
Association Request start TX time.
const Time m_interferenceDuration
interference duration
static constexpr uint8_t m_tid
TID of generated packet.
Ptr< PacketSocketClient > m_client
client to be installed on the AP after association
void MissedBackoff()
Indicate that a new backoff value has not been generated as expected.
EventId m_nextBackoffGen
timer elapsing when next backoff value is expected to be generated
void DoRun() override
Implementation to actually run this TestCase.
std::size_t m_nAcks
number of transmitted Ack frames
void DoSetup() override
Implementation to do any local setup required for this TestCase.
void BackoffGenerated(AcIndex ac, uint32_t backoff, uint8_t linkId)
Callback invoked when a new backoff value is generated by the given AC on the station.
Time m_assocReqPpduHdrDuration
Association Request PPDU header TX duration.
bool m_generateBackoffIfTxopWithoutTx
whether the GenerateBackoffIfTxopWithoutTx attribute is set to true
std::size_t m_nExpectedGenBackoff
expected total number of generated backoff values
bool m_proactiveBackoff
whether the ProactiveBackoff attribute is set to true
BackoffGenerationTest(TestType type)
Constructor.
TestType
Tested attributes.
@ GEN_BACKOFF_IF_TXOP_NO_TX
ChannelAccessManager Stub.
ChannelAccessManagerStub()
Time GetEifsNoDifs() const override
Return the EIFS duration minus a DIFS.
void SetEifsNoDifs(Time eifsNoDifs)
Set the duration of EIFS - DIFS.
void SetSlot(Time slot)
Set the slot duration.
Time GetSlot() const override
Return the slot duration for this PHY.
Time m_sifs
SIFS duration.
Time GetSifs() const override
Return the Short Interframe Space (SIFS) for this PHY.
void SetSifs(Time sifs)
Set the Short Interframe Space (SIFS).
Time m_eifsNoDifs
EIFS duration minus a DIFS.
Channel Access Manager Test.
void AddAccessRequestWithSuccessfulAck(uint64_t at, uint64_t txTime, uint64_t expectedGrantTime, uint32_t ackDelay, uint32_t from)
Add access request with successful ack.
void AddAckTimeoutReset(uint64_t at)
Add Ack timeout reset function.
void NotifyInternalCollision(Ptr< TxopTest< TxopType > > state)
Notify internal collision function.
void AddRxOkEvt(uint64_t at, uint64_t duration)
Add receive OK event function.
void AddRxStartEvt(uint64_t at, uint64_t duration)
Add receive start event function.
uint32_t m_ackTimeoutValue
the Ack timeout value
void AddAccessRequestWithAckTimeout(uint64_t at, uint64_t txTime, uint64_t expectedGrantTime, uint32_t from)
Add access request with Ack timeout.
ChannelAccessManagerTest()
void AddPhyReconnectEvt(uint64_t at, uint64_t duration)
Add a PHY reconnect event consisting in another PHY operating on the link for the given time.
void GenerateBackoff(uint32_t i)
Generate backoff function.
void NotifyAccessGranted(uint32_t i)
Notify access granted function.
void StartTest(uint64_t slotTime, uint64_t sifs, uint64_t eifsNoDifsNoSifs, uint32_t ackTimeoutValue=20, MHz_u chWidth=MHz_u{20})
Start test function.
std::vector< Ptr< TxopTest< TxopType > > > TxopTests
the TXOP tests typedef
void ExpectBackoff(uint64_t time, uint32_t nSlots, uint32_t from)
Expect generate backoff function.
void DoRun() override
Implementation to actually run this TestCase.
void AddTxop(uint32_t aifsn)
Add Txop function.
Ptr< SpectrumWifiPhy > m_phy
the PHY object
void DoAccessRequest(uint64_t txTime, uint64_t expectedGrantTime, Ptr< TxopTest< TxopType > > state)
Add access request with successful Ack.
void AddAccessRequest(uint64_t at, uint64_t txTime, uint64_t expectedGrantTime, uint32_t from)
Add access function.
void AddSwitchingEvt(uint64_t at, uint64_t duration)
Add switching event function.
Ptr< ChannelAccessManagerStub > m_ChannelAccessManager
the channel access manager
void AddRxErrorEvt(uint64_t at, uint64_t duration)
Add receive error event function for error at end of frame.
void ExpectBusy(uint64_t time, bool busy)
Schedule a check that the channel access manager is busy or idle.
void EndTest()
End test function.
TxopTests m_txop
the vector of Txop test instances
void ExpectInternalCollision(uint64_t time, uint32_t nSlots, uint32_t from)
Expect internal collision function.
void AddPhyDisconnectEvt(uint64_t at, uint64_t duration, uint64_t threshold, uint32_t from)
Add a PHY disconnect event consisting in the PHY leaving the link and returning after a given time.
void AddNavStart(uint64_t at, uint64_t duration)
Add NAV start function.
void AddRxInsideSifsEvt(uint64_t at, uint64_t duration)
Add receive inside SIFS event function.
void AddCcaBusyEvt(uint64_t at, uint64_t duration, WifiChannelListType channelType=WIFI_CHANLIST_PRIMARY)
Add CCA busy event function.
Ptr< FrameExchangeManagerStub< TxopType > > m_feManager
the Frame Exchange Manager stubbed
void DoCheckBusy(bool busy)
Perform check that channel access manager is busy or idle.
void AddNavReset(uint64_t at, uint64_t duration)
Add NAV reset function.
void AddTxEvt(uint64_t at, uint64_t duration)
Add transmit event function.
void NotifyChannelSwitching()
Notify channel switching function.
ChannelAccessManager Test Suite.
ChannelAccessManagerTestSuite()
Frame Exchange Manager Stub.
void NotifySwitchingStartNow(Time duration) override
void NotifyInternalCollision(Ptr< Txop > txop) override
Notify that an internal collision has occurred for the given Txop.
bool StartTransmission(Ptr< Txop > dcf, MHz_u allowedWidth) override
Request the FrameExchangeManager to start a frame exchange sequence.
ChannelAccessManagerTest< TxopType > * m_test
the test DCF/EDCA manager
FrameExchangeManagerStub(ChannelAccessManagerTest< TxopType > *test)
Constructor.
Test the calculation of the largest idle primary channel performed by ChannelAccessManager::GetLarges...
Ptr< SpectrumWifiPhy > m_phy
PHY object.
LargestIdlePrimaryChannelTest()
void RunOne(MHz_u chWidth, WifiChannelListType busyChannel)
Test a specific combination of operating channel width and busy channel type.
~LargestIdlePrimaryChannelTest() override=default
void DoRun() override
Implementation to actually run this TestCase.
Ptr< ChannelAccessManager > m_cam
channel access manager
ExpectedBackoffs m_expectedInternalCollision
expected backoff due to an internal collision
void DoDispose() override
Destructor implementation.
void GenerateBackoff(uint8_t linkId) override
Generate a new backoff for the given link now.
uint32_t m_i
the index of the Txop
void NotifyChannelAccessed(uint8_t linkId, Time txopDuration=Seconds(0)) override
Called by the FrameExchangeManager to notify that channel access has been granted on the given link f...
void QueueTx(uint64_t txTime, uint64_t expectedGrantTime)
Queue transmit function.
ExpectedBackoffs m_expectedBackoff
expected backoff (not due to an internal collision)
std::list< ExpectedGrant > ExpectedGrants
the collection of expected grants typedef
void NotifySleep(uint8_t linkId) override
Notify that the given link switched to sleep mode.
ChannelAccessManagerTest< TxopType > * m_test
Check if the Txop has frames to transmit.
ExpectedGrants m_expectedGrants
expected grants
std::list< ExpectedBackoff > ExpectedBackoffs
expected backoffs typedef
void NotifyWakeUp(uint8_t linkId) override
When wake up operation occurs on a link, channel access on that link will be restarted.
bool HasFramesToTransmit(uint8_t linkId) override
Check if the Txop has frames to transmit over the given link.
TxopTest(ChannelAccessManagerTest< TxopType > *test, uint32_t i)
Constructor.
std::pair< uint64_t, uint64_t > ExpectedGrant
the expected grant typedef
AttributeValue implementation for Boolean.
Manage a set of ns3::Txop.
void NotifyRxStartNow(Time duration)
void NotifySwitchingStartNow(PhyListener *phyListener, Time duration)
void NotifyAckTimeoutResetNow()
Notify that ack timer has reset.
void NotifyTxStartNow(Time duration)
void NotifyRxEndOkNow()
Notify the Txop that a packet reception was just completed successfully.
void NotifyCcaBusyStartNow(Time duration, WifiChannelListType channelType, const std::vector< Time > &per20MhzDurations)
void RemovePhyListener(Ptr< WifiPhy > phy)
Remove current registered listener for PHY events on the given PHY.
void NotifyRxEndErrorNow(const WifiTxVector &txVector)
Notify the Txop that a packet reception was just completed unsuccessfuly.
void NotifyNavResetNow(Time duration)
void NotifyNavStartNow(Time duration)
An identifier for simulation events.
FrameExchangeManager is a base class handling the basic frame exchange sequences for non-QoS stations...
Helper class used to assign positions and mobility models to nodes.
holds a vector of ns3::NetDevice pointers
uint32_t AddApplication(Ptr< Application > application)
Associate an Application to this Node.
static WifiMode GetOfdmRate6Mbps()
Return a WifiMode for OFDM at 6 Mbps.
an address for a packet socket
void SetProtocol(uint16_t protocol)
Set the protocol.
void SetPhysicalAddress(const Address address)
Set the destination address.
void SetSingleDevice(uint32_t device)
Set the address to match only a specified NetDevice.
Give ns3::PacketSocket powers to ns3::Node.
void Install(Ptr< Node > node) const
Aggregate an instance of a ns3::PacketSocketFactory onto the provided node.
AttributeValue implementation for Pointer.
Smart pointer class similar to boost::intrusive_ptr.
static void SetRun(uint64_t run)
Set the run number of simulation.
static void SetSeed(uint32_t seed)
Set the seed.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
static Time Now()
Return the current simulation virtual time.
static void Run()
Run the simulation.
static void Stop()
Tell the Simulator the calling event should be the last one executed.
static Time GetDelayLeft(const EventId &id)
Get the remaining time until this event will execute.
Make it easy to create and manage PHY objects for the spectrum model.
void AddChannel(const Ptr< SpectrumChannel > channel, const FrequencyRange &freqRange=WHOLE_WIFI_SPECTRUM)
The IEEE 802.11 SSID Information Element.
AttributeValue implementation for Ssid.
Hold variables of type string.
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Simulation virtual time values and global simulation resolution.
AttributeValue implementation for Time.
LinkEntity & GetLink(uint8_t linkId) const
Get a reference to the link associated with the given ID.
Hold an unsigned integer type.
helps to create WifiNetDevice objects
static int64_t AssignStreams(NetDeviceContainer c, int64_t stream)
Assign a fixed random variable stream number to the random variables used by the PHY and MAC aspects ...
create MAC layers for a ns3::WifiNetDevice.
void SetPcapDataLinkType(SupportedPcapDataLinkTypes dlt)
Set the data link type of PCAP traces to be used.
void Set(std::string name, const AttributeValue &v)
@ DLT_IEEE802_11_RADIO
Include Radiotap link layer information.
std::tuple< uint8_t, MHz_u, WifiPhyBand, uint8_t > ChannelTuple
Tuple identifying a segment of an operating channel.
static Time CalculateTxDuration(uint32_t size, const WifiTxVector &txVector, WifiPhyBand band, uint16_t staId=SU_STA_ID)
static Time CalculatePhyPreambleAndHeaderDuration(const WifiTxVector &txVector)
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
void SetDefault(std::string name, const AttributeValue &value)
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Ptr< T > CreateObjectWithAttributes(Args... args)
Allocate an Object on the heap and initialize with a set of attributes.
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Time Now()
create an ns3::Time instance which contains the current simulation time.
#define NS_TEST_EXPECT_MSG_LT(actual, limit, msg)
Test that an actual value is less than a limit and report if not.
#define NS_TEST_EXPECT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report if not.
#define NS_TEST_ASSERT_MSG_GT(actual, limit, msg)
Test that an actual value is greater than a limit and report and abort if not.
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Time Seconds(double value)
Construct a Time in the indicated unit.
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
WifiChannelListType
Enumeration of the possible channel-list parameter elements defined in Table 8-5 of IEEE 802....
AcIndex
This enumeration defines the Access Categories as an enumeration with values corresponding to the AC ...
@ WIFI_PHY_BAND_6GHZ
The 6 GHz band.
@ WIFI_CHANLIST_SECONDARY40
@ WIFI_CHANLIST_SECONDARY
@ WIFI_CHANLIST_SECONDARY160
@ WIFI_CHANLIST_SECONDARY80
Every class exported by the ns3 library is enclosed in the ns3 namespace.
U * PeekPointer(const Ptr< U > &p)
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
std::size_t Count20MHzSubchannels(MHz_u channelWidth)
Return the number of 20 MHz subchannels covering the channel width.
static constexpr uint8_t SINGLE_LINK_OP_ID
Link ID for single link operations (helps tracking places where correct link ID is to be used to supp...
Watt_u DbmToW(dBm_u val)
Convert from dBm to Watts.
std::unordered_map< uint16_t, Ptr< const WifiPsdu > > WifiConstPsduMap
Map of const PSDUs indexed by STA-ID.
-ns3 Test suite for the ns3 wrapper script
ExpectedBackoff structure.
uint32_t nSlots
number of slots
ChannelAccessStatus access
channel access status