00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "ns3/assert.h"
00022 #include "ns3/packet.h"
00023 #include "ns3/simulator.h"
00024 #include "ns3/tag.h"
00025 #include "ns3/log.h"
00026 #include "ns3/node.h"
00027
00028 #include "mac-low.h"
00029 #include "wifi-phy.h"
00030 #include "wifi-mac-trailer.h"
00031
00032 NS_LOG_COMPONENT_DEFINE ("MacLow");
00033
00034 #undef NS_LOG_APPEND_CONTEXT
00035 #define NS_LOG_APPEND_CONTEXT std::clog << "[mac=" << m_self << "] "
00036
00037
00038 namespace ns3 {
00039
00040 class SnrTag : public Tag
00041 {
00042 public:
00043
00044 static TypeId GetTypeId (void);
00045 virtual TypeId GetInstanceTypeId (void) const;
00046
00047 virtual uint32_t GetSerializedSize (void) const;
00048 virtual void Serialize (TagBuffer i) const;
00049 virtual void Deserialize (TagBuffer i);
00050 virtual void Print (std::ostream &os) const;
00051
00052 void Set (double snr);
00053 double Get (void) const;
00054 private:
00055 double m_snr;
00056 };
00057
00058 TypeId
00059 SnrTag::GetTypeId (void)
00060 {
00061 static TypeId tid = TypeId ("ns3::SnrTag")
00062 .SetParent<Tag> ()
00063 .AddConstructor<SnrTag> ()
00064 .AddAttribute ("Snr", "The snr of the last packet received",
00065 DoubleValue (0.0),
00066 MakeDoubleAccessor (&SnrTag::Get),
00067 MakeDoubleChecker<double> ())
00068 ;
00069 return tid;
00070 }
00071 TypeId
00072 SnrTag::GetInstanceTypeId (void) const
00073 {
00074 return GetTypeId ();
00075 }
00076
00077 uint32_t
00078 SnrTag::GetSerializedSize (void) const
00079 {
00080 return sizeof (double);
00081 }
00082 void
00083 SnrTag::Serialize (TagBuffer i) const
00084 {
00085 i.WriteDouble (m_snr);
00086 }
00087 void
00088 SnrTag::Deserialize (TagBuffer i)
00089 {
00090 m_snr = i.ReadDouble ();
00091 }
00092 void
00093 SnrTag::Print (std::ostream &os) const
00094 {
00095 os << "Snr=" << m_snr;
00096 }
00097 void
00098 SnrTag::Set (double snr)
00099 {
00100 m_snr = snr;
00101 }
00102 double
00103 SnrTag::Get (void) const
00104 {
00105 return m_snr;
00106 }
00107
00108
00109 MacLowTransmissionListener::MacLowTransmissionListener ()
00110 {}
00111 MacLowTransmissionListener::~MacLowTransmissionListener ()
00112 {}
00113 MacLowNavListener::MacLowNavListener ()
00114 {}
00115 MacLowNavListener::~MacLowNavListener ()
00116 {}
00117
00118 MacLowTransmissionParameters::MacLowTransmissionParameters ()
00119 : m_nextSize (0),
00120 m_waitAck (ACK_NONE),
00121 m_sendRts (false),
00122 m_overrideDurationId (Seconds (0))
00123 {}
00124 void
00125 MacLowTransmissionParameters::EnableNextData (uint32_t size)
00126 {
00127 m_nextSize = size;
00128 }
00129 void
00130 MacLowTransmissionParameters::DisableNextData (void)
00131 {
00132 m_nextSize = 0;
00133 }
00134 void
00135 MacLowTransmissionParameters::EnableOverrideDurationId (Time durationId)
00136 {
00137 m_overrideDurationId = durationId;
00138 }
00139 void
00140 MacLowTransmissionParameters::DisableOverrideDurationId (void)
00141 {
00142 m_overrideDurationId = Seconds (0);
00143 }
00144 void
00145 MacLowTransmissionParameters::EnableSuperFastAck (void)
00146 {
00147 m_waitAck = ACK_SUPER_FAST;
00148 }
00149 void
00150 MacLowTransmissionParameters::EnableFastAck (void)
00151 {
00152 m_waitAck = ACK_FAST;
00153 }
00154 void
00155 MacLowTransmissionParameters::EnableAck (void)
00156 {
00157 m_waitAck = ACK_NORMAL;
00158 }
00159 void
00160 MacLowTransmissionParameters::DisableAck (void)
00161 {
00162 m_waitAck = ACK_NONE;
00163 }
00164 void
00165 MacLowTransmissionParameters::EnableRts (void)
00166 {
00167 m_sendRts = true;
00168 }
00169 void
00170 MacLowTransmissionParameters::DisableRts (void)
00171 {
00172 m_sendRts = false;
00173 }
00174 bool
00175 MacLowTransmissionParameters::MustWaitAck (void) const
00176 {
00177 return (m_waitAck != ACK_NONE)?true:false;
00178 }
00179 bool
00180 MacLowTransmissionParameters::MustWaitNormalAck (void) const
00181 {
00182 return (m_waitAck == ACK_NORMAL)?true:false;
00183 }
00184 bool
00185 MacLowTransmissionParameters::MustWaitFastAck (void) const
00186 {
00187 return (m_waitAck == ACK_FAST)?true:false;
00188 }
00189 bool
00190 MacLowTransmissionParameters::MustWaitSuperFastAck (void) const
00191 {
00192 return (m_waitAck == ACK_SUPER_FAST)?true:false;
00193 }
00194 bool
00195 MacLowTransmissionParameters::MustSendRts (void) const
00196 {
00197 return m_sendRts;
00198 }
00199 bool
00200 MacLowTransmissionParameters::HasDurationId (void) const
00201 {
00202 return (m_overrideDurationId != Seconds (0))?true:false;
00203 }
00204 Time
00205 MacLowTransmissionParameters::GetDurationId (void) const
00206 {
00207 NS_ASSERT (m_overrideDurationId != Seconds (0));
00208 return m_overrideDurationId;
00209 }
00210 bool
00211 MacLowTransmissionParameters::HasNextPacket (void) const
00212 {
00213 return (m_nextSize != 0)?true:false;
00214 }
00215 uint32_t
00216 MacLowTransmissionParameters::GetNextPacketSize (void) const
00217 {
00218 NS_ASSERT (HasNextPacket ());
00219 return m_nextSize;
00220 }
00221
00222 std::ostream &operator << (std::ostream &os, const MacLowTransmissionParameters ¶ms)
00223 {
00224 os << "["
00225 << "send rts=" << params.m_sendRts << ", "
00226 << "next size=" << params.m_nextSize << ", "
00227 << "dur=" << params.m_overrideDurationId << ", "
00228 << "ack=";
00229 switch (params.m_waitAck) {
00230 case MacLowTransmissionParameters::ACK_NONE:
00231 os << "none";
00232 break;
00233 case MacLowTransmissionParameters::ACK_NORMAL:
00234 os << "normal";
00235 break;
00236 case MacLowTransmissionParameters::ACK_FAST:
00237 os << "fast";
00238 break;
00239 case MacLowTransmissionParameters::ACK_SUPER_FAST:
00240 os << "super-fast";
00241 break;
00242 }
00243 os << "]";
00244 return os;
00245 }
00246
00247 MacLow::MacLow ()
00248 : m_normalAckTimeoutEvent (),
00249 m_fastAckTimeoutEvent (),
00250 m_superFastAckTimeoutEvent (),
00251 m_fastAckFailedTimeoutEvent (),
00252 m_ctsTimeoutEvent (),
00253 m_sendCtsEvent (),
00254 m_sendAckEvent (),
00255 m_sendDataEvent (),
00256 m_waitSifsEvent (),
00257 m_currentPacket (0),
00258 m_listener (0)
00259 {
00260 NS_LOG_FUNCTION (this);
00261 m_lastNavDuration = Seconds (0);
00262 m_lastNavStart = Seconds (0);
00263 }
00264
00265 MacLow::~MacLow ()
00266 {
00267 NS_LOG_FUNCTION (this);
00268 }
00269
00270 void
00271 MacLow::DoDispose (void)
00272 {
00273 NS_LOG_FUNCTION (this);
00274 CancelAllEvents ();
00275 m_phy = 0;
00276 m_stationManager = 0;
00277 }
00278
00279 void
00280 MacLow::CancelAllEvents (void)
00281 {
00282 NS_LOG_FUNCTION (this);
00283 bool oneRunning = false;
00284 if (m_normalAckTimeoutEvent.IsRunning ())
00285 {
00286 m_normalAckTimeoutEvent.Cancel ();
00287 oneRunning = true;
00288 }
00289 if (m_fastAckTimeoutEvent.IsRunning ())
00290 {
00291 m_fastAckTimeoutEvent.Cancel ();
00292 oneRunning = true;
00293 }
00294 if (m_superFastAckTimeoutEvent.IsRunning ())
00295 {
00296 m_superFastAckTimeoutEvent.Cancel ();
00297 oneRunning = true;
00298 }
00299 if (m_fastAckFailedTimeoutEvent.IsRunning ())
00300 {
00301 m_fastAckFailedTimeoutEvent.Cancel ();
00302 oneRunning = true;
00303 }
00304 if (m_ctsTimeoutEvent.IsRunning ())
00305 {
00306 m_ctsTimeoutEvent.Cancel ();
00307 oneRunning = true;
00308 }
00309 if (m_sendCtsEvent.IsRunning ())
00310 {
00311 m_sendCtsEvent.Cancel ();
00312 oneRunning = true;
00313 }
00314 if (m_sendAckEvent.IsRunning ())
00315 {
00316 m_sendAckEvent.Cancel ();
00317 oneRunning = true;
00318 }
00319 if (m_sendDataEvent.IsRunning ())
00320 {
00321 m_sendDataEvent.Cancel ();
00322 oneRunning = true;
00323 }
00324 if (m_waitSifsEvent.IsRunning ())
00325 {
00326 m_waitSifsEvent.Cancel ();
00327 oneRunning = true;
00328 }
00329 if (oneRunning && m_listener != 0)
00330 {
00331 m_listener->Cancel ();
00332 m_listener = 0;
00333 }
00334 }
00335
00336 void
00337 MacLow::SetPhy (Ptr<WifiPhy> phy)
00338 {
00339 m_phy = phy;
00340 m_phy->SetReceiveOkCallback (MakeCallback (&MacLow::ReceiveOk, this));
00341 m_phy->SetReceiveErrorCallback (MakeCallback (&MacLow::ReceiveError, this));
00342 }
00343 void
00344 MacLow::SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> manager)
00345 {
00346 m_stationManager = manager;
00347 }
00348
00349 void
00350 MacLow::SetAddress (Mac48Address ad)
00351 {
00352 m_self = ad;
00353 }
00354 void
00355 MacLow::SetAckTimeout (Time ackTimeout)
00356 {
00357 m_ackTimeout = ackTimeout;
00358 }
00359 void
00360 MacLow::SetCtsTimeout (Time ctsTimeout)
00361 {
00362 m_ctsTimeout = ctsTimeout;
00363 }
00364 void
00365 MacLow::SetSifs (Time sifs)
00366 {
00367 m_sifs = sifs;
00368 }
00369 void
00370 MacLow::SetSlotTime (Time slotTime)
00371 {
00372 m_slotTime = slotTime;
00373 }
00374 void
00375 MacLow::SetPifs (Time pifs)
00376 {
00377 m_pifs = pifs;
00378 }
00379 void
00380 MacLow::SetBssid (Mac48Address bssid)
00381 {
00382 m_bssid = bssid;
00383 }
00384 Mac48Address
00385 MacLow::GetAddress (void) const
00386 {
00387 return m_self;
00388 }
00389 Time
00390 MacLow::GetAckTimeout (void) const
00391 {
00392 return m_ackTimeout;
00393 }
00394 Time
00395 MacLow::GetCtsTimeout (void) const
00396 {
00397 return m_ctsTimeout;
00398 }
00399 Time
00400 MacLow::GetSifs (void) const
00401 {
00402 return m_sifs;
00403 }
00404 Time
00405 MacLow::GetSlotTime (void) const
00406 {
00407 return m_slotTime;
00408 }
00409 Time
00410 MacLow::GetPifs (void) const
00411 {
00412 return m_pifs;
00413 }
00414 Mac48Address
00415 MacLow::GetBssid (void) const
00416 {
00417 return m_bssid;
00418 }
00419
00420 void
00421 MacLow::SetRxCallback (Callback<void,Ptr<Packet>,const WifiMacHeader *> callback)
00422 {
00423 m_rxCallback = callback;
00424 }
00425 void
00426 MacLow::RegisterNavListener (MacLowNavListener *listener)
00427 {
00428 m_navListeners.push_back (listener);
00429 }
00430
00431
00432 void
00433 MacLow::StartTransmission (Ptr<const Packet> packet,
00434 WifiMacHeader const*hdr,
00435 MacLowTransmissionParameters params,
00436 MacLowTransmissionListener *listener)
00437 {
00438 NS_LOG_FUNCTION (this << packet << hdr << params << listener);
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453 m_currentPacket = packet->Copy ();
00454 m_currentHdr = *hdr;
00455 CancelAllEvents ();
00456 m_listener = listener;
00457 m_txParams = params;
00458
00459
00460
00461 NS_LOG_DEBUG ("startTx size="<< GetSize (m_currentPacket, &m_currentHdr) <<
00462 ", to=" << m_currentHdr.GetAddr1()<<", listener="<<m_listener);
00463
00464 if (m_txParams.MustSendRts ())
00465 {
00466 SendRtsForPacket ();
00467 }
00468 else
00469 {
00470 SendDataPacket ();
00471 }
00472
00473
00474 NS_ASSERT (m_phy->IsStateTx ());
00475 }
00476
00477 void
00478 MacLow::ReceiveError (Ptr<const Packet> packet)
00479 {
00480 NS_LOG_FUNCTION (this << packet);
00481 NS_LOG_DEBUG ("rx failed ");
00482 if (m_txParams.MustWaitFastAck ())
00483 {
00484 NS_ASSERT (m_fastAckFailedTimeoutEvent.IsExpired ());
00485 m_fastAckFailedTimeoutEvent = Simulator::Schedule (GetSifs (),
00486 &MacLow::FastAckFailedTimeout, this);
00487 }
00488 return;
00489 }
00490
00491 void
00492 MacLow::ReceiveOk (Ptr<Packet> packet)
00493 {
00494 NS_LOG_FUNCTION (this << packet);
00495
00496
00497
00498 WifiMacHeader hdr;
00499 packet->RemoveHeader (hdr);
00500
00501 WifiPhyTxTag phyTxTag;
00502 packet->FindFirstMatchingTag(phyTxTag);
00503
00504 WifiPhyRxTag phyRxTag;
00505 packet->FindFirstMatchingTag(phyRxTag);
00506
00507 WifiMode txMode = phyTxTag.GetWifiMode();
00508 double rxSnr = phyRxTag.GetSnr();
00509
00510 bool isPrevNavZero = IsNavZero ();
00511 NS_LOG_DEBUG ("duration/id=" << hdr.GetDuration ());
00512 NotifyNav (hdr, txMode, phyTxTag.GetWifiPreamble());
00513
00514 if (hdr.IsRts ())
00515 {
00516
00517
00518
00519
00520
00521
00522 if (isPrevNavZero &&
00523 hdr.GetAddr1 () == m_self)
00524 {
00525 NS_LOG_DEBUG ("rx RTS from=" << hdr.GetAddr2 () << ", schedule CTS");
00526 NS_ASSERT (m_sendCtsEvent.IsExpired ());
00527 WifiRemoteStation *station = GetStation (hdr.GetAddr2 ());
00528 station->ReportRxOk (rxSnr, txMode);
00529 m_sendCtsEvent = Simulator::Schedule (GetSifs (),
00530 &MacLow::SendCtsAfterRts, this,
00531 hdr.GetAddr2 (),
00532 hdr.GetDuration (),
00533 txMode,
00534 rxSnr);
00535 }
00536 else
00537 {
00538 NS_LOG_DEBUG ("rx RTS from=" << hdr.GetAddr2 () << ", cannot schedule CTS");
00539 }
00540 }
00541 else if (hdr.IsCts () &&
00542 hdr.GetAddr1 () == m_self &&
00543 m_ctsTimeoutEvent.IsRunning () &&
00544 m_currentPacket != 0)
00545 {
00546 NS_LOG_DEBUG ("receive cts from="<<m_currentHdr.GetAddr1 ());
00547 SnrTag tag;
00548 packet->FindFirstMatchingTag (tag);
00549 WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
00550 station->ReportRxOk (rxSnr, txMode);
00551 station->ReportRtsOk (rxSnr, txMode, tag.Get ());
00552
00553 m_ctsTimeoutEvent.Cancel ();
00554 m_listener->GotCts (rxSnr, txMode);
00555 NS_ASSERT (m_sendDataEvent.IsExpired ());
00556 m_sendDataEvent = Simulator::Schedule (GetSifs (),
00557 &MacLow::SendDataAfterCts, this,
00558 hdr.GetAddr1 (),
00559 hdr.GetDuration (),
00560 txMode);
00561 }
00562 else if (hdr.IsAck () &&
00563 hdr.GetAddr1 () == m_self &&
00564 (m_normalAckTimeoutEvent.IsRunning () ||
00565 m_fastAckTimeoutEvent.IsRunning () ||
00566 m_superFastAckTimeoutEvent.IsRunning ()) &&
00567 m_txParams.MustWaitAck ())
00568 {
00569 NS_LOG_DEBUG ("receive ack from="<<m_currentHdr.GetAddr1 ());
00570 SnrTag tag;
00571 packet->FindFirstMatchingTag (tag);
00572 WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
00573 station->ReportRxOk (rxSnr, txMode);
00574 station->ReportDataOk (rxSnr, txMode, tag.Get ());
00575 bool gotAck = false;
00576 if (m_txParams.MustWaitNormalAck () &&
00577 m_normalAckTimeoutEvent.IsRunning ())
00578 {
00579 m_normalAckTimeoutEvent.Cancel ();
00580 gotAck = true;
00581 }
00582 if (m_txParams.MustWaitFastAck () &&
00583 m_fastAckTimeoutEvent.IsRunning ())
00584 {
00585 m_fastAckTimeoutEvent.Cancel ();
00586 gotAck = true;
00587 }
00588 if (gotAck)
00589 {
00590 m_listener->GotAck (rxSnr, txMode);
00591 }
00592 if (m_txParams.HasNextPacket ())
00593 {
00594 m_waitSifsEvent = Simulator::Schedule (GetSifs (),
00595 &MacLow::WaitSifsAfterEndTx, this);
00596 }
00597 }
00598 else if (hdr.IsCtl ())
00599 {
00600 NS_LOG_DEBUG ("rx drop " << hdr.GetTypeString ());
00601 }
00602 else if (hdr.GetAddr1 () == m_self)
00603 {
00604 WifiRemoteStation *station = GetStation (hdr.GetAddr2 ());
00605 station->ReportRxOk (rxSnr, txMode);
00606
00607 if (hdr.IsQosData () && hdr.IsQosNoAck ())
00608 {
00609 NS_LOG_DEBUG ("rx unicast/noAck from="<<hdr.GetAddr2 ());
00610 }
00611 else if (hdr.IsData () || hdr.IsMgt ())
00612 {
00613 NS_LOG_DEBUG ("rx unicast/sendAck from=" << hdr.GetAddr2 ());
00614 NS_ASSERT (m_sendAckEvent.IsExpired ());
00615 m_sendAckEvent = Simulator::Schedule (GetSifs (),
00616 &MacLow::SendAckAfterData, this,
00617 hdr.GetAddr2 (),
00618 hdr.GetDuration (),
00619 txMode,
00620 rxSnr);
00621 }
00622 goto rxPacket;
00623 }
00624 else if (hdr.GetAddr1 ().IsBroadcast ())
00625 {
00626 if (hdr.IsData () || hdr.IsMgt ())
00627 {
00628 NS_LOG_DEBUG ("rx broadcast from=" << hdr.GetAddr2 ());
00629 goto rxPacket;
00630 }
00631 else
00632 {
00633
00634 }
00635 }
00636 else
00637 {
00638
00639 }
00640 return;
00641 rxPacket:
00642 WifiMacTrailer fcs;
00643 packet->RemoveTrailer (fcs);
00644 m_rxCallback (packet, &hdr);
00645 return;
00646 }
00647
00648 uint32_t
00649 MacLow::GetAckSize (void) const
00650 {
00651 WifiMacHeader ack;
00652 ack.SetType (WIFI_MAC_CTL_ACK);
00653 return ack.GetSize () + 4;
00654 }
00655 uint32_t
00656 MacLow::GetRtsSize (void) const
00657 {
00658 WifiMacHeader rts;
00659 rts.SetType (WIFI_MAC_CTL_RTS);
00660 return rts.GetSize () + 4;
00661 }
00662 Time
00663 MacLow::GetAckDuration (Mac48Address to, WifiMode dataTxMode) const
00664 {
00665 WifiMode ackMode = GetAckTxModeForData (to, dataTxMode);
00666 return m_phy->CalculateTxDuration (GetAckSize (), ackMode, WIFI_PREAMBLE_LONG);
00667 }
00668 Time
00669 MacLow::GetCtsDuration (Mac48Address to, WifiMode rtsTxMode) const
00670 {
00671 WifiMode ctsMode = GetCtsTxModeForRts (to, rtsTxMode);
00672 return m_phy->CalculateTxDuration (GetCtsSize (), ctsMode, WIFI_PREAMBLE_LONG);
00673 }
00674 uint32_t
00675 MacLow::GetCtsSize (void) const
00676 {
00677 WifiMacHeader cts;
00678 cts.SetType (WIFI_MAC_CTL_CTS);
00679 return cts.GetSize () + 4;
00680 }
00681 uint32_t
00682 MacLow::GetSize (Ptr<const Packet> packet, const WifiMacHeader *hdr) const
00683 {
00684 WifiMacTrailer fcs;
00685 return packet->GetSize () + hdr->GetSize () + fcs.GetSerializedSize ();
00686 }
00687
00688 WifiMode
00689 MacLow::GetRtsTxMode (Ptr<const Packet> packet, const WifiMacHeader *hdr) const
00690 {
00691 Mac48Address to = hdr->GetAddr1 ();
00692 return GetStation (to)->GetRtsMode (packet);
00693 }
00694 WifiMode
00695 MacLow::GetDataTxMode (Ptr<const Packet> packet, const WifiMacHeader *hdr) const
00696 {
00697 Mac48Address to = hdr->GetAddr1 ();
00698 WifiMacTrailer fcs;
00699 uint32_t size = packet->GetSize () + hdr->GetSize () + fcs.GetSerializedSize ();
00700 return GetStation (to)->GetDataMode (packet, size);
00701 }
00702
00703 WifiMode
00704 MacLow::GetCtsTxModeForRts (Mac48Address to, WifiMode rtsTxMode) const
00705 {
00706 return GetStation (to)->GetCtsMode (rtsTxMode);
00707 }
00708 WifiMode
00709 MacLow::GetAckTxModeForData (Mac48Address to, WifiMode dataTxMode) const
00710 {
00711 return GetStation (to)->GetAckMode (dataTxMode);
00712 }
00713
00714
00715 Time
00716 MacLow::CalculateOverallTxTime (Ptr<const Packet> packet,
00717 WifiMacHeader const*hdr,
00718 MacLowTransmissionParameters const& params) const
00719 {
00720 Time txTime = Seconds (0);
00721 WifiMode rtsMode = GetRtsTxMode (packet, hdr);
00722 WifiMode dataMode = GetDataTxMode (packet, hdr);
00723 if (params.MustSendRts ())
00724 {
00725 txTime += m_phy->CalculateTxDuration (GetRtsSize (), rtsMode, WIFI_PREAMBLE_LONG);
00726 txTime += GetCtsDuration (hdr->GetAddr1 (), rtsMode);
00727 txTime += GetSifs () * Scalar (2);
00728 }
00729 uint32_t dataSize = GetSize (packet, hdr);
00730 txTime += m_phy->CalculateTxDuration (dataSize, dataMode, WIFI_PREAMBLE_LONG);
00731 if (params.MustWaitAck ())
00732 {
00733 txTime += GetSifs ();
00734 txTime += GetAckDuration (hdr->GetAddr1 (), dataMode);
00735 }
00736 return txTime;
00737 }
00738
00739 Time
00740 MacLow::CalculateTransmissionTime (Ptr<const Packet> packet,
00741 WifiMacHeader const*hdr,
00742 MacLowTransmissionParameters const& params) const
00743 {
00744 Time txTime = CalculateOverallTxTime (packet, hdr, params);
00745 if (params.HasNextPacket ())
00746 {
00747 WifiMode dataMode = GetDataTxMode (packet, hdr);
00748 txTime += GetSifs ();
00749 txTime += m_phy->CalculateTxDuration (params.GetNextPacketSize (), dataMode, WIFI_PREAMBLE_LONG);
00750 }
00751 return txTime;
00752 }
00753
00754 void
00755 MacLow::NotifyNav (const WifiMacHeader &hdr, WifiMode txMode, WifiPreamble preamble)
00756 {
00757 NS_ASSERT (m_lastNavStart <= Simulator::Now ());
00758 Time duration = hdr.GetDuration ();
00759
00760 if (hdr.IsCfpoll () &&
00761 hdr.GetAddr2 () == m_bssid)
00762 {
00763
00764 DoNavResetNow (duration);
00765 return;
00766 }
00767
00768
00769 else if (hdr.GetAddr1 () != m_self)
00770 {
00771
00772 bool navUpdated = DoNavStartNow (duration);
00773 if (hdr.IsRts () && navUpdated)
00774 {
00775
00776
00777
00778
00779
00780
00781
00782
00783 WifiMacHeader cts;
00784 cts.SetType (WIFI_MAC_CTL_CTS);
00785 Time navCounterResetCtsMissedDelay =
00786 m_phy->CalculateTxDuration (cts.GetSerializedSize (), txMode, preamble) +
00787 Scalar (2) * GetSifs () + Scalar (2) * GetSlotTime ();
00788 m_navCounterResetCtsMissed = Simulator::Schedule (navCounterResetCtsMissedDelay,
00789 &MacLow::NavCounterResetCtsMissed, this,
00790 Simulator::Now ());
00791 }
00792 }
00793 }
00794
00795 void
00796 MacLow::NavCounterResetCtsMissed (Time rtsEndRxTime)
00797 {
00798 if (m_phy->GetLastRxStartTime () > rtsEndRxTime)
00799 {
00800 DoNavResetNow (Seconds (0.0));
00801 }
00802 }
00803
00804 void
00805 MacLow::DoNavResetNow (Time duration)
00806 {
00807 for (NavListenersCI i = m_navListeners.begin (); i != m_navListeners.end (); i++)
00808 {
00809 (*i)->NavReset (duration);
00810 }
00811 m_lastNavStart = Simulator::Now ();
00812 m_lastNavStart = duration;
00813 }
00814 bool
00815 MacLow::DoNavStartNow (Time duration)
00816 {
00817 for (NavListenersCI i = m_navListeners.begin (); i != m_navListeners.end (); i++)
00818 {
00819 (*i)->NavStart (duration);
00820 }
00821 Time newNavEnd = Simulator::Now () + duration;
00822 Time oldNavEnd = m_lastNavStart + m_lastNavDuration;
00823 if (newNavEnd > oldNavEnd)
00824 {
00825 m_lastNavStart = Simulator::Now ();
00826 m_lastNavDuration = duration;
00827 return true;
00828 }
00829 return false;
00830 }
00831
00832 void
00833 MacLow::ForwardDown (Ptr<const Packet> packet, WifiMacHeader const* hdr,
00834 WifiMode txMode)
00835 {
00836 NS_LOG_FUNCTION (this << packet << hdr << txMode);
00837 NS_LOG_DEBUG ("send " << hdr->GetTypeString () <<
00838 ", to=" << hdr->GetAddr1 () <<
00839 ", size=" << packet->GetSize () <<
00840 ", mode=" << txMode <<
00841 ", duration=" << hdr->GetDuration () <<
00842 ", seq=0x"<< std::hex << m_currentHdr.GetSequenceControl () << std::dec);
00843 m_phy->SendPacket (packet, txMode, WIFI_PREAMBLE_LONG, 0);
00844
00845
00846
00847
00848
00849 Time txDuration = m_phy->CalculateTxDuration (packet->GetSize (), txMode, WIFI_PREAMBLE_LONG);
00850 Simulator::Schedule (txDuration, &MacLow::NotifyNav, this, *hdr, txMode, WIFI_PREAMBLE_LONG);
00851 }
00852
00853 void
00854 MacLow::CtsTimeout (void)
00855 {
00856 NS_LOG_FUNCTION (this);
00857 NS_LOG_DEBUG ("cts timeout");
00858
00859
00860
00861 WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
00862 station->ReportRtsFailed ();
00863 m_currentPacket = 0;
00864 MacLowTransmissionListener *listener = m_listener;
00865 m_listener = 0;
00866 listener->MissedCts ();
00867 }
00868 void
00869 MacLow::NormalAckTimeout (void)
00870 {
00871 NS_LOG_FUNCTION (this);
00872 NS_LOG_DEBUG ("normal ack timeout");
00873
00874
00875
00876 WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
00877 station->ReportDataFailed ();
00878 MacLowTransmissionListener *listener = m_listener;
00879 m_listener = 0;
00880 listener->MissedAck ();
00881 }
00882 void
00883 MacLow::FastAckTimeout (void)
00884 {
00885 NS_LOG_FUNCTION (this);
00886 WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
00887 station->ReportDataFailed ();
00888 MacLowTransmissionListener *listener = m_listener;
00889 m_listener = 0;
00890 if (m_phy->IsStateIdle ())
00891 {
00892 NS_LOG_DEBUG ("fast Ack idle missed");
00893 listener->MissedAck ();
00894 }
00895 else
00896 {
00897 NS_LOG_DEBUG ("fast Ack ok");
00898 }
00899 }
00900 void
00901 MacLow::SuperFastAckTimeout ()
00902 {
00903 NS_LOG_FUNCTION (this);
00904 WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
00905 station->ReportDataFailed ();
00906 MacLowTransmissionListener *listener = m_listener;
00907 m_listener = 0;
00908 if (m_phy->IsStateIdle ())
00909 {
00910 NS_LOG_DEBUG ("super fast Ack failed");
00911 listener->MissedAck ();
00912 }
00913 else
00914 {
00915 NS_LOG_DEBUG ("super fast Ack ok");
00916 listener->GotAck (0.0, WifiMode ());
00917 }
00918 }
00919
00920 void
00921 MacLow::SendRtsForPacket (void)
00922 {
00923 NS_LOG_FUNCTION (this);
00924
00925 WifiMacHeader rts;
00926 rts.SetType (WIFI_MAC_CTL_RTS);
00927 rts.SetDsNotFrom ();
00928 rts.SetDsNotTo ();
00929 rts.SetNoRetry ();
00930 rts.SetNoMoreFragments ();
00931 rts.SetAddr1 (m_currentHdr.GetAddr1 ());
00932 rts.SetAddr2 (m_self);
00933 WifiMode rtsTxMode = GetRtsTxMode (m_currentPacket, &m_currentHdr);
00934 Time duration = Seconds (0);
00935 if (m_txParams.HasDurationId ())
00936 {
00937 duration += m_txParams.GetDurationId ();
00938 }
00939 else
00940 {
00941 WifiMode dataTxMode = GetDataTxMode (m_currentPacket, &m_currentHdr);
00942 duration += GetSifs ();
00943 duration += GetCtsDuration (m_currentHdr.GetAddr1 (), rtsTxMode);
00944 duration += GetSifs ();
00945 duration += m_phy->CalculateTxDuration (GetSize (m_currentPacket, &m_currentHdr),
00946 dataTxMode, WIFI_PREAMBLE_LONG);
00947 duration += GetSifs ();
00948 duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxMode);
00949 }
00950 rts.SetDuration (duration);
00951
00952 Time txDuration = m_phy->CalculateTxDuration (GetRtsSize (), rtsTxMode, WIFI_PREAMBLE_LONG);
00953 Time timerDelay = txDuration + GetCtsTimeout ();
00954
00955 NS_ASSERT (m_ctsTimeoutEvent.IsExpired ());
00956 m_ctsTimeoutEvent = Simulator::Schedule (timerDelay, &MacLow::CtsTimeout, this);
00957
00958 Ptr<Packet> packet = Create<Packet> ();
00959 packet->AddHeader (rts);
00960 WifiMacTrailer fcs;
00961 packet->AddTrailer (fcs);
00962
00963 ForwardDown (packet, &rts, rtsTxMode);
00964 }
00965
00966 void
00967 MacLow::StartDataTxTimers (void)
00968 {
00969 WifiMode dataTxMode = GetDataTxMode (m_currentPacket, &m_currentHdr);
00970 Time txDuration = m_phy->CalculateTxDuration (GetSize (m_currentPacket, &m_currentHdr), dataTxMode, WIFI_PREAMBLE_LONG);
00971 if (m_txParams.MustWaitNormalAck ())
00972 {
00973 Time timerDelay = txDuration + GetAckTimeout ();
00974 NS_ASSERT (m_normalAckTimeoutEvent.IsExpired ());
00975 m_normalAckTimeoutEvent = Simulator::Schedule (timerDelay, &MacLow::NormalAckTimeout, this);
00976 }
00977 else if (m_txParams.MustWaitFastAck ())
00978 {
00979 Time timerDelay = txDuration + GetPifs ();
00980 NS_ASSERT (m_fastAckTimeoutEvent.IsExpired ());
00981 m_fastAckTimeoutEvent = Simulator::Schedule (timerDelay, &MacLow::FastAckTimeout, this);
00982 }
00983 else if (m_txParams.MustWaitSuperFastAck ())
00984 {
00985 Time timerDelay = txDuration + GetPifs ();
00986 NS_ASSERT (m_superFastAckTimeoutEvent.IsExpired ());
00987 m_superFastAckTimeoutEvent = Simulator::Schedule (timerDelay,
00988 &MacLow::SuperFastAckTimeout, this);
00989 }
00990 else if (m_txParams.HasNextPacket ())
00991 {
00992 Time delay = txDuration + GetSifs ();
00993 NS_ASSERT (m_waitSifsEvent.IsExpired ());
00994 m_waitSifsEvent = Simulator::Schedule (delay, &MacLow::WaitSifsAfterEndTx, this);
00995 }
00996 else
00997 {
00998
00999 m_listener = 0;
01000 }
01001 }
01002
01003 void
01004 MacLow::SendDataPacket (void)
01005 {
01006 NS_LOG_FUNCTION (this);
01007
01008 StartDataTxTimers ();
01009
01010 WifiMode dataTxMode = GetDataTxMode (m_currentPacket, &m_currentHdr);
01011 Time duration = Seconds (0.0);
01012 if (m_txParams.HasDurationId ())
01013 {
01014 duration += m_txParams.GetDurationId ();
01015 }
01016 else
01017 {
01018 if (m_txParams.MustWaitAck ())
01019 {
01020 duration += GetSifs ();
01021 duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxMode);
01022 }
01023 if (m_txParams.HasNextPacket ())
01024 {
01025 duration += GetSifs ();
01026 duration += m_phy->CalculateTxDuration (m_txParams.GetNextPacketSize (),
01027 dataTxMode, WIFI_PREAMBLE_LONG);
01028 if (m_txParams.MustWaitAck ())
01029 {
01030 duration += GetSifs ();
01031 duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxMode);
01032 }
01033 }
01034 }
01035 m_currentHdr.SetDuration (duration);
01036
01037 m_currentPacket->AddHeader (m_currentHdr);
01038 WifiMacTrailer fcs;
01039 m_currentPacket->AddTrailer (fcs);
01040
01041 ForwardDown (m_currentPacket, &m_currentHdr, dataTxMode);
01042 m_currentPacket = 0;
01043 }
01044
01045 bool
01046 MacLow::IsNavZero (void) const
01047 {
01048 if (m_lastNavStart + m_lastNavDuration < Simulator::Now ())
01049 {
01050 return true;
01051 }
01052 else
01053 {
01054 return false;
01055 }
01056 }
01057
01058 WifiRemoteStation *
01059 MacLow::GetStation (Mac48Address ad) const
01060 {
01061 return m_stationManager->Lookup (ad);
01062 }
01063
01064 void
01065 MacLow::SendCtsAfterRts (Mac48Address source, Time duration, WifiMode rtsTxMode, double rtsSnr)
01066 {
01067 NS_LOG_FUNCTION (this << source << duration << rtsTxMode << rtsSnr);
01068
01069
01070
01071 WifiMode ctsTxMode = GetCtsTxModeForRts (source, rtsTxMode);
01072 WifiMacHeader cts;
01073 cts.SetType (WIFI_MAC_CTL_CTS);
01074 cts.SetDsNotFrom ();
01075 cts.SetDsNotTo ();
01076 cts.SetNoMoreFragments ();
01077 cts.SetNoRetry ();
01078 cts.SetAddr1 (source);
01079 duration -= GetCtsDuration (source, rtsTxMode);
01080 duration -= GetSifs ();
01081 NS_ASSERT (duration >= MicroSeconds (0));
01082 cts.SetDuration (duration);
01083
01084 Ptr<Packet> packet = Create<Packet> ();
01085 packet->AddHeader (cts);
01086 WifiMacTrailer fcs;
01087 packet->AddTrailer (fcs);
01088
01089 struct SnrTag tag;
01090 tag.Set (rtsSnr);
01091 packet->AddTag (tag);
01092
01093 ForwardDown (packet, &cts, ctsTxMode);
01094 }
01095
01096 void
01097 MacLow::SendDataAfterCts (Mac48Address source, Time duration, WifiMode txMode)
01098 {
01099 NS_LOG_FUNCTION (this);
01100
01101
01102
01103 NS_ASSERT (m_currentPacket != 0);
01104 StartDataTxTimers ();
01105
01106 WifiMode dataTxMode = GetDataTxMode (m_currentPacket, &m_currentHdr);
01107 Time newDuration = Seconds (0);
01108 newDuration += GetSifs ();
01109 newDuration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxMode);
01110 Time txDuration = m_phy->CalculateTxDuration (GetSize (m_currentPacket, &m_currentHdr),
01111 dataTxMode, WIFI_PREAMBLE_LONG);
01112 duration -= txDuration;
01113 duration -= GetSifs ();
01114
01115 duration = std::max (duration, newDuration);
01116 NS_ASSERT (duration >= MicroSeconds (0));
01117 m_currentHdr.SetDuration (duration);
01118
01119 m_currentPacket->AddHeader (m_currentHdr);
01120 WifiMacTrailer fcs;
01121 m_currentPacket->AddTrailer (fcs);
01122
01123 ForwardDown (m_currentPacket, &m_currentHdr, dataTxMode);
01124 m_currentPacket = 0;
01125 }
01126
01127 void
01128 MacLow::WaitSifsAfterEndTx (void)
01129 {
01130 m_listener->StartNext ();
01131 }
01132
01133 void
01134 MacLow::FastAckFailedTimeout (void)
01135 {
01136 NS_LOG_FUNCTION (this);
01137 MacLowTransmissionListener *listener = m_listener;
01138 m_listener = 0;
01139 listener->MissedAck ();
01140 NS_LOG_DEBUG ("fast Ack busy but missed");
01141 }
01142
01143 void
01144 MacLow::SendAckAfterData (Mac48Address source, Time duration, WifiMode dataTxMode, double dataSnr)
01145 {
01146 NS_LOG_FUNCTION (this);
01147
01148
01149
01150 WifiMode ackTxMode = GetAckTxModeForData (source, dataTxMode);
01151 WifiMacHeader ack;
01152 ack.SetType (WIFI_MAC_CTL_ACK);
01153 ack.SetDsNotFrom ();
01154 ack.SetDsNotTo ();
01155 ack.SetNoRetry ();
01156 ack.SetNoMoreFragments ();
01157 ack.SetAddr1 (source);
01158 duration -= GetAckDuration (source, dataTxMode);
01159 duration -= GetSifs ();
01160 NS_ASSERT (duration >= MicroSeconds (0));
01161 ack.SetDuration (duration);
01162
01163 Ptr<Packet> packet = Create<Packet> ();
01164 packet->AddHeader (ack);
01165 WifiMacTrailer fcs;
01166 packet->AddTrailer (fcs);
01167
01168 struct SnrTag tag;
01169 tag.Set (dataSnr);
01170 packet->AddTag (tag);
01171
01172 ForwardDown (packet, &ack, ackTxMode);
01173 }
01174
01175 }