23 #include "ns3/assert.h"
24 #include "ns3/packet.h"
25 #include "ns3/simulator.h"
29 #include "ns3/double.h"
33 #include "wifi-mac-trailer.h"
34 #include "qos-utils.h"
35 #include "edca-txop-n.h"
40 #undef NS_LOG_APPEND_CONTEXT
41 #define NS_LOG_APPEND_CONTEXT std::clog << "[mac=" << m_self << "] "
46 MacLowTransmissionListener::MacLowTransmissionListener ()
49 MacLowTransmissionListener::~MacLowTransmissionListener ()
61 MacLowDcfListener::MacLowDcfListener ()
64 MacLowDcfListener::~MacLowDcfListener ()
68 MacLowBlockAckEventListener::MacLowBlockAckEventListener ()
71 MacLowBlockAckEventListener::~MacLowBlockAckEventListener ()
75 MacLowTransmissionParameters::MacLowTransmissionParameters ()
79 m_overrideDurationId (
Seconds (0))
95 m_overrideDurationId = durationId;
100 m_overrideDurationId =
Seconds (0);
105 m_waitAck = ACK_SUPER_FAST;
110 m_waitAck = BLOCK_ACK_BASIC;
115 m_waitAck = BLOCK_ACK_COMPRESSED;
120 m_waitAck = BLOCK_ACK_MULTI_TID;
125 m_waitAck = ACK_FAST;
130 m_waitAck = ACK_NORMAL;
135 m_waitAck = ACK_NONE;
150 return (m_waitAck != ACK_NONE);
155 return (m_waitAck == ACK_NORMAL);
160 return (m_waitAck == ACK_FAST);
165 return (m_waitAck == ACK_SUPER_FAST);
170 return (m_waitAck == BLOCK_ACK_BASIC) ?
true :
false;
175 return (m_waitAck == BLOCK_ACK_COMPRESSED) ?
true :
false;
180 return (m_waitAck == BLOCK_ACK_MULTI_TID) ?
true :
false;
190 return (m_overrideDurationId !=
Seconds (0));
196 return m_overrideDurationId;
201 return (m_nextSize != 0);
213 <<
"send rts=" << params.m_sendRts <<
", "
214 <<
"next size=" << params.m_nextSize <<
", "
215 <<
"dur=" << params.m_overrideDurationId <<
", "
217 switch (params.m_waitAck)
219 case MacLowTransmissionParameters::ACK_NONE:
222 case MacLowTransmissionParameters::ACK_NORMAL:
225 case MacLowTransmissionParameters::ACK_FAST:
228 case MacLowTransmissionParameters::ACK_SUPER_FAST:
231 case MacLowTransmissionParameters::BLOCK_ACK_BASIC:
232 os <<
"basic-block-ack";
234 case MacLowTransmissionParameters::BLOCK_ACK_COMPRESSED:
235 os <<
"compressed-block-ack";
237 case MacLowTransmissionParameters::BLOCK_ACK_MULTI_TID:
238 os <<
"multi-tid-block-ack";
290 : m_normalAckTimeoutEvent (),
291 m_fastAckTimeoutEvent (),
292 m_superFastAckTimeoutEvent (),
293 m_fastAckFailedTimeoutEvent (),
294 m_blockAckTimeoutEvent (),
295 m_ctsTimeoutEvent (),
300 m_endTxNoAckEvent (),
305 m_lastNavDuration =
Seconds (0);
318 MacLow::SetupPhyMacLowListener (Ptr<WifiPhy> phy)
320 m_phyMacLowListener =
new PhyMacLowListener (
this);
321 phy->RegisterListener (m_phyMacLowListener);
329 m_normalAckTimeoutEvent.
Cancel ();
330 m_fastAckTimeoutEvent.
Cancel ();
331 m_superFastAckTimeoutEvent.
Cancel ();
332 m_fastAckFailedTimeoutEvent.
Cancel ();
333 m_blockAckTimeoutEvent.
Cancel ();
334 m_ctsTimeoutEvent.
Cancel ();
337 m_sendDataEvent.
Cancel ();
338 m_waitSifsEvent.
Cancel ();
339 m_endTxNoAckEvent.
Cancel ();
341 m_stationManager = 0;
342 delete m_phyMacLowListener;
343 m_phyMacLowListener = 0;
347 MacLow::CancelAllEvents (
void)
350 bool oneRunning =
false;
351 if (m_normalAckTimeoutEvent.
IsRunning ())
353 m_normalAckTimeoutEvent.
Cancel ();
358 m_fastAckTimeoutEvent.
Cancel ();
361 if (m_superFastAckTimeoutEvent.
IsRunning ())
363 m_superFastAckTimeoutEvent.
Cancel ();
366 if (m_fastAckFailedTimeoutEvent.
IsRunning ())
368 m_fastAckFailedTimeoutEvent.
Cancel ();
373 m_blockAckTimeoutEvent.
Cancel ();
378 m_ctsTimeoutEvent.
Cancel ();
393 m_sendDataEvent.
Cancel ();
398 m_waitSifsEvent.
Cancel ();
403 m_endTxNoAckEvent.
Cancel ();
406 if (oneRunning && m_listener != 0)
414 MacLow::SetPhy (Ptr<WifiPhy> phy)
419 SetupPhyMacLowListener (phy);
422 MacLow::GetPhy (
void)
427 MacLow::SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> manager)
429 m_stationManager = manager;
433 MacLow::SetAddress (Mac48Address ad)
438 MacLow::SetAckTimeout (Time ackTimeout)
440 m_ackTimeout = ackTimeout;
443 MacLow::SetBasicBlockAckTimeout (Time blockAckTimeout)
445 m_basicBlockAckTimeout = blockAckTimeout;
448 MacLow::SetCompressedBlockAckTimeout (Time blockAckTimeout)
450 m_compressedBlockAckTimeout = blockAckTimeout;
453 MacLow::SetCtsTimeout (Time ctsTimeout)
455 m_ctsTimeout = ctsTimeout;
458 MacLow::SetSifs (Time sifs)
463 MacLow::SetSlotTime (Time slotTime)
465 m_slotTime = slotTime;
468 MacLow::SetPifs (Time pifs)
473 MacLow::SetBssid (Mac48Address bssid)
478 MacLow::SetPromisc (
void)
483 MacLow::GetAddress (
void)
const
488 MacLow::GetAckTimeout (
void)
const
493 MacLow::GetBasicBlockAckTimeout ()
const
495 return m_basicBlockAckTimeout;
498 MacLow::GetCompressedBlockAckTimeout ()
const
500 return m_compressedBlockAckTimeout;
503 MacLow::GetCtsTimeout (
void)
const
508 MacLow::GetSifs (
void)
const
513 MacLow::GetSlotTime (
void)
const
518 MacLow::GetPifs (
void)
const
523 MacLow::GetBssid (
void)
const
531 m_rxCallback = callback;
536 m_dcfListeners.push_back (listener);
561 m_currentPacket = packet->
Copy ();
564 m_listener = listener;
569 NS_LOG_DEBUG (
"startTx size=" << GetSize (m_currentPacket, &m_currentHdr) <<
570 ", to=" << m_currentHdr.GetAddr1 () <<
", listener=" << m_listener);
594 &MacLow::FastAckFailedTimeout,
this);
602 NS_LOG_DEBUG (
"switching channel. Cancelling MAC pending events");
603 m_stationManager->Reset ();
605 if (m_navCounterResetCtsMissed.
IsRunning ())
607 m_navCounterResetCtsMissed.
Cancel ();
610 m_lastNavDuration =
Seconds (0);
619 m_stationManager->Reset ();
621 if (m_navCounterResetCtsMissed.
IsRunning ())
623 m_navCounterResetCtsMissed.
Cancel ();
626 m_lastNavDuration =
Seconds (0);
643 bool isPrevNavZero = IsNavZero ();
655 && hdr.GetAddr1 () == m_self)
657 NS_LOG_DEBUG (
"rx RTS from=" << hdr.GetAddr2 () <<
", schedule CTS");
659 m_stationManager->ReportRxOk (hdr.GetAddr2 (), &hdr,
662 &MacLow::SendCtsAfterRts,
this,
670 NS_LOG_DEBUG (
"rx RTS from=" << hdr.GetAddr2 () <<
", cannot schedule CTS");
673 else if (hdr.IsCts ()
674 && hdr.GetAddr1 () == m_self
676 && m_currentPacket != 0)
678 NS_LOG_DEBUG (
"receive cts from=" << m_currentHdr.GetAddr1 ());
681 m_stationManager->ReportRxOk (m_currentHdr.GetAddr1 (), &m_currentHdr,
683 m_stationManager->ReportRtsOk (m_currentHdr.GetAddr1 (), &m_currentHdr,
684 rxSnr, txMode, tag.Get ());
686 m_ctsTimeoutEvent.
Cancel ();
687 NotifyCtsTimeoutResetNow ();
688 m_listener->
GotCts (rxSnr, txMode);
691 &MacLow::SendDataAfterCts,
this,
696 else if (hdr.IsAck ()
697 && hdr.GetAddr1 () == m_self
700 || m_superFastAckTimeoutEvent.
IsRunning ())
703 NS_LOG_DEBUG (
"receive ack from=" << m_currentHdr.GetAddr1 ());
706 m_stationManager->ReportRxOk (m_currentHdr.GetAddr1 (), &m_currentHdr,
708 m_stationManager->ReportDataOk (m_currentHdr.GetAddr1 (), &m_currentHdr,
709 rxSnr, txMode, tag.Get ());
714 m_normalAckTimeoutEvent.
Cancel ();
715 NotifyAckTimeoutResetNow ();
721 m_fastAckTimeoutEvent.
Cancel ();
722 NotifyAckTimeoutResetNow ();
727 m_listener->
GotAck (rxSnr, txMode);
732 &MacLow::WaitSifsAfterEndTx,
this);
735 else if (hdr.IsBlockAck () && hdr.GetAddr1 () == m_self
739 NS_LOG_DEBUG (
"got block ack from " << hdr.GetAddr2 ());
742 m_blockAckTimeoutEvent.
Cancel ();
743 m_listener->
GotBlockAck (&blockAck, hdr.GetAddr2 ());
745 else if (hdr.IsBlockAckReq () && hdr.GetAddr1 () == m_self)
749 if (!blockAckReq.IsMultiTid ())
751 uint8_t tid = blockAckReq.GetTidInfo ();
752 AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), tid));
753 if (it != m_bAckAgreements.end ())
756 BlockAckCachesI i = m_bAckCaches.find (std::make_pair (hdr.GetAddr2 (), tid));
758 (*i).second.UpdateWithBlockAckReq (blockAckReq.GetStartingSequence ());
762 ResetBlockAckInactivityTimerIfNeeded (it->second.first);
763 if ((*it).second.first.IsImmediateBlockAck ())
765 NS_LOG_DEBUG (
"rx blockAckRequest/sendImmediateBlockAck from=" << hdr.GetAddr2 ());
767 &MacLow::SendBlockAckAfterBlockAckRequest,
this,
780 NS_LOG_DEBUG (
"There's not a valid agreement for this block ack request.");
788 else if (hdr.IsCtl ())
792 else if (hdr.GetAddr1 () == m_self)
794 m_stationManager->ReportRxOk (hdr.GetAddr2 (), &hdr,
797 if (hdr.IsQosData () && StoreMpduIfNeeded (packet, hdr))
806 AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), hdr.GetQosTid ()));
808 hdr.GetAddr2 (), hdr.GetQosTid ());
812 &MacLow::SendAckAfterData,
this,
818 else if (hdr.IsQosBlockAck ())
820 AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), hdr.GetQosTid ()));
822 ResetBlockAckInactivityTimerIfNeeded (it->second.first);
826 else if (hdr.IsQosData () && hdr.IsQosBlockAck ())
837 m_edcaListeners[ac]->BlockAckInactivityTimeout (hdr.GetAddr2 (), hdr.GetQosTid ());
840 else if (hdr.IsQosData () && hdr.IsQosNoAck ())
842 NS_LOG_DEBUG (
"rx unicast/noAck from=" << hdr.GetAddr2 ());
844 else if (hdr.IsData () || hdr.IsMgt ())
846 NS_LOG_DEBUG (
"rx unicast/sendAck from=" << hdr.GetAddr2 ());
849 &MacLow::SendAckAfterData,
this,
857 else if (hdr.GetAddr1 ().
IsGroup ())
859 if (hdr.IsData () || hdr.IsMgt ())
885 m_rxCallback (packet, &hdr);
890 MacLow::GetAckSize (
void)
const
893 ack.SetType (WIFI_MAC_CTL_ACK);
894 return ack.GetSize () + 4;
897 MacLow::GetBlockAckSize (
enum BlockAckType type)
const
900 hdr.SetType (WIFI_MAC_CTL_BACKRESP);
901 CtrlBAckResponseHeader blockAck;
902 if (type == BASIC_BLOCK_ACK)
904 blockAck.SetType (BASIC_BLOCK_ACK);
906 else if (type == COMPRESSED_BLOCK_ACK)
908 blockAck.SetType (COMPRESSED_BLOCK_ACK);
910 else if (type == MULTI_TID_BLOCK_ACK)
915 return hdr.GetSize () + blockAck.GetSerializedSize () + 4;
918 MacLow::GetRtsSize (
void)
const
921 rts.SetType (WIFI_MAC_CTL_RTS);
922 return rts.GetSize () + 4;
925 MacLow::GetAckDuration (Mac48Address to, WifiMode dataTxMode)
const
927 WifiMode ackMode = GetAckTxModeForData (to, dataTxMode);
931 MacLow::GetBlockAckDuration (Mac48Address to, WifiMode blockAckReqTxMode,
enum BlockAckType type)
const
941 return m_phy->
CalculateTxDuration (GetBlockAckSize (type), blockAckReqTxMode, WIFI_PREAMBLE_LONG);
944 MacLow::GetCtsDuration (Mac48Address to, WifiMode rtsTxMode)
const
946 WifiMode ctsMode = GetCtsTxModeForRts (to, rtsTxMode);
950 MacLow::GetCtsSize (
void)
const
953 cts.SetType (WIFI_MAC_CTL_CTS);
954 return cts.GetSize () + 4;
957 MacLow::GetSize (Ptr<const Packet> packet,
const WifiMacHeader *hdr)
const
960 return packet->GetSize () + hdr->GetSize () + fcs.GetSerializedSize ();
964 MacLow::GetRtsTxMode (Ptr<const Packet> packet,
const WifiMacHeader *hdr)
const
966 Mac48Address to = hdr->GetAddr1 ();
967 return m_stationManager->GetRtsMode (to, hdr, packet);
970 MacLow::GetDataTxMode (Ptr<const Packet> packet,
const WifiMacHeader *hdr)
const
972 Mac48Address to = hdr->GetAddr1 ();
974 uint32_t size = packet->GetSize () + hdr->GetSize () + fcs.GetSerializedSize ();
975 return m_stationManager->GetDataMode (to, hdr, packet, size);
979 MacLow::GetCtsTxModeForRts (Mac48Address to, WifiMode rtsTxMode)
const
981 return m_stationManager->GetCtsMode (to, rtsTxMode);
984 MacLow::GetAckTxModeForData (Mac48Address to, WifiMode dataTxMode)
const
986 return m_stationManager->GetAckMode (to, dataTxMode);
991 MacLow::CalculateOverallTxTime (Ptr<const Packet> packet,
992 const WifiMacHeader* hdr,
993 const MacLowTransmissionParameters& params)
const
996 WifiMode rtsMode = GetRtsTxMode (packet, hdr);
997 WifiMode dataMode = GetDataTxMode (packet, hdr);
998 if (params.MustSendRts ())
1001 txTime += GetCtsDuration (hdr->GetAddr1 (), rtsMode);
1002 txTime += Time (GetSifs () * 2);
1004 uint32_t dataSize = GetSize (packet, hdr);
1006 if (params.MustWaitAck ())
1008 txTime += GetSifs ();
1009 txTime += GetAckDuration (hdr->GetAddr1 (), dataMode);
1019 Time txTime = CalculateOverallTxTime (packet, hdr, params);
1022 WifiMode dataMode = GetDataTxMode (packet, hdr);
1023 txTime += GetSifs ();
1033 Time duration = hdr.GetDuration ();
1036 && hdr.GetAddr2 () == m_bssid)
1039 DoNavResetNow (duration);
1044 else if (hdr.GetAddr1 () != m_self)
1047 bool navUpdated = DoNavStartNow (duration);
1048 if (hdr.IsRts () && navUpdated)
1059 cts.SetType (WIFI_MAC_CTL_CTS);
1060 Time navCounterResetCtsMissedDelay =
1062 Time (2 * GetSifs ()) +
Time (2 * GetSlotTime ());
1064 &MacLow::NavCounterResetCtsMissed,
this,
1071 MacLow::NavCounterResetCtsMissed (
Time rtsEndRxTime)
1073 if (m_phy->GetLastRxStartTime () > rtsEndRxTime)
1075 DoNavResetNow (
Seconds (0.0));
1080 MacLow::DoNavResetNow (Time duration)
1082 for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++)
1084 (*i)->NavReset (duration);
1087 m_lastNavStart = duration;
1090 MacLow::DoNavStartNow (Time duration)
1092 for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++)
1094 (*i)->NavStart (duration);
1097 Time oldNavEnd = m_lastNavStart + m_lastNavDuration;
1098 if (newNavEnd > oldNavEnd)
1101 m_lastNavDuration = duration;
1107 MacLow::NotifyAckTimeoutStartNow (Time duration)
1109 for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++)
1111 (*i)->AckTimeoutStart (duration);
1115 MacLow::NotifyAckTimeoutResetNow ()
1117 for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++)
1119 (*i)->AckTimeoutReset ();
1123 MacLow::NotifyCtsTimeoutStartNow (Time duration)
1125 for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++)
1127 (*i)->CtsTimeoutStart (duration);
1131 MacLow::NotifyCtsTimeoutResetNow ()
1133 for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++)
1135 (*i)->CtsTimeoutReset ();
1140 MacLow::ForwardDown (Ptr<const Packet> packet,
const WifiMacHeader* hdr,
1145 ", to=" << hdr->GetAddr1 () <<
1146 ", size=" << packet->GetSize () <<
1147 ", mode=" << txMode <<
1148 ", duration=" << hdr->GetDuration () <<
1149 ", seq=0x" << std::hex << m_currentHdr.GetSequenceControl () << std::dec);
1150 m_phy->
SendPacket (packet, txMode, WIFI_PREAMBLE_LONG, 0);
1154 MacLow::CtsTimeout (
void)
1161 m_stationManager->ReportRtsFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
1162 m_currentPacket = 0;
1163 MacLowTransmissionListener *listener = m_listener;
1168 MacLow::NormalAckTimeout (
void)
1175 m_stationManager->ReportDataFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
1176 MacLowTransmissionListener *listener = m_listener;
1181 MacLow::FastAckTimeout (
void)
1184 m_stationManager->ReportDataFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
1185 MacLowTransmissionListener *listener = m_listener;
1190 listener->MissedAck ();
1198 MacLow::BlockAckTimeout (
void)
1203 m_stationManager->ReportDataFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
1204 MacLowTransmissionListener *listener = m_listener;
1209 MacLow::SuperFastAckTimeout ()
1212 m_stationManager->ReportDataFailed (m_currentHdr.GetAddr1 (), &m_currentHdr);
1213 MacLowTransmissionListener *listener = m_listener;
1218 listener->MissedAck ();
1223 listener->GotAck (0.0, WifiMode ());
1228 MacLow::SendRtsForPacket (
void)
1233 rts.SetType (WIFI_MAC_CTL_RTS);
1234 rts.SetDsNotFrom ();
1237 rts.SetNoMoreFragments ();
1238 rts.SetAddr1 (m_currentHdr.GetAddr1 ());
1239 rts.SetAddr2 (m_self);
1240 WifiMode rtsTxMode = GetRtsTxMode (m_currentPacket, &m_currentHdr);
1248 WifiMode dataTxMode = GetDataTxMode (m_currentPacket, &m_currentHdr);
1249 duration += GetSifs ();
1250 duration += GetCtsDuration (m_currentHdr.GetAddr1 (), rtsTxMode);
1251 duration += GetSifs ();
1253 dataTxMode, WIFI_PREAMBLE_LONG);
1254 duration += GetSifs ();
1255 duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxMode);
1257 rts.SetDuration (duration);
1259 Time txDuration = m_phy->
CalculateTxDuration (GetRtsSize (), rtsTxMode, WIFI_PREAMBLE_LONG);
1260 Time timerDelay = txDuration + GetCtsTimeout ();
1263 NotifyCtsTimeoutStartNow (timerDelay);
1266 Ptr<Packet> packet = Create<Packet> ();
1267 packet->AddHeader (rts);
1269 packet->AddTrailer (fcs);
1271 ForwardDown (packet, &rts, rtsTxMode);
1275 MacLow::StartDataTxTimers (
void)
1277 WifiMode dataTxMode = GetDataTxMode (m_currentPacket, &m_currentHdr);
1278 Time txDuration = m_phy->
CalculateTxDuration (GetSize (m_currentPacket, &m_currentHdr), dataTxMode, WIFI_PREAMBLE_LONG);
1281 Time timerDelay = txDuration + GetAckTimeout ();
1283 NotifyAckTimeoutStartNow (timerDelay);
1284 m_normalAckTimeoutEvent =
Simulator::Schedule (timerDelay, &MacLow::NormalAckTimeout,
this);
1288 Time timerDelay = txDuration + GetPifs ();
1290 NotifyAckTimeoutStartNow (timerDelay);
1295 Time timerDelay = txDuration + GetPifs ();
1297 NotifyAckTimeoutStartNow (timerDelay);
1299 &MacLow::SuperFastAckTimeout,
this);
1303 Time timerDelay = txDuration + GetBasicBlockAckTimeout ();
1305 m_blockAckTimeoutEvent =
Simulator::Schedule (timerDelay, &MacLow::BlockAckTimeout,
this);
1309 Time timerDelay = txDuration + GetCompressedBlockAckTimeout ();
1311 m_blockAckTimeoutEvent =
Simulator::Schedule (timerDelay, &MacLow::BlockAckTimeout,
this);
1315 Time delay = txDuration + GetSifs ();
1327 MacLow::SendDataPacket (
void)
1331 StartDataTxTimers ();
1333 WifiMode dataTxMode = GetDataTxMode (m_currentPacket, &m_currentHdr);
1334 Time duration =
Seconds (0.0);
1343 duration += GetSifs ();
1344 duration += GetBlockAckDuration (m_currentHdr.GetAddr1 (), dataTxMode, BASIC_BLOCK_ACK);
1348 duration += GetSifs ();
1349 duration += GetBlockAckDuration (m_currentHdr.GetAddr1 (), dataTxMode, COMPRESSED_BLOCK_ACK);
1353 duration += GetSifs ();
1354 duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxMode);
1358 duration += GetSifs ();
1360 dataTxMode, WIFI_PREAMBLE_LONG);
1363 duration += GetSifs ();
1364 duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxMode);
1368 m_currentHdr.SetDuration (duration);
1370 m_currentPacket->
AddHeader (m_currentHdr);
1374 ForwardDown (m_currentPacket, &m_currentHdr, dataTxMode);
1375 m_currentPacket = 0;
1379 MacLow::IsNavZero (
void)
const
1392 MacLow::SendCtsAfterRts (Mac48Address source, Time duration, WifiMode rtsTxMode,
double rtsSnr)
1398 WifiMode ctsTxMode = GetCtsTxModeForRts (source, rtsTxMode);
1400 cts.SetType (WIFI_MAC_CTL_CTS);
1401 cts.SetDsNotFrom ();
1403 cts.SetNoMoreFragments ();
1405 cts.SetAddr1 (source);
1406 duration -= GetCtsDuration (source, rtsTxMode);
1407 duration -= GetSifs ();
1409 cts.SetDuration (duration);
1411 Ptr<Packet> packet = Create<Packet> ();
1412 packet->AddHeader (cts);
1414 packet->AddTrailer (fcs);
1418 packet->AddPacketTag (tag);
1420 ForwardDown (packet, &cts, ctsTxMode);
1424 MacLow::SendDataAfterCts (Mac48Address source, Time duration, WifiMode txMode)
1431 StartDataTxTimers ();
1433 WifiMode dataTxMode = GetDataTxMode (m_currentPacket, &m_currentHdr);
1434 Time newDuration =
Seconds (0);
1435 newDuration += GetSifs ();
1436 newDuration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxMode);
1438 dataTxMode, WIFI_PREAMBLE_LONG);
1439 duration -= txDuration;
1440 duration -= GetSifs ();
1442 duration = std::max (duration, newDuration);
1444 m_currentHdr.SetDuration (duration);
1446 m_currentPacket->
AddHeader (m_currentHdr);
1450 ForwardDown (m_currentPacket, &m_currentHdr, dataTxMode);
1451 m_currentPacket = 0;
1455 MacLow::WaitSifsAfterEndTx (
void)
1461 MacLow::EndTxNoAck (
void)
1463 MacLowTransmissionListener *listener = m_listener;
1469 MacLow::FastAckFailedTimeout (
void)
1472 MacLowTransmissionListener *listener = m_listener;
1479 MacLow::SendAckAfterData (Mac48Address source, Time duration, WifiMode dataTxMode,
double dataSnr)
1485 WifiMode ackTxMode = GetAckTxModeForData (source, dataTxMode);
1487 ack.SetType (WIFI_MAC_CTL_ACK);
1488 ack.SetDsNotFrom ();
1491 ack.SetNoMoreFragments ();
1492 ack.SetAddr1 (source);
1493 duration -= GetAckDuration (source, dataTxMode);
1494 duration -= GetSifs ();
1496 ack.SetDuration (duration);
1498 Ptr<Packet> packet = Create<Packet> ();
1499 packet->AddHeader (ack);
1501 packet->AddTrailer (fcs);
1505 packet->AddPacketTag (tag);
1507 ForwardDown (packet, &ack, ackTxMode);
1511 MacLow::StoreMpduIfNeeded (Ptr<Packet> packet, WifiMacHeader hdr)
1513 AgreementsI it = m_bAckAgreements.find (std::make_pair (hdr.GetAddr2 (), hdr.GetQosTid ()));
1514 if (it != m_bAckAgreements.end ())
1517 packet->RemoveTrailer (fcs);
1518 BufferedPacket bufferedPacket (packet, hdr);
1520 uint16_t endSequence = ((*it).second.first.GetStartingSequence () + 2047) % 4096;
1523 BufferedPacketI i = (*it).second.second.begin ();
1524 for (; i != (*it).second.second.end ()
1529 (*it).second.second.insert (i, bufferedPacket);
1532 BlockAckCachesI j = m_bAckCaches.find (std::make_pair (hdr.GetAddr2 (), hdr.GetQosTid ()));
1534 (*j).second.UpdateWithMpdu (&hdr);
1543 uint16_t startingSeq)
1545 uint8_t tid = respHdr->GetTid ();
1547 if (respHdr->IsImmediateBlockAck ())
1549 agreement.SetImmediateBlockAck ();
1553 agreement.SetDelayedBlockAck ();
1555 agreement.SetAmsduSupport (respHdr->IsAmsduSupported ());
1556 agreement.SetBufferSize (respHdr->GetBufferSize () + 1);
1557 agreement.SetTimeout (respHdr->GetTimeout ());
1558 agreement.SetStartingSequence (startingSeq);
1560 std::list<BufferedPacket> buffer (0);
1561 AgreementKey key (originator, respHdr->GetTid ());
1562 AgreementValue value (agreement, buffer);
1563 m_bAckAgreements.insert (std::make_pair (key, value));
1566 cache.Init (startingSeq, respHdr->GetBufferSize () + 1);
1567 m_bAckCaches.insert (std::make_pair (key, cache));
1569 if (respHdr->GetTimeout () != 0)
1571 AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, respHdr->GetTid ()));
1578 m_edcaListeners[ac],
1586 AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid));
1587 if (it != m_bAckAgreements.end ())
1591 m_bAckAgreements.erase (it);
1593 BlockAckCachesI i = m_bAckCaches.find (std::make_pair (originator, tid));
1595 m_bAckCaches.erase (i);
1602 AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid));
1603 if (it != m_bAckAgreements.end ())
1605 uint16_t endSequence = ((*it).second.first.GetStartingSequence () + 2047) % 4096;
1607 uint16_t guard = (*it).second.second.begin ()->second.GetSequenceControl () & 0xfff0;
1608 BufferedPacketI last = (*it).second.second.begin ();
1610 BufferedPacketI i = (*it).second.second.begin ();
1611 for (; i != (*it).second.second.end ()
1614 if (guard == (*i).second.GetSequenceControl ())
1616 if (!(*i).second.IsMoreFragments ())
1620 m_rxCallback ((*last).first, &(*last).second);
1623 m_rxCallback ((*last).first, &(*last).second);
1626 while (i != (*it).second.second.end () && ((guard >> 4) & 0x0fff) == (*i).second.GetSequenceNumber ())
1630 if (i != (*it).second.second.end ())
1632 guard = (*i).second.GetSequenceControl () & 0xfff0;
1644 while (i != (*it).second.second.end () && ((guard >> 4) & 0x0fff) == (*i).second.GetSequenceNumber ())
1648 if (i != (*it).second.second.end ())
1650 guard = (*i).second.GetSequenceControl () & 0xfff0;
1655 (*it).second.second.erase ((*it).second.second.begin (), i);
1662 AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid));
1663 if (it != m_bAckAgreements.end ())
1665 uint16_t startingSeqCtrl = ((*it).second.first.GetStartingSequence () << 4) & 0xfff0;
1666 uint16_t guard = startingSeqCtrl;
1668 BufferedPacketI lastComplete = (*it).second.second.begin ();
1669 BufferedPacketI i = (*it).second.second.begin ();
1670 for (; i != (*it).second.second.end () && guard == (*i).second.GetSequenceControl (); i++)
1672 if (!(*i).second.IsMoreFragments ())
1674 while (lastComplete != i)
1676 m_rxCallback ((*lastComplete).first, &(*lastComplete).second);
1679 m_rxCallback ((*lastComplete).first, &(*lastComplete).second);
1682 guard = (*i).second.IsMoreFragments () ? (guard + 1) : ((guard + 16) & 0xfff0);
1684 (*it).second.first.SetStartingSequence ((guard >> 4) & 0x0fff);
1687 (*it).second.second.erase ((*it).second.second.begin (), lastComplete);
1699 hdr.SetType (WIFI_MAC_CTL_BACKRESP);
1700 hdr.SetAddr1 (originator);
1701 hdr.SetAddr2 (GetAddress ());
1702 hdr.SetDsNotFrom ();
1705 hdr.SetNoMoreFragments ();
1707 m_currentPacket = packet;
1712 duration -= GetSifs ();
1713 if (blockAck->IsBasic ())
1715 duration -= GetBlockAckDuration (originator, blockAckReqTxMode, BASIC_BLOCK_ACK);
1717 else if (blockAck->IsCompressed ())
1719 duration -= GetBlockAckDuration (originator, blockAckReqTxMode, COMPRESSED_BLOCK_ACK);
1721 else if (blockAck->IsMultiTid ())
1729 duration += GetSifs ();
1730 duration += GetAckDuration (originator, blockAckReqTxMode);
1736 StartDataTxTimers ();
1740 hdr.SetDuration (duration);
1746 ForwardDown (packet, &hdr, blockAckReqTxMode);
1747 m_currentPacket = 0;
1751 MacLow::SendBlockAckAfterBlockAckRequest (
const CtrlBAckRequestHeader reqHdr, Mac48Address originator,
1752 Time duration, WifiMode blockAckReqTxMode)
1755 CtrlBAckResponseHeader blockAck;
1757 bool immediate =
false;
1758 if (!reqHdr.IsMultiTid ())
1760 tid = reqHdr.GetTidInfo ();
1761 AgreementsI it = m_bAckAgreements.find (std::make_pair (originator, tid));
1762 if (it != m_bAckAgreements.end ())
1764 blockAck.SetStartingSequence (reqHdr.GetStartingSequence ());
1765 blockAck.SetTidInfo (tid);
1766 immediate = (*it).second.first.IsImmediateBlockAck ();
1767 if (reqHdr.IsBasic ())
1769 blockAck.SetType (BASIC_BLOCK_ACK);
1771 else if (reqHdr.IsCompressed ())
1773 blockAck.SetType (COMPRESSED_BLOCK_ACK);
1775 BlockAckCachesI i = m_bAckCaches.find (std::make_pair (originator, tid));
1777 (*i).second.FillBlockAckBitmap (&blockAck);
1787 NS_LOG_DEBUG (
"there's not a valid block ack agreement with " << originator);
1795 SendBlockAckResponse (&blockAck, originator, immediate, duration, blockAckReqTxMode);
1799 MacLow::ResetBlockAckInactivityTimerIfNeeded (BlockAckAgreement &agreement)
1801 if (agreement.GetTimeout () != 0)
1803 NS_ASSERT (agreement.m_inactivityEvent.IsRunning ());
1804 agreement.m_inactivityEvent.Cancel ();
1805 Time timeout =
MicroSeconds (1024 * agreement.GetTimeout ());
1813 m_edcaListeners[ac],
1814 agreement.GetPeer (),
1815 agreement.GetTid ());
1822 m_edcaListeners.insert (std::make_pair (ac, listener));
1826 MacLow::SetTxRadio(
bool isTx)
1838 MacLow::SetRxRadio(
bool isRx)
uint32_t RemoveHeader(Header &header)
bool MustSendRts(void) const
virtual void SendPacket(Ptr< const Packet > packet, WifiMode mode, enum WifiPreamble preamble, uint8_t txPowerLevel)=0
#define NS_LOG_FUNCTION(parameters)
virtual void GotAck(double snr, WifiMode txMode)=0
void EnableBasicBlockAck(void)
virtual void MissedAck(void)=0
#define NS_ASSERT(condition)
#define NS_LOG_COMPONENT_DEFINE(name)
virtual void NotifyRxEndError(void)
virtual void BlockAckInactivityTimeout(Mac48Address originator, uint8_t tid)=0
bool HasDurationId(void) const
bool IsRunning(void) const
void SetRxCallback(Callback< void, Ptr< Packet >, const WifiMacHeader * > callback)
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
listen to events coming from ns3::MacLow.
represent a single transmission modeA WifiMode is implemented by a single integer which is used to lo...
bool MustWaitFastAck(void) const
control how a packet is transmitted.The ns3::MacLow::StartTransmission method expects an instance of ...
#define NS_FATAL_ERROR(msg)
fatal error handling
virtual bool IsStateIdle(void)=0
void DestroyBlockAckAgreement(Mac48Address originator, uint8_t tid)
virtual void SetReceiveErrorCallback(RxErrorCallback callback)=0
void CreateBlockAckAgreement(const MgtAddBaResponseHeader *respHdr, Mac48Address originator, uint16_t startingSeq)
receive notifications about phy events.
void EnableSuperFastAck(void)
virtual void StartNext(void)=0
virtual void EndTxNoAck(void)=0
virtual void GotCts(double snr, WifiMode txMode)=0
AcIndex QosUtilsMapTidToAc(uint8_t tid)
virtual void NotifyRxStart(Time duration)
bool MustWaitMultiTidBlockAck(void) const
uint32_t GetNextPacketSize(void) const
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
bool HasNextPacket(void) const
static Time CalculateTxDuration(uint32_t size, WifiMode payloadMode, enum WifiPreamble preamble)
void RegisterDcfListener(MacLowDcfListener *listener)
void NotifySwitchingStartNow(Time duration)
void StartTransmission(Ptr< const Packet > packet, const WifiMacHeader *hdr, MacLowTransmissionParameters parameters, MacLowTransmissionListener *listener)
std::ostream & operator<<(std::ostream &os, const Angles &a)
Ptr< Packet > Copy(void) const
void EnableCompressedBlockAck(void)
listen for block ack events.
Time CalculateTransmissionTime(Ptr< const Packet > packet, const WifiMacHeader *hdr, const MacLowTransmissionParameters ¶meters) const
void AddTrailer(const Trailer &trailer)
bool MustWaitBasicBlockAck(void) const
bool MustWaitCompressedBlockAck(void) const
uint32_t RemoveTrailer(Trailer &trailer)
virtual void Cancel(void)=0
void NotifyNav(const WifiMacHeader &hdr, WifiMode txMode, WifiPreamble preamble)
virtual void NotifySensingStart(Time duration)
listen to NAV eventsThis class is typically connected to an instance of ns3::Dcf and calls to its met...
void EnableMultiTidBlockAck(void)
void RxCompleteBufferedPacketsWithSmallerSequence(uint16_t seq, Mac48Address originator, uint8_t tid)
virtual bool IsStateTx(void)=0
Time GetDurationId(void) const
virtual void MissedBlockAck(void)
void ReceiveError(Ptr< const Packet > packet, double rxSnr)
virtual void NotifyMaybeCcaBusyStart(Time duration)
handle RTS/CTS/DATA/ACK transactions.
virtual void MissedCts(void)=0
virtual void DoDispose(void)
bool MustWaitSuperFastAck(void) const
Time Seconds(double seconds)
create ns3::Time instances in units of seconds.
Maintains information for a block ack agreement.
uint32_t QosUtilsMapSeqControlToUniqueInteger(uint16_t seqControl, uint16_t endSequence)
bool RemovePacketTag(Tag &tag)
#define NS_LOG_DEBUG(msg)
virtual void NotifyTxStart(Time duration)
virtual void GotBlockAck(const CtrlBAckResponseHeader *blockAck, Mac48Address source)
void NotifySensingStartNow(Time duration)
virtual void NotifySwitchingStart(Time duration, uint16_t toChannel)
void EnableOverrideDurationId(Time durationId)
virtual void SetReceiveOkCallback(RxOkCallback callback)=0
void EnableNextData(uint32_t size)
void DisableOverrideDurationId(void)
void DisableNextData(void)
void ReceiveOk(Ptr< Packet > packet, double rxSnr, WifiMode txMode, WifiPreamble preamble)
bool MustWaitAck(void) const
void RegisterBlockAckListenerForAc(enum AcIndex ac, MacLowBlockAckEventListener *listener)
bool IsExpired(void) const
Time MicroSeconds(uint64_t us)
create ns3::Time instances in units of microseconds.
bool MustWaitNormalAck(void) const
void AddHeader(const Header &header)
virtual void NotifyRxEndOk(void)
void RxCompleteBufferedPacketsUntilFirstLost(Mac48Address originator, uint8_t tid)