23 #include "ns3/simulator.h" 25 #include "ns3/socket.h" 43 #undef NS_LOG_APPEND_CONTEXT 44 #define NS_LOG_APPEND_CONTEXT std::clog << "[mac=" << m_self << "] " 108 : m_normalAckTimeoutEvent (),
109 m_blockAckTimeoutEvent (),
110 m_ctsTimeoutEvent (),
115 m_endTxNoAckEvent (),
119 m_lastNavDuration (
Seconds (0)),
122 m_cfpForeshortening (
Seconds (0)),
125 m_phyMacLowListener (0),
126 m_ctsToSelfSupported (false),
130 for (uint8_t i = 0; i < 8; i++)
147 .SetGroupName (
"Wifi")
148 .AddConstructor<
MacLow> ()
190 for (uint8_t i = 0; i < 8; i++)
201 bool oneRunning =
false;
464 uint32_t size, actualSize;
469 if (actualSize > size)
549 std::map<AcIndex, Ptr<QosTxop> >::const_iterator edcaIt =
m_edca.find (ac);
551 for (uint32_t i = 0; i < sentMpdus; i++)
556 edcaIt->second->GetMpduAggregator ()->Aggregate (newPacket, aggregatedPacket);
644 NS_LOG_DEBUG (
"switching channel. Cancelling MAC pending events");
660 NS_LOG_DEBUG (
"Device in sleep mode. Cancelling MAC pending events");
675 NS_LOG_DEBUG (
"Device is switched off. Cancelling MAC pending events");
717 && hdr.GetAddr1 () ==
m_self)
719 NS_LOG_DEBUG (
"rx RTS from=" << hdr.GetAddr2 () <<
", schedule CTS");
732 NS_LOG_DEBUG (
"rx RTS from=" << hdr.GetAddr2 () <<
", cannot schedule CTS");
736 else if (hdr.IsCts ()
737 && hdr.GetAddr1 () ==
m_self 753 rxSnr, txVector.
GetMode (), tag.Get ());
762 else if (hdr.IsAck ()
763 && hdr.GetAddr1 () ==
m_self 776 rxSnr, txVector.
GetMode (), tag.Get (),
819 else if (hdr.IsBlockAck () && hdr.GetAddr1 () ==
m_self 823 NS_LOG_DEBUG (
"got block ack from " << hdr.GetAddr2 ());
845 else if (hdr.IsBlockAckReq () && hdr.GetAddr1 () ==
m_self)
864 if ((*it).second.first.IsImmediateBlockAck ())
866 NS_LOG_DEBUG (
"rx blockAckRequest/sendImmediateBlockAck from=" << hdr.GetAddr2 ());
882 NS_LOG_DEBUG (
"There's not a valid agreement for this block ack request.");
890 else if (hdr.IsCtl ())
919 else if (hdr.GetAddr1 () ==
m_self)
942 if (hdr.IsQosAck () && !ampduSubframe)
944 NS_LOG_DEBUG (
"rx QoS unicast/sendAck from=" << hdr.GetAddr2 ());
948 hdr.GetAddr2 (), hdr.GetQosTid ());
958 else if (hdr.IsQosBlockAck ())
966 else if (hdr.IsQosData () && hdr.IsQosBlockAck ())
977 m_edca[ac]->SendDelbaFrame (hdr.GetAddr2 (), hdr.GetQosTid (),
false);
980 else if (hdr.IsQosData () && hdr.IsQosNoAck ())
984 NS_LOG_DEBUG (
"rx Ampdu with No Ack Policy from=" << hdr.GetAddr2 ());
988 NS_LOG_DEBUG (
"rx unicast/noAck from=" << hdr.GetAddr2 ());
991 else if (hdr.IsData () || hdr.IsMgt ())
993 if (hdr.IsProbeResp ())
1000 if (hdr.IsMgt () && ampduSubframe)
1002 NS_FATAL_ERROR (
"Received management packet as part of an A-MPDU");
1016 NS_LOG_DEBUG (
"rx unicast/sendAck from=" << hdr.GetAddr2 ());
1029 else if (hdr.GetAddr1 ().IsGroup ())
1033 NS_FATAL_ERROR (
"Received group addressed packet as part of an A-MPDU");
1037 if (hdr.IsData () || hdr.IsMgt ())
1040 if (hdr.IsBeacon ())
1067 NS_LOG_DEBUG (
"rx not for me from=" << hdr.GetAddr2 ());
1184 uint32_t fragmentSize)
const 1196 if (fragmentSize > 0)
1250 if (hdr.
IsRts () && navUpdated)
1263 Time navCounterResetCtsMissedDelay =
1288 (*i)->NotifyNavResetNow (duration);
1299 (*i)->NotifyNavStartNow (duration);
1303 if (newNavEnd > oldNavEnd)
1317 (*i)->NotifyAckTimeoutStartNow (duration);
1326 (*i)->NotifyAckTimeoutResetNow ();
1335 (*i)->NotifyCtsTimeoutStartNow (duration);
1344 (*i)->NotifyCtsTimeoutResetNow ();
1354 ", size=" << packet->
GetSize () <<
1355 ", mode=" << txVector.
GetMode () <<
1392 bool singleMpdu =
false;
1396 uint8_t tid =
GetTid (packet, *hdr);
1398 std::map<AcIndex, Ptr<QosTxop> >::const_iterator edcaIt =
m_edca.find (ac);
1409 if (queueSize > 1 || singleMpdu)
1413 for (; queueSize > 0; queueSize--)
1416 newHdr = dequeuedItem->GetHeader ();
1417 newPacket = dequeuedItem->GetPacket ()->Copy ();
1427 edcaIt->second->GetMpduAggregator ()->AddHeaderAndPad (newPacket, last, singleMpdu);
1444 remainingAmpduDuration -= mpduDuration;
1468 delay = delay + mpduDuration;
1491 busy = (*i)->IsBusy ();
1641 Time delay = txDuration;
1654 Time delay = txDuration;
1868 cts.SetDsNotFrom ();
1870 cts.SetNoMoreFragments ();
1872 cts.SetAddr1 (source);
1876 cts.SetDuration (duration);
1904 for (std::vector<Item>::size_type i = 0; i !=
m_txPackets[tid].size (); i++)
1907 std::map<AcIndex, Ptr<QosTxop> >::const_iterator edcaIt =
m_edca.find (ac);
1957 duration -= txDuration;
1960 duration =
std::max (duration, newDuration);
2064 uint16_t delta = (seqNumber - (*it).second.first.GetWinEnd () + 4096) % 4096;
2067 (*it).second.first.SetWinEnd (seqNumber);
2068 int16_t winEnd = (*it).second.first.GetWinEnd ();
2069 int16_t bufferSize = (*it).second.first.GetBufferSize ();
2070 uint16_t sum = (
static_cast<uint16_t
> (std::abs (winEnd - bufferSize + 1))) % 4096;
2071 (*it).second.first.SetStartingSequence (sum);
2076 (*it).second.first.SetWinEnd (((*it).second.first.GetStartingSequence () + (*it).second.first.GetBufferSize () - 1) % 4096);
2095 uint16_t endSequence = ((*it).second.first.GetStartingSequence () + 2047) % 4096;
2099 for (; i != (*it).second.second.end ()
2103 (*it).second.second.insert (i, bufferedPacket);
2108 (*j).second.UpdateWithMpdu (&hdr);
2116 uint16_t startingSeq)
2119 uint8_t tid = respHdr->
GetTid ();
2134 std::list<BufferedPacket> buffer (0);
2152 m_edca[ac], originator, tid,
false);
2178 uint16_t endSequence = ((*it).second.first.GetStartingSequence () + 2047) % 4096;
2182 if (last != (*it).second.second.end ())
2184 guard = (*it).second.second.begin ()->second.GetSequenceControl ();
2187 for (; i != (*it).second.second.end ()
2190 if (guard == (*i).second.GetSequenceControl ())
2192 if (!(*i).second.IsMoreFragments ())
2202 while (i != (*it).second.second.end () && guard == (*i).second.GetSequenceControl ())
2206 if (i != (*it).second.second.end ())
2208 guard = (*i).second.GetSequenceControl ();
2220 while (i != (*it).second.second.end () && guard == (*i).second.GetSequenceControl ())
2224 if (i != (*it).second.second.end ())
2226 guard = (*i).second.GetSequenceControl ();
2231 (*it).second.second.erase ((*it).second.second.begin (), i);
2241 uint16_t guard = (*it).second.first.GetStartingSequenceControl ();
2244 for (; i != (*it).second.second.end () && guard == (*i).second.GetSequenceControl (); i++)
2246 if (!(*i).second.IsMoreFragments ())
2248 while (lastComplete != i)
2250 m_rxCallback ((*lastComplete).first, &(*lastComplete).second);
2253 m_rxCallback ((*lastComplete).first, &(*lastComplete).second);
2256 guard = (*i).second.IsMoreFragments () ? (guard + 1) : ((guard + 16) & 0xfff0);
2258 (*it).second.first.SetStartingSequenceControl (guard);
2261 (*it).second.second.erase ((*it).second.second.begin (), lastComplete);
2266 Time duration,
WifiMode blockAckReqTxMode,
double rxSnr)
2333 uint16_t seqNumber = 0;
2336 seqNumber = (*i).second.GetWinStart ();
2338 bool immediate =
true;
2340 blockAck.SetStartingSequence (seqNumber);
2341 blockAck.SetTidInfo (tid);
2342 immediate = (*it).second.first.IsImmediateBlockAck ();
2344 NS_LOG_DEBUG (
"Got Implicit block Ack Req with seq " << seqNumber);
2345 (*i).second.FillBlockAckBitmap (&blockAck);
2357 Time duration,
WifiMode blockAckReqTxMode,
double rxSnr)
2362 bool immediate =
false;
2371 immediate = (*it).second.first.IsImmediateBlockAck ();
2382 (*i).second.FillBlockAckBitmap (&blockAck);
2400 (*it).second.first.SetWinEnd (((*it).second.first.GetStartingSequence () + (*it).second.first.GetBufferSize () - 1) % 4096);
2403 (*it).second.first.SetWinEnd (((*it).second.first.GetStartingSequence () + (*it).second.first.GetBufferSize () - 1) % 4096);
2409 NS_LOG_DEBUG (
"there's not a valid block ack agreement with " << originator);
2431 agreement.
GetTid (),
false);
2438 m_edca.insert (std::make_pair (ac, edca));
2446 bool normalAck =
false;
2447 bool ampduSubframe =
false;
2450 ampduSubframe =
true;
2455 (*n).first->PeekHeader (firsthdr);
2461 bool singleMpdu = (*n).second.GetEof ();
2466 ampduSubframe =
false;
2481 ReceiveOk ((*n).first, rxSnr, txVector, ampduSubframe);
2486 ReceiveOk ((*n).first, rxSnr, txVector, ampduSubframe);
2505 NS_FATAL_ERROR (
"Sending a BlockAckReq with QosPolicy equal to Normal Ack");
2518 NS_LOG_DEBUG (
"There's not a valid agreement for this block ack request.");
2526 ReceiveOk (aggregatedPacket, rxSnr, txVector, ampduSubframe);
2533 if (peekedPacket == 0)
2540 uint8_t tid =
GetTid (peekedPacket, peekedHdr);
2542 std::map<AcIndex, Ptr<QosTxop> >::const_iterator edcaIt =
m_edca.find (ac);
2552 NS_LOG_DEBUG (
"no more packets can be aggregated to satisfy PPDU <= aPPDUMaxTime");
2556 if (!edcaIt->second->GetMpduAggregator ()->CanBeAggregated (peekedPacket->
GetSize () + peekedHdr.
GetSize () +
WIFI_MAC_FCS_LENGTH, aggregatedPacket, blockAckSize))
2558 NS_LOG_DEBUG (
"no more packets can be aggregated because the maximum A-MPDU size has been reached");
2568 bool isAmpdu =
false;
2571 newPacket = packet->
Copy ();
2589 uint8_t tid =
GetTid (packet, hdr);
2593 std::map<AcIndex, Ptr<QosTxop> >::const_iterator edcaIt =
m_edca.find (ac);
2595 queue = edcaIt->second->GetWifiMacQueue ();
2600 if (edcaIt->second->GetBaAgreementExists (hdr.
GetAddr1 (), tid))
2604 currentAggregatedPacket = Create<Packet> ();
2606 uint16_t startingSequenceNumber = 0;
2607 uint16_t currentSequenceNumber = 0;
2608 uint8_t qosPolicy = 0;
2609 uint8_t blockAckSize = 0;
2610 bool aggregated =
false;
2612 aggPacket = newPacket->
Copy ();
2618 startingSequenceNumber = peekedHdr.GetSequenceNumber ();
2621 currentSequenceNumber = peekedHdr.GetSequenceNumber ();
2625 aggregated = edcaIt->second->GetMpduAggregator ()->Aggregate (newPacket, currentAggregatedPacket);
2629 NS_LOG_DEBUG (
"Adding packet with sequence number " << currentSequenceNumber <<
" to A-MPDU, packet size = " << newPacket->
GetSize () <<
", A-MPDU size = " << currentAggregatedPacket->
GetSize ());
2631 m_aggregateQueue[tid]->Enqueue (Create<WifiMacQueueItem> (aggPacket, peekedHdr));
2644 Ptr<const Packet> peekedPacket = edcaIt->second->PeekNextRetransmitPacket (peekedHdr, tid, &tstamp);
2645 if (peekedPacket == 0)
2651 peekedPacket = item->GetPacket ();
2652 peekedHdr = item->GetHeader ();
2653 tstamp = item->GetTimeStamp ();
2655 currentSequenceNumber = edcaIt->second->PeekNextSequenceNumberFor (&peekedHdr);
2658 if (peekedPacket != 0 && edcaIt->second->GetMsduAggregator () != 0)
2660 tempPacket =
PerformMsduAggregation (peekedPacket, &peekedHdr, &tstamp, currentAggregatedPacket, blockAckSize);
2661 if (tempPacket != 0)
2663 peekedPacket = tempPacket->
Copy ();
2670 currentSequenceNumber = peekedHdr.GetSequenceNumber ();
2673 while (
IsInWindow (currentSequenceNumber, startingSequenceNumber, 64) && !
StopMpduAggregation (peekedPacket, peekedHdr, currentAggregatedPacket, blockAckSize))
2678 currentSequenceNumber = edcaIt->second->GetNextSequenceNumberFor (&peekedHdr);
2679 peekedHdr.SetSequenceNumber (currentSequenceNumber);
2680 peekedHdr.SetFragmentNumber (0);
2681 peekedHdr.SetNoMoreFragments ();
2682 peekedHdr.SetNoRetry ();
2693 newPacket = peekedPacket->
Copy ();
2694 aggPacket = newPacket->
Copy ();
2698 aggregated = edcaIt->second->GetMpduAggregator ()->Aggregate (newPacket, currentAggregatedPacket);
2701 m_aggregateQueue[tid]->Enqueue (Create<WifiMacQueueItem> (aggPacket, peekedHdr));
2706 edcaIt->second->CompleteMpduTx (packet, hdr, tstamp);
2713 NS_LOG_DEBUG (
"Adding packet with sequence number " << peekedHdr.GetSequenceNumber () <<
" to A-MPDU, packet size = " << newPacket->
GetSize () <<
", A-MPDU size = " << currentAggregatedPacket->
GetSize ());
2718 edcaIt->second->CompleteMpduTx (peekedPacket, peekedHdr, tstamp);
2726 edcaIt->second->RemoveRetransmitPacket (tid, hdr.
GetAddr1 (), peekedHdr.GetSequenceNumber ());
2730 queue->Remove (peekedPacket);
2740 peekedPacket = edcaIt->second->PeekNextRetransmitPacket (peekedHdr, tid, &tstamp);
2741 if (peekedPacket == 0)
2749 peekedPacket = item->GetPacket ();
2750 peekedHdr = item->GetHeader ();
2751 tstamp = item->GetTimeStamp ();
2753 currentSequenceNumber = edcaIt->second->PeekNextSequenceNumberFor (&peekedHdr);
2755 if (edcaIt->second->GetMsduAggregator () != 0)
2757 tempPacket =
PerformMsduAggregation (peekedPacket, &peekedHdr, &tstamp, currentAggregatedPacket, blockAckSize);
2758 if (tempPacket != 0)
2760 peekedPacket = tempPacket->
Copy ();
2767 currentSequenceNumber = peekedHdr.GetSequenceNumber ();
2776 peekedPacket = item->GetPacket ();
2777 peekedHdr = item->GetHeader ();
2778 tstamp = item->GetTimeStamp ();
2780 currentSequenceNumber = edcaIt->second->PeekNextSequenceNumberFor (&peekedHdr);
2782 if (edcaIt->second->GetMsduAggregator () != 0 &&
IsInWindow (currentSequenceNumber, startingSequenceNumber, 64))
2784 tempPacket =
PerformMsduAggregation (peekedPacket, &peekedHdr, &tstamp, currentAggregatedPacket, blockAckSize);
2785 if (tempPacket != 0)
2787 peekedPacket = tempPacket->
Copy ();
2802 newPacket = packet->
Copy ();
2804 aggPacket = newPacket->
Copy ();
2805 m_aggregateQueue[tid]->Enqueue (Create<WifiMacQueueItem> (aggPacket, peekedHdr));
2808 edcaIt->second->GetMpduAggregator ()->Aggregate (newPacket, currentAggregatedPacket);
2809 currentAggregatedPacket->
AddHeader (blockAckReq);
2814 edcaIt->second->CompleteAmpduTransfer (hdr.
GetAddr1 (), tid);
2820 newPacket = currentAggregatedPacket;
2824 edcaIt->second->SetAmpduExist (hdr.
GetAddr1 (),
true);
2847 currentAggregatedPacket = Create<Packet> ();
2848 edcaIt->second->GetMpduAggregator ()->AggregateSingleMpdu (packet, currentAggregatedPacket);
2849 m_aggregateQueue[tid]->Enqueue (Create<WifiMacQueueItem> (packet, peekedHdr));
2854 if (edcaIt->second->GetBaAgreementExists (hdr.
GetAddr1 (), tid))
2856 edcaIt->second->CompleteAmpduTransfer (peekedHdr.
GetAddr1 (), tid);
2861 newPacket = currentAggregatedPacket;
2867 edcaIt->second->SetAmpduExist (hdr.
GetAddr1 (),
true);
2899 bool msduAggregation =
false;
2900 bool isAmsdu =
false;
2901 Ptr<Packet> currentAmsduPacket = Create<Packet> ();
2906 std::map<AcIndex, Ptr<QosTxop> >::const_iterator edcaIt =
m_edca.find (ac);
2908 queue = edcaIt->second->GetWifiMacQueue ();
2914 *hdr = peekedItem->GetHeader ();
2917 edcaIt->second->GetMsduAggregator ()->Aggregate (packet, currentAmsduPacket,
2918 edcaIt->second->MapSrcAddressForAggregation (*hdr),
2919 edcaIt->second->MapDestAddressForAggregation (*hdr));
2922 while (peekedItem != 0)
2924 *hdr = peekedItem->GetHeader ();
2925 *tstamp = peekedItem->GetTimeStamp ();
2926 tempPacket = currentAmsduPacket;
2928 msduAggregation = edcaIt->second->GetMsduAggregator ()->Aggregate (peekedItem->GetPacket (), tempPacket,
2929 edcaIt->second->MapSrcAddressForAggregation (*hdr),
2930 edcaIt->second->MapDestAddressForAggregation (*hdr));
2932 if (msduAggregation && !
StopMpduAggregation (tempPacket, *hdr, currentAmpduPacket, blockAckSize))
2935 currentAmsduPacket = tempPacket;
2936 queue->Remove (peekedItem->GetPacket ());
2950 return currentAmsduPacket;
2954 queue->PushFront (Create<WifiMacQueueItem> (packet, *hdr));
2965 return remainingCfpDuration;
void WaitIfsAfterEndTxPacket(void)
Event handler that is usually scheduled to fired at the appropriate time after sending a packet...
bool HasVhtSupported(void) const
Return whether the device has VHT capability support enabled.
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.
Time GetRifs(void) const
Return Reduced Interframe Space (RIFS) of this MacLow.
void SetPifs(Time pifs)
Set PCF Interframe Space (PIFS) of this MacLow.
Time m_ctsTimeout
CTS timeout duration.
bool IsStateOff(void) const
bool GetRifsPermitted(void) const
Return whether the device can use RIFS.
bool IsBroadcast(void) const
Simulation virtual time values and global simulation resolution.
EventId m_navCounterResetCtsMissed
Event to reset NAV when CTS is not received.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
std::vector< Ptr< ChannelAccessManager > >::const_iterator ChannelAccessManagersCI
typedef for an iterator for a list of ChannelAccessManager.
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.
Time CalculateOverallTxTime(Ptr< const Packet > packet, const WifiMacHeader *hdr, const MacLowTransmissionParameters ¶ms, uint32_t fragmentSize=0) const
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.
void SendBlockAckAfterBlockAckRequest(const CtrlBAckRequestHeader reqHdr, Mac48Address originator, Time duration, WifiMode blockAckReqTxMode, double rxSnr)
Invoked after that a block ack request has been received.
bool MustWaitCompressedBlockAck(void) const
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
NS_ASSERT_MSG(false, "Ipv4AddressGenerator::MaskToIndex(): Impossible")
void SetPromisc(void)
Enable promiscuous mode.
void AddWifiMacTrailer(Ptr< Packet > packet)
Add FCS trailer to a packet.
virtual void StartNextPacket(void)
Start transmission for the next packet if allowed by the TxopLimit.
void DoNavResetNow(Time duration)
Reset NAV with the given duration.
Ptr< Txop > m_currentTxop
Current TXOP.
virtual void EndTxNoAck(void)
Event handler when a transmission that does not require an ACK has completed.
void NotifyMaybeCcaBusyStart(Time duration)
bool GetGreenfield(void) const
Return whether Greenfield is supported.
void SetupPhyMacLowListener(const Ptr< WifiPhy > phy)
Set up WifiPhy listener for this MacLow.
virtual void StartNextFragment(void)
Start transmission for the next fragment.
uint32_t GetRtsSize(void)
Return the total RTS size (including FCS trailer).
Time m_pifs
PCF Interframe Space (PIFS) duration.
void SetPhy(const Ptr< WifiPhy > phy)
Set up WifiPhy associated with this MacLow.
bool StopMpduAggregation(Ptr< const Packet > peekedPacket, WifiMacHeader peekedHdr, Ptr< Packet > aggregatedPacket, uint8_t blockAckSize) const
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...
bool DoNavStartNow(Time duration)
Start NAV with the given duration.
void SetSifs(Time sifs)
Set Short Interframe Space (SIFS) of this MacLow.
void NotifySwitchingStart(Time duration)
void ReportDataOk(Mac48Address address, const WifiMacHeader *header, double ackSnr, WifiMode ackMode, double dataSnr, uint32_t packetSize)
Should be invoked whenever we receive the Ack associated to a data packet we just sent...
void ForwardDown(Ptr< const Packet > packet, const WifiMacHeader *hdr, WifiTxVector txVector)
Forward the packet down to WifiPhy for transmission.
std::pair< Mac48Address, uint8_t > AgreementKey
agreement key typedef
void SetReceiveErrorCallback(RxErrorCallback callback)
virtual void MissedAck(void)
Event handler when an ACK is missed.
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.
WifiTxVector GetRtsTxVector(Ptr< const Packet > packet, const WifiMacHeader *hdr) const
Return a TXVECTOR for the RTS frame given the destination.
bool IsNavZero(void) const
Check if NAV is zero.
static DeaggregatedMpdus Deaggregate(Ptr< Packet > aggregatedPacket)
Deaggregates an A-MPDU by removing the A-MPDU subframe header and padding.
void NotifyOffNow(void)
This method is typically invoked by the PhyMacLowListener to notify the MAC layer that the device has...
void NotifySleepNow(void)
This method is typically invoked by the PhyMacLowListener to notify the MAC layer that the device has...
void NotifyNav(Ptr< const Packet > packet, const WifiMacHeader &hdr)
Notify NAV function.
Mac48Address GetBssid(void) const
Return the Basic Service Set Identification.
virtual WifiTxVector GetDataTxVector(Ptr< const Packet > packet, const WifiMacHeader *hdr) const
Return a TXVECTOR for the DATA frame given the destination.
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 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...
#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. ...
bool IsStrictlyPositive(void) const
void SendPacket(Ptr< const Packet > packet, WifiTxVector txVector, MpduType mpdutype=NORMAL_MPDU)
virtual void Cancel(void)
Cancel the transmission.
uint32_t GetAckSize(void)
Return the total ACK size (including FCS trailer).
void(* Time)(Time oldValue, Time newValue)
TracedValue callback signature for Time.
bool m_ampdu
Flag if the current transmission involves an A-MPDU.
bool NeedRts(Mac48Address address, const WifiMacHeader *header, Ptr< const Packet > packet, WifiTxVector txVector)
Callback< R > MakeNullCallback(void)
TimeWithUnit As(const enum Unit unit) const
Attach a unit to a Time, to facilitate output in a specific unit.
Mac48Address m_bssid
BSSID address (Mac48Address)
Ptr< Packet > AggregateToAmpdu(Ptr< const Packet > packet, const WifiMacHeader hdr)
EventId m_sendCtsEvent
Event to send CTS.
virtual void StartTransmission(Ptr< const Packet > packet, const WifiMacHeader *hdr, MacLowTransmissionParameters parameters, Ptr< Txop > txop)
MacLowRxCallback m_rxCallback
Callback to pass packet up.
bool NeedRts(void) const
Check if the current packet should be sent with a RTS protection.
void DeaggregateAmpduAndReceive(Ptr< Packet > aggregatedPacket, double rxSnr, WifiTxVector txVector)
bool appendCfAck
Flag used for PCF to indicate whether a CF-ACK should be appended.
EventId m_sendAckEvent
Event to send ACK.
represent a single transmission modeA WifiMode is implemented by a single integer which is used to lo...
bool MustSendRts(void) const
Time m_cfpMaxDuration
CFP max duration.
bool IsExpired(void) const
This method is syntactic sugar for the ns3::Simulator::IsExpired method.
Time CalculateTransmissionTime(Ptr< const Packet > packet, const WifiMacHeader *hdr, const MacLowTransmissionParameters ¶meters) const
control how a packet is transmitted.
MpduType
The type of an MPDU.
void SetCtsToSelfSupported(bool enable)
Enable or disable CTS-to-self capability.
bool expectCfAck
Flag used for PCF to indicate whether a CF-ACK should be expected.
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
uint32_t GetNextPacketSize(void) const
Time timestamp
the timestamp
WifiPreamble GetPreambleType(void) const
void RemovePhyMacLowListener(Ptr< WifiPhy > phy)
Remove current WifiPhy listener for this MacLow.
Time CalculateTxDuration(uint32_t size, WifiTxVector txVector, uint16_t frequency)
bool IsPromisc(void) const
Check if MacLow is operating in promiscuous mode.
void NotifyOn(void)
Notify listeners that we went to switch on.
WifiTxVector m_currentTxVector
TXVECTOR used for the current packet transmission.
The MPDU is not part of an A-MPDU.
void DestroyBlockAckAgreement(Mac48Address originator, uint8_t tid)
Time m_lastNavDuration
The duration of the latest NAV.
void SetCfpMaxDuration(Time duration)
Time GetCtsDuration(WifiTxVector ctsTxVector) const
Return the time required to transmit the CTS (including preamble and FCS).
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 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.
Mac48Address GetAddress(void) const
Return the MAC address of this MacLow.
void CreateBlockAckAgreement(const MgtAddBaResponseHeader *respHdr, Mac48Address originator, uint16_t startingSeq)
Time m_lastBeacon
The time when the last beacon frame transmission started.
void ReportRtsFailed(Mac48Address address, const WifiMacHeader *header)
Should be invoked whenever the RtsTimeout associated to a transmission attempt expires.
uint16_t GetTimeout(void) const
Return the timeout.
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.
static const uint16_t MAX_MSDU_SIZE
This value conforms to the 802.11 specification.
Time GetSifs(void) const
Return Short Interframe Space (SIFS) of this MacLow.
void EndTxNoAck(void)
A transmission that does not require an ACK has completed.
uint32_t GetSerializedSize(void) const
void SendBlockAckAfterAmpdu(uint8_t tid, Mac48Address originator, Time duration, WifiTxVector blockAckReqTxVector, double rxSnr)
Invoked after an A-MPDU has been received.
bool MustWaitNormalAck(void) const
std::map< AgreementKey, BlockAckCache >::iterator BlockAckCachesI
block ack caches iterator typedef
virtual bool IsCfPeriod(void) const
This function indicates whether it is the CF period.
void SetAckTimeout(Time ackTimeout)
Set ACK timeout of this MacLow.
static TypeId GetTypeId(void)
Register this type.
indicates whether the socket has a priority set.
AcIndex QosUtilsMapTidToAc(uint8_t tid)
Maps TID (Traffic ID) to Access classes.
Time GetCtsTimeout(void) const
Return CTS timeout of this MacLow.
WifiMode GetMode(void) const
void NavCounterResetCtsMissed(Time rtsEndRxTime)
Reset NAV after CTS was missed when the NAV was set with RTS.
Ptr< WifiRemoteStationManager > m_stationManager
Pointer to WifiRemoteStationManager (rate control)
uint32_t PeekHeader(Header &header) const
Deserialize but does not remove the header from the internal buffer.
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
void SendDataAfterCts(Time duration)
Send DATA after receiving CTS.
void RegisterEdcaForAc(AcIndex ac, Ptr< QosTxop > edca)
Agreements m_bAckAgreements
block ack agreements
Ptr< WifiMacQueue > m_aggregateQueue[8]
Queues per TID used for MPDU aggregation.
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 ...
void NotifySwitchingStartNow(Time duration)
WifiModulationClass GetModulationClass() const
bool HasNextPacket(void) const
void NotifyOff(void)
Notify listeners that we went to switch off.
Time GetCfpMaxDuration(void) const
Time m_slotTime
Slot duration.
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...
Mac48Address GetPeer(void) const
Return the peer address.
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.
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...
std::list< BufferedPacket >::iterator BufferedPacketI
buffered packet iterator typedef
void SetStartingSequence(uint16_t seq)
Set starting sequence number.
void BlockAckTimeout(void)
Event handler when block ACK timeout occurs.
void NotifyCtsTimeoutStartNow(Time duration)
Notify ChannelAccessManager that CTS timer should be started for the given duration.
The MPDU is part of an A-MPDU, but is not the last aggregate.
uint8_t GetRemainingNbOfMpdus(void) const
Time GetAckTimeout(void) const
Return ACK timeout of this MacLow.
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.
Time GetRemainingCfpDuration(void) const
void GotCfEnd(void)
Event handler when a CF-END frame is received.
Time GetCompressedBlockAckTimeout() const
Return Compressed Block ACK timeout of this MacLow.
bool HasHeSupported(void) const
Return whether the device has HE capability support enabled.
void RegisterDcf(Ptr< ChannelAccessManager > dcf)
void SetAggregation(bool aggregation)
Sets if PSDU contains A-MPDU.
void SetBssid(Mac48Address ad)
Set the Basic Service Set Identification.
uint16_t GetFrequency(void) const
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.
virtual void MissedBlockAck(uint8_t nMpdus)
Event handler when a Block ACK timeout has occurred.
bool HasPcfSupported(void) const
Return whether the device has PCF capability support enabled.
EventId m_normalAckTimeoutEvent
Normal ACK timeout event.
void StartDataTxTimers(WifiTxVector dataTxVector)
Start a DATA timer by scheduling appropriate ACK timeout.
void NotifyWakeup(void)
Notify listeners that we woke up.
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Time m_beaconInterval
Expected interval between two beacon transmissions.
void NotifyCtsTimeoutResetNow()
Notify ChannelAccessManager that CTS timer should be reset.
bool IsInWindow(uint16_t seq, uint16_t winstart, uint16_t winsize)
uint32_t RemoveTrailer(Trailer &trailer)
Remove a deserialized trailer from the internal buffer.
Ptr< const Packet > packet
the packet
Time m_cfpForeshortening
The delay the current CF period should be foreshortened.
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 GetAckDuration(WifiTxVector ackTxVector) const
Return the time required to transmit the ACK (including preamble and FCS).
Time m_ackTimeout
ACK timeout duration.
uint8_t GetTid(Ptr< const Packet > packet, const WifiMacHeader hdr)
Extraction operator for TypeId.
Time GetRemainingAmpduDuration(void) const
void DisableRts(void)
Do not send rts and wait for cts before sending data.
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.
bool HasHtSupported(void) const
Return whether the device has HT capability support enabled.
Time m_basicBlockAckTimeout
Basic block ACK timeout duration.
bool GetCtsToSelfSupported() const
Return whether CTS-to-self capability is supported.
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.
void SetBeaconInterval(Time interval)
void SetDelayedBlockAck(void)
Set Block ACK policy to delayed ACK.
void NotifySleep(void)
Notify listeners that we went to sleep.
uint32_t GetCtsSize(void)
Return the total CTS size (including FCS trailer).
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.
handle RTS/CTS/DATA/ACK transactions.
Mac48Address address
Address of the station to be acknowledged.
void SetReceiveOkCallback(RxOkCallback callback)
EventId m_sendDataEvent
Event to send DATA.
bool IsStateTx(void) const
bool ReceiveMpdu(Ptr< Packet > packet, WifiMacHeader hdr)
void ReportDataFailed(Mac48Address address, const WifiMacHeader *header, uint32_t packetSize)
Should be invoked whenever the AckTimeout associated to a transmission attempt expires.
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 ChannelAccessManager that ACK timer should be reset.
WifiTxVector GetDataTxVector(Mac48Address address, const WifiMacHeader *header, Ptr< const Packet > packet)
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 ...
Mac48Address m_self
Address of this MacLow (Mac48Address)
Maintains information for a block ack agreement.
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 ...
void AddPacketTag(const Tag &tag) const
Add a packet tag.
uint32_t QosUtilsMapSeqControlToUniqueInteger(uint16_t seqControl, uint16_t endSequence)
Next function is useful to correctly sort buffered packets under block ack.
void EnableRts(void)
Send a RTS, and wait CTSTimeout for a CTS.
void NotifyAckTimeoutStartNow(Time duration)
Notify ChannelAccessManager that ACK timer should be started for the given duration.
bool CanTransmitNextCfFrame(void) const
This function decides if a CF frame can be transmitted in the current CFP.
void SetSlotTime(Time slotTime)
Set slot duration of this MacLow.
virtual void GotAck(void)
Event handler when an ACK is received.
Ptr< Packet > m_currentPacket
Current packet transmitted/to be transmitted.
bool IsPositive(void) const
void Reset(void)
Reset the station, invoked in a STA upon dis-association or in an AP upon reboot. ...
bool GetUseNonErpProtection(void) const
Return whether the device supports protection of non-ERP stations.
virtual void MissedCts(void)
Event handler when a CTS timeout has occurred.
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Time m_cfpStart
The time when the latest CF period started.
ns3::MacLow * m_macLow
the MAC
The MPDU is the last aggregate in an A-MPDU.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
uint32_t GetBlockAckSize(BlockAckType type)
Return the total Block ACK size (including FCS trailer).
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.
bool IsRunning(void) const
This method is syntactic sugar for !IsExpired().
void MissedCfPollResponse(bool expectedCfAck)
Event handler when a response to a CF-POLL frame is missed.
Time GetBlockAckDuration(WifiTxVector blockAckReqTxVector, BlockAckType type) const
Return the time required to transmit the Block ACK to the specified address given the TXVECTOR of the...
CfAckInfo m_cfAckInfo
Info about piggyback ACKs used in PCF.
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 SetImmediateBlockAck(void)
Set Block ACK policy to immediate ACK.
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.
Time GetPifs(void) const
Return PCF Interframe Space (PIFS) of this MacLow.
WifiMacHeader m_currentHdr
Header of the current transmitted packet.
void SetAddress(Mac48Address ad)
Set MAC address of this MacLow.
uint32_t GetCfEndSize(void) const
Return the total CF-END size (including FCS trailer).
WifiTxVector GetRtsTxVector(Mac48Address address, const WifiMacHeader *header, Ptr< const Packet > packet)
A base class which provides memory management and object aggregation.
bool MustWaitBasicBlockAck(void) const
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.
Time GetBeaconInterval(void) const
Ptr< Packet > PerformMsduAggregation(Ptr< const Packet > packet, WifiMacHeader *hdr, Time *tstamp, Ptr< Packet > currentAmpduPacket, uint8_t blockAckSize)
Perform MSDU aggregation for a given MPDU in an A-MPDU.
bool PeekPacketTag(Tag &tag) const
Search a matching tag and call Tag::Deserialize if it is found.
Time m_compressedBlockAckTimeout
Compressed block ACK timeout duration.
void CfPollTimeout(void)
Event handler when CF-POLL timeout occurs.
void SetRemainingNbOfMpdus(uint8_t nbofmpdus)
WifiTxVector GetBlockAckTxVector(Mac48Address address, WifiMode dataMode)
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.
virtual void GotBlockAck(const CtrlBAckResponseHeader *blockAck, Mac48Address recipient, double rxSnr, WifiMode txMode, double dataSnr)
Event handler when a Block ACK is received.
void DisableAck(void)
Do not wait for Ack after data transmission.
std::pair< BlockAckAgreement, std::list< BufferedPacket > > AgreementValue
agreement value typedef
Time GetSlotTime(void) const
Return slot duration of this MacLow.
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.
a unique identifier for an interface.
void SetRxCallback(Callback< void, Ptr< Packet >, const WifiMacHeader *> callback)
WifiTxVector GetAckTxVector(Mac48Address address, WifiMode dataMode)
bool NeedCtsToSelf(void) const
Check if CTS-to-self mechanism should be used for the current packet.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Time GetLastRxStartTime(void) const
Return the start time of the last received packet.
uint8_t GetTid(void) const
Return the Traffic ID (TID).
Time GetBasicBlockAckTimeout() const
Return Basic Block ACK timeout of this MacLow.
bool IsStateRx(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.
Introspection did not find any typical Config paths.
bool StoreMpduIfNeeded(Ptr< Packet > packet, WifiMacHeader hdr)
virtual bool HasTxop(void) const
Check if the station has TXOP granted for the next MPDU.
A struct for packet, Wifi header, and timestamp.item structure.
Ptr< WifiPhy > m_phy
Pointer to WifiPhy (actually send/receives frames)
uint64_t GetDataRate(uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
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.
Ptr< WifiPhy > GetPhy(void) const
class PhyMacLowListener * m_phyMacLowListener
Listener needed to monitor when a channel switching occurs.
ChannelAccessManagers m_channelAccessManagers
List of ChannelAccessManager.
void SendRtsForPacket(void)
Send RTS to begin RTS-CTS-DATA-ACK transaction.
BlockAckType
The different block ACK policies.
void RxCompleteBufferedPacketsUntilFirstLost(Mac48Address originator, uint8_t tid)
void SetRemainingAmpduDuration(Time duration)
Time GetTxopLimit(void) const
Return the TXOP limit.