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/log.h"
00024 #include "ns3/simulator.h"
00025 #include "ns3/node.h"
00026 #include "ns3/uinteger.h"
00027
00028 #include "dca-txop.h"
00029 #include "dcf-manager.h"
00030 #include "mac-low.h"
00031 #include "wifi-mac-queue.h"
00032 #include "mac-tx-middle.h"
00033 #include "wifi-mac-trailer.h"
00034 #include "wifi-mac.h"
00035 #include "random-stream.h"
00036
00037 NS_LOG_COMPONENT_DEFINE ("DcaTxop");
00038
00039 #define MY_DEBUG(x) \
00040 NS_LOG_DEBUG (m_low->GetAddress () << " " << x)
00041
00042
00043 namespace ns3 {
00044
00045 class DcaTxop::Dcf : public DcfState
00046 {
00047 public:
00048 Dcf (DcaTxop *txop)
00049 : m_txop (txop)
00050 {}
00051 private:
00052 virtual void DoNotifyAccessGranted (void) {
00053 m_txop->NotifyAccessGranted ();
00054 }
00055 virtual void DoNotifyInternalCollision (void) {
00056 m_txop->NotifyInternalCollision ();
00057 }
00058 virtual void DoNotifyCollision (void) {
00059 m_txop->NotifyCollision ();
00060 }
00061
00062 DcaTxop *m_txop;
00063 };
00064
00065 class DcaTxop::TransmissionListener : public MacLowTransmissionListener {
00066 public:
00067 TransmissionListener (DcaTxop *txop)
00068 : MacLowTransmissionListener (),
00069 m_txop (txop) {}
00070
00071 virtual ~TransmissionListener () {}
00072
00073 virtual void GotCts (double snr, WifiMode txMode) {
00074 m_txop->GotCts (snr, txMode);
00075 }
00076 virtual void MissedCts (void) {
00077 m_txop->MissedCts ();
00078 }
00079 virtual void GotAck (double snr, WifiMode txMode) {
00080 m_txop->GotAck (snr, txMode);
00081 }
00082 virtual void MissedAck (void) {
00083 m_txop->MissedAck ();
00084 }
00085 virtual void StartNext (void) {
00086 m_txop->StartNext ();
00087 }
00088 virtual void Cancel (void) {
00089 m_txop->Cancel ();
00090 }
00091
00092 private:
00093 DcaTxop *m_txop;
00094 };
00095
00096 TypeId
00097 DcaTxop::GetTypeId (void)
00098 {
00099 static TypeId tid = TypeId ("DcaTxop")
00100 .SetParent<Object> ()
00101 .AddConstructor<DcaTxop> ()
00102 .AddAttribute ("MinCw", "The minimum value of the contention window.",
00103 UintegerValue (15),
00104 MakeUintegerAccessor (&DcaTxop::SetMinCw,
00105 &DcaTxop::GetMinCw),
00106 MakeUintegerChecker<uint32_t> ())
00107 .AddAttribute ("MaxCw", "The maximum value of the contention window.",
00108 UintegerValue (1023),
00109 MakeUintegerAccessor (&DcaTxop::SetMaxCw,
00110 &DcaTxop::GetMaxCw),
00111 MakeUintegerChecker<uint32_t> ())
00112 .AddAttribute ("Aifsn", "The AIFSN: the default value conforms to simple DCA.",
00113 UintegerValue (2),
00114 MakeUintegerAccessor (&DcaTxop::SetAifsn,
00115 &DcaTxop::GetAifsn),
00116 MakeUintegerChecker<uint32_t> ())
00117 ;
00118 return tid;
00119 }
00120
00121 DcaTxop::DcaTxop ()
00122 : m_manager (0),
00123 m_currentPacket (0)
00124 {
00125 NS_LOG_FUNCTION (this);
00126 m_transmissionListener = new DcaTxop::TransmissionListener (this);
00127 m_dcf = new DcaTxop::Dcf (this);
00128 m_queue = CreateObject<WifiMacQueue> ();
00129 m_rng = new RealRandomStream ();
00130 m_txMiddle = new MacTxMiddle ();
00131 }
00132
00133 DcaTxop::~DcaTxop ()
00134 {
00135 NS_LOG_FUNCTION (this);
00136 }
00137
00138 void
00139 DcaTxop::DoDispose (void)
00140 {
00141 NS_LOG_FUNCTION (this);
00142 m_queue = 0;
00143 m_low = 0;
00144 m_stationManager = 0;
00145 delete m_transmissionListener;
00146 delete m_dcf;
00147 delete m_rng;
00148 delete m_txMiddle;
00149 m_transmissionListener = 0;
00150 m_dcf = 0;
00151 m_rng = 0;
00152 m_txMiddle = 0;
00153 }
00154
00155 void
00156 DcaTxop::SetManager (DcfManager *manager)
00157 {
00158 NS_LOG_FUNCTION (this << manager);
00159 m_manager = manager;
00160 m_manager->Add (m_dcf);
00161 }
00162
00163 void
00164 DcaTxop::SetLow (Ptr<MacLow> low)
00165 {
00166 NS_LOG_FUNCTION (this << low);
00167 m_low = low;
00168 }
00169 void
00170 DcaTxop::SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> remoteManager)
00171 {
00172 NS_LOG_FUNCTION (this << remoteManager);
00173 m_stationManager = remoteManager;
00174 }
00175 void
00176 DcaTxop::SetTxOkCallback (TxOk callback)
00177 {
00178 m_txOkCallback = callback;
00179 }
00180 void
00181 DcaTxop::SetTxFailedCallback (TxFailed callback)
00182 {
00183 m_txFailedCallback = callback;
00184 }
00185
00186 void
00187 DcaTxop::SetMaxQueueSize (uint32_t size)
00188 {
00189 NS_LOG_FUNCTION (this << size);
00190 m_queue->SetMaxSize (size);
00191 }
00192 void
00193 DcaTxop::SetMaxQueueDelay (Time delay)
00194 {
00195 NS_LOG_FUNCTION (this << delay);
00196 m_queue->SetMaxDelay (delay);
00197 }
00198 void
00199 DcaTxop::SetMinCw (uint32_t minCw)
00200 {
00201 NS_LOG_FUNCTION (this << minCw);
00202 m_dcf->SetCwMin (minCw);
00203 }
00204 void
00205 DcaTxop::SetMaxCw (uint32_t maxCw)
00206 {
00207 NS_LOG_FUNCTION (this << maxCw);
00208 m_dcf->SetCwMax (maxCw);
00209 }
00210 void
00211 DcaTxop::SetAifsn (uint32_t aifsn)
00212 {
00213 NS_LOG_FUNCTION (this << aifsn);
00214 m_dcf->SetAifsn (aifsn);
00215 }
00216 uint32_t
00217 DcaTxop::GetMinCw (void) const
00218 {
00219 return m_dcf->GetCwMin ();
00220 }
00221 uint32_t
00222 DcaTxop::GetMaxCw (void) const
00223 {
00224 return m_dcf->GetCwMax ();
00225 }
00226 uint32_t
00227 DcaTxop::GetAifsn (void) const
00228 {
00229 return m_dcf->GetAifsn ();
00230 }
00231
00232 void
00233 DcaTxop::Queue (Ptr<const Packet> packet, WifiMacHeader const &hdr)
00234 {
00235 NS_LOG_FUNCTION (this << packet << &hdr);
00236 WifiMacTrailer fcs;
00237 uint32_t fullPacketSize = hdr.GetSerializedSize () + packet->GetSize () + fcs.GetSerializedSize ();
00238 WifiRemoteStation *station = GetStation (hdr.GetAddr1 ());
00239 station->PrepareForQueue (packet, fullPacketSize);
00240 m_queue->Enqueue (packet, hdr);
00241 StartAccessIfNeeded ();
00242 }
00243
00244 WifiRemoteStation *
00245 DcaTxop::GetStation (Mac48Address ad) const
00246 {
00247 return m_stationManager->Lookup (ad);
00248 }
00249
00250 void
00251 DcaTxop::RestartAccessIfNeeded (void)
00252 {
00253 NS_LOG_FUNCTION (this);
00254 if ((m_currentPacket != 0 ||
00255 !m_queue->IsEmpty ()) &&
00256 !m_dcf->IsAccessRequested ())
00257 {
00258 m_manager->RequestAccess (m_dcf);
00259 }
00260 }
00261
00262 void
00263 DcaTxop::StartAccessIfNeeded (void)
00264 {
00265 NS_LOG_FUNCTION (this);
00266 if (m_currentPacket == 0 &&
00267 !m_queue->IsEmpty () &&
00268 !m_dcf->IsAccessRequested ())
00269 {
00270 m_manager->RequestAccess (m_dcf);
00271 }
00272 }
00273
00274
00275 Ptr<MacLow>
00276 DcaTxop::Low (void)
00277 {
00278 return m_low;
00279 }
00280
00281 bool
00282 DcaTxop::NeedRts (void)
00283 {
00284 WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
00285 return station->NeedRts (m_currentPacket);
00286 }
00287
00288 bool
00289 DcaTxop::NeedRtsRetransmission (void)
00290 {
00291 WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
00292 return station->NeedRtsRetransmission (m_currentPacket);
00293 }
00294
00295 bool
00296 DcaTxop::NeedDataRetransmission (void)
00297 {
00298 WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
00299 return station->NeedDataRetransmission (m_currentPacket);
00300 }
00301 bool
00302 DcaTxop::NeedFragmentation (void)
00303 {
00304 WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
00305 return station->NeedFragmentation (m_currentPacket);
00306 }
00307
00308 void
00309 DcaTxop::NextFragment (void)
00310 {
00311 m_fragmentNumber++;
00312 }
00313
00314 uint32_t
00315 DcaTxop::GetFragmentSize (void)
00316 {
00317 WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
00318 return station->GetFragmentSize (m_currentPacket, m_fragmentNumber);
00319 }
00320 bool
00321 DcaTxop::IsLastFragment (void)
00322 {
00323 WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
00324 return station->IsLastFragment (m_currentPacket, m_fragmentNumber);
00325 }
00326
00327 uint32_t
00328 DcaTxop::GetNextFragmentSize (void)
00329 {
00330 WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
00331 return station->GetFragmentSize (m_currentPacket, m_fragmentNumber + 1);
00332 }
00333
00334 uint32_t
00335 DcaTxop::GetFragmentOffset (void)
00336 {
00337 WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
00338 return station->GetFragmentOffset (m_currentPacket, m_fragmentNumber);
00339 }
00340
00341 Ptr<Packet>
00342 DcaTxop::GetFragmentPacket (WifiMacHeader *hdr)
00343 {
00344 *hdr = m_currentHdr;
00345 hdr->SetFragmentNumber (m_fragmentNumber);
00346 uint32_t startOffset = GetFragmentOffset ();
00347 Ptr<Packet> fragment;
00348 if (IsLastFragment ())
00349 {
00350 hdr->SetNoMoreFragments ();
00351 }
00352 else
00353 {
00354 hdr->SetMoreFragments ();
00355 }
00356 fragment = m_currentPacket->CreateFragment (startOffset,
00357 GetFragmentSize ());
00358 return fragment;
00359 }
00360
00361 bool
00362 DcaTxop::NeedsAccess (void) const
00363 {
00364 return !m_queue->IsEmpty () || m_currentPacket != 0;
00365 }
00366 void
00367 DcaTxop::NotifyAccessGranted (void)
00368 {
00369 NS_LOG_FUNCTION (this);
00370 if (m_currentPacket == 0)
00371 {
00372 if (m_queue->IsEmpty ())
00373 {
00374 MY_DEBUG ("queue empty");
00375 return;
00376 }
00377 m_currentPacket = m_queue->Dequeue (&m_currentHdr);
00378 NS_ASSERT (m_currentPacket != 0);
00379 uint16_t sequence = m_txMiddle->GetNextSequenceNumberfor (&m_currentHdr);
00380 m_currentHdr.SetSequenceNumber (sequence);
00381 m_currentHdr.SetFragmentNumber (0);
00382 m_currentHdr.SetNoMoreFragments ();
00383 m_currentHdr.SetNoRetry ();
00384 m_fragmentNumber = 0;
00385 MY_DEBUG ("dequeued size="<<m_currentPacket->GetSize ()<<
00386 ", to="<<m_currentHdr.GetAddr1 ()<<
00387 ", seq="<<m_currentHdr.GetSequenceControl ());
00388 }
00389 MacLowTransmissionParameters params;
00390 params.DisableOverrideDurationId ();
00391 if (m_currentHdr.GetAddr1 ().IsBroadcast ())
00392 {
00393 params.DisableRts ();
00394 params.DisableAck ();
00395 params.DisableNextData ();
00396 Low ()->StartTransmission (m_currentPacket,
00397 &m_currentHdr,
00398 params,
00399 m_transmissionListener);
00400 m_currentPacket = 0;
00401 m_dcf->ResetCw ();
00402 m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ()));
00403 StartAccessIfNeeded ();
00404 MY_DEBUG ("tx broadcast");
00405 }
00406 else
00407 {
00408 params.EnableAck ();
00409
00410 if (NeedFragmentation ())
00411 {
00412 params.DisableRts ();
00413 WifiMacHeader hdr;
00414 Ptr<Packet> fragment = GetFragmentPacket (&hdr);
00415 if (IsLastFragment ())
00416 {
00417 MY_DEBUG ("fragmenting last fragment size="<<fragment->GetSize ());
00418 params.DisableNextData ();
00419 }
00420 else
00421 {
00422 MY_DEBUG ("fragmenting size="<<fragment->GetSize ());
00423 params.EnableNextData (GetNextFragmentSize ());
00424 }
00425 Low ()->StartTransmission (fragment, &hdr, params,
00426 m_transmissionListener);
00427 }
00428 else
00429 {
00430 if (NeedRts ())
00431 {
00432 params.EnableRts ();
00433 MY_DEBUG ("tx unicast rts");
00434 }
00435 else
00436 {
00437 params.DisableRts ();
00438 MY_DEBUG ("tx unicast");
00439 }
00440 params.DisableNextData ();
00441 Low ()->StartTransmission (m_currentPacket, &m_currentHdr,
00442 params, m_transmissionListener);
00443 }
00444 }
00445 }
00446
00447 void
00448 DcaTxop::NotifyInternalCollision (void)
00449 {
00450 NS_LOG_FUNCTION (this);
00451 NotifyCollision ();
00452 }
00453 void
00454 DcaTxop::NotifyCollision (void)
00455 {
00456 NS_LOG_FUNCTION (this);
00457 MY_DEBUG ("collision");
00458 m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ()));
00459 RestartAccessIfNeeded ();
00460 }
00461
00462 void
00463 DcaTxop::GotCts (double snr, WifiMode txMode)
00464 {
00465 NS_LOG_FUNCTION (this << snr << txMode);
00466 MY_DEBUG ("got cts");
00467 }
00468 void
00469 DcaTxop::MissedCts (void)
00470 {
00471 NS_LOG_FUNCTION (this);
00472 MY_DEBUG ("missed cts");
00473 if (!NeedRtsRetransmission ())
00474 {
00475 MY_DEBUG ("Cts Fail");
00476 WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
00477 station->ReportFinalRtsFailed ();
00478 if (!m_txFailedCallback.IsNull ())
00479 {
00480 m_txFailedCallback (m_currentHdr);
00481 }
00482
00483 m_currentPacket = 0;
00484 m_dcf->ResetCw ();
00485 }
00486 else
00487 {
00488 m_dcf->UpdateFailedCw ();
00489 }
00490 m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ()));
00491 RestartAccessIfNeeded ();
00492 }
00493 void
00494 DcaTxop::GotAck (double snr, WifiMode txMode)
00495 {
00496 NS_LOG_FUNCTION (this << snr << txMode);
00497 if (!NeedFragmentation () ||
00498 IsLastFragment ())
00499 {
00500 MY_DEBUG ("got ack. tx done.");
00501 if (!m_txOkCallback.IsNull ())
00502 {
00503 m_txOkCallback (m_currentHdr);
00504 }
00505
00506
00507
00508
00509 m_currentPacket = 0;
00510 m_dcf->ResetCw ();
00511 m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ()));
00512 RestartAccessIfNeeded ();
00513 }
00514 else
00515 {
00516 MY_DEBUG ("got ack. tx not done, size="<<m_currentPacket->GetSize ());
00517 }
00518 }
00519 void
00520 DcaTxop::MissedAck (void)
00521 {
00522 NS_LOG_FUNCTION (this);
00523 MY_DEBUG ("missed ack");
00524 if (!NeedDataRetransmission ())
00525 {
00526 MY_DEBUG ("Ack Fail");
00527 WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ());
00528 station->ReportFinalDataFailed ();
00529 if (!m_txFailedCallback.IsNull ())
00530 {
00531 m_txFailedCallback (m_currentHdr);
00532 }
00533
00534 m_currentPacket = 0;
00535 m_dcf->ResetCw ();
00536 }
00537 else
00538 {
00539 MY_DEBUG ("Retransmit");
00540 m_currentHdr.SetRetry ();
00541 m_dcf->UpdateFailedCw ();
00542 }
00543 m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ()));
00544 RestartAccessIfNeeded ();
00545 }
00546 void
00547 DcaTxop::StartNext (void)
00548 {
00549 NS_LOG_FUNCTION (this);
00550 MY_DEBUG ("start next packet fragment");
00551
00552 NextFragment ();
00553 WifiMacHeader hdr;
00554 Ptr<Packet> fragment = GetFragmentPacket (&hdr);
00555 MacLowTransmissionParameters params;
00556 params.EnableAck ();
00557 params.DisableRts ();
00558 params.DisableOverrideDurationId ();
00559 if (IsLastFragment ())
00560 {
00561 params.DisableNextData ();
00562 }
00563 else
00564 {
00565 params.EnableNextData (GetNextFragmentSize ());
00566 }
00567 Low ()->StartTransmission (fragment, &hdr, params, m_transmissionListener);
00568 }
00569
00570 void
00571 DcaTxop::Cancel (void)
00572 {
00573 NS_LOG_FUNCTION (this);
00574 MY_DEBUG ("transmission cancelled");
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600 }
00601
00602 }