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 << "] "
98 : m_normalAckTimeoutEvent (),
99 m_fastAckTimeoutEvent (),
100 m_superFastAckTimeoutEvent (),
101 m_fastAckFailedTimeoutEvent (),
102 m_blockAckTimeoutEvent (),
103 m_ctsTimeoutEvent (),
108 m_endTxNoAckEvent (),
112 m_lastNavDuration (
Seconds (0)),
115 m_phyMacLowListener (0),
116 m_ctsToSelfSupported (false)
119 for (uint8_t i = 0; i < 8; i++)
136 .SetGroupName (
"Wifi")
137 .AddConstructor<
MacLow> ()
182 for (uint8_t i = 0; i < 8; i++)
193 bool oneRunning =
false;
447 uint32_t size, actualSize;
452 if (actualSize > size)
532 std::map<AcIndex, Ptr<EdcaTxopN> >::const_iterator edcaIt =
m_edca.find (ac);
534 for (uint8_t i = 0; i < sentMpdus; i++)
539 edcaIt->second->GetMpduAggregator ()->Aggregate (newPacket, aggregatedPacket);
620 NS_LOG_DEBUG (
"switching channel. Cancelling MAC pending events");
636 NS_LOG_DEBUG (
"Device in sleep mode. Cancelling MAC pending events");
651 NS_LOG_DEBUG (
"Device is switched off. Cancelling MAC pending events");
694 && hdr.GetAddr1 () ==
m_self)
696 NS_LOG_DEBUG (
"rx RTS from=" << hdr.GetAddr2 () <<
", schedule CTS");
709 NS_LOG_DEBUG (
"rx RTS from=" << hdr.GetAddr2 () <<
", cannot schedule CTS");
713 else if (hdr.IsCts ()
714 && hdr.GetAddr1 () ==
m_self
730 rxSnr, txVector.
GetMode (), tag.Get ());
739 else if (hdr.IsAck ()
740 && hdr.GetAddr1 () ==
m_self
755 rxSnr, txVector.
GetMode (), tag.Get ());
804 else if (hdr.IsBlockAck () && hdr.GetAddr1 () ==
m_self
808 NS_LOG_DEBUG (
"got block ack from " << hdr.GetAddr2 ());
816 m_currentDca->GotBlockAck (&blockAck, hdr.GetAddr2 (), rxSnr, txVector.
GetMode (), tag.Get ());
830 else if (hdr.IsBlockAckReq () && hdr.GetAddr1 () ==
m_self)
849 if ((*it).second.first.IsImmediateBlockAck ())
851 NS_LOG_DEBUG (
"rx blockAckRequest/sendImmediateBlockAck from=" << hdr.GetAddr2 ());
867 NS_LOG_DEBUG (
"There's not a valid agreement for this block ack request.");
875 else if (hdr.IsCtl ())
879 else if (hdr.GetAddr1 () ==
m_self)
890 if (hdr.IsQosAck () && !ampduSubframe)
892 NS_LOG_DEBUG (
"rx QoS unicast/sendAck from=" << hdr.GetAddr2 ());
896 hdr.GetAddr2 (), hdr.GetQosTid ());
906 else if (hdr.IsQosBlockAck ())
914 else if (hdr.IsQosData () && hdr.IsQosBlockAck ())
925 m_edca[ac]->SendDelbaFrame (hdr.GetAddr2 (), hdr.GetQosTid (),
false);
928 else if (hdr.IsQosData () && hdr.IsQosNoAck ())
932 NS_LOG_DEBUG (
"rx Ampdu with No Ack Policy from=" << hdr.GetAddr2 ());
936 NS_LOG_DEBUG (
"rx unicast/noAck from=" << hdr.GetAddr2 ());
939 else if (hdr.IsData () || hdr.IsMgt ())
941 if (hdr.IsProbeResp ())
948 if (hdr.IsMgt () && ampduSubframe)
950 NS_FATAL_ERROR (
"Received management packet as part of an A-MPDU");
954 NS_LOG_DEBUG (
"rx unicast/sendAck from=" << hdr.GetAddr2 ());
966 else if (hdr.GetAddr1 ().IsGroup ())
970 NS_FATAL_ERROR (
"Received group addressed packet as part of an A-MPDU");
974 if (hdr.IsData () || hdr.IsMgt ())
998 NS_LOG_DEBUG (
"rx not for me from=" << hdr.GetAddr2 ());
1094 uint32_t fragmentSize)
const
1106 if (fragmentSize > 0)
1158 if (hdr.
IsRts () && navUpdated)
1171 Time navCounterResetCtsMissedDelay =
1195 (*i)->NotifyNavResetNow (duration);
1206 (*i)->NotifyNavStartNow (duration);
1210 if (newNavEnd > oldNavEnd)
1213 m_lastNavDuration = duration;
1224 (*i)->NotifyAckTimeoutStartNow (duration);
1233 (*i)->NotifyAckTimeoutResetNow ();
1242 (*i)->NotifyCtsTimeoutStartNow (duration);
1251 (*i)->NotifyCtsTimeoutResetNow ();
1261 ", size=" << packet->
GetSize () <<
1262 ", mode=" << txVector.
GetMode () <<
1276 bool singleMpdu =
false;
1280 uint8_t tid =
GetTid (packet, *hdr);
1282 std::map<AcIndex, Ptr<EdcaTxopN> >::const_iterator edcaIt =
m_edca.find (ac);
1293 if (queueSize > 1 || singleMpdu)
1297 for (; queueSize > 0; queueSize--)
1300 newHdr = dequeuedItem->GetHeader ();
1301 newPacket = dequeuedItem->GetPacket ()->Copy ();
1311 edcaIt->second->GetMpduAggregator ()->AddHeaderAndPad (newPacket, last, singleMpdu);
1328 remainingAmpduDuration -= mpduDuration;
1352 delay = delay + mpduDuration;
1430 dca->MissedBlockAck (nTxMpdus);
1557 Time delay = txDuration;
1570 Time delay = txDuration;
1730 cts.SetDsNotFrom ();
1732 cts.SetNoMoreFragments ();
1734 cts.SetAddr1 (source);
1738 cts.SetDuration (duration);
1766 for (std::vector<Item>::size_type i = 0; i !=
m_txPackets[tid].size (); i++)
1769 std::map<AcIndex, Ptr<EdcaTxopN> >::const_iterator edcaIt =
m_edca.find (ac);
1819 duration -= txDuration;
1822 duration =
std::max (duration, newDuration);
1926 uint16_t delta = (seqNumber - (*it).second.first.GetWinEnd () + 4096) % 4096;
1929 (*it).second.first.SetWinEnd (seqNumber);
1930 int16_t winEnd = (*it).second.first.GetWinEnd ();
1931 int16_t bufferSize = (*it).second.first.GetBufferSize ();
1932 uint16_t sum = (
static_cast<uint16_t
> (std::abs (winEnd - bufferSize + 1))) % 4096;
1933 (*it).second.first.SetStartingSequence (sum);
1938 (*it).second.first.SetWinEnd (((*it).second.first.GetStartingSequence () + (*it).second.first.GetBufferSize () - 1) % 4096);
1957 uint16_t endSequence = ((*it).second.first.GetStartingSequence () + 2047) % 4096;
1961 for (; i != (*it).second.second.end ()
1965 (*it).second.second.insert (i, bufferedPacket);
1970 (*j).second.UpdateWithMpdu (&hdr);
1978 uint16_t startingSeq)
1981 uint8_t tid = respHdr->
GetTid ();
1996 std::list<BufferedPacket> buffer (0);
2014 m_edca[ac], originator, tid,
false);
2040 uint16_t endSequence = ((*it).second.first.GetStartingSequence () + 2047) % 4096;
2044 if (last != (*it).second.second.end ())
2046 guard = (*it).second.second.begin ()->second.GetSequenceControl ();
2049 for (; i != (*it).second.second.end ()
2052 if (guard == (*i).second.GetSequenceControl ())
2054 if (!(*i).second.IsMoreFragments ())
2064 while (i != (*it).second.second.end () && guard == (*i).second.GetSequenceControl ())
2068 if (i != (*it).second.second.end ())
2070 guard = (*i).second.GetSequenceControl ();
2082 while (i != (*it).second.second.end () && guard == (*i).second.GetSequenceControl ())
2086 if (i != (*it).second.second.end ())
2088 guard = (*i).second.GetSequenceControl ();
2093 (*it).second.second.erase ((*it).second.second.begin (), i);
2103 uint16_t guard = (*it).second.first.GetStartingSequenceControl ();
2106 for (; i != (*it).second.second.end () && guard == (*i).second.GetSequenceControl (); i++)
2108 if (!(*i).second.IsMoreFragments ())
2110 while (lastComplete != i)
2112 m_rxCallback ((*lastComplete).first, &(*lastComplete).second);
2115 m_rxCallback ((*lastComplete).first, &(*lastComplete).second);
2118 guard = (*i).second.IsMoreFragments () ? (guard + 1) : ((guard + 16) & 0xfff0);
2120 (*it).second.first.SetStartingSequenceControl (guard);
2123 (*it).second.second.erase ((*it).second.second.begin (), lastComplete);
2128 Time duration,
WifiMode blockAckReqTxMode,
double rxSnr)
2195 uint16_t seqNumber = 0;
2198 seqNumber = (*i).second.GetWinStart ();
2200 bool immediate =
true;
2202 blockAck.SetStartingSequence (seqNumber);
2203 blockAck.SetTidInfo (tid);
2204 immediate = (*it).second.first.IsImmediateBlockAck ();
2206 NS_LOG_DEBUG (
"Got Implicit block Ack Req with seq " << seqNumber);
2207 (*i).second.FillBlockAckBitmap (&blockAck);
2219 Time duration,
WifiMode blockAckReqTxMode,
double rxSnr)
2224 bool immediate =
false;
2233 immediate = (*it).second.first.IsImmediateBlockAck ();
2244 (*i).second.FillBlockAckBitmap (&blockAck);
2262 (*it).second.first.SetWinEnd (((*it).second.first.GetStartingSequence () + (*it).second.first.GetBufferSize () - 1) % 4096);
2265 (*it).second.first.SetWinEnd (((*it).second.first.GetStartingSequence () + (*it).second.first.GetBufferSize () - 1) % 4096);
2271 NS_LOG_DEBUG (
"there's not a valid block ack agreement with " << originator);
2293 agreement.
GetTid (),
false);
2300 m_edca.insert (std::make_pair (ac, edca));
2308 bool normalAck =
false;
2309 bool ampduSubframe =
false;
2312 ampduSubframe =
true;
2317 (*n).first->PeekHeader (firsthdr);
2323 bool singleMpdu = (*n).second.GetEof ();
2328 ampduSubframe =
false;
2343 ReceiveOk ((*n).first, rxSnr, txVector, ampduSubframe);
2348 ReceiveOk ((*n).first, rxSnr, txVector, ampduSubframe);
2367 NS_FATAL_ERROR (
"Sending a BlockAckReq with QosPolicy equal to Normal Ack");
2380 NS_LOG_DEBUG (
"There's not a valid agreement for this block ack request.");
2388 ReceiveOk (aggregatedPacket, rxSnr, txVector, ampduSubframe);
2395 if (peekedPacket == 0)
2402 uint8_t tid =
GetTid (peekedPacket, peekedHdr);
2404 std::map<AcIndex, Ptr<EdcaTxopN> >::const_iterator edcaIt =
m_edca.find (ac);
2414 NS_LOG_DEBUG (
"no more packets can be aggregated to satisfy PPDU <= aPPDUMaxTime");
2420 NS_LOG_DEBUG (
"no more packets can be aggregated because the maximum A-MPDU size has been reached");
2430 bool isAmpdu =
false;
2433 newPacket = packet->
Copy ();
2451 uint8_t tid =
GetTid (packet, hdr);
2454 std::map<AcIndex, Ptr<EdcaTxopN> >::const_iterator edcaIt =
m_edca.find (ac);
2456 queue = edcaIt->second->GetQueue ();
2461 if (edcaIt->second->GetBaAgreementExists (hdr.
GetAddr1 (), tid))
2465 currentAggregatedPacket = Create<Packet> ();
2467 uint16_t startingSequenceNumber = 0;
2468 uint16_t currentSequenceNumber = 0;
2469 uint8_t qosPolicy = 0;
2470 uint16_t blockAckSize = 0;
2471 bool aggregated =
false;
2479 startingSequenceNumber = peekedHdr.GetSequenceNumber ();
2482 currentSequenceNumber = peekedHdr.GetSequenceNumber ();
2486 aggregated = edcaIt->second->GetMpduAggregator ()->Aggregate (newPacket, currentAggregatedPacket);
2490 NS_LOG_DEBUG (
"Adding packet with sequence number " << currentSequenceNumber <<
" to A-MPDU, packet size = " << newPacket->
GetSize () <<
", A-MPDU size = " << currentAggregatedPacket->
GetSize ());
2492 m_aggregateQueue[tid]->Enqueue (Create<WifiMacQueueItem> (aggPacket, peekedHdr));
2505 Ptr<const Packet> peekedPacket = edcaIt->second->PeekNextRetransmitPacket (peekedHdr, peekedHdr.GetAddr1 (), tid, &tstamp);
2506 if (peekedPacket == 0)
2513 peekedPacket = item->GetPacket ();
2514 peekedHdr = item->GetHeader ();
2515 tstamp = item->GetTimeStamp ();
2517 currentSequenceNumber = edcaIt->second->PeekNextSequenceNumberFor (&peekedHdr);
2520 if (peekedPacket != 0 && edcaIt->second->GetMsduAggregator () != 0)
2522 tempPacket =
PerformMsduAggregation (peekedPacket, &peekedHdr, &tstamp, currentAggregatedPacket, blockAckSize);
2523 if (tempPacket != 0)
2525 peekedPacket = tempPacket->
Copy ();
2532 currentSequenceNumber = peekedHdr.GetSequenceNumber ();
2535 while (
IsInWindow (currentSequenceNumber, startingSequenceNumber, 64) && !
StopMpduAggregation (peekedPacket, peekedHdr, currentAggregatedPacket, blockAckSize))
2540 currentSequenceNumber = edcaIt->second->GetNextSequenceNumberFor (&peekedHdr);
2541 peekedHdr.SetSequenceNumber (currentSequenceNumber);
2542 peekedHdr.SetFragmentNumber (0);
2543 peekedHdr.SetNoMoreFragments ();
2544 peekedHdr.SetNoRetry ();
2555 newPacket = peekedPacket->
Copy ();
2560 aggregated = edcaIt->second->GetMpduAggregator ()->Aggregate (newPacket, currentAggregatedPacket);
2563 m_aggregateQueue[tid]->Enqueue (Create<WifiMacQueueItem> (aggPacket, peekedHdr));
2568 edcaIt->second->CompleteMpduTx (packet, hdr, tstamp);
2575 NS_LOG_DEBUG (
"Adding packet with sequence number " << peekedHdr.GetSequenceNumber () <<
" to A-MPDU, packet size = " << newPacket->
GetSize () <<
", A-MPDU size = " << currentAggregatedPacket->
GetSize ());
2580 edcaIt->second->CompleteMpduTx (peekedPacket, peekedHdr, tstamp);
2588 edcaIt->second->RemoveRetransmitPacket (tid, hdr.
GetAddr1 (), peekedHdr.GetSequenceNumber ());
2592 queue->Remove (peekedPacket);
2602 peekedPacket = edcaIt->second->PeekNextRetransmitPacket (peekedHdr, hdr.
GetAddr1 (), tid, &tstamp);
2603 if (peekedPacket == 0)
2612 peekedPacket = item->GetPacket ();
2613 peekedHdr = item->GetHeader ();
2614 tstamp = item->GetTimeStamp ();
2616 currentSequenceNumber = edcaIt->second->PeekNextSequenceNumberFor (&peekedHdr);
2618 if (edcaIt->second->GetMsduAggregator () != 0)
2620 tempPacket =
PerformMsduAggregation (peekedPacket, &peekedHdr, &tstamp, currentAggregatedPacket, blockAckSize);
2621 if (tempPacket != 0)
2623 peekedPacket = tempPacket->
Copy ();
2630 currentSequenceNumber = peekedHdr.GetSequenceNumber ();
2639 peekedPacket = item->GetPacket ();
2640 peekedHdr = item->GetHeader ();
2641 tstamp = item->GetTimeStamp ();
2643 currentSequenceNumber = edcaIt->second->PeekNextSequenceNumberFor (&peekedHdr);
2645 if (edcaIt->second->GetMsduAggregator () != 0 &&
IsInWindow (currentSequenceNumber, startingSequenceNumber, 64))
2647 tempPacket =
PerformMsduAggregation (peekedPacket, &peekedHdr, &tstamp, currentAggregatedPacket, blockAckSize);
2648 if (tempPacket != 0)
2650 peekedPacket = tempPacket->
Copy ();
2665 newPacket = packet->
Copy ();
2668 m_aggregateQueue[tid]->Enqueue (Create<WifiMacQueueItem> (aggPacket, peekedHdr));
2671 edcaIt->second->GetMpduAggregator ()->Aggregate (newPacket, currentAggregatedPacket);
2672 currentAggregatedPacket->
AddHeader (blockAckReq);
2677 edcaIt->second->CompleteAmpduTransfer (hdr.
GetAddr1 (), tid);
2683 newPacket = currentAggregatedPacket;
2687 edcaIt->second->SetAmpduExist (hdr.
GetAddr1 (),
true);
2710 currentAggregatedPacket = Create<Packet> ();
2711 edcaIt->second->GetMpduAggregator ()->AggregateSingleMpdu (packet, currentAggregatedPacket);
2712 m_aggregateQueue[tid]->Enqueue (Create<WifiMacQueueItem> (packet, peekedHdr));
2717 if (edcaIt->second->GetBaAgreementExists (hdr.
GetAddr1 (), tid))
2719 edcaIt->second->CompleteAmpduTransfer (peekedHdr.
GetAddr1 (), tid);
2724 newPacket = currentAggregatedPacket;
2730 edcaIt->second->SetAmpduExist (hdr.
GetAddr1 (),
true);
2762 bool msduAggregation =
false;
2763 bool isAmsdu =
false;
2764 Ptr<Packet> currentAmsduPacket = Create<Packet> ();
2769 std::map<AcIndex, Ptr<EdcaTxopN> >::const_iterator edcaIt =
m_edca.find (ac);
2771 queue = edcaIt->second->GetQueue ();
2778 *hdr = peekedItem->GetHeader ();
2781 edcaIt->second->GetMsduAggregator ()->Aggregate (packet, currentAmsduPacket,
2782 edcaIt->second->MapSrcAddressForAggregation (*hdr),
2783 edcaIt->second->MapDestAddressForAggregation (*hdr));
2786 while (peekedItem != 0)
2788 *hdr = peekedItem->GetHeader ();
2789 *tstamp = peekedItem->GetTimeStamp ();
2790 tempPacket = currentAmsduPacket;
2792 msduAggregation = edcaIt->second->GetMsduAggregator ()->Aggregate (peekedItem->GetPacket (), tempPacket,
2793 edcaIt->second->MapSrcAddressForAggregation (*hdr),
2794 edcaIt->second->MapDestAddressForAggregation (*hdr));
2796 if (msduAggregation && !
StopMpduAggregation (tempPacket, *hdr, currentAmpduPacket, blockAckSize))
2799 currentAmsduPacket = tempPacket;
2800 queue->Remove (peekedItem->GetPacket ());
2814 return currentAmsduPacket;
2818 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.
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 AddWifiMacTrailer(Ptr< Packet > packet)
Add FCS trailer to a packet.
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 SetupPhyMacLowListener(const Ptr< WifiPhy > phy)
Set up WifiPhy listener for this MacLow.
uint32_t GetRtsSize(void)
Return the total RTS size (including FCS trailer).
Mac48Address GetPeer(void) const
Return the peer address.
bool IsStateRx(void) const
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.
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 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.
Ptr< DcaTxop > m_currentDca
Current DCA.
std::pair< Mac48Address, uint8_t > AgreementKey
agreement key typedef
void SetReceiveErrorCallback(RxErrorCallback callback)
WifiTxVector GetCtsTxVector(Mac48Address address, WifiMode rtsMode)
Time CalculateOverallTxTime(Ptr< const Packet > packet, const WifiMacHeader *hdr, const MacLowTransmissionParameters ¶ms, uint32_t fragmentSize=0) const
#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 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.
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)
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 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
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.
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)
void NotifyOn(void)
Notify listeners that we went to switch on.
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.
NS_ASSERT_MSG(false,"Ipv4AddressGenerator::MaskToIndex(): Impossible")
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.
void CreateBlockAckAgreement(const MgtAddBaResponseHeader *respHdr, Mac48Address originator, uint16_t startingSeq)
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 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.
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)
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Mac48Address GetAddress(void) const
Return the MAC address of this MacLow.
void SendDataAfterCts(Time duration)
Send DATA after receiving CTS.
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 ...
void NotifySwitchingStartNow(Time duration)
void NotifyOff(void)
Notify listeners that we went to switch off.
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.
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.
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.
void StartDataTxTimers(WifiTxVector dataTxVector)
Start a DATA timer by scheduling appropriate ACK timeout.
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
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 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.
uint8_t GetTid(Ptr< const Packet > packet, const WifiMacHeader hdr)
Extraction operator for TypeId.
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.
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.
bool IsStateTx(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.
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.
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.
WifiTxVector GetRtsTxVector(Ptr< const Packet > packet, const WifiMacHeader *hdr) const
Return a TXVECTOR for the RTS frame given the destination.
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)
bool HasHeSupported(void) const
Return whether the device has HE capability support enabled.
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.
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.
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...
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.
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 IsStateOff(void) const
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 SetImmediateBlockAck(void)
Set Block ACK policy to immediate ACK.
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.
bool IsStateIdle(void) const
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)