22#undef NS_LOG_APPEND_CONTEXT 
   23#define NS_LOG_APPEND_CONTEXT WIFI_FEM_NS_LOG_APPEND_CONTEXT 
   28#define PSDU_DURATION_SAFEGUARD 400 
   41        TypeId(
"ns3::FrameExchangeManager")
 
   43            .AddConstructor<FrameExchangeManager>()
 
   45            .AddAttribute(
"ProtectedIfResponded",
 
   46                          "Whether a station is assumed to be protected if replied to a frame " 
   47                          "requiring acknowledgment. If a station is protected, subsequent " 
   48                          "transmissions to the same station in the same TXOP are not " 
   49                          "preceded by protection mechanisms.",
 
 
   62      m_moreFragments(false)
 
 
  205                                                         const std::vector<bool>&>());
 
 
  293                         << 
" (txVector: " << txVector << 
")");
 
  296                  "The TX timer and the NAV reset event cannot be both running");
 
 
  325    UpdateNav(macHdr, txVector, psduDuration);
 
 
  328std::optional<std::reference_wrapper<const FrameExchangeManager::OngoingRxInfo>>
 
  338std::optional<std::reference_wrapper<const WifiMacHeader>>
 
  341    if (
auto info = 
GetOngoingRxInfo(); info.has_value() && info->get().macHdr.has_value())
 
  343        return info->get().
macHdr.value();
 
 
  366    queue->WipeAllExpiredMpdus();
 
  380    NS_ASSERT(mpdu->GetHeader().IsData() || mpdu->GetHeader().IsMgt());
 
  383    if (!mpdu->IsFragment() && !mpdu->GetHeader().IsRetry())
 
  385        uint16_t sequence = 
m_txMiddle->GetNextSequenceNumberFor(&mpdu->GetHeader());
 
  386        mpdu->AssignSeqNo(sequence);
 
  389    NS_LOG_DEBUG(
"MPDU payload size=" << mpdu->GetPacketSize()
 
  390                                      << 
", to=" << mpdu->GetHeader().GetAddr1()
 
  391                                      << 
", seq=" << mpdu->GetHeader().GetSequenceControl());
 
 
  416    if (mpdu->IsFragment())
 
  431        item->GetHeader().SetMoreFragments();
 
  432        m_mac->GetTxopQueue(mpdu->GetQueueAc())->Replace(mpdu, item);
 
 
  509const std::set<Mac48Address>&
 
  534                    NS_LOG_DEBUG(
"Prepare groupcast MPDU for retry");
 
  535                    mpdu->ResetInFlight(m_linkId);
 
  537                    if (m_apMac->GetGcrManager()->UseConcealment(mpdu->GetHeader()))
 
  539                        mpdu->GetHeader().SetAddr1(mpdu->begin()->second.GetDestinationAddr());
 
  541                    mpdu->GetHeader().SetRetry();
 
  546                if (
m_apMac->GetGcrManager()->GetRetransmissionPolicy() ==
 
  554        else if (!
m_mpdu->GetHeader().IsQosData() ||
 
  568        m_mpdu->GetHeader().SetDuration(
 
  569            GetFrameDurationId(m_mpdu->GetHeader(),
 
  570                               GetPsduSize(m_mpdu, m_txParams.m_txVector),
 
  572                               m_fragmentedPacket));
 
  577        auto normalAcknowledgment = 
static_cast<WifiNormalAck*
>(m_txParams.m_acknowledgment.get());
 
  580            txDuration + m_phy->GetSifs() + m_phy->GetSlot() +
 
  585                      {m_mpdu->GetHeader().GetAddr1()},
 
  589                      m_txParams.m_txVector);
 
  590        m_channelAccessManager->NotifyAckTimeoutStartNow(
timeout);
 
  594        NS_ABORT_MSG(
"Unable to handle the selected acknowledgment method (" 
  595                     << m_txParams.m_acknowledgment.get() << 
")");
 
  599    ForwardMpduDown(m_mpdu, m_txParams.m_txVector);
 
  601    if (m_txTimer.IsRunning())
 
  604        m_sentFrameTo = {m_mpdu->GetHeader().GetAddr1()};
 
 
  613    auto psdu = Create<WifiPsdu>(mpdu, 
false);
 
  614    FinalizeMacHeader(psdu);
 
  616    const auto txDuration = WifiPhy::CalculateTxDuration(psdu, txVector, m_phy->GetPhyBand());
 
  617    SetTxNav(mpdu, txDuration);
 
  618    m_phy->Send(psdu, txVector);
 
 
  626    if (m_mac->GetTypeOfStation() != 
STA)
 
  631    auto pmMode = StaticCast<StaWifiMac>(m_mac)->GetPmMode(m_linkId);
 
  639            mpdu->GetHeader().SetNoPowerManagement();
 
  643            mpdu->GetHeader().SetPowerManagement();
 
 
  656    if (mpdu->IsQueued())
 
  658        m_mac->GetTxopQueue(mpdu->GetQueueAc())->DequeueIfQueued({mpdu});
 
 
  665    return mpdu->GetSize();
 
 
  674    if (protection->
method == WifiProtection::NONE)
 
  678    else if (protection->
method == WifiProtection::RTS_CTS)
 
  683                                         rtsCtsProtection->rtsTxVector,
 
  684                                         m_phy->GetPhyBand()) +
 
  686                                         rtsCtsProtection->ctsTxVector,
 
  687                                         m_phy->GetPhyBand()) +
 
  688            2 * m_phy->GetSifs();
 
  690    else if (protection->
method == WifiProtection::CTS_TO_SELF)
 
  695                                         ctsToSelfProtection->ctsTxVector,
 
  696                                         m_phy->GetPhyBand()) +
 
 
  707    if (acknowledgment->
method == WifiAcknowledgment::NONE)
 
  711    else if (acknowledgment->
method == WifiAcknowledgment::NORMAL_ACK)
 
  713        auto normalAcknowledgment = 
static_cast<WifiNormalAck*
>(acknowledgment);
 
  715            m_phy->GetSifs() + WifiPhy::CalculateTxDuration(
GetAckSize(),
 
  716                                                            normalAcknowledgment->ackTxVector,
 
  717                                                            m_phy->GetPhyBand());
 
 
  722FrameExchangeManager::GetTxDuration(
uint32_t ppduPayloadSize,
 
  726    return WifiPhy::CalculateTxDuration(ppduPayloadSize, txParams.
m_txVector, m_phy->GetPhyBand());
 
 
  741    NS_LOG_FUNCTION(
this << header << size << &txParams << fragmentedPacket);
 
  754            std::min(fragmentedPacket->GetSize() - nextFragmentOffset, payloadSize);
 
  756            GetWifiRemoteStationManager()->GetAckTxVector(header.
GetAddr1(), txParams.
m_txVector);
 
  758        durationId += 2 * m_phy->GetSifs() +
 
  759                      WifiPhy::CalculateTxDuration(
GetAckSize(), ackTxVector, m_phy->GetPhyBand()) +
 
  760                      WifiPhy::CalculateTxDuration(nextFragmentSize,
 
  762                                                   m_phy->GetPhyBand());
 
 
  775    ctsTxVector = GetWifiRemoteStationManager()->GetCtsTxVector(m_self, rtsTxVector.
GetMode());
 
  777    return m_phy->GetSifs() +
 
  778           WifiPhy::CalculateTxDuration(
GetCtsSize(), ctsTxVector, m_phy->GetPhyBand()) 
 
  779           + m_phy->GetSifs() + txDuration + response;
 
 
  789    const auto& hdr = txParams.
GetPsduInfoMap().begin()->second.header;
 
  806    rts.
SetDuration(GetRtsDurationId(rtsCtsProtection->rtsTxVector,
 
  809    Ptr<WifiMpdu> mpdu = Create<WifiMpdu>(Create<Packet>(), rts);
 
  815                                                rtsCtsProtection->rtsTxVector,
 
  816                                                m_phy->GetPhyBand()) +
 
  817                   m_phy->GetSifs() + m_phy->GetSlot() +
 
  818                   WifiPhy::CalculatePhyPreambleAndHeaderDuration(rtsCtsProtection->ctsTxVector);
 
  820    m_txTimer.Set(WifiTxTimer::WAIT_CTS,
 
  823                  &FrameExchangeManager::CtsTimeout,
 
  826                  rtsCtsProtection->rtsTxVector);
 
  827    m_channelAccessManager->NotifyCtsTimeoutStartNow(
timeout);
 
  829    m_sentRtsTo = {receiver};
 
  831    ForwardMpduDown(mpdu, rtsCtsProtection->rtsTxVector);
 
 
  849                    WifiPhy::CalculateTxDuration(
GetCtsSize(), ctsTxVector, m_phy->GetPhyBand());
 
  861    packet->AddPacketTag(tag);
 
  864    ForwardMpduDown(Create<WifiMpdu>(packet, cts), ctsTxVector);
 
 
  875        GetWifiRemoteStationManager()->GetCtsTxVector(rtsHdr.
GetAddr2(), rtsTxVector.
GetMode());
 
  876    DoSendCtsAfterRts(rtsHdr, ctsTxVector, rtsSnr);
 
 
  880FrameExchangeManager::GetCtsToSelfDurationId(
const WifiTxVector& ctsTxVector,
 
  886    return m_phy->GetSifs() + txDuration + response;
 
 
  903              txParams.
m_protection->method == WifiProtection::CTS_TO_SELF);
 
  908    cts.
SetDuration(GetCtsToSelfDurationId(ctsToSelfProtection->ctsTxVector,
 
  912    ForwardMpduDown(Create<WifiMpdu>(Create<Packet>(), cts), ctsToSelfProtection->ctsTxVector);
 
  915                                                    ctsToSelfProtection->ctsTxVector,
 
  916                                                    m_phy->GetPhyBand());
 
  917    Simulator::Schedule(ctsDuration, &FrameExchangeManager::ProtectionCompleted, 
this);
 
 
  928        GetWifiRemoteStationManager()->GetAckTxVector(hdr.
GetAddr2(), dataTxVector);
 
  939                    WifiPhy::CalculateTxDuration(
GetAckSize(), ackTxVector, m_phy->GetPhyBand());
 
  951    packet->AddPacketTag(tag);
 
  953    ForwardMpduDown(Create<WifiMpdu>(packet, ack), ackTxVector);
 
 
  957FrameExchangeManager::GetNextFragment()
 
  960    NS_ASSERT(m_mpdu->GetHeader().IsMoreFragments());
 
  966    uint32_t size = m_fragmentedPacket->GetSize() - startOffset;
 
  968    if (size > m_mpdu->GetPacketSize())
 
  971        size = m_mpdu->GetPacketSize();
 
  979    return Create<WifiMpdu>(m_fragmentedPacket->CreateFragment(startOffset, size), hdr);
 
 
  983FrameExchangeManager::TransmissionSucceeded()
 
  986    m_sentFrameTo.clear();
 
  992        NS_LOG_DEBUG(
"Schedule transmission of next fragment in a SIFS");
 
  993        Simulator::Schedule(m_phy->GetSifs(),
 
  994                            &FrameExchangeManager::StartTransmission,
 
  998        m_moreFragments = 
false;
 
 1002        NotifyChannelReleased(m_dcf);
 
 
 1008FrameExchangeManager::TransmissionFailed(
bool forceCurrentCw)
 
 1011    if (!forceCurrentCw)
 
 1013        m_dcf->UpdateFailedCw(m_linkId);
 
 1015    m_sentFrameTo.clear();
 
 1019    NotifyChannelReleased(m_dcf);
 
 
 1027    txop->NotifyChannelReleased(m_linkId);
 
 1028    m_protectedStas.clear();
 
 
 1036    const auto mpdusToDrop = GetWifiRemoteStationManager()->GetMpdusToDropOnTxFailure(psdu);
 
 1039    for (
const auto& mpdu : mpdusToDrop)
 
 1043        NotifyPacketDiscarded(mpdu);
 
 
 1055    GetWifiRemoteStationManager()->ReportDataFailed(mpdu);
 
 1056    if (
auto droppedMpdu = DropMpduIfRetryLimitReached(Create<WifiPsdu>(mpdu, 
false)))
 
 1059        GetWifiRemoteStationManager()->ReportFinalDataFailed(droppedMpdu);
 
 1064    if (mpdu->IsQueued())
 
 1066        mpdu = m_mac->GetTxopQueue(mpdu->GetQueueAc())->GetOriginal(mpdu);
 
 1067        mpdu->ResetInFlight(m_linkId);
 
 1068        mpdu->GetHeader().SetRetry();
 
 1069        RetransmitMpduAfterMissedAck(mpdu);
 
 1073    TransmissionFailed();
 
 
 1087    DoCtsTimeout(
WifiPsduMap{{SU_STA_ID, Create<WifiPsdu>(m_mpdu, 
true)}});
 
 
 1097    const auto updateCw = GetUpdateCwOnCtsTimeout();
 
 1098    const auto reportRts = GetReportRtsFailed();
 
 1100    m_sentRtsTo.clear();
 
 1101    for (
const auto& [staId, psdu] : psduMap)
 
 1105            if (mpdu->IsQueued())
 
 1107                mpdu->ResetInFlight(m_linkId);
 
 1111        if (
const auto& hdr = psdu->GetHeader(0);
 
 1116                GetWifiRemoteStationManager()->ReportRtsFailed(hdr);
 
 1119            if (
auto droppedMpdu = DropMpduIfRetryLimitReached(psdu))
 
 1121                GetWifiRemoteStationManager()->ReportFinalRtsFailed(droppedMpdu->GetHeader());
 
 1129        ReleaseSequenceNumbers(psdu);
 
 1132    TransmissionFailed(!updateCw);
 
 
 1136FrameExchangeManager::GetUpdateCwOnCtsTimeout()
 const 
 
 1142FrameExchangeManager::GetReportRtsFailed()
 const 
 
 1152    NS_ASSERT_MSG(psdu->GetNMpdus() == 1, 
"A-MPDUs should be handled by the HT FEM override");
 
 1153    auto mpdu = *psdu->begin();
 
 1159    if (!mpdu->GetHeader().IsRetry() && !mpdu->IsInFlight())
 
 1161        mpdu->UnassignSeqNo();
 
 1162        m_txMiddle->SetSequenceNumberFor(&mpdu->GetOriginal()->GetHeader());
 
 
 1167FrameExchangeManager::NotifyInternalCollision(
Ptr<Txop> txop)
 
 1175    Ptr<QosTxop> qosTxop = (txop->IsQosTxop() ? StaticCast<QosTxop>(txop) : 
nullptr);
 
 1178            (qosTxop ? qosTxop->PeekNextMpdu(m_linkId) : txop->GetWifiMacQueue()->Peek(m_linkId));
 
 1179        mpdu && !mpdu->GetHeader().GetAddr1().IsGroup())
 
 1181        if (mpdu->GetHeader().HasData())
 
 1183            GetWifiRemoteStationManager()->ReportDataFailed(mpdu);
 
 1186        if (DropMpduIfRetryLimitReached(Create<WifiPsdu>(mpdu, 
false)))
 
 1188            GetWifiRemoteStationManager()->ReportFinalDataFailed(mpdu);
 
 1192    txop->UpdateFailedCw(m_linkId);
 
 1193    txop->Txop::NotifyChannelReleased(m_linkId);
 
 
 1197FrameExchangeManager::NotifySwitchingStartNow(
Time duration)
 
 1199    NS_LOG_DEBUG(
"Switching channel. Cancelling MAC pending events");
 
 1200    Simulator::Schedule(duration, &WifiMac::NotifyChannelSwitching, m_mac, m_linkId);
 
 1201    if (m_txTimer.IsRunning())
 
 1206        m_txTimer.Reschedule(
Seconds(0));
 
 1208    Simulator::ScheduleNow(&FrameExchangeManager::Reset, 
this);
 
 
 1212FrameExchangeManager::NotifySleepNow()
 
 1214    NS_LOG_DEBUG(
"Device in sleep mode. Cancelling MAC pending events");
 
 
 1219FrameExchangeManager::NotifyOffNow()
 
 1221    NS_LOG_DEBUG(
"Device is switched off. Cancelling MAC pending events");
 
 
 1235                              const std::vector<bool>& perMpduStatus)
 
 1238        this << psdu << rxSignalInfo << txVector << perMpduStatus.size()
 
 1239             << std::all_of(perMpduStatus.begin(), perMpduStatus.end(), [](
bool v) { return v; }));
 
 1241    if (!perMpduStatus.empty())
 
 1244        PreProcessFrame(psdu, txVector);
 
 1249    if (addr1.
IsGroup() || addr1 == m_self)
 
 1252        if (psdu->GetNMpdus() == 1)
 
 1257            NS_ASSERT(perMpduStatus.empty() || (perMpduStatus.size() == 1 && perMpduStatus[0]));
 
 1259            if (
const auto& hdr = psdu->GetHeader(0); !hdr.IsAck() && !hdr.IsCts())
 
 1261                GetWifiRemoteStationManager()->ReportRxOk(psdu->GetAddr2(), rxSignalInfo, txVector);
 
 1263            ReceiveMpdu(*(psdu->begin()), rxSignalInfo, txVector, perMpduStatus.empty());
 
 1267            EndReceiveAmpdu(psdu, rxSignalInfo, txVector, perMpduStatus);
 
 1274            if (!mpdu->GetHeader().IsCtl())
 
 1276                m_rxMiddle->Receive(mpdu, m_linkId);
 
 1281    if (!perMpduStatus.empty())
 
 1284        PostProcessFrame(psdu, txVector);
 
 
 1299    UpdateNav(psdu->GetHeader(0), txVector);
 
 
 1305                                const Time& surplus)
 
 1316    duration += surplus;
 
 1327    Time navEnd = Simulator::Now() + duration;
 
 1328    if (navEnd > m_navEnd)
 
 1346                GetWifiRemoteStationManager()->GetCtsTxVector(addr2, txVector.
GetMode());
 
 1347            Time navResetDelay =
 
 1348                2 * m_phy->GetSifs() +
 
 1349                WifiPhy::CalculateTxDuration(
GetCtsSize(), ctsTxVector, m_phy->GetPhyBand()) +
 
 1350                WifiPhy::CalculatePhyPreambleAndHeaderDuration(ctsTxVector) + 2 * m_phy->GetSlot();
 
 1351            m_navResetEvent.Cancel();
 
 1353                Simulator::Schedule(navResetDelay, &FrameExchangeManager::NavResetTimeout, 
this);
 
 1358    m_channelAccessManager->NotifyNavStartNow(duration);
 
 
 1362FrameExchangeManager::NavResetTimeout()
 
 1365    m_navEnd = Simulator::Now();
 
 1366    m_channelAccessManager->NotifyNavResetNow(
Seconds(0));
 
 
 1377    if (!mpdu->GetHeader().IsPsPoll())
 
 1379        const auto txNav = Simulator::Now() + txDuration + mpdu->GetHeader().GetDuration();
 
 1380        NS_LOG_DEBUG(
"Setting TXNAV to " << txNav.As(Time::S));
 
 1381        m_txNav = 
Max(m_txNav, txNav);
 
 
 1386FrameExchangeManager::ResetTxNav()
 
 1389    m_txNav = Simulator::Now();
 
 
 1393FrameExchangeManager::VirtualCsMediumIdle()
 const 
 1395    return m_navEnd <= Simulator::Now();
 
 
 1404    NS_LOG_FUNCTION(
this << *mpdu << rxSignalInfo << txVector << inAmpdu);
 
 1406    NS_ASSERT(mpdu->GetHeader().GetAddr1().IsGroup() || mpdu->GetHeader().GetAddr1() == m_self);
 
 1408    double rxSnr = rxSignalInfo.
snr;
 
 1421            if (VirtualCsMediumIdle())
 
 1424                m_sendCtsEvent = Simulator::Schedule(m_phy->GetSifs(),
 
 1425                                                     &FrameExchangeManager::SendCtsAfterRts,
 
 1436        else if (hdr.
IsCts() && m_txTimer.IsRunning() &&
 
 1437                 m_txTimer.GetReason() == WifiTxTimer::WAIT_CTS && m_mpdu)
 
 1446            mpdu->GetPacket()->PeekPacketTag(tag);
 
 1447            GetWifiRemoteStationManager()->ReportRxOk(sender, rxSignalInfo, txVector);
 
 1448            GetWifiRemoteStationManager()->ReportRtsOk(m_mpdu->GetHeader(),
 
 1454            m_channelAccessManager->NotifyCtsTimeoutResetNow();
 
 1455            ProtectionCompleted();
 
 1457        else if (hdr.
IsAck() && m_mpdu && m_txTimer.IsRunning() &&
 
 1458                 m_txTimer.GetReason() == WifiTxTimer::WAIT_NORMAL_ACK)
 
 1462            mpdu->GetPacket()->PeekPacketTag(tag);
 
 1463            ReceivedNormalAck(m_mpdu, m_txParams.m_txVector, txVector, rxSignalInfo, tag.
Get());
 
 1467    else if (hdr.
IsMgt())
 
 1469        NS_ABORT_MSG_IF(inAmpdu, 
"Received management frame as part of an A-MPDU");
 
 1477            packet->AddPacketTag(tag);
 
 1478            mpdu = Create<WifiMpdu>(packet, hdr);
 
 1484                                     << 
", schedule ACK");
 
 1485            Simulator::Schedule(m_phy->GetSifs(),
 
 1486                                &FrameExchangeManager::SendNormalAck,
 
 1493        m_rxMiddle->Receive(mpdu, m_linkId);
 
 1500                                     << 
", schedule ACK");
 
 1501            Simulator::Schedule(m_phy->GetSifs(),
 
 1502                                &FrameExchangeManager::SendNormalAck,
 
 1509        m_rxMiddle->Receive(mpdu, m_linkId);
 
 
 1522    m_txTimer.GotResponseFrom(sender);
 
 1524    NotifyReceivedNormalAck(mpdu);
 
 1527    if (!mpdu->GetHeader().IsMoreFragments())
 
 1529        GetWifiRemoteStationManager()->ReportRxOk(sender, rxInfo, ackTxVector);
 
 1530        GetWifiRemoteStationManager()->ReportDataOk(mpdu,
 
 1538    m_channelAccessManager->NotifyAckTimeoutResetNow();
 
 1542    m_dcf->ResetCw(m_linkId);
 
 1544    if (mpdu->GetHeader().IsMoreFragments())
 
 1547        m_dcf->GetWifiMacQueue()->Replace(mpdu, GetNextFragment());
 
 1548        m_moreFragments = 
true;
 
 1556    TransmissionSucceeded();
 
 
 1565    if (!m_ackedMpduCallback.IsNull())
 
 1567        m_ackedMpduCallback(mpdu);
 
 
 1575                                      const std::vector<bool>& perMpduStatus)
 
 1577    NS_ASSERT_MSG(
false, 
"A non-QoS station should not receive an A-MPDU");
 
 
 1583    NS_ASSERT_MSG(
false, 
"A non-QoS station should not use GCR-UR");
 
 
AttributeValue implementation for Boolean.
bool IsNull() const
Check for null implementation.
void Cancel()
This method is syntactic sugar for the ns3::Simulator::Cancel method.
bool IsPending() const
This method is syntactic sugar for !IsExpired().
std::set< Mac48Address > m_sentRtsTo
the STA(s) which we sent an RTS to (waiting for CTS)
Ptr< WifiMpdu > m_mpdu
the MPDU being transmitted
virtual void SetAckManager(Ptr< WifiAckManager > ackManager)
Set the Acknowledgment Manager to use.
virtual void NotifyLastGcrUrTx(Ptr< const WifiMpdu > mpdu)
Notify the last (re)transmission of a groupcast MPDU using the GCR-UR service.
static TypeId GetTypeId()
Get the type ID.
uint8_t m_linkId
the ID of the link this object is associated with
Ptr< WifiMac > m_mac
the MAC layer on this station
DroppedMpdu m_droppedMpduCallback
the dropped MPDU callback
bool m_protectedIfResponded
whether a STA is assumed to be protected if replied to a frame requiring acknowledgment
virtual void SetWifiMac(const Ptr< WifiMac > mac)
Set the MAC layer to use.
virtual void ResetPhy()
Remove WifiPhy associated with this FrameExchangeManager.
void SendMpduWithProtection(Ptr< WifiMpdu > mpdu, WifiTxParameters &txParams)
Send an MPDU with the given TX parameters (with the specified protection).
Ptr< WifiAckManager > m_ackManager
Acknowledgment manager.
Ptr< WifiRemoteStationManager > GetWifiRemoteStationManager() const
void UpdateTxDuration(Mac48Address receiver, WifiTxParameters &txParams) const
Update the TX duration field of the given TX parameters after that the PSDU addressed to the given re...
virtual void CalculateAcknowledgmentTime(WifiAcknowledgment *acknowledgment) const
Calculate the time required to acknowledge a frame according to the given acknowledgment method.
Ptr< MacTxMiddle > m_txMiddle
the MAC TX Middle on this station
Ptr< Packet > m_fragmentedPacket
the MSDU being fragmented
virtual void SetDroppedMpduCallback(DroppedMpdu callback)
Set the callback to invoke when an MPDU is dropped.
virtual void Reset()
Reset this frame exchange manager.
Mac48Address m_self
the MAC address of this device
virtual void StartProtection(const WifiTxParameters &txParams)
Start the protection mechanism indicated by the given TX parameters.
virtual void NotifyPacketDiscarded(Ptr< const WifiMpdu > mpdu)
Pass the given MPDU, discarded because of the max retry limit was reached, to the MPDU dropped callba...
std::optional< std::reference_wrapper< const WifiMacHeader > > GetReceivedMacHdr() const
WifiTxTimer m_txTimer
the timer set upon frame transmission
std::set< Mac48Address > m_protectedStas
STAs that have replied to an RTS in this TXOP.
Mac48Address GetAddress() const
Get the MAC address.
Ptr< WifiProtectionManager > m_protectionManager
Protection manager.
OngoingRxInfo m_ongoingRxInfo
information about the MAC header of the MPDU being received
virtual void ProtectionCompleted()
Transmit prepared frame immediately, if no protection was used, or in a SIFS, if protection was compl...
virtual void SetLinkId(uint8_t linkId)
Set the ID of the link this Frame Exchange Manager is associated with.
void SendRts(const WifiTxParameters &txParams)
Send RTS to begin RTS-CTS-Data-Ack transaction.
virtual void NotifyChannelReleased(Ptr< Txop > txop)
Notify the given Txop that channel has been released.
virtual void NormalAckTimeout(Ptr< WifiMpdu > mpdu, const WifiTxVector &txVector)
Called when the Ack timeout expires.
virtual void SetBssid(Mac48Address bssid)
Set the Basic Service Set Identification.
void SendCtsToSelf(const WifiTxParameters &txParams)
Send CTS for a CTS-to-self mechanism.
virtual void ReceivedMacHdr(const WifiMacHeader &macHdr, const WifiTxVector &txVector, Time psduDuration)
Store information about the MAC header of the MPDU being received.
std::optional< std::reference_wrapper< const OngoingRxInfo > > GetOngoingRxInfo() const
virtual void SetAddress(Mac48Address address)
Set the MAC address.
Ptr< WifiAckManager > GetAckManager() const
Get the Acknowledgment Manager used by this node.
virtual void DequeueMpdu(Ptr< const WifiMpdu > mpdu)
Dequeue the given MPDU from the queue in which it is stored.
const std::set< Mac48Address > & GetProtectedStas() const
Ptr< WifiProtectionManager > GetProtectionManager() const
Get the Protection Manager used by this node.
bool IsPromisc() const
Check if the device is operating in promiscuous mode.
void SendMpdu()
Send the current MPDU, which can be acknowledged by a Normal Ack.
Ptr< MacRxMiddle > m_rxMiddle
the MAC RX Middle on this station
virtual void TransmissionSucceeded()
Take necessary actions upon a transmission success.
Ptr< Txop > m_dcf
the DCF/EDCAF that gained channel access
EventId m_sendCtsEvent
the event to send a CTS after an (MU-)RTS
Ptr< WifiPhy > m_phy
the PHY layer on this station
Ptr< WifiMpdu > GetFirstFragmentIfNeeded(Ptr< WifiMpdu > mpdu)
Fragment the given MPDU if needed.
void SetAckedMpduCallback(AckedMpdu callback)
Set the callback to invoke when an MPDU is successfully acked.
~FrameExchangeManager() override
Ptr< ApWifiMac > m_apMac
AP MAC layer pointer (null if not an AP)
Mac48Address m_bssid
BSSID address (Mac48Address)
virtual void SetWifiPhy(const Ptr< WifiPhy > phy)
Set the PHY layer to use.
void Receive(Ptr< const WifiPsdu > psdu, RxSignalInfo rxSignalInfo, const WifiTxVector &txVector, const std::vector< bool > &perMpduStatus)
This method is intended to be called by the PHY layer every time an MPDU is received and also when th...
AckedMpdu m_ackedMpduCallback
the acknowledged MPDU callback
virtual uint32_t GetPsduSize(Ptr< const WifiMpdu > mpdu, const WifiTxVector &txVector) const
Get the size in bytes of the given MPDU, which is to be transmitted with the given TXVECTOR.
Ptr< ChannelAccessManager > m_channelAccessManager
the channel access manager
bool m_promisc
Flag if the device is operating in promiscuous mode.
virtual void SetChannelAccessManager(const Ptr< ChannelAccessManager > channelAccessManager)
Set the channel access manager to use.
virtual bool StartTransmission(Ptr< Txop > dcf, MHz_u allowedWidth)
Request the FrameExchangeManager to start a frame exchange sequence.
void SetPromisc()
Enable promiscuous mode.
MHz_u m_allowedWidth
the allowed width for the current transmission
MHz_u GetAllowedWidth() const
virtual void PsduRxError(Ptr< const WifiPsdu > psdu)
This method is called when the reception of a PSDU fails.
Time m_navEnd
NAV expiration time.
virtual void UpdateNav(const WifiMacHeader &hdr, const WifiTxVector &txVector, const Time &surplus=Time{0})
Update the NAV, if needed, based on the Duration/ID of the given MAC header and the given surplus.
virtual void SetMacTxMiddle(const Ptr< MacTxMiddle > txMiddle)
Set the MAC TX Middle to use.
virtual void SetMacRxMiddle(const Ptr< MacRxMiddle > rxMiddle)
Set the MAC RX Middle to use.
virtual void SetProtectionManager(Ptr< WifiProtectionManager > protectionManager)
Set the Protection Manager to use.
Mac48Address GetBssid() const
Get the Basic Service Set Identification.
Ptr< StaWifiMac > m_staMac
STA MAC layer pointer (null if not a STA)
void DoDispose() override
Destructor implementation.
WifiTxParameters m_txParams
the TX parameters for the current frame
virtual void RxStartIndication(WifiTxVector txVector, Time psduDuration)
EventId m_navResetEvent
the event to reset the NAV after an RTS
const WifiTxTimer & GetWifiTxTimer() const
Get a const reference to the WifiTxTimer object.
bool TraceConnectWithoutContext(std::string name, const CallbackBase &cb)
Connect a TraceSource to a Callback without a context.
bool TraceDisconnectWithoutContext(std::string name, const CallbackBase &cb)
Disconnect from a TraceSource a Callback previously connected without a context.
A base class which provides memory management and object aggregation.
virtual void DoDispose()
Destructor implementation.
Ptr< Packet > CreateFragment(uint32_t start, uint32_t length) const
Create a new packet which contains a fragment of the original packet.
Smart pointer class similar to boost::intrusive_ptr.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
static Time Now()
Return the current simulation virtual time.
Introspection did not find any typical Config paths.
void Set(double snr)
Set the SNR to the given value.
double Get() const
Return the SNR value.
Simulation virtual time values and global simulation resolution.
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
bool IsStrictlyPositive() const
Exactly equivalent to t > 0.
bool IsStrictlyNegative() const
Exactly equivalent to t < 0.
virtual void NotifyChannelAccessed(uint8_t linkId, Time txopDuration=Seconds(0))
Called by the FrameExchangeManager to notify that channel access has been granted on the given link f...
a unique identifier for an interface.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
static void SetQosAckPolicy(Ptr< WifiMpdu > item, const WifiAcknowledgment *acknowledgment)
Set the QoS Ack policy for the given MPDU, which must be a QoS data frame.
Time GetSifs() const
Return the Short Interframe Space (SIFS) for this PHY.
void SetReceiveErrorCallback(RxErrorCallback callback)
static Time CalculateTxDuration(uint32_t size, const WifiTxVector &txVector, WifiPhyBand band, uint16_t staId=SU_STA_ID)
Ptr< WifiPhyStateHelper > GetState() const
Return the WifiPhyStateHelper of this PHY.
WifiPhyBand GetPhyBand() const
Get the configured Wi-Fi band.
void SetReceiveOkCallback(RxOkCallback callback)
static Time CalculatePhyPreambleAndHeaderDuration(const WifiTxVector &txVector)
This class stores the TX parameters (TX vector, protection mechanism, acknowledgment mechanism,...
std::optional< Time > m_txDuration
TX duration of the frame.
const PsduInfoMap & GetPsduInfoMap() const
Get a const reference to the map containing information about PSDUs.
std::unique_ptr< WifiProtection > m_protection
protection method
uint32_t GetSize(Mac48Address receiver) const
Get the size in bytes of the (A-)MPDU addressed to the given receiver.
std::unique_ptr< WifiAcknowledgment > m_acknowledgment
acknowledgment method
WifiTxVector m_txVector
TXVECTOR of the frame being prepared.
void AddMpdu(Ptr< const WifiMpdu > mpdu)
Record that an MPDU is being added to the current frame.
void Clear()
Reset the TX parameters.
This class is used to handle the timer that a station starts when transmitting a frame that solicits ...
bool IsRunning() const
Return true if the timer is running.
void Cancel()
Cancel the timer.
void Reschedule(const Time &delay)
Reschedule the timer to time out the given amount of time from the moment this function is called.
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
WifiMode GetMode(uint16_t staId=SU_STA_ID) const
If this TX vector is associated with an SU PPDU, return the selected payload transmission mode.
MHz_u GetChannelWidth() const
#define PSDU_DURATION_SAFEGUARD
#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.
Callback< R, Args... > MakeNullCallback()
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
#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_NOARGS()
Output the name of the function.
#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 NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Time Seconds(double value)
Construct a Time in the indicated unit.
@ WIFI_MAC_DROP_REACHED_RETRY_LIMIT
@ WIFI_PM_SWITCHING_TO_ACTIVE
@ WIFI_PM_SWITCHING_TO_PS
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...
uint32_t GetRtsSize()
Return the total RTS size (including FCS trailer).
double MHz_u
MHz weak type.
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
std::unordered_map< uint16_t, Ptr< WifiPsdu > > WifiPsduMap
Map of PSDUs indexed by STA-ID.
uint32_t GetAckSize()
Return the total Ack size (including FCS trailer).
uint32_t GetCtsSize()
Return the total CTS size (including FCS trailer).
Mac48Address GetIndividuallyAddressedRecipient(Ptr< WifiMac > mac, const WifiMacHeader &hdr)
Get the MAC address of the individually addressed recipient to use for a given packet.
Time endOfPsduRx
time when reception of PSDU ends
std::optional< WifiMacHeader > macHdr
MAC header of the MPDU being received.
RxSignalInfo structure containing info on the received signal.
double snr
SNR in linear scale.
WifiAcknowledgment is an abstract base struct.
const Method method
acknowledgment method
std::optional< Time > acknowledgmentTime
time required by the acknowledgment method
WifiCtsToSelfProtection specifies that CTS-to-self protection method is used.
WifiNormalAck specifies that acknowledgment via Normal Ack is required.
WifiProtection is an abstract base struct.
std::optional< Time > protectionTime
time required by the protection method
const Method method
protection method
WifiRtsCtsProtection specifies that RTS/CTS protection method is used.