22 #include "ns3/abort.h" 32 #undef NS_LOG_APPEND_CONTEXT 33 #define NS_LOG_APPEND_CONTEXT std::clog << "[mac=" << m_self << "] " 38 #define PSDU_DURATION_SAFEGUARD 400 51 .AddConstructor<FrameExchangeManager> ()
52 .SetGroupName (
"Wifi")
60 m_moreFragments (false)
208 m_mac->NotifyTxDrop (mpdu->GetPacket ());
215 <<
" (txVector: " << txVector <<
")");
217 if (psduDuration.
IsZero ())
226 "The TX timer and the NAV reset event cannot be both running");
259 if (queue->IsEmpty ())
289 txParams.
m_txVector =
m_mac->GetWifiRemoteStationManager ()->GetDataTxVector (mpdu->GetHeader ());
310 else if (
m_mac->GetWifiRemoteStationManager ()->NeedFragmentation (mpdu))
404 NS_ABORT_MSG (
"Unable to handle the selected acknowledgment method (" 426 m_phy->
Send (Create<WifiPsdu> (mpdu,
false), txVector);
509 NS_LOG_FUNCTION (
this << header << size << &txParams << fragmentedPacket);
520 uint32_t nextFragmentSize =
std::min (fragmentedPacket->
GetSize () - nextFragmentOffset,
538 ctsTxVector =
m_mac->GetWifiRemoteStationManager ()->GetCtsTxVector (
m_self, rtsTxVector.
GetMode ());
627 Time txDuration,
Time response)
const 711 hdr.SetMoreFragments ();
715 hdr.SetNoMoreFragments ();
730 NS_LOG_DEBUG (
"Schedule transmission of next fragment in a SIFS");
755 m_mac->GetWifiRemoteStationManager ()->ReportDataFailed (mpdu);
757 if (!
m_mac->GetWifiRemoteStationManager ()->NeedRetransmission (mpdu))
761 m_mac->GetWifiRemoteStationManager ()->ReportFinalDataFailed (mpdu);
793 if (!
m_mac->GetWifiRemoteStationManager ()->NeedRetransmission (
m_mpdu))
830 NS_LOG_DEBUG (
"Switching channel. Cancelling MAC pending events");
831 m_mac->GetWifiRemoteStationManager ()->Reset ();
838 NS_LOG_DEBUG (
"Device in sleep mode. Cancelling MAC pending events");
845 NS_LOG_DEBUG (
"Device is switched off. Cancelling MAC pending events");
853 NS_LOG_FUNCTION (
this << psdu << rxSignalInfo << txVector << perMpduStatus.size ()
854 << std::all_of (perMpduStatus.begin(), perMpduStatus.end(), [](
bool v) {
return v; }));
856 if (!perMpduStatus.empty ())
866 if (
m_promisc && psdu->GetNMpdus () == 1 && psdu->GetHeader (0).IsData ())
873 if (psdu->GetNMpdus () == 1)
878 NS_ASSERT (perMpduStatus.empty () || (perMpduStatus.size () == 1 && perMpduStatus[0]));
880 if (!psdu->GetHeader (0).IsAck () && !psdu->GetHeader (0).IsCts ())
882 m_mac->GetWifiRemoteStationManager ()->ReportRxOk (psdu->GetHeader (0).GetAddr2 (),
883 rxSignalInfo, txVector.
GetMode ());
885 ReceiveMpdu (*(psdu->begin ()), rxSignalInfo, txVector, perMpduStatus.empty ());
968 NS_LOG_FUNCTION (
this << *mpdu << rxSignalInfo << txVector << inAmpdu);
974 double rxSnr = rxSignalInfo.
snr;
988 NS_LOG_DEBUG (
"Received RTS from=" << hdr.GetAddr2 () <<
", schedule CTS");
990 this, hdr, txVector.
GetMode (), rxSnr);
994 NS_LOG_DEBUG (
"Received RTS from=" << hdr.GetAddr2 () <<
", cannot schedule CTS");
1008 m_mac->GetWifiRemoteStationManager ()->ReportRxOk (sender, rxSignalInfo, txVector.
GetMode ());
1026 else if (hdr.IsMgt ())
1028 NS_ABORT_MSG_IF (inAmpdu,
"Received management frame as part of an A-MPDU");
1030 if (hdr.IsBeacon () || hdr.IsProbeResp ())
1037 mpdu = Create<WifiMacQueueItem> (packet, hdr);
1040 if (hdr.GetAddr1 () ==
m_self)
1042 NS_LOG_DEBUG (
"Received " << hdr.GetTypeString () <<
" from=" << hdr.GetAddr2 () <<
", schedule ACK");
1044 this, hdr, txVector, rxSnr);
1049 else if (hdr.IsData () && !hdr.IsQosData ())
1051 if (hdr.GetAddr1 () ==
m_self)
1053 NS_LOG_DEBUG (
"Received " << hdr.GetTypeString () <<
" from=" << hdr.GetAddr2 () <<
", schedule ACK");
1055 this, hdr, txVector, rxSnr);
1075 m_mac->GetWifiRemoteStationManager ()->ReportRxOk (sender, rxSignalInfo, ackTxVector.
GetMode ());
1076 m_mac->GetWifiRemoteStationManager ()->ReportDataOk (mpdu, rxSignalInfo.
snr, ackTxVector.
GetMode (), snr, txVector);
1108 const WifiTxVector& txVector,
const std::vector<bool>& perMpduStatus)
1110 NS_ASSERT_MSG (
false,
"A non-QoS station should not receive an A-MPDU");
void NormalAckTimeout(Ptr< WifiMacQueueItem > mpdu)
Called when the Ack timeout expires.
void Set(double snr)
Set the SNR to the given value.
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
TimeWithUnit As(const enum Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Simulation virtual time values and global simulation resolution.
virtual void ReceivedNormalAck(Ptr< WifiMacQueueItem > mpdu, const WifiTxVector &txVector, const WifiTxVector &ackTxVector, RxSignalInfo rxSignalInfo, double snr)
Perform the actions needed when a Normal Ack is received.
bool m_moreFragments
true if a fragment has to be sent after a SIFS
Smart pointer class similar to boost::intrusive_ptr.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
#define PSDU_DURATION_SAFEGUARD
virtual void DequeueMpdu(Ptr< WifiMacQueueItem > mpdu)
Dequeue the given MPDU from the queue in which it is stored.
void SendCtsToSelf(const WifiTxParameters &txParams)
Send CTS for a CTS-to-self mechanism.
WifiTxTimer m_txTimer
the timer set upon frame transmission
virtual void SetProtectionManager(Ptr< WifiProtectionManager > protectionManager)
Set the Protection Manager to use.
bool IsPromisc(void) const
Check if the device is operating in promiscuous mode.
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
void SendMpduWithProtection(Ptr< WifiMacQueueItem > mpdu, WifiTxParameters &txParams)
Send an MPDU with the given TX parameters (with the specified protection).
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
virtual void SetAddress(Mac48Address address)
Set the MAC address.
Ptr< WifiProtectionManager > GetProtectionManager(void) const
Get the Protection Manager used by this node.
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Ptr< WifiPhy > m_phy
the PHY layer on this station
static Time Min()
Minimum representable Time Not to be confused with Min(Time,Time).
Ptr< Packet > m_fragmentedPacket
the MSDU being fragmented
WifiPhyBand GetPhyBand(void) const
Get the configured Wi-Fi band.
std::unique_ptr< WifiProtection > m_protection
protection method
uint32_t GetRtsSize(void)
Return the total RTS size (including FCS trailer).
void SetPromisc(void)
Enable promiscuous mode.
uint32_t GetSize(void) const
Return the size of the packet stored by this item, including header size and trailer size...
void Clear(void)
Reset the TX parameters.
Time acknowledgmentTime
time required by the acknowledgment method
WifiAcknowledgment is an abstract base struct.
Ptr< WifiMacQueueItem > m_mpdu
the MPDU being transmitted
Ptr< Packet > CreateFragment(uint32_t start, uint32_t length) const
Create a new packet which contains a fragment of the original packet.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
virtual void PreProcessFrame(Ptr< const WifiPsdu > psdu, const WifiTxVector &txVector)
Perform actions that are possibly needed when receiving any frame, independently of whether the frame...
Time GetTimeStamp(void) const
Get the timestamp included in this item.
Information needed to remove an MSDU from the queue.
static const uint16_t WIFI_MAC_FCS_LENGTH
The length in octects of the IEEE 802.11 MAC FCS field.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
ConstIterator it
iterator pointing to the MSDU in the queue
virtual void ForwardMpduDown(Ptr< WifiMacQueueItem > mpdu, WifiTxVector &txVector)
Forward an MPDU down to the PHY layer.
WifiTxVector ackTxVector
Ack TXVECTOR.
WifiTxVector ctsTxVector
CTS TXVECTOR.
virtual void CalculateProtectionTime(WifiProtection *protection) const
Calculate the time required to protect a frame according to the given protection method.
bool m_promisc
Flag if the device is operating in promiscuous mode.
bool IsStrictlyPositive(void) const
Exactly equivalent to t > 0.
uint32_t GetAckSize(void)
Return the total Ack size (including FCS trailer).
virtual void CtsTimeout(void)
Called when the CTS timeout expires.
virtual void DoDispose(void)
Destructor implementation.
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
Time m_txDuration
TX duration of the frame.
void NotifySwitchingStartNow(Time duration)
Ptr< ChannelAccessManager > m_channelAccessManager
the channel access manager
Callback< R, Ts... > MakeNullCallback(void)
virtual void DoDispose()
Destructor implementation.
Ptr< WifiMacQueueItem > Dequeue(void)
Dequeue the packet in the front of the queue.
virtual void TransmissionFailed(void)
Take necessary actions upon a transmission failure.
WifiTxVector rtsTxVector
RTS TXVECTOR.
represent a single transmission modeA WifiMode is implemented by a single integer which is used to lo...
const Method method
acknowledgment method
virtual void CalculateAcknowledgmentTime(WifiAcknowledgment *acknowledgment) const
Calculate the time required to acknowledge a frame according to the given acknowledgment method...
virtual void ResetPhy(void)
Remove WifiPhy associated with this MacLow.
Ptr< WifiAckManager > GetAckManager(void) const
Get the Acknowledgment Manager used by this node.
double Get(void) const
Return the SNR value.
Ptr< RegularWifiMac > m_mac
the MAC layer on this station
virtual void SetMacRxMiddle(const Ptr< MacRxMiddle > rxMiddle)
Set the MAC RX Middle to use.
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...
Ptr< WifiMacQueueItem > GetFirstFragmentIfNeeded(Ptr< WifiMacQueueItem > mpdu)
Fragment the given MPDU if needed.
static Time CalculateTxDuration(uint32_t size, const WifiTxVector &txVector, WifiPhyBand band, uint16_t staId=SU_STA_ID)
const PsduInfoMap & GetPsduInfoMap(void) const
Get a const reference to the map containing information about PSDUs.
void UpdateFailedCw(void)
Update the value of the CW variable to take into account a transmission failure.
virtual void SetAckManager(Ptr< WifiAckManager > ackManager)
Set the Acknowledgment Manager to use.
RxSignalInfo structure containing info on the received signal.
Mac48Address m_bssid
BSSID address (Mac48Address)
const WifiMacHeader & GetHeader(void) const
Get the header stored in this item.
virtual Time GetFrameDurationId(const WifiMacHeader &header, uint32_t size, const WifiTxParameters &txParams, Ptr< Packet > fragmentedPacket) const
Compute how to set the Duration/ID field of a frame being transmitted with the given TX parameters...
void Receive(Ptr< WifiPsdu > psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, 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...
void Set(Reason reason, const Time &delay, MEM mem_ptr, OBJ obj, Args... args)
This method is called when a frame soliciting a response is transmitted.
bool IsZero(void) const
Exactly equivalent to t == 0.
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Reason GetReason(void) const
Get the reason why the timer was started.
virtual void UpdateNav(Ptr< const WifiPsdu > psdu, const WifiTxVector &txVector)
Update the NAV, if needed, based on the Duration/ID of the given psdu.
virtual void SetMacTxMiddle(const Ptr< MacTxMiddle > txMiddle)
Set the MAC TX Middle to use.
void NotifyOffNow(void)
This method is typically invoked by the PhyMacLowListener to notify the MAC layer that the device has...
EventId m_navResetEvent
the event to reset the NAV after an RTS
virtual void SetChannelAccessManager(const Ptr< ChannelAccessManager > channelAccessManager)
Set the channel access manager to use.
virtual void NotifyChannelReleased(void)
Called by the FrameExchangeManager to notify the completion of the transmissions. ...
virtual bool StartTransmission(Ptr< Txop > dcf)
Request the FrameExchangeManager to start a frame exchange sequence.
bool TraceDisconnectWithoutContext(std::string name, const CallbackBase &cb)
Disconnect from a TraceSource a Callback previously connected without a context.
virtual Time GetRtsDurationId(const WifiTxVector &rtsTxVector, Time txDuration, Time response) const
Compute how to set the Duration/ID field of an RTS frame to send to protect a frame transmitted with ...
Time GetDuration(void) const
Get the duration from the Duration/ID field, which is common to all the MPDUs.
Ptr< WifiAckManager > m_ackManager
Acknowledgment manager.
Time protectionTime
time required by the protection method
const WifiMacHeader & GetHeader(std::size_t i) const
Get the header of the i-th MPDU.
virtual void NotifyPacketDiscarded(Ptr< const WifiMacQueueItem > mpdu)
Pass the packet included in the given MPDU to the packet dropped callback.
Mac48Address m_self
the MAC address of this device
WifiProtection is an abstract base struct.
Ptr< const Packet > GetPacket(void) const
Get the packet stored in this item.
bool TraceConnectWithoutContext(std::string name, const CallbackBase &cb)
Connect a TraceSource to a Callback without a context.
bool IsFragment(void) const
Return true if this item contains an MSDU fragment, false otherwise.
WifiTxVector m_txVector
TXVECTOR of the frame being prepared.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void SendRts(const WifiTxParameters &txParams)
Send RTS to begin RTS-CTS-Data-Ack transaction.
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
void Cancel(void)
Cancel the timer.
bool IsRunning(void) const
Return true if the timer is running.
static void SetQosAckPolicy(Ptr< WifiMacQueueItem > item, const WifiAcknowledgment *acknowledgment)
Set the QoS Ack policy for the given MPDU, which must be a QoS data frame.
WifiRtsCtsProtection specifies that RTS/CTS protection method is used.
void SendCtsAfterRts(const WifiMacHeader &rtsHdr, WifiMode rtsTxMode, double rtsSnr)
Send CTS after receiving RTS.
static Time Now(void)
Return the current simulation virtual time.
virtual void SetWifiMac(const Ptr< RegularWifiMac > mac)
Set the MAC layer to use.
WifiTxParameters m_txParams
the TX parameters for the current frame
static TypeId GetTypeId(void)
Get the type ID.
void SendNormalAck(const WifiMacHeader &hdr, const WifiTxVector &dataTxVector, double dataSnr)
Send Normal Ack.
virtual Time GetTxDuration(uint32_t ppduPayloadSize, Mac48Address receiver, const WifiTxParameters &txParams) const
Get the updated TX duration of the frame associated with the given TX parameters if the size of the P...
void AddMpdu(Ptr< const WifiMacQueueItem > mpdu)
Record that an MPDU is being added to the current frame.
virtual ~FrameExchangeManager()
virtual void NotifyChannelAccessed(Time txopDuration=Seconds(0))
Called by the FrameExchangeManager to notify that channel access has been granted for the given amoun...
uint32_t GetSize(Mac48Address receiver) const
Get the size in bytes of the (A-)MPDU addressed to the given receiver.
uint32_t GetCtsSize(void)
Return the total CTS size (including FCS trailer).
#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< WifiProtectionManager > m_protectionManager
Protection manager.
void Reschedule(const Time &delay)
Reschedule the timer to time out the given amount of time from the moment this function is called...
void NotifySleepNow(void)
This method is typically invoked by the PhyMacLowListener to notify the MAC layer that the device has...
void SetReceiveOkCallback(RxOkCallback callback)
WifiMacQueue * queue
pointer to the queue where the MSDU is enqueued
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Time GetSifs(void) const
Return the Short Interframe Space (SIFS) for this PHY.
void AddPacketTag(const Tag &tag) const
Add a packet tag.
virtual void Reset(void)
Reset this frame exchange manager.
bool IsQueued(void) const
Return true if this item is stored in some queue, false otherwise.
double snr
SNR in linear scale.
bool PushFront(Ptr< WifiMacQueueItem > item)
Enqueue the given Wifi MAC queue item at the front of the queue.
virtual void SetBssid(Mac48Address bssid)
Set the Basic Service Set Identification.
bool IsStrictlyNegative(void) const
Exactly equivalent to t < 0.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
WifiTxVector ctsTxVector
CTS TXVECTOR.
Time Seconds(double value)
Construct a Time in the indicated unit.
Ptr< WifiMacQueue > GetWifiMacQueue() const
Return the packet queue associated with this Txop.
This class stores the TX parameters (TX vector, protection mechanism, acknowledgment mechanism...
Ptr< Txop > m_dcf
the DCF/EDCAF that gained channel access
bool IsRunning(void) const
This method is syntactic sugar for !IsExpired().
Time GetSlot(void) const
Return the slot duration for this PHY.
WifiCtsToSelfProtection specifies that CTS-to-self protection method is used.
static Time CalculatePhyPreambleAndHeaderDuration(const WifiTxVector &txVector)
void Send(Ptr< const WifiPsdu > psdu, const WifiTxVector &txVector)
virtual Time GetCtsToSelfDurationId(const WifiTxVector &ctsTxVector, Time txDuration, Time response) const
Compute how to set the Duration/ID field of a CTS-to-self frame to send to protect a frame transmitte...
const Method method
protection method
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Time m_navEnd
NAV expiration time.
virtual void ReceiveMpdu(Ptr< WifiMacQueueItem > mpdu, RxSignalInfo rxSignalInfo, const WifiTxVector &txVector, bool inAmpdu)
This method handles the reception of an MPDU (possibly included in an A-MPDU)
virtual void RetransmitMpduAfterMissedAck(Ptr< WifiMacQueueItem > mpdu) const
Retransmit an MPDU that was not acknowledged.
virtual void TransmissionSucceeded(void)
Take necessary actions upon a transmission success.
void RxStartIndication(WifiTxVector txVector, Time psduDuration)
void DoSendCtsAfterRts(const WifiMacHeader &rtsHdr, WifiTxVector &ctsTxVector, double rtsSnr)
Send CTS after receiving RTS.
Ptr< WifiMacQueueItem > GetNextFragment(void)
Get the next fragment of the current MSDU.
std::unique_ptr< WifiAcknowledgment > m_acknowledgment
acknowledgment method
virtual void NotifyReceivedNormalAck(Ptr< WifiMacQueueItem > mpdu)
Notify other components that an MPDU was acknowledged.
A base class which provides memory management and object aggregation.
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...
Mac48Address GetAddr1(void) const
Get the Receiver Address (RA), which is common to all the MPDUs.
bool PeekPacketTag(Tag &tag) const
Search a matching tag and call Tag::Deserialize if it is found.
uint32_t GetPacketSize(void) const
Return the size in bytes of the packet or control header or management header stored by this item...
Ptr< MacRxMiddle > m_rxMiddle
the MAC RX Middle on this station
WifiNormalAck specifies that acknowledgment via Normal Ack is required.
virtual void SetWifiPhy(const Ptr< WifiPhy > phy)
Set the PHY layer to use.
virtual void EndReceiveAmpdu(Ptr< const WifiPsdu > psdu, double rxSnr, const WifiTxVector &txVector, const std::vector< bool > &perMpduStatus)
This method is called when the reception of an A-MPDU including multiple MPDUs is completed...
Ptr< MacTxMiddle > m_txMiddle
the MAC TX Middle on this station
void ResetCw(void)
Update the value of the CW variable to take into account a transmission success or a transmission abo...
a unique identifier for an interface.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
const std::list< QueueIteratorPair > & GetQueueIteratorPairs(void) const
Get a const reference to the list of iterators pointing to the positions of the items in the queue...
void SendMpdu(void)
Send the current MPDU, which can be acknowledged by a Normal Ack.
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Introspection did not find any typical Config paths.
virtual void NavResetTimeout(void)
Reset the NAV upon expiration of the NAV reset timer.
virtual void RetransmitMpduAfterMissedCts(Ptr< WifiMacQueueItem > mpdu) const
Retransmit an MPDU that was not sent because a CTS was not received.