21#include "ns3/eht-configuration.h" 
   22#include "ns3/eht-frame-exchange-manager.h" 
   23#include "ns3/he-configuration.h" 
   24#include "ns3/ht-configuration.h" 
   26#include "ns3/object-vector.h" 
   27#include "ns3/packet.h" 
   28#include "ns3/pointer.h" 
   29#include "ns3/shuffle.h" 
   30#include "ns3/socket.h" 
   31#include "ns3/string.h" 
   32#include "ns3/vht-configuration.h" 
   70                          "The ssid we want to belong to.",
 
   74            .AddAttribute(
"QosSupported",
 
   75                          "This Boolean attribute is set to enable 802.11e/WMM-style QoS support " 
   82            .AddAttribute(
"CtsToSelfSupported",
 
   83                          "Use CTS to Self when using a rate that is not in the basic rate set.",
 
   88                "ShortSlotTimeSupported",
 
   89                "Whether or not short slot time is supported (only used by ERP APs or STAs).",
 
  101            .AddAttribute(
"VO_Txop",
 
  102                          "Queue that manages packets belonging to AC_VO access class.",
 
  108            .AddAttribute(
"VI_Txop",
 
  109                          "Queue that manages packets belonging to AC_VI access class.",
 
  115            .AddAttribute(
"BE_Txop",
 
  116                          "Queue that manages packets belonging to AC_BE access class.",
 
  122            .AddAttribute(
"BK_Txop",
 
  123                          "Queue that manages packets belonging to AC_BK access class.",
 
  130                "ChannelAccessManagers",
 
  131                "The Channel Access Manager(s) attached to this device.",
 
  136                "FrameExchangeManagers",
 
  137                "The Frame Exchange Manager(s) attached to this device.",
 
  143                "The size (in number of MPDUs) of the buffer used for each BlockAck " 
  144                "agreement in which this node is a recipient. The provided value is " 
  145                "capped to the maximum allowed value based on the supported standard.",
 
  151                "The maximum number of transmission attempts of a frame that are made before a " 
  152                "failure condition is indicated. This corresponds to the dot11ShortRetryLimit " 
  153                "parameter in the standard.",
 
  157            .AddAttribute(
"VO_MaxAmsduSize",
 
  158                          "Maximum length in bytes of an A-MSDU for AC_VO access class " 
  159                          "(capped to 7935 for HT PPDUs and 11398 for VHT/HE/EHT PPDUs). " 
  160                          "Value 0 means A-MSDU aggregation is disabled for that AC.",
 
  164            .AddAttribute(
"VI_MaxAmsduSize",
 
  165                          "Maximum length in bytes of an A-MSDU for AC_VI access class " 
  166                          "(capped to 7935 for HT PPDUs and 11398 for VHT/HE/EHT PPDUs). " 
  167                          "Value 0 means A-MSDU aggregation is disabled for that AC.",
 
  171            .AddAttribute(
"BE_MaxAmsduSize",
 
  172                          "Maximum length in bytes of an A-MSDU for AC_BE access class " 
  173                          "(capped to 7935 for HT PPDUs and 11398 for VHT/HE/EHT PPDUs). " 
  174                          "Value 0 means A-MSDU aggregation is disabled for that AC.",
 
  178            .AddAttribute(
"BK_MaxAmsduSize",
 
  179                          "Maximum length in bytes of an A-MSDU for AC_BK access class " 
  180                          "(capped to 7935 for HT PPDUs and 11398 for VHT/HE/EHT PPDUs). " 
  181                          "Value 0 means A-MSDU aggregation is disabled for that AC.",
 
  187                "Maximum length in bytes of an A-MPDU for AC_VO access class " 
  188                "(capped to 65535 for HT PPDUs, 1048575 for VHT PPDUs, 6500631 for HE PPDUs " 
  189                "and 15523200 for EHT PPDUs). " 
  190                "Value 0 means A-MPDU aggregation is disabled for that AC.",
 
  196                "Maximum length in bytes of an A-MPDU for AC_VI access class " 
  197                "(capped to 65535 for HT PPDUs, 1048575 for VHT PPDUs, 6500631 for HE PPDUs " 
  198                "and 15523200 for EHT PPDUs). " 
  199                "Value 0 means A-MPDU aggregation is disabled for that AC.",
 
  205                "Maximum length in bytes of an A-MPDU for AC_BE access class " 
  206                "(capped to 65535 for HT PPDUs, 1048575 for VHT PPDUs, 6500631 for HE PPDUs " 
  207                "and 15523200 for EHT PPDUs). " 
  208                "Value 0 means A-MPDU aggregation is disabled for that AC.",
 
  214                "Maximum length in bytes of an A-MPDU for AC_BK access class " 
  215                "(capped to 65535 for HT PPDUs, 1048575 for VHT PPDUs, 6500631 for HE PPDUs " 
  216                "and 15523200 for EHT PPDUs). " 
  217                "Value 0 means A-MPDU aggregation is disabled for that AC.",
 
  222                "VO_BlockAckThreshold",
 
  223                "If number of packets in VO queue reaches this value, " 
  224                "block ack mechanism is used. If this value is 0, block ack is never used." 
  225                "When A-MPDU is enabled, block ack mechanism is used regardless of this value.",
 
  230                "VI_BlockAckThreshold",
 
  231                "If number of packets in VI queue reaches this value, " 
  232                "block ack mechanism is used. If this value is 0, block ack is never used." 
  233                "When A-MPDU is enabled, block ack mechanism is used regardless of this value.",
 
  238                "BE_BlockAckThreshold",
 
  239                "If number of packets in BE queue reaches this value, " 
  240                "block ack mechanism is used. If this value is 0, block ack is never used." 
  241                "When A-MPDU is enabled, block ack mechanism is used regardless of this value.",
 
  246                "BK_BlockAckThreshold",
 
  247                "If number of packets in BK queue reaches this value, " 
  248                "block ack mechanism is used. If this value is 0, block ack is never used." 
  249                "When A-MPDU is enabled, block ack mechanism is used regardless of this value.",
 
  254                "VO_BlockAckInactivityTimeout",
 
  255                "Represents max time (blocks of 1024 microseconds) allowed for block ack" 
  256                "inactivity for AC_VO. If this value isn't equal to 0 a timer start after that a" 
  257                "block ack setup is completed and will be reset every time that a block ack" 
  258                "frame is received. If this value is 0, block ack inactivity timeout won't be " 
  264                "VI_BlockAckInactivityTimeout",
 
  265                "Represents max time (blocks of 1024 microseconds) allowed for block ack" 
  266                "inactivity for AC_VI. If this value isn't equal to 0 a timer start after that a" 
  267                "block ack setup is completed and will be reset every time that a block ack" 
  268                "frame is received. If this value is 0, block ack inactivity timeout won't be " 
  274                "BE_BlockAckInactivityTimeout",
 
  275                "Represents max time (blocks of 1024 microseconds) allowed for block ack" 
  276                "inactivity for AC_BE. If this value isn't equal to 0 a timer start after that a" 
  277                "block ack setup is completed and will be reset every time that a block ack" 
  278                "frame is received. If this value is 0, block ack inactivity timeout won't be " 
  284                "BK_BlockAckInactivityTimeout",
 
  285                "Represents max time (blocks of 1024 microseconds) allowed for block ack" 
  286                "inactivity for AC_BK. If this value isn't equal to 0 a timer start after that a" 
  287                "block ack setup is completed and will be reset every time that a block ack" 
  288                "frame is received. If this value is 0, block ack inactivity timeout won't be " 
  293            .AddAttribute(
"RobustAVStreamingSupported",
 
  294                          "Whether or not Robust Audio Video Streaming is supported (only allowed " 
  295                          "for AP STAs or non-AP that are HT capable).",
 
  302                "A packet has been received by the WifiNetDevice and is about to be enqueued; " 
  303                "it has a LlcSnapHeader prepended but not yet a WifiMacHeader.",
 
  305                "ns3::Packet::TracedCallback")
 
  308                "A packet has been dropped in the MAC layer before being queued for transmission. " 
  309                "This trace source is fired, e.g., when an AP's MAC receives from the upper layer " 
  310                "a packet destined to a station that is not associated with the AP or a STA's MAC " 
  311                "receives a packet from the upper layer while it is not associated with any AP.",
 
  313                "ns3::Packet::TracedCallback")
 
  316                "A packet has been received by this device, has been passed up from the physical " 
  318                "and is being forwarded up the local protocol stack.  This is a promiscuous trace.",
 
  320                "ns3::Packet::TracedCallback")
 
  321            .AddTraceSource(
"MacRx",
 
  322                            "A packet has been received by this device, has been passed up from " 
  323                            "the physical layer " 
  324                            "and is being forwarded up the local protocol stack. This is a " 
  325                            "non-promiscuous trace.",
 
  327                            "ns3::Packet::TracedCallback")
 
  328            .AddTraceSource(
"MacRxDrop",
 
  329                            "A packet has been dropped in the MAC layer after it has been passed " 
  330                            "up from the physical layer.",
 
  332                            "ns3::Packet::TracedCallback")
 
  333            .AddTraceSource(
"AckedMpdu",
 
  334                            "An MPDU that was successfully acknowledged, via either a " 
  335                            "Normal Ack or a Block Ack.",
 
  337                            "ns3::WifiMpdu::TracedCallback")
 
  338            .AddTraceSource(
"NAckedMpdu",
 
  339                            "An MPDU that was negatively acknowledged via a Block Ack.",
 
  341                            "ns3::WifiMpdu::TracedCallback")
 
  344                "An MPDU that was dropped for the given reason (see WifiMacDropReason).",
 
  346                "ns3::WifiMac::DroppedMpduCallback")
 
  348                "MpduResponseTimeout",
 
  349                "An MPDU whose response was not received before the timeout, along with " 
  350                "an identifier of the type of timeout (see WifiTxTimer::Reason) and the " 
  351                "TXVECTOR used to transmit the MPDU. This trace source is fired when a " 
  352                "CTS is missing after an RTS, when all CTS frames are missing after an MU-RTS, " 
  353                "or when a Normal Ack is missing after an MPDU or after a DL MU PPDU " 
  354                "acknowledged in SU format.",
 
  356                "ns3::WifiMac::MpduResponseTimeoutCallback")
 
  358                "PsduResponseTimeout",
 
  359                "A PSDU whose response was not received before the timeout, along with " 
  360                "an identifier of the type of timeout (see WifiTxTimer::Reason) and the " 
  361                "TXVECTOR used to transmit the PSDU. This trace source is fired when a " 
  362                "BlockAck is missing after an A-MPDU, a BlockAckReq (possibly in the " 
  363                "context of the acknowledgment of a DL MU PPDU in SU format) or a TB PPDU " 
  364                "(in the latter case the missing BlockAck is a Multi-STA BlockAck).",
 
  366                "ns3::WifiMac::PsduResponseTimeoutCallback")
 
  368                "PsduMapResponseTimeout",
 
  369                "A PSDU map for which not all the responses were received before the timeout, " 
  370                "along with an identifier of the type of timeout (see WifiTxTimer::Reason), " 
  371                "the set of MAC addresses of the stations that did not respond and the total " 
  372                "number of stations that had to respond. This trace source is fired when not " 
  373                "all the addressed stations responded to an MU-BAR Trigger frame (either sent as " 
  374                "a SU frame or aggregated to PSDUs in the DL MU PPDU), a Basic Trigger Frame or " 
  375                "a BSRP Trigger Frame.",
 
  377                "ns3::WifiMac::PsduMapResponseTimeoutCallback")
 
  378            .AddTraceSource(
"IcfDropReason",
 
  379                            "An ICF sent by the given sender is dropped by an EMLSR client for " 
  380                            "the given reason on the link with the given ID. This trace source " 
  381                            "is actually fed by the EHT Frame Exchange Manager through the " 
  382                            "m_icfDropCallback member variable.",
 
  384                            "ns3::WifiMac::IcfDropCallback");
 
 
  427    for (
auto it = 
m_edca.begin(); it != 
m_edca.end(); ++it)
 
  429        it->second->Initialize();
 
  432    for (
const auto& [
id, link] : 
m_links)
 
  434        if (
auto cam = link->channelAccessManager)
 
 
  456    for (
auto it = 
m_edca.begin(); it != 
m_edca.end(); ++it)
 
  458        it->second->Dispose();
 
  459        it->second = 
nullptr;
 
 
  500    if (device->GetHtConfiguration())
 
 
  555    for (
auto& [
id, link] : 
m_links)
 
  557        link->feManager->SetPromisc();
 
 
  627    const auto it = std::find_if(
m_edca.cbegin(), 
m_edca.cend(), [ac](
const auto& pair) {
 
  628        return pair.first == ac;
 
  630    return (it == 
m_edca.cend() ? 
nullptr : it->second);
 
 
  667    return (txop ? txop->GetWifiMacQueue() : 
nullptr);
 
 
  677    for (
const auto& [aci, qosTxop] : 
m_edca)
 
  679        if (qosTxop->HasFramesToTransmit(linkId))
 
 
  750    m_txop->SetDroppedMpduCallback(
 
 
  759    auto edcaIt = 
m_edca.find(ac);
 
  763    edcaIt->second->GetBaManager()->SetTxOkCallback(
 
  765    edcaIt->second->GetBaManager()->SetTxFailedCallback(
 
  767    edcaIt->second->SetDroppedMpduCallback(
 
  769    edcaIt->second->GetWifiMacQueue()->TraceConnectWithoutContext(
 
 
  777    std::list<bool> isDsssOnly;
 
  778    for (
const auto& [
id, link] : 
m_links)
 
  780        isDsssOnly.push_back(link->dsssSupported && !link->erpSupported);
 
  791    for (
auto it = 
m_edca.begin(); it != 
m_edca.end(); ++it)
 
  793        ConfigureDcf(it->second, cwMin, cwMax, isDsssOnly, it->first);
 
 
  801                      std::list<bool> isDsss,
 
  808    uint8_t aifsnValue = 0;
 
  809    Time txopLimitDsss(0);
 
  810    Time txopLimitNoDsss(0);
 
  816        cwMinValue = (cwmin + 1) / 4 - 1;
 
  817        cwMaxValue = (cwmin + 1) / 2 - 1;
 
  823        cwMinValue = (cwmin + 1) / 2 - 1;
 
  857    const auto& userDefinedParams = dcf->GetUserAccessParams();
 
  859    dcf->SetMinCws(!userDefinedParams.cwMins.empty()
 
  860                       ? userDefinedParams.cwMins
 
  861                       : std::vector<uint32_t>(
m_links.size(), cwMinValue));
 
  862    dcf->SetMaxCws(!userDefinedParams.cwMaxs.empty()
 
  863                       ? userDefinedParams.cwMaxs
 
  864                       : std::vector<uint32_t>(
m_links.size(), cwMaxValue));
 
  865    dcf->SetAifsns(!userDefinedParams.aifsns.empty()
 
  866                       ? userDefinedParams.aifsns
 
  867                       : std::vector<uint8_t>(
m_links.size(), aifsnValue));
 
  869    if (!userDefinedParams.txopLimits.empty())
 
  871        dcf->SetTxopLimits(userDefinedParams.txopLimits);
 
  875        std::vector<Time> txopLimitValues(
m_links.size());
 
  876        std::transform(isDsss.begin(),
 
  878                       txopLimitValues.begin(),
 
  879                       [&txopLimitDsss, &txopLimitNoDsss](
bool dsss) {
 
  880                           return (dsss ? txopLimitDsss : txopLimitNoDsss);
 
  882        dcf->SetTxopLimits(txopLimitValues);
 
 
  891    const auto& link = *
m_links.cbegin()->second;
 
  893    if (!link.phy || !link.stationManager || !link.channelAccessManager || !link.feManager)
 
  900    for (
auto& [
id, link] : 
m_links)
 
  903            !link->phy || !link->phy->GetOperatingChannel().IsSet(),
 
  905                       << 
"] PHY must have been set and an operating channel must have been set");
 
  908                        "[LinkID " << +
id << 
"] A channel access manager must have been set");
 
  911                        "[LinkID " << +
id << 
"] A frame exchange manager must have been set");
 
  913        link->channelAccessManager->SetupPhyListener(link->phy);
 
  914        link->channelAccessManager->SetupFrameExchangeManager(link->feManager);
 
  916        link->feManager->SetWifiPhy(link->phy);
 
  923            link->channelAccessManager->Add(
m_txop);
 
  925        for (
auto it = 
m_edca.begin(); it != 
m_edca.end(); ++it)
 
  927            it->second->SetWifiMac(
this);
 
  928            link->channelAccessManager->Add(it->second);
 
 
  963    for (std::size_t i = 0; i < nLinks; i++)
 
 
  979                        "The number of provided Frame Exchange Manager objects (" 
  980                            << feManagers.size() << 
") must match the number of existing links (" 
  984    for (
auto managerIt = feManagers.cbegin(); 
auto& [
id, link] : 
m_links)
 
  986        link->feManager = *managerIt++;
 
  987        link->feManager->SetWifiMac(
this);
 
  988        link->feManager->SetLinkId(
id);
 
  990        link->feManager->GetWifiTxTimer().SetMpduResponseTimeoutCallback(
 
  991            MakeCallback(&MpduResponseTimeoutTracedCallback::operator(),
 
  993        link->feManager->GetWifiTxTimer().SetPsduResponseTimeoutCallback(
 
  994            MakeCallback(&PsduResponseTimeoutTracedCallback::operator(),
 
  996        link->feManager->GetWifiTxTimer().SetPsduMapResponseTimeoutCallback(
 
  997            MakeCallback(&PsduMapResponseTimeoutTracedCallback::operator(),
 
  999        link->feManager->SetDroppedMpduCallback(
 
 1001        link->feManager->SetAckedMpduCallback(
 
 1005            ehtFem->m_icfDropCallback.ConnectWithoutContext(
 
 
 1027                        "The number of provided Channel Access Manager objects (" 
 1028                            << caManagers.size() << 
") must match the number of existing links (" 
 1032    for (
auto managerIt = caManagers.cbegin(); 
auto& [
id, link] : 
m_links)
 
 1034        link->channelAccessManager = *managerIt++;
 
 1035        link->channelAccessManager->SetLinkId(
id);
 
 
 1063                        "The number of provided Remote Manager objects (" 
 1064                            << stationManagers.size()
 
 1065                            << 
") must match the number of existing links (" << 
m_links.size()
 
 1069    for (
auto managerIt = stationManagers.cbegin(); 
auto& [
id, link] : 
m_links)
 
 1071        link->stationManager = *managerIt++;
 
 1072        link->stationManager->SetLinkId(
id);
 
 
 1084std::unique_ptr<WifiMac::LinkEntity>
 
 1087    return std::make_unique<LinkEntity>();
 
 
 1090const std::map<uint8_t, std::unique_ptr<WifiMac::LinkEntity>>&
 
 
 1099    auto it = 
m_links.find(linkId);
 
 
 1111const std::set<uint8_t>&
 
 1125        link.feManager->SetLinkId(
id);
 
 1127    if (link.channelAccessManager)
 
 1129        link.channelAccessManager->SetLinkId(
id);
 
 1131    if (link.stationManager)
 
 1133        link.stationManager->SetLinkId(
id);
 
 
 1137std::optional<uint8_t>
 
 1140    for (
const auto& [
id, link] : 
m_links)
 
 1142        if (link->feManager->GetAddress() == address)
 
 1147    return std::nullopt;
 
 
 1150std::optional<uint8_t>
 
 1153    for (
const auto& [
id, link] : 
m_links)
 
 1155        if (link->phy == phy)
 
 1160    return std::nullopt;
 
 
 1163std::optional<uint8_t>
 
 1167    auto phy = 
m_device->GetPhy(phyId);
 
 
 1177    std::map<uint8_t, std::reference_wrapper<const LinkEntity>> origLinkRefMap;
 
 1178    for (
const auto& [
id, link] : 
m_links)
 
 1180        origLinkRefMap.insert_or_assign(
id, *link.get());
 
 1183    while (!links.empty())
 
 1185        auto from = links.cbegin()->first;
 
 1186        auto to = links.cbegin()->second;
 
 1191            links.erase(links.cbegin());
 
 1195        std::unique_ptr<LinkEntity> linkToMove;
 
 1197        linkToMove.swap(
m_links.at(from)); 
 
 1202            auto [it, inserted] =
 
 1215            auto nextTo = links.find(to);
 
 1216            if (nextTo == links.cend())
 
 1219                m_links[empty].swap(linkToMove);
 
 1224            to = nextTo->second;
 
 1229    for (
const auto& [
id, link] : 
m_links)
 
 1234    std::map<uint8_t, uint8_t> actualPairs;
 
 1235    for (
const auto& [from, ref] : origLinkRefMap)
 
 1238        for (
const auto& [to, link] : 
m_links)
 
 1240            if (link.get() == &ref.get())
 
 1242                actualPairs[from] = to; 
 
 1252        m_txop->SwapLinks(actualPairs);
 
 1254    for (
auto& [ac, edca] : 
m_edca)
 
 1256        edca->SwapLinks(actualPairs);
 
 
 
 1276                    "DL and UL directions for TID-to-Link mapping must be set separately");
 
 1280    auto [it, inserted] = mappings.emplace(mldAddr, mapping);
 
 1289    if (mapping.empty())
 
 1296    for (
const auto& [tid, linkSet] : mapping)
 
 1298        it->second[tid] = linkSet;
 
 
 1302std::optional<std::reference_wrapper<const WifiTidLinkMapping>>
 
 1306                    "Cannot request TID-to-Link mapping for both directions");
 
 1308    const auto& mappings =
 
 1311    if (
const auto it = mappings.find(mldAddr); it != mappings.cend())
 
 1315    return std::nullopt;
 
 
 1322                    "Cannot request TID-to-Link mapping for both directions");
 
 1330    const auto& mappings =
 
 1333    const auto it = mappings.find(mldAddr);
 
 1335    if (it == mappings.cend())
 
 1341    auto linkSetIt = it->second.find(tid);
 
 1343    if (linkSetIt == it->second.cend())
 
 1350    return std::find(linkSetIt->second.cbegin(), linkSetIt->second.cend(), linkId) !=
 
 1351           linkSetIt->second.cend();
 
 
 1363                        "The number of provided PHY objects (" 
 1364                            << phys.size() << 
") must match the number of existing links (" 
 1368    for (
auto phyIt = phys.cbegin(); 
auto& [
id, link] : 
m_links)
 
 1370        link->phy = *phyIt++;
 
 
 1386    for (
auto& [
id, link] : 
m_links)
 
 1388        if (link->feManager)
 
 1390            link->feManager->ResetPhy();
 
 1392        if (link->channelAccessManager)
 
 1394            link->channelAccessManager->RemovePhyListener(link->phy);
 
 1396        link->phy = 
nullptr;
 
 
 1498        "This method can be used to enforce TID-to-Link mapping for one direction at a time");
 
 1500    const auto& mappings =
 
 1503    auto it = mappings.find(mldAddr);
 
 1505    if (it == mappings.cend())
 
 1511    std::set<uint8_t> setupLinks;
 
 1514    for (
const auto& [
id, link] : 
m_links)
 
 1516        if (link->stationManager->GetMldAddress(mldAddr))
 
 1518            setupLinks.insert(
id);
 
 1522    auto linkMapping = it->second;
 
 1524    if (linkMapping.empty())
 
 1527        for (uint8_t tid = 0; tid < 8; tid++)
 
 1529            linkMapping.emplace(tid, setupLinks);
 
 1533    for (
const auto& [tid, linkSet] : linkMapping)
 
 1535        decltype(setupLinks) mappedLinks; 
 
 1536        auto notMappedLinks = setupLinks; 
 
 1538        for (
const auto id : linkSet)
 
 1540            if (setupLinks.find(
id) != setupLinks.cend())
 
 1543                mappedLinks.insert(
id);
 
 1544                notMappedLinks.erase(
id);
 
 1549        NS_ABORT_MSG_IF(mappedLinks.empty(), 
"Every TID must be mapped to at least a link");
 
 1560        if (!notMappedLinks.empty())
 
 
 1576                               const std::set<uint8_t>& linkIds)
 
 1578    std::stringstream ss;
 
 1581        std::copy(linkIds.cbegin(), linkIds.cend(), std::ostream_iterator<uint16_t>(ss, 
" "));
 
 1586    for (
const auto linkId : linkIds)
 
 1589        auto linkAddr = link.stationManager->GetAffiliatedStaAddress(address);
 
 1591        if (link.stationManager->GetMldAddress(address) == address && !linkAddr.has_value())
 
 1593            NS_LOG_DEBUG(
"Link " << +linkId << 
" has not been setup with the MLD, skip");
 
 1605                                     {ac.GetLowTid(), ac.GetHighTid()},
 
 1611                                     linkAddr.value_or(address),
 
 1612                                     link.feManager->GetAddress(),
 
 
 1622                                 const std::set<uint8_t>& linkIds)
 
 1627    std::vector<uint8_t> shuffledLinkIds(linkIds.cbegin(), linkIds.cend());
 
 1630    std::stringstream ss;
 
 1633        std::copy(shuffledLinkIds.cbegin(),
 
 1634                  shuffledLinkIds.cend(),
 
 1635                  std::ostream_iterator<uint16_t>(ss, 
" "));
 
 1639    for (
const auto linkId : shuffledLinkIds)
 
 1642        auto linkAddr = link.stationManager->GetAffiliatedStaAddress(address);
 
 1644        if (link.stationManager->GetMldAddress(address) == address && !linkAddr.has_value())
 
 1646            NS_LOG_DEBUG(
"Link " << +linkId << 
" has not been setup with the MLD, skip");
 
 1653            auto hasFramesToTransmit = 
GetQosTxop(acIndex)->HasFramesToTransmit(linkId);
 
 1661                                       {ac.GetLowTid(), ac.GetHighTid()},
 
 1667                                       linkAddr.value_or(address),
 
 1668                                       link.feManager->GetAddress(),
 
 1676                                   hasFramesToTransmit,
 
 
 1688    auto mask = 
m_scheduler->GetQueueLinkMask(ac, queueId, linkId);
 
 1690    if (!mask.has_value())
 
 1698    return mask->test(
static_cast<std::size_t
>(reason));
 
 
 1706    const auto& hdr = mpdu->GetHeader();
 
 1707    const auto remoteAddr = hdr.GetAddr1();
 
 1709    if (remoteAddr.IsGroup() || hdr.IsCtl() || !hdr.IsRetry() || mpdu->IsInFlight())
 
 1714    std::optional<Mac48Address> optAddr;
 
 1715    for (
const auto& [
id, link] : 
m_links)
 
 1717        if (link->stationManager->GetMldAddress(remoteAddr) == remoteAddr)
 
 1720            optAddr = link->feManager->GetAddress(); 
 
 1724    const auto localAddr =
 
 1727    NS_ASSERT_MSG(linkId.has_value(), 
"No link with address " << localAddr);
 
 
 1753    if (packet->RemovePacketTag(qos) && qos.
GetPriority() < 8)
 
 1758    Enqueue(packet, to, from, tid);
 
 
 1767                    "This Mac does not support forwarding frames");
 
 
 1820    const auto& hdr = mpdu->GetOriginal()->GetHeader();
 
 1821    const auto to = hdr.GetAddr1();
 
 1837    if ((hdr.IsData() && !hdr.HasData()) || hdr.IsMgt())
 
 1842    NS_FATAL_ERROR(
"Don't know how to handle frame (type=" << hdr.GetType());
 
 
 1852                  msduPair.second.GetSourceAddr(),
 
 1853                  msduPair.second.GetDestinationAddr());
 
 
 1857std::optional<Mac48Address>
 
 1860    for (
const auto& [
id, link] : 
m_links)
 
 1862        if (
auto mldAddress = link->stationManager->GetMldAddress(remoteAddr))
 
 1867    return std::nullopt;
 
 
 1873    for (
const auto& [
id, link] : 
m_links)
 
 1875        if (
auto mldAddress = link->stationManager->GetMldAddress(remoteAddr))
 
 1878            if (mldAddress != remoteAddr)
 
 1881                return link->feManager->GetAddress();
 
 
 1907                                               std::optional<Mac48Address> gcrGroupAddr)
 const 
 1913        GetQosTxop(tid)->GetBaManager()->GetAgreementAsOriginator(recipient, tid, gcrGroupAddr);
 
 1914    if (!agreement || !agreement->get().IsEstablished())
 
 1916        return std::nullopt;
 
 
 1924                                              std::optional<Mac48Address> gcrGroupAddr)
 const 
 1927    originator = 
GetMldAddress(originator).value_or(originator);
 
 1928    return GetQosTxop(tid)->GetBaManager()->GetAgreementAsRecipient(originator, tid, gcrGroupAddr);
 
 
 1936                    "No existing Block Ack agreement with " << recipient << 
" TID: " << +tid);
 
 1937    return agreement->get().GetBlockAckType();
 
 
 1945                    "No existing Block Ack agreement with " << recipient << 
" TID: " << +tid);
 
 1946    return agreement->get().GetBlockAckReqType();
 
 
 1954                    "No existing Block Ack agreement with " << originator << 
" TID: " << +tid);
 
 1955    return agreement->get().GetBlockAckType();
 
 
 1963                    "No existing Block Ack agreement with " << originator << 
" TID: " << +tid);
 
 1964    return agreement->get().GetBlockAckReqType();
 
 
 1970    return GetDevice()->GetHtConfiguration();
 
 
 1976    return GetDevice()->GetVhtConfiguration();
 
 
 1982    return GetDevice()->GetHeConfiguration();
 
 
 1988    return GetDevice()->GetEhtConfiguration();
 
 
 2021    for (
const auto& [
id, link] : 
m_links)
 
 2023        if (link->stationManager->GetHtSupported(address))
 
 
 2034    for (
const auto& [
id, link] : 
m_links)
 
 2036        if (link->stationManager->GetVhtSupported(address))
 
 
 2047    for (
const auto& [
id, link] : 
m_links)
 
 2049        if (link->stationManager->GetHeSupported(address))
 
 
 2060    for (
const auto& [
id, link] : 
m_links)
 
 2062        if (link->stationManager->GetEhtSupported(address))
 
 
 2119        GetVOQueue()->SetBlockAckThreshold(threshold);
 
 
 2129        GetVIQueue()->SetBlockAckThreshold(threshold);
 
 
 2139        GetBEQueue()->SetBlockAckThreshold(threshold);
 
 
 2149        GetBKQueue()->SetBlockAckThreshold(threshold);
 
 
 2198    return capabilities;
 
 
 2209    bool sgiSupported = htConfiguration->m_sgiSupported;
 
 2210    capabilities.
SetLdpc(htConfiguration->m_ldpcSupported);
 
 2211    const auto width = phy->GetChannelWidth();
 
 2216    uint16_t maxAmsduSize =
 
 2218    if (maxAmsduSize <= 3839)
 
 2229    maxAmpduLength = (1UL << 
static_cast<uint32_t>(std::ceil(std::log2(maxAmpduLength + 1)))) - 1;
 
 2231    capabilities.
SetMaxAmpduLength(std::min(std::max(maxAmpduLength, 8191U), 65535U));
 
 2234    uint64_t maxSupportedRate = 0; 
 
 2238        uint8_t nss = (mcs.GetMcsValue() / 8) + 1;
 
 2241            mcs.GetDataRate(std::min(width, 
MHz_u{40}), 
NanoSeconds(sgiSupported ? 400 : 800), nss);
 
 2242        if (dataRate > maxSupportedRate)
 
 2244            maxSupportedRate = dataRate;
 
 2245            NS_LOG_DEBUG(
"Updating maxSupportedRate to " << maxSupportedRate);
 
 2249        static_cast<uint16_t
>(maxSupportedRate / 1e6)); 
 
 2256    return capabilities;
 
 
 2267    const auto sgiSupported = htConfiguration->m_sgiSupported;
 
 2268    const auto width = phy->GetChannelWidth();
 
 2271    uint16_t maxAmsduSize =
 
 2273    if (maxAmsduSize <= 3839)
 
 2277    else if (maxAmsduSize <= 7935)
 
 2288    maxAmpduLength = (1UL << 
static_cast<uint32_t>(std::ceil(std::log2(maxAmpduLength + 1)))) - 1;
 
 2290    capabilities.
SetMaxAmpduLength(std::min(std::max(maxAmpduLength, 8191U), 1048575U));
 
 2292    capabilities.
SetRxLdpc(htConfiguration->m_ldpcSupported);
 
 2298        if (mcs.GetMcsValue() > maxMcs)
 
 2300            maxMcs = mcs.GetMcsValue();
 
 2304    for (uint8_t nss = 1; nss <= phy->GetMaxSupportedRxSpatialStreams(); nss++)
 
 2308    for (uint8_t nss = 1; nss <= phy->GetMaxSupportedTxSpatialStreams(); nss++)
 
 2312    uint64_t maxSupportedRateLGI = 0; 
 
 2315        if (!mcs.IsAllowed(width, 1))
 
 2319        if (mcs.GetDataRate(width) > maxSupportedRateLGI)
 
 2321            maxSupportedRateLGI = mcs.GetDataRate(width);
 
 2322            NS_LOG_DEBUG(
"Updating maxSupportedRateLGI to " << maxSupportedRateLGI);
 
 2326        static_cast<uint16_t
>(maxSupportedRateLGI / 1e6)); 
 
 2328        static_cast<uint16_t
>(maxSupportedRateLGI / 1e6)); 
 
 2333    return capabilities;
 
 
 2345    uint8_t channelWidthSet = 0;
 
 2346    const auto width = phy->GetChannelWidth();
 
 2349        if (width >= 
MHz_u{40})
 
 2351            channelWidthSet |= 0x01;
 
 2356        if (width >= 
MHz_u{40})
 
 2358            channelWidthSet |= 0x02;
 
 2360        if (width >= 
MHz_u{160})
 
 2362            channelWidthSet |= 0x04;
 
 2363            if (phy->GetOperatingChannel().GetNSegments() > 1)
 
 2365                channelWidthSet |= 0x08;
 
 2371    if (heConfiguration->GetGuardInterval().GetNanoSeconds() == 800)
 
 2382    maxAmpduLength = (1UL << 
static_cast<uint32_t>(std::ceil(std::log2(maxAmpduLength + 1)))) - 1;
 
 2384    capabilities.
SetMaxAmpduLength(std::min(std::max(maxAmpduLength, 1048575U), 8388607U));
 
 2389        if (mcs.GetMcsValue() > maxMcs)
 
 2391            maxMcs = mcs.GetMcsValue();
 
 2397    return capabilities;
 
 
 2405                  "Getting HE 6 GHz band capabilities on band different than 6 GHz");
 
 2410    const auto maxAmsduSize =
 
 2412    if (maxAmsduSize <= 3839)
 
 2416    else if (maxAmsduSize <= 7935)
 
 2425    auto maxAmpduLength =
 
 2428    maxAmpduLength = (1UL << 
static_cast<uint32_t>(std::ceil(std::log2(maxAmpduLength + 1)))) - 1;
 
 2430    capabilities.
SetMaxAmpduLength(std::min(std::max(maxAmpduLength, 8191U), 1048575U));
 
 2432    return capabilities;
 
 
 2446        uint16_t maxAmsduSize =
 
 2449        if (maxAmsduSize <= 3839)
 
 2453        else if (maxAmsduSize <= 7935)
 
 2467    maxAmpduLength = (1UL << 
static_cast<uint32_t>(std::ceil(std::log2(maxAmpduLength + 1)))) - 1;
 
 2469    capabilities.
SetMaxAmpduLength(std::min(std::max(maxAmpduLength, 8388607U), 16777215U));
 
 2474        support4096Qam ? 1 : 0;
 
 2476        support4096Qam ? 1 : 0;
 
 2478    const auto maxTxNss = phy->GetMaxSupportedTxSpatialStreams();
 
 2479    const auto maxRxNss = phy->GetMaxSupportedRxSpatialStreams();
 
 2480    const auto width = phy->GetChannelWidth();
 
 2481    if (width == 
MHz_u{20})
 
 2483        for (
auto maxMcs : {7, 9, 11, 13})
 
 2497        for (
auto maxMcs : {9, 11, 13})
 
 2509    if (width >= 
MHz_u{160})
 
 2511        for (
auto maxMcs : {9, 11, 13})
 
 2523    if (width >= 
MHz_u{320})
 
 2526        for (
auto maxMcs : {9, 11, 13})
 
 2538    return capabilities;
 
 
 2569    uint16_t maxSize = 0;
 
 
 2602                  "Robust AV Streaming requires STA to be HT-capable");
 
 
 2614    auto recordFromIes = [&](
auto&& frame) {
 
 2615        NS_ASSERT(frame.template Get<SupportedRates>());
 
 2617                                             frame.template Get<ExtendedSupportedRatesIE>()};
 
 2618        for (
const auto& mode : phy->GetModeList())
 
 2620            if (rates.IsSupportedRate(mode.GetDataRate(phy->GetChannelWidth())))
 
 2622                remoteStationManager->AddSupportedMode(from, mode);
 
 2623                if (rates.IsBasicRate(mode.GetDataRate(phy->GetChannelWidth())))
 
 2625                    remoteStationManager->AddBasicMode(mode);
 
 2635            if (
const auto& htCapabilities = frame.template Get<HtCapabilities>())
 
 2637                remoteStationManager->AddStationHtCapabilities(from, *htCapabilities);
 
 2639            if (
const auto& extendedCapabilities = frame.template Get<ExtendedCapabilities>())
 
 2641                remoteStationManager->AddStationExtendedCapabilities(from, *extendedCapabilities);
 
 2649            const auto& vhtCapabilities = frame.template Get<VhtCapabilities>();
 
 2652            if (vhtCapabilities.has_value() &&
 
 2653                vhtCapabilities->GetRxHighestSupportedLgiDataRate() > 0)
 
 2655                remoteStationManager->AddStationVhtCapabilities(from, *vhtCapabilities);
 
 2664        const auto& heCapabilities = frame.template Get<HeCapabilities>();
 
 2665        if (heCapabilities.has_value() && heCapabilities->GetSupportedMcsAndNss() != 0)
 
 2667            remoteStationManager->AddStationHeCapabilities(from, *heCapabilities);
 
 2672            if (
const auto& he6GhzCapabilities = frame.template Get<He6GhzBandCapabilities>())
 
 2674                remoteStationManager->AddStationHe6GhzCapabilities(from, *he6GhzCapabilities);
 
 2683        if (
const auto& ehtCapabilities = frame.template Get<EhtCapabilities>())
 
 2685            remoteStationManager->AddStationEhtCapabilities(from, *ehtCapabilities);
 
 2690    std::visit(recordFromIes, frame);
 
 
 
AttributeValue implementation for Boolean.
The IEEE 802.11be EHT Capabilities.
void SetMaxMpduLength(uint16_t length)
Set the maximum MPDU length.
void SetSupportedTxEhtMcsAndNss(EhtMcsAndNssSet::EhtMcsMapType mapType, uint8_t upperMcs, uint8_t maxNss)
Set a subfield of the Supported EHT-MCS And NSS Set.
EhtPhyCapabilities m_phyCapabilities
EHT PHY Capabilities Info subfield.
void SetMaxAmpduLength(uint32_t maxAmpduLength)
Set the maximum A-MPDU length.
void SetSupportedRxEhtMcsAndNss(EhtMcsAndNssSet::EhtMcsMapType mapType, uint8_t upperMcs, uint8_t maxNss)
Set a subfield of the Supported EHT-MCS And NSS Set.
The Extended Capabilities Information Element.
uint8_t m_robustAvStreaming
Robust AV Streaming.
The HE 6 GHz Band Capabilities (IEEE 802.11ax-2021 9.4.2.263)
void SetMaxAmpduLength(uint32_t maxAmpduLength)
Set the maximum AMPDU length.
void SetMaxMpduLength(uint16_t length)
Set the maximum MPDU length.
The IEEE 802.11ax HE Capabilities.
void SetHeSuPpdu1xHeLtf800nsGi(bool heSuPpdu1xHeLtf800nsGi)
Set 1xHE-LTF and 800ns GI in HE SU PPDU reception support.
void SetLdpcCodingInPayload(uint8_t ldpcCodingInPayload)
Set indication whether the transmission and reception of LDPC encoded packets is supported.
void SetHePpdu4xHeLtf800nsGi(bool heSuPpdu4xHeLtf800nsGi)
Set 4xHE-LTF and 800ns GI in HE SU PPDU and HE MU PPDU reception support.
void SetHighestNssSupported(uint8_t nss)
Set highest NSS supported.
void SetMaxAmpduLength(uint32_t maxAmpduLength)
Set the maximum AMPDU length.
void SetChannelWidthSet(uint8_t channelWidthSet)
Set channel width set.
void SetHighestMcsSupported(uint8_t mcs)
Set highest MCS supported.
The HT Capabilities Information Element.
void SetLdpc(uint8_t ldpc)
Set the LDPC field.
void SetTxRxMcsSetUnequal(uint8_t txRxMcsSetUnequal)
Set the transmit / receive MCS set unequal.
void SetRxHighestSupportedDataRate(uint16_t maxSupportedRate)
Set the receive highest supported data rate.
void SetLSigProtectionSupport(uint8_t lSigProtection)
Set the LSIG protection support.
void SetMaxAmsduLength(uint16_t maxAmsduLength)
Set the maximum AMSDU length.
void SetTxMaxNSpatialStreams(uint8_t maxTxSpatialStreams)
Set the transmit maximum N spatial streams.
void SetShortGuardInterval20(uint8_t shortGuardInterval)
Set the short guard interval 20 field.
void SetTxUnequalModulation(uint8_t txUnequalModulation)
Set the transmit unequal modulation.
void SetTxMcsSetDefined(uint8_t txMcsSetDefined)
Set the transmit MCS set defined.
void SetRxMcsBitmask(uint8_t index)
Set the receive MCS bitmask.
void SetSupportedChannelWidth(uint8_t supportedChannelWidth)
Set the supported channel width field.
void SetMaxAmpduLength(uint32_t maxAmpduLength)
Set the maximum AMPDU length.
void SetShortGuardInterval40(uint8_t shortGuardInterval)
Set the short guard interval 40 field.
static Mac48Address ConvertFrom(const Address &address)
bool IsInitialized() const
Check if the object has been initialized.
AttributeValue implementation for Pointer.
Smart pointer class similar to boost::intrusive_ptr.
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
indicates whether the socket has a priority set.
uint8_t GetPriority() const
Get the tag's priority.
The IEEE 802.11 SSID Information Element.
AttributeValue implementation for Ssid.
Simulation virtual time values and global simulation resolution.
void StartAccessAfterEvent(uint8_t linkId, bool hadFramesToTransmit, bool checkMediumBusy)
Request channel access on the given link after the occurrence of an event that possibly requires to g...
static constexpr bool CHECK_MEDIUM_BUSY
generation of backoff (also) depends on the busy/idle state of the medium
a unique identifier for an interface.
@ ATTR_GET
The attribute can be read.
@ ATTR_CONSTRUCT
The attribute can be written at construction-time.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Hold an unsigned integer type.
The IEEE 802.11ac VHT Capabilities.
void SetRxHighestSupportedLgiDataRate(uint16_t supportedDatarate)
Set the receive highest supported LGI data rate.
void SetSupportedChannelWidthSet(uint8_t channelWidthSet)
Set the supported channel width set.
void SetMaxMpduLength(uint16_t length)
Set the maximum MPDU length.
void SetRxLdpc(uint8_t rxLdpc)
Set the receive LDPC.
void SetTxStbc(uint8_t txStbc)
Set the transmit STBC.
void SetTxMcsMap(uint8_t mcs, uint8_t nss)
void SetShortGuardIntervalFor80Mhz(uint8_t shortGuardInterval)
Set the short guard interval 80 MHz.
void SetTxHighestSupportedLgiDataRate(uint16_t supportedDatarate)
Set the transmit highest supported LGI data rate.
void SetShortGuardIntervalFor160Mhz(uint8_t shortGuardInterval)
Set the short guard interval 160 MHz.
void SetMaxAmpduLength(uint32_t maxAmpduLength)
Set the maximum AMPDU length.
void SetRxMcsMap(uint8_t mcs, uint8_t nss)
void SetRxStbc(uint8_t rxStbc)
Set the receive STBC.
base class for all MAC-level wifi objects.
virtual void DoCompleteConfig()=0
Allow subclasses to complete the configuration of the MAC layer components.
RecipientAgreementOptConstRef GetBaAgreementEstablishedAsRecipient(Mac48Address originator, uint8_t tid, std::optional< Mac48Address > gcrGroupAddr=std::nullopt) const
uint16_t GetMaxAmsduSize(AcIndex ac) const
Return the maximum A-MSDU size of the given Access Category.
Ptr< FrameExchangeManager > GetFrameExchangeManager(uint8_t linkId=SINGLE_LINK_OP_ID) const
Get the Frame Exchange Manager associated with the given link.
Ptr< QosTxop > GetBEQueue() const
Accessor for the AC_BE channel access function.
virtual void NotifyChannelSwitching(uint8_t linkId)
Notify that channel on the given link has been switched.
std::optional< Mac48Address > GetMldAddress(const Mac48Address &remoteAddr) const
virtual void SetMacQueueScheduler(Ptr< WifiMacQueueScheduler > scheduler)
Set the wifi MAC queue scheduler.
Mac48Address GetBssid(uint8_t linkId) const
uint16_t m_viMaxAmsduSize
maximum A-MSDU size for AC_VI (in bytes)
bool m_shortSlotTimeSupported
flag whether short slot time is supported
void ConfigurePhyDependentParameters(uint8_t linkId)
Configure PHY dependent parameters such as CWmin and CWmax on the given link.
Ptr< HeConfiguration > GetHeConfiguration() const
DroppedMpduTracedCallback m_droppedMpduCallback
This trace indicates that an MPDU was dropped for the given reason.
TypeOfStation GetTypeOfStation() const
Return the type of station.
uint32_t GetFrameRetryLimit() const
bool m_qosSupported
This Boolean is set true iff this WifiMac is to model 802.11e/WMM style Quality of Service.
void SetBkQueue(Ptr< QosTxop > edca)
Set the AC_BK channel access function This method is private so that it is only used while constructi...
const std::map< uint8_t, std::unique_ptr< LinkEntity > > & GetLinks() const
Ptr< Txop > GetTxop() const
Accessor for the Txop object.
VhtCapabilities GetVhtCapabilities(uint8_t linkId) const
Return the VHT capabilities of the device for the given link.
Callback< void > m_linkDown
Callback when a link is down.
bool GetQosSupported() const
Return whether the device supports QoS.
virtual void SetAddress(Mac48Address address)
void SetFrameExchangeManagers(const std::vector< Ptr< FrameExchangeManager > > &feManagers)
bool CreateLinksIfNeeded(std::size_t nLinks)
If no link has been already created, create the given number links; otherwise, do nothing.
Ptr< Txop > m_txop
TXOP used for transmission of frames to non-QoS peers.
void SetQosSupported(bool enable)
Enable or disable QoS support for the device.
Mac48Address m_address
MAC address of this station.
std::set< uint8_t > m_linkIds
IDs of the links in use.
Ptr< WifiMacQueueScheduler > GetMacQueueScheduler() const
Get the wifi MAC queue scheduler.
uint16_t GetMpduBufferSize() const
uint8_t GetNLinks() const
Get the number of links (can be greater than 1 for 11be devices only).
BlockAckType GetBaTypeAsRecipient(Mac48Address originator, uint8_t tid) const
void SwapLinks(std::map< uint8_t, uint8_t > links)
Swap the links based on the information included in the given map.
void Enqueue(Ptr< Packet > packet, Mac48Address to)
void UnblockUnicastTxOnLinks(WifiQueueBlockedReason reason, Mac48Address address, const std::set< uint8_t > &linkIds)
Unblock the transmission on the given links of all unicast frames addressed to the station with the g...
uint16_t m_voMaxAmsduSize
maximum A-MSDU size for AC_VO (in bytes)
Ptr< MacRxMiddle > m_rxMiddle
RX middle (defragmentation etc.)
Ptr< WifiMacQueueScheduler > m_scheduler
wifi MAC queue scheduler
void DoInitialize() override
Initialize() implementation.
TypeOfStation m_typeOfStation
the type of station
uint16_t m_mpduBufferSize
BlockAck buffer size (in number of MPDUs)
uint32_t m_beMaxAmpduSize
maximum A-MPDU size for AC_BE (in bytes)
void SetChannelAccessManagers(const std::vector< Ptr< ChannelAccessManager > > &caManagers)
bool TidMappedOnLink(Mac48Address mldAddr, WifiDirection dir, uint8_t tid, uint8_t linkId) const
Check whether the given TID is mapped on the given link in the given direction for the given MLD.
std::variant< MgtBeaconHeader, MgtProbeResponseHeader, MgtAssocResponseHeader > MgtFrameType
type of the management frames
void SetWifiRemoteStationManagers(const std::vector< Ptr< WifiRemoteStationManager > > &stationManagers)
void SetBeBlockAckThreshold(uint8_t threshold)
Set the block ack threshold for AC_BE.
bool GetErpSupported(uint8_t linkId) const
Return whether the device supports ERP on the given link.
void ResetWifiPhys()
Remove currently attached WifiPhy objects from this MAC.
TracedCallback< Ptr< const Packet > > m_macTxTrace
The trace source fired when packets come into the "top" of the device at the L3/L2 transition,...
void SetErpSupported(bool enable, uint8_t linkId)
Enable or disable ERP support for the given link.
bool GetTxBlockedOnLink(AcIndex ac, const WifiContainerQueueId &queueId, uint8_t linkId, WifiQueueBlockedReason reason=WifiQueueBlockedReason::REASONS_COUNT) const
Check whether the transmission of the packets in the given container queue of the given Access Catego...
uint32_t m_voMaxAmpduSize
maximum A-MPDU size for AC_VO (in bytes)
void ConfigureDcf(Ptr< Txop > dcf, uint32_t cwmin, uint32_t cwmax, std::list< bool > isDsss, AcIndex ac)
Ptr< WifiNetDevice > m_device
Pointer to the device.
bool GetRobustAVStreamingSupported() const
Return whether the device supports Robust AV Streaming.
virtual void NotifyDropPacketToEnqueue(Ptr< Packet > packet, Mac48Address to)
Allow subclasses to take actions when a packet to enqueue has been dropped.
void UpdateLinkId(uint8_t id)
This method is intended to be called when a link changes ID in order to update the link ID stored by ...
IcfDropTracedCallback m_icfDropCallback
traced callback for ICF drop events
Ptr< QosTxop > GetVOQueue() const
Accessor for the AC_VO channel access function.
void SetTypeOfStation(TypeOfStation type)
This method is invoked by a subclass to specify what type of station it is implementing.
MpduTracedCallback m_ackedMpduCallback
ack'ed MPDU callback
void NotifyRsmOfExpiredMpdu(Ptr< const WifiMpdu > mpdu)
Notify the remote station manager if the given expired (hence dropped) MPDU is a management or data f...
Ptr< WifiPhy > GetWifiPhy(uint8_t linkId=SINGLE_LINK_OP_ID) const
void SetMpduBufferSize(uint16_t size)
void RecordCapabilities(const MgtFrameType &frame, const Mac48Address &addr, uint8_t linkId)
Update capabilities information from the given management frame.
MpduTracedCallback m_nackedMpduCallback
nack'ed MPDU callback
bool GetEhtSupported() const
Return whether the device supports EHT.
void SetTxop(Ptr< Txop > dcf)
Set the Txop object.
bool GetHeSupported() const
Return whether the device supports HE.
HtCapabilities GetHtCapabilities(uint8_t linkId) const
Return the HT capabilities of the device for the given link.
void SetBkBlockAckThreshold(uint8_t threshold)
Set the block ack threshold for AC_BK.
void SetVoBlockAckThreshold(uint8_t threshold)
Set the block ack threshold for AC_VO.
virtual std::optional< uint8_t > GetLinkIdByAddress(const Mac48Address &address) const
Get the ID of the link having the given MAC address, if any.
std::optional< std::reference_wrapper< const RecipientBlockAckAgreement > > RecipientAgreementOptConstRef
optional const reference to RecipientBlockAckAgreement
void NotifyPromiscRx(Ptr< const Packet > packet)
std::unordered_map< Mac48Address, WifiTidLinkMapping, WifiAddressHash > m_dlTidLinkMappings
DL TID-to-Link Mapping negotiated with an MLD (identified by its MLD address)
void SetVoQueue(Ptr< QosTxop > edca)
Set the AC_VO channel access function This method is private so that it is only used while constructi...
virtual bool HasFramesToTransmit(uint8_t linkId)
Check if the MAC has frames to transmit over the given link.
void SetWifiRemoteStationManager(Ptr< WifiRemoteStationManager > stationManager)
UniformRandomBitGenerator m_shuffleLinkIdsGen
random number generator to shuffle link IDs
void ApplyTidLinkMapping(const Mac48Address &mldAddr, WifiDirection dir)
Apply the TID-to-Link Mapping negotiated with the given MLD for the given direction by properly confi...
void CompleteConfig()
Complete the configuration of the MAC layer components.
void SetBeBlockAckInactivityTimeout(uint16_t timeout)
Set BE block ack inactivity timeout.
Ptr< EhtConfiguration > GetEhtConfiguration() const
TracedCallback< Ptr< const Packet > > m_macRxTrace
The trace source fired for packets successfully received by the device immediately before being forwa...
bool GetVhtSupported(uint8_t linkId) const
Return whether the device supports VHT on the given link.
void SetDsssSupported(bool enable, uint8_t linkId)
Enable or disable DSSS support for the given link.
TracedCallback< Ptr< const Packet > > m_macTxDropTrace
The trace source fired when packets coming into the "top" of the device are dropped at the MAC layer ...
void BlockUnicastTxOnLinks(WifiQueueBlockedReason reason, Mac48Address address, const std::set< uint8_t > &linkIds)
Block the transmission on the given links of all unicast frames addressed to the station with the giv...
Ptr< MacTxMiddle > m_txMiddle
TX middle (aggregation etc.)
void NotifyTx(Ptr< const Packet > packet)
virtual int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
static TypeId GetTypeId()
Get the type ID.
Ptr< HtConfiguration > GetHtConfiguration() const
void SetFrameRetryLimit(uint32_t limit)
Set the frame retry limit.
std::optional< std::reference_wrapper< const WifiTidLinkMapping > > GetTidToLinkMapping(Mac48Address mldAddr, WifiDirection dir) const
Get the TID-to-Link Mapping negotiated with the given MLD (if any) for the given direction.
uint32_t GetMaxAmpduSize(AcIndex ac) const
Return the maximum A-MPDU size of the given Access Category.
BlockAckReqType GetBarTypeAsRecipient(Mac48Address originator, uint8_t tid) const
Ssid m_ssid
Service Set ID (SSID)
std::map< uint8_t, std::unique_ptr< LinkEntity > > m_links
ID-indexed map of Link objects.
virtual void DeaggregateAmsduAndForward(Ptr< const WifiMpdu > mpdu)
This method can be called to de-aggregate an A-MSDU and forward the constituent packets up the stack.
Ptr< QosTxop > GetVIQueue() const
Accessor for the AC_VI channel access function.
void SetBssid(Mac48Address bssid, uint8_t linkId)
Ptr< WifiNetDevice > GetDevice() const
Return the device this PHY is associated with.
void NotifyRx(Ptr< const Packet > packet)
TracedCallback< Ptr< const Packet > > m_macRxDropTrace
The trace source fired when packets coming into the "top" of the device are dropped at the MAC layer ...
void UpdateTidToLinkMapping(const Mac48Address &mldAddr, WifiDirection dir, const WifiTidLinkMapping &mapping)
Update the TID-to-Link Mappings for the given MLD in the given direction based on the given negotiate...
BlockAckType GetBaTypeAsOriginator(const Mac48Address &recipient, uint8_t tid) const
MpduResponseTimeoutTracedCallback m_mpduResponseTimeoutCallback
MPDU response timeout traced callback.
void SetForwardUpCallback(ForwardUpCallback upCallback)
PsduMapResponseTimeoutTracedCallback m_psduMapResponseTimeoutCallback
PSDU map response timeout traced callback.
OriginatorAgreementOptConstRef GetBaAgreementEstablishedAsOriginator(Mac48Address recipient, uint8_t tid, std::optional< Mac48Address > gcrGroupAddr=std::nullopt) const
ExtendedCapabilities GetExtendedCapabilities() const
Return the extended capabilities of the device.
TracedCallback< Ptr< const Packet > > m_macPromiscRxTrace
The trace source fired for packets successfully received by the device immediately before being forwa...
uint16_t m_bkMaxAmsduSize
maximum A-MSDU size for AC_BK (in bytes)
void SetBkBlockAckInactivityTimeout(uint16_t timeout)
Set BK block ack inactivity timeout.
std::unordered_map< Mac48Address, WifiTidLinkMapping, WifiAddressHash > m_ulTidLinkMappings
UL TID-to-Link Mapping negotiated with an MLD (identified by its MLD address)
virtual bool SupportsSendFrom() const
He6GhzBandCapabilities GetHe6GhzBandCapabilities(uint8_t linkId) const
Return the HE 6GHz band capabilities of the device for the given 6 GHz link.
uint16_t GetMaxBaBufferSize(std::optional< Mac48Address > address=std::nullopt) const
Get the maximum Block Ack buffer size (in number of MPDUs) supported by the given device,...
virtual Ptr< WifiMacQueue > GetTxopQueue(AcIndex ac) const
Get the wifi MAC queue of the (Qos)Txop associated with the given AC, if such (Qos)Txop is installed,...
std::optional< uint8_t > GetLinkForPhy(Ptr< const WifiPhy > phy) const
Get the ID of the link (if any) on which the given PHY is operating.
void SetViBlockAckThreshold(uint8_t threshold)
Set the block ack threshold for AC_VI.
void SetViBlockAckInactivityTimeout(uint16_t timeout)
Set VI block ack inactivity timeout.
bool GetShortSlotTimeSupported() const
BlockAckReqType GetBarTypeAsOriginator(const Mac48Address &recipient, uint8_t tid) const
void NotifyConstructionCompleted() override
Notifier called once the ObjectBase is fully constructed.
void SetupEdcaQueue(AcIndex ac)
This method is a private utility invoked to configure the channel access function for the specified A...
void SetLinkDownCallback(Callback< void > linkDown)
bool m_robustAVStreamingSupported
flag whether robust AV streaming is supported
Ptr< QosTxop > GetBKQueue() const
Accessor for the AC_BK channel access function.
void SetPromisc()
Sets the interface in promiscuous mode.
Ptr< VhtConfiguration > GetVhtConfiguration() const
void NotifyRxDrop(Ptr< const Packet > packet)
virtual void SetLinkUpCallback(Callback< void > linkUp)
Ptr< WifiRemoteStationManager > GetWifiRemoteStationManager(uint8_t linkId=0) const
const std::set< uint8_t > & GetLinkIds() const
void SetDevice(const Ptr< WifiNetDevice > device)
Sets the device this PHY is associated with.
void SetCtsToSelfSupported(bool enable)
Enable or disable CTS-to-self feature.
Mac48Address GetLocalAddress(const Mac48Address &remoteAddr) const
Get the local MAC address used to communicate with a remote STA.
EdcaQueues m_edca
This is a map from Access Category index to the corresponding channel access function.
uint32_t m_bkMaxAmpduSize
maximum A-MPDU size for AC_BK (in bytes)
bool GetHtSupported(uint8_t linkId) const
Return whether the device supports HT on the given link.
void ForwardUp(Ptr< const Packet > packet, Mac48Address from, Mac48Address to)
Forward the packet up to the device.
virtual void ConfigureContentionWindow(uint32_t cwMin, uint32_t cwMax)
bool Is6GhzBand(uint8_t linkId) const
Indicate if a given link is on the 6 GHz band.
virtual void Receive(Ptr< const WifiMpdu > mpdu, uint8_t linkId)
This method acts as the MacRxMiddle receive callback and is invoked to notify us that a frame has bee...
std::optional< std::reference_wrapper< const OriginatorBlockAckAgreement > > OriginatorAgreementOptConstRef
optional const reference to OriginatorBlockAckAgreement
Mac48Address GetAddress() const
ForwardUpCallback m_forwardUp
Callback to forward packet up the stack.
EhtCapabilities GetEhtCapabilities(uint8_t linkId) const
Return the EHT capabilities of the device for the given link.
Callback< void > m_linkUp
Callback when a link is up.
LinkEntity & GetLink(uint8_t linkId) const
Get a reference to the link associated with the given ID.
void SetupDcfQueue()
This method is a private utility invoked to configure the channel access function for devices that do...
void SetBeQueue(Ptr< QosTxop > edca)
Set the AC_BE channel access function This method is private so that it is only used while constructi...
HeCapabilities GetHeCapabilities(uint8_t linkId) const
Return the HE capabilities of the device for the given link.
virtual bool CanForwardPacketsTo(Mac48Address to) const =0
Return true if packets can be forwarded to the given destination, false otherwise.
virtual void SetWifiPhys(const std::vector< Ptr< WifiPhy > > &phys)
Callback< void, Ptr< const Packet >, Mac48Address, Mac48Address > ForwardUpCallback
This type defines the callback of a higher layer that a WifiMac(-derived) object invokes to pass a pa...
PsduResponseTimeoutTracedCallback m_psduResponseTimeoutCallback
PSDU response timeout traced callback.
Ptr< QosTxop > GetQosTxop(AcIndex ac) const
Accessor for a specified EDCA object.
void NotifyTxDrop(Ptr< const Packet > packet)
void DoDispose() override
Destructor implementation.
void SetRobustAVStreamingSupported(bool enable)
Enable or disable Robust AV Streaming support for the device.
uint32_t m_frameRetryLimit
the frame retry limit
bool GetDsssSupported(uint8_t linkId) const
Return whether the device supports DSSS on the given link.
Ptr< ChannelAccessManager > GetChannelAccessManager(uint8_t linkId=SINGLE_LINK_OP_ID) const
Get the Channel Access Manager associated with the given link.
void SetVoBlockAckInactivityTimeout(uint16_t timeout)
Set VO block ack inactivity timeout.
virtual std::unique_ptr< LinkEntity > CreateLinkEntity() const
Create a LinkEntity object.
void SetViQueue(Ptr< QosTxop > edca)
Set the AC_VI channel access function This method is private so that it is only used while constructi...
void SetShortSlotTimeSupported(bool enable)
Enable or disable short slot time feature.
bool m_ctsToSelfSupported
flag indicating whether CTS-To-Self is supported
uint16_t m_beMaxAmsduSize
maximum A-MSDU size for AC_BE (in bytes)
virtual Mac48Address DoGetLocalAddress(const Mac48Address &remoteAddr) const
This method is called if this device is an MLD to determine the MAC address of the affiliated STA use...
uint32_t m_viMaxAmpduSize
maximum A-MPDU size for AC_VI (in bytes)
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Ptr< const AttributeChecker > MakeBooleanChecker()
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Ptr< const AttributeChecker > MakeObjectVectorChecker()
ObjectPtrContainerValue ObjectVectorValue
ObjectVectorValue is an alias for ObjectPtrContainerValue.
Ptr< const AttributeAccessor > MakeObjectVectorAccessor(U T::*memberVariable)
MakeAccessorHelper implementation for ObjectVector.
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Ptr< AttributeChecker > MakePointerChecker()
Create a PointerChecker for a type.
Ptr< const AttributeChecker > MakeSsidChecker()
Ptr< const AttributeAccessor > MakeSsidAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Ptr< const AttributeChecker > MakeUintegerChecker()
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
#define NS_ABORT_UNLESS(cond)
Abnormal program termination if a condition is false.
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
#define NS_ABORT_IF(cond)
Abnormal program termination if a condition is true.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
TypeOfStation
Enumeration for type of WiFi station.
WifiStandard
Identifies the IEEE 802.11 specifications that a Wifi device can be configured to use.
AcIndex QosUtilsMapTidToAc(uint8_t tid)
Maps TID (Traffic ID) to Access classes.
WifiQueueBlockedReason
Enumeration of the reasons to block container queues.
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_PHY_BAND_2_4GHZ
The 2.4 GHz band.
@ WIFI_PHY_BAND_5GHZ
The 5 GHz band.
@ WIFI_MOD_CLASS_HT
HT (Clause 19)
@ WIFI_MOD_CLASS_EHT
EHT (Clause 36)
@ WIFI_MOD_CLASS_VHT
VHT (Clause 22)
@ WIFI_MOD_CLASS_HE
HE (Clause 27)
@ AC_UNDEF
Total number of ACs.
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...
double MHz_u
MHz weak type.
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
void Shuffle(RND_ACCESS_ITER first, RND_ACCESS_ITER last, Ptr< UniformRandomVariable > rv)
Shuffle the elements in the range first to last.
WifiDirection
Wifi direction.
std::tuple< WifiContainerQueueType, WifiRcvAddr, Mac48Address, std::optional< uint8_t > > WifiContainerQueueId
Tuple (queue type, receiver address type, Address, TID) identifying a container queue.
@ LOG_FUNCTION
Function tracing for non-trivial function calls.
Ptr< T1 > StaticCast(const Ptr< T2 > &p)
Cast a Ptr.
std::map< tid_t, std::set< linkId_t > > WifiTidLinkMapping
TID-indexed map of the link set to which the TID is mapped.
const std::map< AcIndex, WifiAc > wifiAcList
Map containing the four ACs in increasing order of priority (according to Table 10-1 "UP-to-AC Mappin...
Struct containing all supported rates.
The different BlockAckRequest variants.
The different BlockAck variants.
@ EHT_MCS_MAP_TYPE_320_MHZ
@ EHT_MCS_MAP_TYPE_20_MHZ_ONLY
@ EHT_MCS_MAP_TYPE_NOT_LARGER_THAN_80_MHZ
@ EHT_MCS_MAP_TYPE_160_MHZ
uint8_t support320MhzIn6Ghz
Support For 320 MHz In 6 GHz.
uint8_t supportTx1024And4096QamForRuSmallerThan242Tones
Tx 1024-QAM And 4096-QAM < 242-tone RU Support.
uint8_t supportRx1024And4096QamForRuSmallerThan242Tones
Rx 1024-QAM And 4096-QAM < 242-tone RU Support.
Structure holding information specific to a single link.
Ptr< WifiRemoteStationManager > stationManager
Remote station manager (rate control, RTS/CTS/fragmentation thresholds etc.)
Ptr< WifiPhy > phy
Wifi PHY object.
virtual ~LinkEntity()
Destructor (a virtual method is needed to make this struct polymorphic)
bool dsssSupported
set to true iff this WifiMac is to model 802.11b
bool erpSupported
set to true iff this WifiMac is to model 802.11g
Ptr< FrameExchangeManager > feManager
Frame Exchange Manager object.
Ptr< ChannelAccessManager > channelAccessManager
channel access manager object