23 #include "ns3/simulator.h"
25 #include "ns3/socket.h"
33 #undef NS_LOG_APPEND_CONTEXT
34 #define NS_LOG_APPEND_CONTEXT std::clog << "[mac=" << m_self << "] "
44 m_overrideDurationId (
Seconds (0))
178 <<
"send rts=" << params.
m_sendRts <<
", "
197 os <<
"basic-block-ack";
200 os <<
"compressed-block-ack";
203 os <<
"multi-tid-block-ack";
262 : m_normalAckTimeoutEvent (),
263 m_fastAckTimeoutEvent (),
264 m_superFastAckTimeoutEvent (),
265 m_fastAckFailedTimeoutEvent (),
266 m_blockAckTimeoutEvent (),
267 m_ctsTimeoutEvent (),
272 m_endTxNoAckEvent (),
276 m_lastNavDuration (
Seconds (0)),
279 m_phyMacLowListener (0),
280 m_ctsToSelfSupported (false)
283 for (uint8_t i = 0; i < 8; i++)
300 .SetGroupName (
"Wifi")
301 .AddConstructor<
MacLow> ()
346 for (uint8_t i = 0; i < 8; i++)
357 bool oneRunning =
false;
611 uint32_t size, actualSize;
616 if (actualSize > size)
693 std::map<AcIndex, Ptr<EdcaTxopN> >::const_iterator edcaIt =
m_edca.find (ac);
695 for (uint32_t i = 0; i < sentMpdus; i++)
700 edcaIt->second->GetMpduAggregator ()->Aggregate (newPacket, aggregatedPacket);
781 NS_LOG_DEBUG (
"switching channel. Cancelling MAC pending events");
797 NS_LOG_DEBUG (
"Device in sleep mode. Cancelling MAC pending events");
840 && hdr.GetAddr1 () ==
m_self)
842 NS_LOG_DEBUG (
"rx RTS from=" << hdr.GetAddr2 () <<
", schedule CTS");
855 NS_LOG_DEBUG (
"rx RTS from=" << hdr.GetAddr2 () <<
", cannot schedule CTS");
859 else if (hdr.IsCts ()
860 && hdr.GetAddr1 () ==
m_self
876 rxSnr, txVector.
GetMode (), tag.Get ());
886 else if (hdr.IsAck ()
887 && hdr.GetAddr1 () ==
m_self
902 rxSnr, txVector.
GetMode (), tag.Get ());
951 else if (hdr.IsBlockAck () && hdr.GetAddr1 () ==
m_self
955 NS_LOG_DEBUG (
"got block ack from " << hdr.GetAddr2 ());
963 m_currentDca->GotBlockAck (&blockAck, hdr.GetAddr2 (), rxSnr, txVector.
GetMode (), tag.Get ());
977 else if (hdr.IsBlockAckReq () && hdr.GetAddr1 () ==
m_self)
996 if ((*it).second.first.IsImmediateBlockAck ())
998 NS_LOG_DEBUG (
"rx blockAckRequest/sendImmediateBlockAck from=" << hdr.GetAddr2 ());
1014 NS_LOG_DEBUG (
"There's not a valid agreement for this block ack request.");
1022 else if (hdr.IsCtl ())
1026 else if (hdr.GetAddr1 () ==
m_self)
1030 if (hdr.IsQosData () &&
ReceiveMpdu (packet, hdr))
1037 if (hdr.IsQosAck () && !ampduSubframe)
1039 NS_LOG_DEBUG (
"rx QoS unicast/sendAck from=" << hdr.GetAddr2 ());
1043 hdr.GetAddr2 (), hdr.GetQosTid ());
1053 else if (hdr.IsQosBlockAck ())
1061 else if (hdr.IsQosData () && hdr.IsQosBlockAck ())
1072 m_edca[ac]->SendDelbaFrame (hdr.GetAddr2 (), hdr.GetQosTid (),
false);
1075 else if (hdr.IsQosData () && hdr.IsQosNoAck ())
1079 NS_LOG_DEBUG (
"rx Ampdu with No Ack Policy from=" << hdr.GetAddr2 ());
1083 NS_LOG_DEBUG (
"rx unicast/noAck from=" << hdr.GetAddr2 ());
1086 else if (hdr.IsData () || hdr.IsMgt ())
1088 if (hdr.IsProbeResp ())
1095 if (hdr.IsMgt () && ampduSubframe)
1097 NS_FATAL_ERROR (
"Received management packet as part of an A-MPDU");
1101 NS_LOG_DEBUG (
"rx unicast/sendAck from=" << hdr.GetAddr2 ());
1113 else if (hdr.GetAddr1 ().IsGroup ())
1117 NS_FATAL_ERROR (
"Received group addressed packet as part of an A-MPDU");
1121 if (hdr.IsData () || hdr.IsMgt ())
1124 if (hdr.IsBeacon ())
1145 NS_LOG_DEBUG (
"rx not for me from=" << hdr.GetAddr2 ());
1333 uint32_t fragmentSize)
const
1389 if (hdr.
IsRts () && navUpdated)
1402 Time navCounterResetCtsMissedDelay =
1426 (*i)->NotifyNavResetNow (duration);
1437 (*i)->NotifyNavStartNow (duration);
1441 if (newNavEnd > oldNavEnd)
1444 m_lastNavDuration = duration;
1455 (*i)->NotifyAckTimeoutStartNow (duration);
1464 (*i)->NotifyAckTimeoutResetNow ();
1473 (*i)->NotifyCtsTimeoutStartNow (duration);
1482 (*i)->NotifyCtsTimeoutResetNow ();
1492 ", size=" << packet->
GetSize () <<
1493 ", mode=" << txVector.
GetMode () <<
1507 bool singleMpdu =
false;
1511 uint8_t tid =
GetTid (packet, *hdr);
1513 std::map<AcIndex, Ptr<EdcaTxopN> >::const_iterator edcaIt =
m_edca.find (ac);
1525 if (queueSize > 1 || singleMpdu)
1529 for (; queueSize > 0; queueSize--)
1532 newHdr = dequeuedItem->GetHeader ();
1533 newPacket = dequeuedItem->GetPacket ()->Copy ();
1543 edcaIt->second->GetMpduAggregator ()->AddHeaderAndPad (newPacket, last, singleMpdu);
1560 remainingAmpduDuration -= mpduDuration;
1584 delay = delay + mpduDuration;
1662 dca->MissedBlockAck (nTxMpdus);
1796 Time delay = txDuration;
1809 Time delay = txDuration;
1994 cts.SetDsNotFrom ();
1996 cts.SetNoMoreFragments ();
1998 cts.SetAddr1 (source);
2002 cts.SetDuration (duration);
2030 for (std::vector<Item>::size_type i = 0; i !=
m_txPackets[tid].size (); i++)
2033 std::map<AcIndex, Ptr<EdcaTxopN> >::const_iterator edcaIt =
m_edca.find (ac);
2082 duration -= txDuration;
2085 duration =
std::max (duration, newDuration);
2167 return ((seq - winstart + 4096) % 4096) < winsize;
2191 uint16_t delta = (seqNumber - (*it).second.first.GetWinEnd () + 4096) % 4096;
2194 (*it).second.first.SetWinEnd (seqNumber);
2195 int16_t winEnd = (*it).second.first.GetWinEnd ();
2196 int16_t bufferSize = (*it).second.first.GetBufferSize ();
2197 uint16_t sum = ((uint16_t)(std::abs (winEnd - bufferSize + 1))) % 4096;
2198 (*it).second.first.SetStartingSequence (sum);
2203 (*it).second.first.SetWinEnd (((*it).second.first.GetStartingSequence () + (*it).second.first.GetBufferSize () - 1) % 4096);
2225 uint16_t endSequence = ((*it).second.first.GetStartingSequence () + 2047) % 4096;
2229 for (; i != (*it).second.second.end ()
2233 (*it).second.second.insert (i, bufferedPacket);
2238 (*j).second.UpdateWithMpdu (&hdr);
2246 uint16_t startingSeq)
2249 uint8_t tid = respHdr->
GetTid ();
2264 std::list<BufferedPacket> buffer (0);
2282 m_edca[ac], originator, tid,
false);
2309 uint16_t endSequence = ((*it).second.first.GetStartingSequence () + 2047) % 4096;
2313 if (last != (*it).second.second.end ())
2315 guard = (*it).second.second.begin ()->second.GetSequenceControl ();
2318 for (; i != (*it).second.second.end ()
2321 if (guard == (*i).second.GetSequenceControl ())
2323 if (!(*i).second.IsMoreFragments ())
2333 while (i != (*it).second.second.end () && guard == (*i).second.GetSequenceControl ())
2337 if (i != (*it).second.second.end ())
2339 guard = (*i).second.GetSequenceControl ();
2351 while (i != (*it).second.second.end () && guard == (*i).second.GetSequenceControl ())
2355 if (i != (*it).second.second.end ())
2357 guard = (*i).second.GetSequenceControl ();
2362 (*it).second.second.erase ((*it).second.second.begin (), i);
2372 uint16_t guard = (*it).second.first.GetStartingSequenceControl ();
2375 for (; i != (*it).second.second.end () && guard == (*i).second.GetSequenceControl (); i++)
2377 if (!(*i).second.IsMoreFragments ())
2379 while (lastComplete != i)
2381 m_rxCallback ((*lastComplete).first, &(*lastComplete).second);
2384 m_rxCallback ((*lastComplete).first, &(*lastComplete).second);
2387 guard = (*i).second.IsMoreFragments () ? (guard + 1) : ((guard + 16) & 0xfff0);
2389 (*it).second.first.SetStartingSequenceControl (guard);
2392 (*it).second.second.erase ((*it).second.second.begin (), lastComplete);
2397 Time duration,
WifiMode blockAckReqTxMode,
double rxSnr)
2464 uint16_t seqNumber = 0;
2467 seqNumber = (*i).second.GetWinStart ();
2469 bool immediate =
true;
2471 blockAck.SetStartingSequence (seqNumber);
2472 blockAck.SetTidInfo (tid);
2473 immediate = (*it).second.first.IsImmediateBlockAck ();
2475 NS_LOG_DEBUG (
"Got Implicit block Ack Req with seq " << seqNumber);
2476 (*i).second.FillBlockAckBitmap (&blockAck);
2488 Time duration,
WifiMode blockAckReqTxMode,
double rxSnr)
2493 bool immediate =
false;
2502 immediate = (*it).second.first.IsImmediateBlockAck ();
2513 (*i).second.FillBlockAckBitmap (&blockAck);
2529 (*it).second.first.SetWinEnd (((*it).second.first.GetStartingSequence () + (*it).second.first.GetBufferSize () - 1) % 4096);
2532 (*it).second.first.SetWinEnd (((*it).second.first.GetStartingSequence () + (*it).second.first.GetBufferSize () - 1) % 4096);
2538 NS_LOG_DEBUG (
"there's not a valid block ack agreement with " << originator);
2561 agreement.
GetTid (),
false);
2568 m_edca.insert (std::make_pair (ac, edca));
2576 bool normalAck =
false;
2577 bool ampduSubframe =
false;
2580 ampduSubframe =
true;
2585 (*n).first->PeekHeader (firsthdr);
2588 NotifyNav ((*n).first, firsthdr, preamble);
2592 bool singleMpdu = (*n).second.GetEof ();
2597 ampduSubframe =
false;
2612 ReceiveOk ((*n).first, rxSnr, txVector, ampduSubframe);
2617 ReceiveOk ((*n).first, rxSnr, txVector, ampduSubframe);
2636 NS_FATAL_ERROR (
"Sending a BlockAckReq with QosPolicy equal to Normal Ack");
2649 NS_LOG_DEBUG (
"There's not a valid agreement for this block ack request.");
2657 ReceiveOk (aggregatedPacket, rxSnr, txVector, ampduSubframe);
2664 if (peekedPacket == 0)
2671 uint8_t tid =
GetTid (peekedPacket, peekedHdr);
2673 std::map<AcIndex, Ptr<EdcaTxopN> >::const_iterator edcaIt =
m_edca.find (ac);
2683 NS_LOG_DEBUG (
"no more packets can be aggregated to satisfy PPDU <= aPPDUMaxTime");
2689 NS_LOG_DEBUG (
"no more packets can be aggregated because the maximum A-MPDU size has been reached");
2699 bool isAmpdu =
false;
2702 newPacket = packet->
Copy ();
2720 uint8_t tid =
GetTid (packet, hdr);
2723 std::map<AcIndex, Ptr<EdcaTxopN> >::const_iterator edcaIt =
m_edca.find (ac);
2725 queue = edcaIt->second->GetQueue ();
2730 if (edcaIt->second->GetBaAgreementExists (hdr.
GetAddr1 (), tid))
2734 currentAggregatedPacket = Create<Packet> ();
2736 uint16_t startingSequenceNumber = 0;
2737 uint16_t currentSequenceNumber = 0;
2738 uint8_t qosPolicy = 0;
2739 uint16_t blockAckSize = 0;
2740 bool aggregated =
false;
2748 startingSequenceNumber = peekedHdr.GetSequenceNumber ();
2751 currentSequenceNumber = peekedHdr.GetSequenceNumber ();
2755 aggregated = edcaIt->second->GetMpduAggregator ()->Aggregate (newPacket, currentAggregatedPacket);
2759 NS_LOG_DEBUG (
"Adding packet with sequence number " << currentSequenceNumber <<
" to A-MPDU, packet size = " << newPacket->
GetSize () <<
", A-MPDU size = " << currentAggregatedPacket->
GetSize ());
2761 m_aggregateQueue[tid]->Enqueue (Create<WifiMacQueueItem> (aggPacket, peekedHdr));
2774 Ptr<const Packet> peekedPacket = edcaIt->second->PeekNextRetransmitPacket (peekedHdr, peekedHdr.GetAddr1 (), tid, &tstamp);
2775 if (peekedPacket == 0)
2782 peekedPacket = item->GetPacket ();
2783 peekedHdr = item->GetHeader ();
2784 tstamp = item->GetTimeStamp ();
2786 currentSequenceNumber = edcaIt->second->PeekNextSequenceNumberFor (&peekedHdr);
2789 if (peekedPacket != 0 && edcaIt->second->GetMsduAggregator () != 0)
2791 tempPacket =
PerformMsduAggregation (peekedPacket, &peekedHdr, &tstamp, currentAggregatedPacket, blockAckSize);
2792 if (tempPacket != 0)
2794 peekedPacket = tempPacket->
Copy ();
2801 currentSequenceNumber = peekedHdr.GetSequenceNumber ();
2804 while (
IsInWindow (currentSequenceNumber, startingSequenceNumber, 64) && !
StopMpduAggregation (peekedPacket, peekedHdr, currentAggregatedPacket, blockAckSize))
2809 currentSequenceNumber = edcaIt->second->GetNextSequenceNumberFor (&peekedHdr);
2810 peekedHdr.SetSequenceNumber (currentSequenceNumber);
2811 peekedHdr.SetFragmentNumber (0);
2812 peekedHdr.SetNoMoreFragments ();
2813 peekedHdr.SetNoRetry ();
2824 newPacket = peekedPacket->
Copy ();
2829 aggregated = edcaIt->second->GetMpduAggregator ()->Aggregate (newPacket, currentAggregatedPacket);
2832 m_aggregateQueue[tid]->Enqueue (Create<WifiMacQueueItem> (aggPacket, peekedHdr));
2837 edcaIt->second->CompleteMpduTx (packet, hdr, tstamp);
2844 NS_LOG_DEBUG (
"Adding packet with sequence number " << peekedHdr.GetSequenceNumber () <<
" to A-MPDU, packet size = " << newPacket->
GetSize () <<
", A-MPDU size = " << currentAggregatedPacket->
GetSize ());
2849 edcaIt->second->CompleteMpduTx (peekedPacket, peekedHdr, tstamp);
2857 edcaIt->second->RemoveRetransmitPacket (tid, hdr.
GetAddr1 (), peekedHdr.GetSequenceNumber ());
2861 queue->Remove (peekedPacket);
2871 peekedPacket = edcaIt->second->PeekNextRetransmitPacket (peekedHdr, hdr.
GetAddr1 (), tid, &tstamp);
2872 if (peekedPacket == 0)
2881 peekedPacket = item->GetPacket ();
2882 peekedHdr = item->GetHeader ();
2883 tstamp = item->GetTimeStamp ();
2885 currentSequenceNumber = edcaIt->second->PeekNextSequenceNumberFor (&peekedHdr);
2887 if (edcaIt->second->GetMsduAggregator () != 0)
2889 tempPacket =
PerformMsduAggregation (peekedPacket, &peekedHdr, &tstamp, currentAggregatedPacket, blockAckSize);
2890 if (tempPacket != 0)
2892 peekedPacket = tempPacket->
Copy ();
2899 currentSequenceNumber = peekedHdr.GetSequenceNumber ();
2908 peekedPacket = item->GetPacket ();
2909 peekedHdr = item->GetHeader ();
2910 tstamp = item->GetTimeStamp ();
2912 currentSequenceNumber = edcaIt->second->PeekNextSequenceNumberFor (&peekedHdr);
2914 if (edcaIt->second->GetMsduAggregator () != 0 &&
IsInWindow (currentSequenceNumber, startingSequenceNumber, 64))
2916 tempPacket =
PerformMsduAggregation (peekedPacket, &peekedHdr, &tstamp, currentAggregatedPacket, blockAckSize);
2917 if (tempPacket != 0)
2919 peekedPacket = tempPacket->
Copy ();
2934 newPacket = packet->
Copy ();
2937 m_aggregateQueue[tid]->Enqueue (Create<WifiMacQueueItem> (aggPacket, peekedHdr));
2940 edcaIt->second->GetMpduAggregator ()->Aggregate (newPacket, currentAggregatedPacket);
2941 currentAggregatedPacket->
AddHeader (blockAckReq);
2946 edcaIt->second->CompleteAmpduTransfer (hdr.
GetAddr1 (), tid);
2953 newPacket = currentAggregatedPacket;
2957 edcaIt->second->SetAmpduExist (hdr.
GetAddr1 (),
true);
2980 currentAggregatedPacket = Create<Packet> ();
2981 edcaIt->second->GetMpduAggregator ()->AggregateSingleMpdu (packet, currentAggregatedPacket);
2982 m_aggregateQueue[tid]->Enqueue (Create<WifiMacQueueItem> (packet, peekedHdr));
2987 if (edcaIt->second->GetBaAgreementExists (hdr.
GetAddr1 (), tid))
2989 edcaIt->second->CompleteAmpduTransfer (peekedHdr.
GetAddr1 (), tid);
2995 newPacket = currentAggregatedPacket;
3001 edcaIt->second->SetAmpduExist (hdr.
GetAddr1 (),
true);
3033 bool msduAggregation =
false;
3034 bool isAmsdu =
false;
3035 Ptr<Packet> currentAmsduPacket = Create<Packet> ();
3040 std::map<AcIndex, Ptr<EdcaTxopN> >::const_iterator edcaIt =
m_edca.find (ac);
3042 queue = edcaIt->second->GetQueue ();
3049 *hdr = peekedItem->GetHeader ();
3052 edcaIt->second->GetMsduAggregator ()->Aggregate (packet, currentAmsduPacket,
3053 edcaIt->second->MapSrcAddressForAggregation (*hdr),
3054 edcaIt->second->MapDestAddressForAggregation (*hdr));
3057 while (peekedItem != 0)
3059 *hdr = peekedItem->GetHeader ();
3060 *tstamp = peekedItem->GetTimeStamp ();
3061 tempPacket = currentAmsduPacket;
3063 msduAggregation = edcaIt->second->GetMsduAggregator ()->Aggregate (peekedItem->GetPacket (), tempPacket,
3064 edcaIt->second->MapSrcAddressForAggregation (*hdr),
3065 edcaIt->second->MapDestAddressForAggregation (*hdr));
3067 if (msduAggregation && !
StopMpduAggregation (tempPacket, *hdr, currentAmpduPacket, blockAckSize))
3070 currentAmsduPacket = tempPacket;
3071 queue->Remove (peekedItem->GetPacket ());
3085 return currentAmsduPacket;
3089 queue->PushFront (Create<WifiMacQueueItem> (packet, *hdr));
void WaitIfsAfterEndTxPacket(void)
Event handler that is usually scheduled to fired at the appropriate time after sending a packet...
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
void Set(double snr)
Set the SNR to the given value.
bool MustSendRts(void) const
Time GetPifs(void) const
Return PCF Interframe Space (PIFS) of this MacLow.
void SetPifs(Time pifs)
Set PCF Interframe Space (PIFS) of this MacLow.
Time m_ctsTimeout
CTS timeout duration.
uint8_t GetTid(void) const
Return the Traffic ID (TID).
Simulation virtual time values and global simulation resolution.
EventId m_navCounterResetCtsMissed
Event to reset NAV when CTS is not received.
static uint32_t GetRtsSize(void)
Return the total RTS size (including FCS trailer).
The MPDU is not part of an A-MPDU.
bool IsPositive(void) const
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
Ptr< WifiPhy > GetPhy(void) const
void ResetBlockAckInactivityTimerIfNeeded(BlockAckAgreement &agreement)
Every time that a block ack request or a packet with ack policy equals to block ack are received...
EventId m_blockAckTimeoutEvent
Block ACK timeout event.
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
std::vector< Item > m_txPackets[8]
Contain temporary items to be sent with the next A-MPDU transmission for a given TID, once RTS/CTS exchange has succeeded.
uint8_t GetRemainingNbOfMpdus(void) const
uint16_t GetTimeout(void) const
Return the timeout.
Time GetAckDuration(WifiTxVector ackTxVector) const
Return the time required to transmit the ACK (including preamble and FCS).
void SendBlockAckAfterBlockAckRequest(const CtrlBAckRequestHeader reqHdr, Mac48Address originator, Time duration, WifiMode blockAckReqTxMode, double rxSnr)
Invoked after that a block ack request has been received.
virtual void StartTransmission(Ptr< const Packet > packet, const WifiMacHeader *hdr, MacLowTransmissionParameters parameters, Ptr< DcaTxop > dca)
void SetPromisc(void)
Enable promiscuous mode.
bool GetGreenfield(void) const
Return whether Greenfield is supported.
void DoNavResetNow(Time duration)
Reset NAV with the given duration.
void ReportDataFailed(Mac48Address address, const WifiMacHeader *header)
Should be invoked whenever the AckTimeout associated to a transmission attempt expires.
void NotifyMaybeCcaBusyStart(Time duration)
bool IsPromisc(void) const
Check if MacLow is operating in promiscuous mode.
bool GetUseNonErpProtection(void) const
Return whether the device supports protection of non-ERP stations.
void EnableBasicBlockAck(void)
Wait BASICBLOCKACKTimeout for a Basic Block Ack Response frame.
void SetupPhyMacLowListener(const Ptr< WifiPhy > phy)
Set up WifiPhy listener for this MacLow.
Mac48Address GetPeer(void) const
Return the peer address.
EventId m_fastAckTimeoutEvent
Fast ACK timeout event.
Time m_pifs
PCF Interframe Space (PIFS) duration.
void SetPhy(const Ptr< WifiPhy > phy)
Set up WifiPhy associated with this MacLow.
void AddPacketTag(const Tag &tag) const
Add a packet tag.
bool DoNavStartNow(Time duration)
Start NAV with the given duration.
void FastAckFailedTimeout(void)
Event handler when fast ACK timeout occurs (busy).
Mac48Address GetBssid(void) const
Return the Basic Service Set Identification.
void SetSifs(Time sifs)
Set Short Interframe Space (SIFS) of this MacLow.
void NotifySwitchingStart(Time duration)
void ForwardDown(Ptr< const Packet > packet, const WifiMacHeader *hdr, WifiTxVector txVector)
Forward the packet down to WifiPhy for transmission.
uint32_t m_nextSize
the next size
Ptr< DcaTxop > m_currentDca
Current DCA.
std::pair< Mac48Address, uint8_t > AgreementKey
agreement key typedef
WifiTxVector GetCtsToSelfTxVector(Ptr< const Packet > packet, const WifiMacHeader *hdr) const
Return a TXVECTOR for the CTS-to-self frame.
void SetReceiveErrorCallback(RxErrorCallback callback)
WifiTxVector GetCtsTxVector(Mac48Address address, WifiMode rtsMode)
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
void Init(uint16_t winStart, uint16_t winSize)
Init function.
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.
The MPDU is the last aggregate in an A-MPDU.
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
static DeaggregatedMpdus Deaggregate(Ptr< Packet > aggregatedPacket)
Deaggregates an A-MPDU by removing the A-MPDU subframe header and padding.
bool IsBroadcast(void) const
void NotifySleepNow(void)
This method is typically invoked by the PhyMacLowListener to notify the MAC layer that the device has...
bool HasDurationId(void) const
std::list< std::pair< Ptr< Packet >, AmpduSubframeHeader > >::const_iterator DeaggregatedMpdusCI
A constant iterator for a list of deaggregated packets and their A-MPDU subframe headers.
void UnregisterListener(WifiPhyListener *listener)
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
bool QosUtilsIsOldPacket(uint16_t startingSeq, uint16_t seqNumber)
This function checks if packet with sequence number seqNumber is an "old" packet. ...
void SendPacket(Ptr< const Packet > packet, WifiTxVector txVector, MpduType mpdutype=NORMAL_MPDU)
void(* Time)(Time oldValue, Time newValue)
TracedValue callback signature for Time.
bool m_ampdu
Flag if the current transmission involves an A-MPDU.
bool IsRunning(void) const
This method is syntactic sugar for !IsExpired().
bool NeedRts(Mac48Address address, const WifiMacHeader *header, Ptr< const Packet > packet, WifiTxVector txVector)
void SetRxCallback(Callback< void, Ptr< Packet >, const WifiMacHeader * > callback)
Time GetCompressedBlockAckTimeout() const
Return Compressed Block ACK timeout of this MacLow.
Callback< R > MakeNullCallback(void)
Mac48Address m_bssid
BSSID address (Mac48Address)
BlockAckType
Enumeration for different block ACK policies.
Ptr< Packet > AggregateToAmpdu(Ptr< const Packet > packet, const WifiMacHeader hdr)
EventId m_sendCtsEvent
Event to send CTS.
MacLowRxCallback m_rxCallback
Callback to pass packet up.
Time GetCtsTimeout(void) const
Return CTS timeout of this MacLow.
EventId m_superFastAckTimeoutEvent
Super fast ACK timeout event.
void DeaggregateAmpduAndReceive(Ptr< Packet > aggregatedPacket, double rxSnr, WifiTxVector txVector)
EventId m_sendAckEvent
Event to send ACK.
uint16_t GetFrequency(void) const
represent a single transmission modeA WifiMode is implemented by a single integer which is used to lo...
Time GetCtsDuration(WifiTxVector ctsTxVector) const
Return the time required to transmit the CTS (including preamble and FCS).
bool MustWaitFastAck(void) const
static void AddWifiMacTrailer(Ptr< Packet > packet)
Add FCS trailer to a packet.
Ptr< Packet > PerformMsduAggregation(Ptr< const Packet > packet, WifiMacHeader *hdr, Time *tstamp, Ptr< Packet > currentAmpduPacket, uint16_t blockAckSize)
Perform MSDU aggregation for a given MPDU in an A-MPDU.
control how a packet is transmitted.
MacLowTransmissionParameters()
WifiTxVector GetCtsToSelfTxVector(const WifiMacHeader *header, Ptr< const Packet > packet)
void SetCtsToSelfSupported(bool enable)
Enable or disable CTS-to-self capability.
QueueEdcas m_edca
EDCA queues.
void NormalAckTimeout(void)
Event handler when normal ACK timeout occurs.
void SetBasicBlockAckTimeout(Time blockAckTimeout)
Set Basic Block ACK timeout of this MacLow.
BlockAckCaches m_bAckCaches
block ack caches
Time timestamp
the timestamp
void RemovePhyMacLowListener(Ptr< WifiPhy > phy)
Remove current WifiPhy listener for this MacLow.
Time CalculateTxDuration(uint32_t size, WifiTxVector txVector, uint16_t frequency)
WifiPreamble
The type of preamble to be used by an IEEE 802.11 transmission.
WifiTxVector m_currentTxVector
TXVECTOR used for the current packet transmission.
void DestroyBlockAckAgreement(Mac48Address originator, uint8_t tid)
bool PeekPacketTag(Tag &tag) const
Search a matching tag and call Tag::Deserialize if it is found.
Time m_lastNavDuration
The duration of the latest NAV.
DcfManagers m_dcfManagers
List of DcfManager.
std::pair< Ptr< Packet >, WifiMacHeader > BufferedPacket
buffered packet typedef
void SendCtsToSelf(void)
Send CTS for a CTS-to-self mechanism.
bool m_ctsToSelfSupported
Flag whether CTS-to-self is supported.
void SetAmpdu(bool supported)
void SendAckAfterData(Mac48Address source, Time duration, WifiMode dataTxMode, double dataSnr)
Send ACK after receiving DATA.
static EventId Schedule(Time const &delay, MEM mem_ptr, OBJ obj)
Schedule an event to expire after delay.
void CreateBlockAckAgreement(const MgtAddBaResponseHeader *respHdr, Mac48Address originator, uint16_t startingSeq)
void NotifyNav(Ptr< const Packet > packet, const WifiMacHeader &hdr, WifiPreamble preamble)
Notify NAV function.
void ReportRtsFailed(Mac48Address address, const WifiMacHeader *header)
Should be invoked whenever the RtsTimeout associated to a transmission attempt expires.
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
receive notifications about phy events.
void CtsTimeout(void)
Event handler when CTS timeout occurs.
void SendDelbaFrame(Mac48Address addr, uint8_t tid, bool byOriginator)
Sends DELBA frame to cancel a block ack agreement with sta addressed by addr for tid tid...
void EnableSuperFastAck(void)
void EndTxNoAck(void)
A transmission that does not require an ACK has completed.
void SendBlockAckAfterAmpdu(uint8_t tid, Mac48Address originator, Time duration, WifiTxVector blockAckReqTxVector, double rxSnr)
Invoked after an A-MPDU has been received.
std::map< AgreementKey, BlockAckCache >::iterator BlockAckCachesI
block ack caches iterator typedef
WifiTxVector GetAckTxVector(Mac48Address to, WifiMode dataTxMode) const
Return a TXVECTOR for the ACK frame given the destination and the mode of the DATA used by the sender...
void SetAckTimeout(Time ackTimeout)
Set ACK timeout of this MacLow.
static TypeId GetTypeId(void)
Register this type.
void SendDataAfterCts(Mac48Address source, Time duration)
Send DATA after receiving CTS.
indicates whether the socket has a priority set.
AcIndex QosUtilsMapTidToAc(uint8_t tid)
Maps TID (Traffic ID) to Access classes.
Time GetRifs(void) const
Return Reduced Interframe Space (RIFS) of this MacLow.
void NavCounterResetCtsMissed(Time rtsEndRxTime)
Reset NAV after CTS was missed when the NAV was setted with RTS.
Ptr< WifiRemoteStationManager > m_stationManager
Pointer to WifiRemoteStationManager (rate control)
bool MustWaitMultiTidBlockAck(void) const
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Mac48Address GetAddress(void) const
Return the MAC address of this MacLow.
uint32_t GetNextPacketSize(void) const
Agreements m_bAckAgreements
block ack agreements
Ptr< WifiMacQueue > m_aggregateQueue[8]
Queues per TID used for MPDU aggregation.
bool HasNextPacket(void) const
void SendMpdu(Ptr< const Packet > packet, WifiTxVector txVector, MpduType mpdutype)
Forward the MPDU down to WifiPhy for transmission.
The aim of the AmpduTag is to provide means for a MAC to specify that a packet includes A-MPDU since ...
WifiTxVector GetAckTxVectorForData(Mac48Address to, WifiMode dataTxMode) const
Return a TXVECTOR for the Block ACK frame given the destination and the mode of the DATA used by the ...
static uint32_t GetBlockAckSize(BlockAckType type)
Return the total Block ACK size (including FCS trailer).
void NotifySwitchingStartNow(Time duration)
Time CalculateOverallTxFragmentTime(Ptr< const Packet > packet, const WifiMacHeader *hdr, const MacLowTransmissionParameters ¶ms, uint32_t fragmentSize) const
Time m_slotTime
Slot duration.
bool m_promisc
Flag if the device is operating in promiscuous mode.
void NotifyRxStart(Time duration)
WifiMacHeader hdr
the header
void CancelAllEvents(void)
Cancel all scheduled events.
std::ostream & operator<<(std::ostream &os, const Angles &a)
print a struct Angles to output
void ReportDataOk(Mac48Address address, const WifiMacHeader *header, double ackSnr, WifiMode ackMode, double dataSnr)
Should be invoked whenever we receive the Ack associated to a data packet we just sent...
std::list< BufferedPacket >::iterator BufferedPacketI
buffered packet iterator typedef
void SetStartingSequence(uint16_t seq)
Set starting sequence number.
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
uint32_t PeekHeader(Header &header) const
Deserialize but does not remove the header from the internal buffer.
void BlockAckTimeout(void)
Event handler when block ACK timeout occurs.
void NotifyCtsTimeoutStartNow(Time duration)
Notify DcfManagerthat CTS timer should be started for the given duration.
Time m_overrideDurationId
override duration ID
void RegisterDcf(Ptr< DcfManager > dcf)
void EnableCompressedBlockAck(void)
Wait COMPRESSEDBLOCKACKTimeout for a Compressed Block Ack Response frame.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void SetAggregation(bool aggregation)
Sets if PSDU contains A-MPDU.
void SuperFastAckTimeout(void)
Event handler when super fast ACK timeout occurs.
void SetBssid(Mac48Address ad)
Set the Basic Service Set Identification.
void SetPreambleType(WifiPreamble preamble)
Sets the preamble type.
EventId m_waitIfsEvent
Wait for IFS event.
void ReceiveOk(Ptr< Packet > packet, double rxSnr, WifiTxVector txVector, bool ampduSubframe)
void EnableAck(void)
Wait ACKTimeout for an ACK.
Time CalculateTransmissionTime(Ptr< const Packet > packet, const WifiMacHeader *hdr, const MacLowTransmissionParameters ¶meters) const
EventId m_normalAckTimeoutEvent
Normal ACK timeout event.
bool m_sendRts
send an RTS?
void StartDataTxTimers(WifiTxVector dataTxVector)
Start a DATA timer by scheduling appropriate ACK timeout.
void AddTrailer(const Trailer &trailer)
Add trailer to this packet.
void NotifyWakeup(void)
Notify listeners that we woke up.
void NotifyCtsTimeoutResetNow()
Notify DcfManager that CTS timer should be resetted.
bool MustWaitBasicBlockAck(void) const
bool MustWaitCompressedBlockAck(void) const
uint32_t RemoveTrailer(Trailer &trailer)
Remove a deserialized trailer from the internal buffer.
Ptr< const Packet > packet
the packet
Time GetLastRxStartTime(void) const
Return the start time of the last received packet.
bool HasVhtSupported(void) const
Return whether the device has VHT capability support enabled.
void NotifyTxStart(Time duration, double txPowerDbm)
void SendBlockAckResponse(const CtrlBAckResponseHeader *blockAck, Mac48Address originator, bool immediate, Time duration, WifiMode blockAckReqTxMode, double rxSnr)
This method creates block ack frame with header equals to blockAck and start its transmission.
Time m_ackTimeout
ACK timeout duration.
static bool IsInWindow(uint16_t seq, uint16_t winstart, uint16_t winsize)
uint8_t GetTid(Ptr< const Packet > packet, const WifiMacHeader hdr)
Extraction operator for TypeId.
static uint32_t GetCtsSize(void)
Return the total CTS size (including FCS trailer).
bool NeedRts(void) const
Check if the current packet should be sent with a RTS protection.
void FastAckTimeout(void)
Event handler when fast ACK timeout occurs (idle).
void DisableRts(void)
Do not send rts and wait for cts before sending data.
void EnableMultiTidBlockAck(void)
NOT IMPLEMENTED FOR NOW.
static Time Now(void)
Return the current simulation virtual time.
void ReportRtsOk(Mac48Address address, const WifiMacHeader *header, double ctsSnr, WifiMode ctsMode, double rtsSnr)
Should be invoked whenever we receive the Cts associated to an RTS we just sent.
EventId m_ctsTimeoutEvent
CTS timeout event.
void RxCompleteBufferedPacketsWithSmallerSequence(uint16_t seq, Mac48Address originator, uint8_t tid)
void SendCtsAfterRts(Mac48Address source, Time duration, WifiTxVector rtsTxVector, double rtsSnr)
Send CTS after receiving RTS.
Time m_basicBlockAckTimeout
Basic block ACK timeout duration.
Time GetDurationId(void) const
void FlushAggregateQueue(uint8_t tid)
This function is called to flush the aggregate queue, which is used for A-MPDU.
Time m_sifs
Short Interframe Space (SIFS) duration.
static uint32_t GetAckSize(void)
Return the total ACK size (including FCS trailer).
bool HasHtSupported(void) const
Return whether the device has HT capability support enabled.
Time GetSlotTime(void) const
Return slot duration of this MacLow.
WifiMacHeader m_lastReceivedHdr
Header of the last received packet.
void SetDelayedBlockAck(void)
Set Block ACK policy to delayed ACK.
WifiPreamble GetPreambleType(void) const
void NotifySleep(void)
Notify listeners that we went to sleep.
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Time m_lastNavStart
The time when the latest NAV started.
EventId m_inactivityEvent
inactivity event
bool NeedCtsToSelf(WifiTxVector txVector)
Return if we need to do Cts-to-self before sending a DATA.
void ReceiveError(Ptr< Packet > packet, double rxSnr)
void SetAmsduSupport(bool supported)
Enable or disable A-MSDU support.
static uint32_t GetSize(Ptr< const Packet > packet, const WifiMacHeader *hdr, bool isAmpdu)
Return the total size of the packet after WifiMacHeader and FCS trailer have been added...
WifiTxVector GetRtsTxVector(Ptr< const Packet > packet, const WifiMacHeader *hdr) const
Return a TXVECTOR for the RTS frame given the destination.
enum ns3::MacLowTransmissionParameters::@73 m_waitAck
wait ack enumerated type
virtual WifiTxVector GetDataTxVector(Ptr< const Packet > packet, const WifiMacHeader *hdr) const
Return a TXVECTOR for the DATA frame given the destination.
handle RTS/CTS/DATA/ACK transactions.
void SetReceiveOkCallback(RxOkCallback callback)
std::vector< Ptr< DcfManager > >::const_iterator DcfManagersCI
typedef for an iterator for a list of DcfManager.
EventId m_sendDataEvent
Event to send DATA.
void RegisterListener(WifiPhyListener *listener)
bool ReceiveMpdu(Ptr< Packet > packet, WifiMacHeader hdr)
void NotifyRxEndError(void)
We have received the last bit of a packet for which NotifyRxStart was invoked first and...
MacLowTransmissionParameters m_txParams
Transmission parameters of the current packet.
void SetRifs(Time rifs)
Set Reduced Interframe Space (RIFS) of this MacLow.
void DoDispose(void)
Destructor implementation.
void NotifyAckTimeoutResetNow()
Notify DcfManager that ACK timer should be resetted.
WifiTxVector GetDataTxVector(Mac48Address address, const WifiMacHeader *header, Ptr< const Packet > packet)
bool MustWaitSuperFastAck(void) const
TimeWithUnit As(const enum Unit unit) const
Attach a unit to a Time, to facilitate output in a specific unit.
Time CalculateOverallTxTime(Ptr< const Packet > packet, const WifiMacHeader *hdr, const MacLowTransmissionParameters ¶ms) const
WifiTxVector GetBlockAckTxVector(Mac48Address to, WifiMode dataTxMode) const
Return a TXVECTOR for the Block ACK frame given the destination and the mode of the DATA used by the ...
Mac48Address m_self
Address of this MacLow (Mac48Address)
Maintains information for a block ack agreement.
EventId m_fastAckFailedTimeoutEvent
Fast ACK failed timeout event.
uint32_t QosUtilsMapSeqControlToUniqueInteger(uint16_t seqControl, uint16_t endSequence)
Next function is useful to correctly sort buffered packets under block ack.
bool IsNavZero(void) const
Check if NAV is zero.
void EnableRts(void)
Send a RTS, and wait CTSTimeout for a CTS.
void NotifyAckTimeoutStartNow(Time duration)
Notify DcfManager that ACK timer should be started for the given duration.
void SetSlotTime(Time slotTime)
Set slot duration of this MacLow.
Ptr< Packet > m_currentPacket
Current packet transmitted/to be transmitted.
Time GetSifs(void) const
Return Short Interframe Space (SIFS) of this MacLow.
bool NeedCtsToSelf(void) const
Check if CTS-to-self mechanism should be used for the current packet.
void Reset(void)
Reset the station, invoked in a STA upon dis-association or in an AP upon reboot. ...
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
bool StopMpduAggregation(Ptr< const Packet > peekedPacket, WifiMacHeader peekedHdr, Ptr< Packet > aggregatedPacket, uint16_t size) const
bool GetRifsPermitted(void) const
Return whether the device can use RIFS.
ns3::MacLow * m_macLow
the MAC
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Time Seconds(double value)
Construct a Time in the indicated unit.
std::map< AgreementKey, AgreementValue >::iterator AgreementsI
agreements iterator
EventId m_endTxNoAckEvent
Event for finishing transmission that does not require ACK.
void EnableOverrideDurationId(Time durationId)
bool GetCtsToSelfSupported() const
Return whether CTS-to-self capability is supported.
void ReportRxOk(Mac48Address address, const WifiMacHeader *header, double rxSnr, WifiMode txMode)
void NotifyRxEndOk(void)
We have received the last bit of a packet for which NotifyRxStart was invoked first and...
std::list< std::pair< Ptr< Packet >, AmpduSubframeHeader > > DeaggregatedMpdus
A list of deaggregated packets and their A-MPDU subframe headers.
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::Cancel method.
void SetCtsTimeout(Time ctsTimeout)
Set CTS timeout of this MacLow.
void EnableNextData(uint32_t size)
void SetImmediateBlockAck(void)
Set Block ACK policy to immediate ACK.
Time GetBlockAckDuration(Mac48Address to, WifiTxVector blockAckReqTxVector, BlockAckType type) const
Return the time required to transmit the Block ACK to the specified address given the TXVECTOR of the...
void DisableOverrideDurationId(void)
Do not force the duration/id field of the packet: its value is automatically calculated by the MacLow...
Time GetAckTimeout(void) const
Return ACK timeout of this MacLow.
void DisableNextData(void)
Do not attempt to send data burst after current transmission.
void SendDataPacket(void)
Send DATA packet, which can be DATA-ACK or RTS-CTS-DATA-ACK transaction.
void SetTimeout(uint16_t timeout)
Set timeout.
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
WifiMacHeader m_currentHdr
Header of the current transmitted packet.
void SetAddress(Mac48Address ad)
Set MAC address of this MacLow.
WifiTxVector GetRtsTxVector(Mac48Address address, const WifiMacHeader *header, Ptr< const Packet > packet)
A base class which provides memory management and object aggregation.
void WaitIfsAfterEndTxFragment(void)
Event handler that is usually scheduled to fired at the appropriate time after completing transmissio...
PhyMacLowListener(ns3::MacLow *macLow)
Create a PhyMacLowListener for the given MacLow.
WifiModulationClass GetModulationClass() const
Time m_compressedBlockAckTimeout
Compressed block ACK timeout duration.
WifiMode GetMode(void) const
void SetRemainingNbOfMpdus(uint8_t nbofmpdus)
WifiTxVector GetBlockAckTxVector(Mac48Address address, WifiMode dataMode)
bool MustWaitAck(void) const
The MPDU is part of an A-MPDU, but is not the last aggregate.
bool IsAmpdu(Ptr< const Packet > packet, const WifiMacHeader hdr)
Checks if the given packet will be aggregated to an A-MPDU or not.
void InsertInTxQueue(Ptr< const Packet > packet, const WifiMacHeader &hdr, Time tStamp, uint8_t tid)
Insert in a temporary queue.
virtual ~PhyMacLowListener()
void ResetPhy(void)
Remove WifiPhy associated with this MacLow.
void DisableAck(void)
Do not wait for Ack after data transmission.
bool IsExpired(void) const
This method is syntactic sugar for the ns3::Simulator::IsExpired method.
std::pair< BlockAckAgreement, std::list< BufferedPacket > > AgreementValue
agreement value typedef
WifiTxVector GetCtsTxVectorForRts(Mac48Address to, WifiMode rtsTxMode) const
Return a TXVECTOR for the CTS frame given the destination and the mode of the RTS used by the sender...
void SetBufferSize(uint16_t bufferSize)
Set buffer size.
Time GetBasicBlockAckTimeout() const
Return Basic Block ACK timeout of this MacLow.
a unique identifier for an interface.
WifiTxVector GetAckTxVector(Mac48Address address, WifiMode dataMode)
MpduType
This enumeration defines the type of an MPDU.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Time GetRemainingAmpduDuration(void) const
Time m_rifs
Reduced Interframe Space (RIFS) duration.
AcIndex
This enumeration defines the Access Categories as an enumeration with values corresponding to the AC ...
Ptr< T > Copy(Ptr< T > object)
Return a deep copy of a Ptr.
WifiTxVector GetCtsTxVector(Mac48Address to, WifiMode rtsTxMode) const
Return a TXVECTOR for the CTS frame given the destination and the mode of the RTS used by the sender...
Introspection did not find any typical Config paths.
bool StoreMpduIfNeeded(Ptr< Packet > packet, WifiMacHeader hdr)
bool MustWaitNormalAck(void) const
A struct for packet, Wifi header, and timestamp.item structure.
Ptr< WifiPhy > m_phy
Pointer to WifiPhy (actually send/receives frames)
void AddHeader(const Header &header)
Add header to this packet.
void SetWifiRemoteStationManager(const Ptr< WifiRemoteStationManager > manager)
Set up WifiRemoteStationManager associated with this MacLow.
void SetCompressedBlockAckTimeout(Time blockAckTimeout)
Set Compressed Block ACK timeout of this MacLow.
Implements the IEEE 802.11 MAC trailer.
class PhyMacLowListener * m_phyMacLowListener
Listener needed to monitor when a channel switching occurs.
void RegisterEdcaForAc(AcIndex ac, Ptr< EdcaTxopN > edca)
uint32_t GetSerializedSize(void) const
void SendRtsForPacket(void)
Send RTS to begin RTS-CTS-DATA-ACK transaction.
void RxCompleteBufferedPacketsUntilFirstLost(Mac48Address originator, uint8_t tid)
void SetRemainingAmpduDuration(Time duration)