A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
dca-txop.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2005 INRIA
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19  */
20 
21 #include "ns3/assert.h"
22 #include "ns3/packet.h"
23 #include "ns3/log.h"
24 #include "ns3/simulator.h"
25 #include "ns3/node.h"
26 #include "ns3/uinteger.h"
27 #include "ns3/pointer.h"
28 
29 #include "dca-txop.h"
30 #include "dcf-manager.h"
31 #include "mac-low.h"
32 #include "wifi-mac-queue.h"
33 #include "mac-tx-middle.h"
34 #include "wifi-mac-trailer.h"
35 #include "wifi-mac.h"
36 #include "random-stream.h"
37 
38 NS_LOG_COMPONENT_DEFINE ("DcaTxop");
39 
40 #undef NS_LOG_APPEND_CONTEXT
41 #define NS_LOG_APPEND_CONTEXT if (m_low != 0) { std::clog << "[mac=" << m_low->GetAddress () << "] "; }
42 
43 namespace ns3 {
44 
45 class DcaTxop::Dcf : public DcfState
46 {
47 public:
48  Dcf (DcaTxop * txop)
49  : m_txop (txop)
50  {
51  }
52 private:
53  virtual void DoNotifyAccessGranted (void)
54  {
56  }
57  virtual void DoNotifyInternalCollision (void)
58  {
60  }
61  virtual void DoNotifyCollision (void)
62  {
64  }
65  virtual void DoNotifyChannelSwitching (void)
66  {
68  }
70 };
71 
73 {
74 public:
77  m_txop (txop) {
78  }
79 
80  virtual ~TransmissionListener () {}
81 
82  virtual void GotCts (double snr, WifiMode txMode)
83  {
84  m_txop->GotCts (snr, txMode);
85  }
86  virtual void MissedCts (void)
87  {
88  m_txop->MissedCts ();
89  }
90  virtual void GotAck (double snr, WifiMode txMode)
91  {
92  m_txop->GotAck (snr, txMode);
93  }
94  virtual void MissedAck (void)
95  {
96  m_txop->MissedAck ();
97  }
98  virtual void StartNext (void)
99  {
100  m_txop->StartNext ();
101  }
102  virtual void Cancel (void)
103  {
104  m_txop->Cancel ();
105  }
106  virtual void EndTxNoAck (void)
107  {
108  m_txop->EndTxNoAck ();
109  }
110 
111 private:
113 };
114 
116 
117 TypeId
119 {
120  static TypeId tid = TypeId ("ns3::DcaTxop")
123  .AddAttribute ("Queue", "The WifiMacQueue object",
124  PointerValue (),
125  MakePointerAccessor (&DcaTxop::GetQueue),
126  MakePointerChecker<WifiMacQueue> ())
127  ;
128  return tid;
129 }
130 
132  : m_manager (0),
133  m_currentPacket (0)
134 {
135  NS_LOG_FUNCTION (this);
137  m_dcf = new DcaTxop::Dcf (this);
138  m_queue = CreateObject<WifiMacQueue> ();
139  m_rng = new RealRandomStream ();
140  m_txMiddle = new MacTxMiddle ();
141 }
142 
144 {
145  NS_LOG_FUNCTION (this);
146 }
147 
148 void
150 {
151  NS_LOG_FUNCTION (this);
152  m_queue = 0;
153  m_low = 0;
154  m_stationManager = 0;
155  delete m_transmissionListener;
156  delete m_dcf;
157  delete m_rng;
158  delete m_txMiddle;
160  m_dcf = 0;
161  m_rng = 0;
162  m_txMiddle = 0;
163 }
164 
165 void
167 {
168  NS_LOG_FUNCTION (this << manager);
169  m_manager = manager;
170  m_manager->Add (m_dcf);
171 }
172 
173 void
175 {
176  NS_LOG_FUNCTION (this << low);
177  m_low = low;
178 }
179 void
181 {
182  NS_LOG_FUNCTION (this << remoteManager);
183  m_stationManager = remoteManager;
184 }
185 void
187 {
188  m_txOkCallback = callback;
189 }
190 void
192 {
193  m_txFailedCallback = callback;
194 }
195 
198 {
199  NS_LOG_FUNCTION (this);
200  return m_queue;
201 }
202 
203 void
204 DcaTxop::SetMinCw (uint32_t minCw)
205 {
206  NS_LOG_FUNCTION (this << minCw);
207  m_dcf->SetCwMin (minCw);
208 }
209 void
210 DcaTxop::SetMaxCw (uint32_t maxCw)
211 {
212  NS_LOG_FUNCTION (this << maxCw);
213  m_dcf->SetCwMax (maxCw);
214 }
215 void
216 DcaTxop::SetAifsn (uint32_t aifsn)
217 {
218  NS_LOG_FUNCTION (this << aifsn);
219  m_dcf->SetAifsn (aifsn);
220 }
221 uint32_t
222 DcaTxop::GetMinCw (void) const
223 {
224  return m_dcf->GetCwMin ();
225 }
226 uint32_t
227 DcaTxop::GetMaxCw (void) const
228 {
229  return m_dcf->GetCwMax ();
230 }
231 uint32_t
232 DcaTxop::GetAifsn (void) const
233 {
234  return m_dcf->GetAifsn ();
235 }
236 
237 void
239 {
240  NS_LOG_FUNCTION (this << packet << &hdr);
241  WifiMacTrailer fcs;
242  uint32_t fullPacketSize = hdr.GetSerializedSize () + packet->GetSize () + fcs.GetSerializedSize ();
244  packet, fullPacketSize);
245  m_queue->Enqueue (packet, hdr);
247 }
248 
249 int64_t
250 DcaTxop::AssignStreams (int64_t stream)
251 {
252  NS_LOG_FUNCTION (this << stream);
253  m_rng->AssignStreams (stream);
254  return 1;
255 }
256 
257 void
259 {
260  NS_LOG_FUNCTION (this);
261  if ((m_currentPacket != 0
262  || !m_queue->IsEmpty ())
263  && !m_dcf->IsAccessRequested ())
264  {
266  }
267 }
268 
269 void
271 {
272  NS_LOG_FUNCTION (this);
273  if (m_currentPacket == 0
274  && !m_queue->IsEmpty ()
275  && !m_dcf->IsAccessRequested ())
276  {
278  }
279 }
280 
281 
284 {
285  return m_low;
286 }
287 
288 bool
290 {
291  return m_stationManager->NeedRts (header->GetAddr1 (), header,
292  packet);
293 }
294 
295 void
297 {
298  m_dcf->ResetCw ();
301 }
302 bool
304 {
307 }
308 
309 bool
311 {
314 }
315 bool
317 {
320 }
321 
322 void
324 {
326 }
327 
328 uint32_t
330 {
333 }
334 bool
336 {
339 }
340 
341 uint32_t
343 {
346 }
347 
348 uint32_t
350 {
353 }
354 
357 {
358  *hdr = m_currentHdr;
360  uint32_t startOffset = GetFragmentOffset ();
361  Ptr<Packet> fragment;
362  if (IsLastFragment ())
363  {
364  hdr->SetNoMoreFragments ();
365  }
366  else
367  {
368  hdr->SetMoreFragments ();
369  }
370  fragment = m_currentPacket->CreateFragment (startOffset,
371  GetFragmentSize ());
372  return fragment;
373 }
374 
375 bool
377 {
378  return !m_queue->IsEmpty () || m_currentPacket != 0;
379 }
380 void
382 {
383  NS_LOG_FUNCTION (this);
384  if (m_currentPacket == 0)
385  {
386  if (m_queue->IsEmpty ())
387  {
388  NS_LOG_DEBUG ("queue empty");
389  return;
390  }
392  NS_ASSERT (m_currentPacket != 0);
393  uint16_t sequence = m_txMiddle->GetNextSequenceNumberfor (&m_currentHdr);
394  m_currentHdr.SetSequenceNumber (sequence);
398  m_fragmentNumber = 0;
399  NS_LOG_DEBUG ("dequeued size=" << m_currentPacket->GetSize () <<
400  ", to=" << m_currentHdr.GetAddr1 () <<
401  ", seq=" << m_currentHdr.GetSequenceControl ());
402  }
404  params.DisableOverrideDurationId ();
405  if (m_currentHdr.GetAddr1 ().IsGroup ())
406  {
407  params.DisableRts ();
408  params.DisableAck ();
409  params.DisableNextData ();
411  &m_currentHdr,
412  params,
414  NS_LOG_DEBUG ("tx broadcast");
415  }
416  else
417  {
418  params.EnableAck ();
419 
420  if (NeedFragmentation ())
421  {
422  WifiMacHeader hdr;
423  Ptr<Packet> fragment = GetFragmentPacket (&hdr);
424  if (NeedRts (fragment, &hdr))
425  {
426  params.EnableRts ();
427  }
428  else
429  {
430  params.DisableRts ();
431  }
432  if (IsLastFragment ())
433  {
434  NS_LOG_DEBUG ("fragmenting last fragment size=" << fragment->GetSize ());
435  params.DisableNextData ();
436  }
437  else
438  {
439  NS_LOG_DEBUG ("fragmenting size=" << fragment->GetSize ());
441  }
442  Low ()->StartTransmission (fragment, &hdr, params,
444  }
445  else
446  {
448  {
449  params.EnableRts ();
450  NS_LOG_DEBUG ("tx unicast rts");
451  }
452  else
453  {
454  params.DisableRts ();
455  NS_LOG_DEBUG ("tx unicast");
456  }
457  params.DisableNextData ();
459  params, m_transmissionListener);
460  }
461  }
462 }
463 
464 void
466 {
467  NS_LOG_FUNCTION (this);
468  NotifyCollision ();
469 }
470 void
472 {
473  NS_LOG_FUNCTION (this);
474  NS_LOG_DEBUG ("collision");
477 }
478 
479 void
481 {
482  m_queue->Flush ();
483  m_currentPacket = 0;
484 }
485 
486 void
487 DcaTxop::GotCts (double snr, WifiMode txMode)
488 {
489  NS_LOG_FUNCTION (this << snr << txMode);
490  NS_LOG_DEBUG ("got cts");
491 }
492 void
494 {
495  NS_LOG_FUNCTION (this);
496  NS_LOG_DEBUG ("missed cts");
497  if (!NeedRtsRetransmission ())
498  {
499  NS_LOG_DEBUG ("Cts Fail");
501  if (!m_txFailedCallback.IsNull ())
502  {
504  }
505  // to reset the dcf.
506  m_currentPacket = 0;
507  m_dcf->ResetCw ();
508  }
509  else
510  {
511  m_dcf->UpdateFailedCw ();
512  }
515 }
516 void
517 DcaTxop::GotAck (double snr, WifiMode txMode)
518 {
519  NS_LOG_FUNCTION (this << snr << txMode);
520  if (!NeedFragmentation ()
521  || IsLastFragment ())
522  {
523  NS_LOG_DEBUG ("got ack. tx done.");
524  if (!m_txOkCallback.IsNull ())
525  {
527  }
528 
529  /* we are not fragmenting or we are done fragmenting
530  * so we can get rid of that packet now.
531  */
532  m_currentPacket = 0;
533  m_dcf->ResetCw ();
536  }
537  else
538  {
539  NS_LOG_DEBUG ("got ack. tx not done, size=" << m_currentPacket->GetSize ());
540  }
541 }
542 void
544 {
545  NS_LOG_FUNCTION (this);
546  NS_LOG_DEBUG ("missed ack");
547  if (!NeedDataRetransmission ())
548  {
549  NS_LOG_DEBUG ("Ack Fail");
551  if (!m_txFailedCallback.IsNull ())
552  {
554  }
555  // to reset the dcf.
556  m_currentPacket = 0;
557  m_dcf->ResetCw ();
558  }
559  else
560  {
561  NS_LOG_DEBUG ("Retransmit");
563  m_dcf->UpdateFailedCw ();
564  }
567 }
568 void
570 {
571  NS_LOG_FUNCTION (this);
572  NS_LOG_DEBUG ("start next packet fragment");
573  /* this callback is used only for fragments. */
574  NextFragment ();
575  WifiMacHeader hdr;
576  Ptr<Packet> fragment = GetFragmentPacket (&hdr);
578  params.EnableAck ();
579  params.DisableRts ();
580  params.DisableOverrideDurationId ();
581  if (IsLastFragment ())
582  {
583  params.DisableNextData ();
584  }
585  else
586  {
588  }
589  Low ()->StartTransmission (fragment, &hdr, params, m_transmissionListener);
590 }
591 
592 void
594 {
595  NS_LOG_FUNCTION (this);
596  NS_LOG_DEBUG ("transmission cancelled");
622 }
623 
624 void
626 {
627  NS_LOG_FUNCTION (this);
628  NS_LOG_DEBUG ("a transmission that did not require an ACK just finished");
629  m_currentPacket = 0;
630  m_dcf->ResetCw ();
633 }
634 
635 } // namespace ns3