A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
wifi-remote-station-manager.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2005,2006,2007 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 
22 #include "ns3/simulator.h"
23 #include "ns3/assert.h"
24 #include "ns3/log.h"
25 #include "ns3/tag.h"
26 #include "ns3/boolean.h"
27 #include "ns3/double.h"
28 #include "ns3/uinteger.h"
29 #include "ns3/wifi-phy.h"
30 #include "ns3/trace-source-accessor.h"
31 #include "wifi-mac-header.h"
32 #include "wifi-mac-trailer.h"
33 
34 NS_LOG_COMPONENT_DEFINE ("WifiRemoteStationManager");
35 
36 
37 /***************************************************************
38  * Packet Mode Tagger
39  ***************************************************************/
40 
41 namespace ns3 {
42 
43 class TxModeTag : public Tag
44 {
45 public:
46  TxModeTag ();
47  TxModeTag (WifiMode rtsMode, WifiMode dataMode);
48  WifiMode GetRtsMode (void) const;
49  WifiMode GetDataMode (void) const;
50 
51  static TypeId GetTypeId (void);
52  virtual TypeId GetInstanceTypeId (void) const;
53  virtual uint32_t GetSerializedSize (void) const;
54  virtual void Serialize (TagBuffer i) const;
55  virtual void Deserialize (TagBuffer i);
56  virtual void Print (std::ostream &os) const;
57 private:
60 };
61 
63 {
64 }
66  : m_rtsMode (rtsMode),
67  m_dataMode (dataMode)
68 {
69 }
72 {
73  return m_rtsMode;
74 }
77 {
78  return m_dataMode;
79 }
80 TypeId
82 {
83  static TypeId tid = TypeId ("ns3::TxModeTag")
84  .SetParent<Tag> ()
85  .AddConstructor<TxModeTag> ()
86  .AddAttribute ("RtsTxMode",
87  "Tx mode of rts to use later",
89  MakeWifiModeAccessor (&TxModeTag::GetRtsMode),
90  MakeWifiModeChecker ())
91  .AddAttribute ("DataTxMode",
92  "Tx mode of data to use later",
94  MakeWifiModeAccessor (&TxModeTag::GetDataMode),
95  MakeWifiModeChecker ())
96  ;
97  return tid;
98 }
99 TypeId
101 {
102  return GetTypeId ();
103 }
104 uint32_t
106 {
107  return sizeof (WifiMode) * 2;
108 }
109 void
111 {
112  i.Write ((uint8_t *)&m_rtsMode, sizeof (WifiMode));
113  i.Write ((uint8_t *)&m_dataMode, sizeof (WifiMode));
114 }
115 void
117 {
118  i.Read ((uint8_t *)&m_rtsMode, sizeof (WifiMode));
119  i.Read ((uint8_t *)&m_dataMode, sizeof (WifiMode));
120 }
121 void
122 TxModeTag::Print (std::ostream &os) const
123 {
124  os << "Rts=" << m_rtsMode << ", Data=" << m_dataMode;
125 }
126 
127 } // namespace ns3
128 
129 
130 namespace ns3 {
131 
132 NS_OBJECT_ENSURE_REGISTERED (WifiRemoteStationManager);
133 
134 TypeId
136 {
137  static TypeId tid = TypeId ("ns3::WifiRemoteStationManager")
138  .SetParent<Object> ()
139  .AddAttribute ("IsLowLatency", "If true, we attempt to modelize a so-called low-latency device: a device"
140  " where decisions about tx parameters can be made on a per-packet basis and feedback about the"
141  " transmission of each packet is obtained before sending the next. Otherwise, we modelize a "
142  " high-latency device, that is a device where we cannot update our decision about tx parameters"
143  " after every packet transmission.",
144  BooleanValue (true), // this value is ignored because there is no setter
145  MakeBooleanAccessor (&WifiRemoteStationManager::IsLowLatency),
146  MakeBooleanChecker ())
147  .AddAttribute ("MaxSsrc", "The maximum number of retransmission attempts for an RTS. This value"
148  " will not have any effect on some rate control algorithms.",
149  UintegerValue (7),
150  MakeUintegerAccessor (&WifiRemoteStationManager::m_maxSsrc),
151  MakeUintegerChecker<uint32_t> ())
152  .AddAttribute ("MaxSlrc", "The maximum number of retransmission attempts for a DATA packet. This value"
153  " will not have any effect on some rate control algorithms.",
154  UintegerValue (7),
155  MakeUintegerAccessor (&WifiRemoteStationManager::m_maxSlrc),
156  MakeUintegerChecker<uint32_t> ())
157  .AddAttribute ("RtsCtsThreshold", "If the size of the data packet + LLC header + MAC header + FCS trailer is bigger than "
158  "this value, we use an RTS/CTS handshake before sending the data, as per IEEE Std. 802.11-2007, Section 9.2.6. "
159  "This value will not have any effect on some rate control algorithms.",
160  UintegerValue (2346),
161  MakeUintegerAccessor (&WifiRemoteStationManager::m_rtsCtsThreshold),
162  MakeUintegerChecker<uint32_t> ())
163  .AddAttribute ("FragmentationThreshold", "If the size of the data packet + LLC header + MAC header + FCS trailer is bigger"
164  "than this value, we fragment it such that the size of the fragments are equal or smaller "
165  "than this value, as per IEEE Std. 802.11-2007, Section 9.4. "
166  "This value will not have any effect on some rate control algorithms.",
167  UintegerValue (2346),
169  MakeUintegerChecker<uint32_t> ())
170  .AddAttribute ("NonUnicastMode", "Wifi mode used for non-unicast transmissions.",
171  WifiModeValue (),
172  MakeWifiModeAccessor (&WifiRemoteStationManager::m_nonUnicastMode),
173  MakeWifiModeChecker ())
174  .AddTraceSource ("MacTxRtsFailed",
175  "The transmission of a RTS by the MAC layer has failed",
177  .AddTraceSource ("MacTxDataFailed",
178  "The transmission of a data packet by the MAC layer has failed",
180  .AddTraceSource ("MacTxFinalRtsFailed",
181  "The transmission of a RTS has exceeded the maximum number of attempts",
183  .AddTraceSource ("MacTxFinalDataFailed",
184  "The transmission of a data packet has exceeded the maximum number of attempts",
186  ;
187  return tid;
188 }
189 
191 {
192 }
193 
195 {
196 }
197 void
199 {
200  for (StationStates::const_iterator i = m_states.begin (); i != m_states.end (); i++)
201  {
202  delete (*i);
203  }
204  m_states.clear ();
205  for (Stations::const_iterator i = m_stations.begin (); i != m_stations.end (); i++)
206  {
207  delete (*i);
208  }
209  m_stations.clear ();
210 }
211 void
213 {
214  // We need to track our PHY because it is the object that knows the
215  // full set of transmit rates that are supported. We need to know
216  // this in order to find the relevant mandatory rates when chosing a
217  // transmit rate for automatic control responses like
218  // acknowledgements.
219  m_wifiPhy = phy;
220  m_defaultTxMode = phy->GetMode (0);
221  Reset ();
222 }
223 
224 uint32_t
226 {
227  return m_maxSsrc;
228 }
229 uint32_t
231 {
232  return m_maxSlrc;
233 }
234 uint32_t
236 {
237  return m_rtsCtsThreshold;
238 }
239 uint32_t
241 {
243 }
244 void
246 {
247  m_maxSsrc = maxSsrc;
248 }
249 void
251 {
252  m_maxSlrc = maxSlrc;
253 }
254 void
256 {
257  m_rtsCtsThreshold = threshold;
258 }
259 void
261 {
262  m_fragmentationThreshold = threshold;
263 }
264 
265 void
267 {
268  NS_ASSERT (!address.IsGroup ());
269  WifiRemoteStationState *state = LookupState (address);
270  state->m_operationalRateSet.clear ();
271  AddSupportedMode (address, GetDefaultMode ());
272 }
273 void
275 {
276  NS_ASSERT (!address.IsGroup ());
277  WifiRemoteStationState *state = LookupState (address);
278  for (WifiModeListIterator i = state->m_operationalRateSet.begin (); i != state->m_operationalRateSet.end (); i++)
279  {
280  if ((*i) == mode)
281  {
282  // already in.
283  return;
284  }
285  }
286  state->m_operationalRateSet.push_back (mode);
287 }
288 bool
290 {
291  if (address.IsGroup ())
292  {
293  return false;
294  }
296 }
297 bool
299 {
300  if (address.IsGroup ())
301  {
302  return true;
303  }
305 }
306 bool
308 {
309  if (address.IsGroup ())
310  {
311  return false;
312  }
314 }
315 void
317 {
318  NS_ASSERT (!address.IsGroup ());
320 }
321 void
323 {
324  NS_ASSERT (!address.IsGroup ());
326 }
327 void
329 {
330  NS_ASSERT (!address.IsGroup ());
332 }
333 void
335 {
336  NS_ASSERT (!address.IsGroup ());
338 }
339 void
341  Ptr<const Packet> packet, uint32_t fullPacketSize)
342 {
343  if (IsLowLatency () || address.IsGroup ())
344  {
345  return;
346  }
347  WifiRemoteStation *station = Lookup (address, header);
348  WifiMode rts = DoGetRtsMode (station);
349  WifiMode data = DoGetDataMode (station, fullPacketSize);
350  TxModeTag tag;
351  // first, make sure that the tag is not here anymore.
352  ConstCast<Packet> (packet)->RemovePacketTag (tag);
353  tag = TxModeTag (rts, data);
354  // and then, add it back
355  packet->AddPacketTag (tag);
356 }
357 WifiMode
359  Ptr<const Packet> packet, uint32_t fullPacketSize)
360 {
361  if (address.IsGroup ())
362  {
363  return GetNonUnicastMode ();
364  }
365  if (!IsLowLatency ())
366  {
367  TxModeTag tag;
368  bool found;
369  found = ConstCast<Packet> (packet)->PeekPacketTag (tag);
370  NS_ASSERT (found);
371  return tag.GetDataMode ();
372  }
373  return DoGetDataMode (Lookup (address, header), fullPacketSize);
374 }
375 WifiMode
377  Ptr<const Packet> packet)
378 {
379  NS_ASSERT (!address.IsGroup ());
380  if (!IsLowLatency ())
381  {
382  TxModeTag tag;
383  bool found;
384  found = ConstCast<Packet> (packet)->PeekPacketTag (tag);
385  NS_ASSERT (found);
386  return tag.GetRtsMode ();
387  }
388  return DoGetRtsMode (Lookup (address, header));
389 }
390 void
392 {
393  NS_ASSERT (!address.IsGroup ());
394  WifiRemoteStation *station = Lookup (address, header);
395  station->m_ssrc++;
396  m_macTxRtsFailed (address);
397  DoReportRtsFailed (station);
398 }
399 void
401 {
402  NS_ASSERT (!address.IsGroup ());
403  WifiRemoteStation *station = Lookup (address, header);
404  station->m_slrc++;
405  m_macTxDataFailed (address);
406  DoReportDataFailed (station);
407 }
408 void
410  double ctsSnr, WifiMode ctsMode, double rtsSnr)
411 {
412  NS_ASSERT (!address.IsGroup ());
413  WifiRemoteStation *station = Lookup (address, header);
414  station->m_state->m_info.NotifyTxSuccess (station->m_ssrc);
415  station->m_ssrc = 0;
416  DoReportRtsOk (station, ctsSnr, ctsMode, rtsSnr);
417 }
418 void
420  double ackSnr, WifiMode ackMode, double dataSnr)
421 {
422  NS_ASSERT (!address.IsGroup ());
423  WifiRemoteStation *station = Lookup (address, header);
424  station->m_state->m_info.NotifyTxSuccess (station->m_slrc);
425  station->m_slrc = 0;
426  DoReportDataOk (station, ackSnr, ackMode, dataSnr);
427 }
428 void
430 {
431  NS_ASSERT (!address.IsGroup ());
432  WifiRemoteStation *station = Lookup (address, header);
433  station->m_state->m_info.NotifyTxFailed ();
434  station->m_ssrc = 0;
435  m_macTxFinalRtsFailed (address);
436  DoReportFinalRtsFailed (station);
437 }
438 void
440 {
441  NS_ASSERT (!address.IsGroup ());
442  WifiRemoteStation *station = Lookup (address, header);
443  station->m_state->m_info.NotifyTxFailed ();
444  station->m_slrc = 0;
445  m_macTxFinalDataFailed (address);
446  DoReportFinalDataFailed (station);
447 }
448 void
450  double rxSnr, WifiMode txMode)
451 {
452  if (address.IsGroup ())
453  {
454  return;
455  }
456  WifiRemoteStation *station = Lookup (address, header);
457  DoReportRxOk (station, rxSnr, txMode);
458 }
459 bool
461  Ptr<const Packet> packet)
462 {
463  if (address.IsGroup ())
464  {
465  return false;
466  }
467  bool normally = (packet->GetSize () + header->GetSize () + WIFI_MAC_FCS_LENGTH) > GetRtsCtsThreshold ();
468  return DoNeedRts (Lookup (address, header), packet, normally);
469 }
470 bool
472  Ptr<const Packet> packet)
473 {
474  NS_ASSERT (!address.IsGroup ());
475  WifiRemoteStation *station = Lookup (address, header);
476  bool normally = station->m_ssrc < GetMaxSsrc ();
477  return DoNeedRtsRetransmission (station, packet, normally);
478 }
479 bool
481  Ptr<const Packet> packet)
482 {
483  NS_ASSERT (!address.IsGroup ());
484  WifiRemoteStation *station = Lookup (address, header);
485  bool normally = station->m_slrc < GetMaxSlrc ();
486  return DoNeedDataRetransmission (station, packet, normally);
487 }
488 bool
490  Ptr<const Packet> packet)
491 {
492  if (address.IsGroup ())
493  {
494  return false;
495  }
496  WifiRemoteStation *station = Lookup (address, header);
497  bool normally = (packet->GetSize () + header->GetSize () + WIFI_MAC_FCS_LENGTH) > GetFragmentationThreshold ();
498  return DoNeedFragmentation (station, packet, normally);
499 }
500 uint32_t
502 {
503  uint32_t nFragments = packet->GetSize () / GetFragmentationThreshold () + 1;
504  return nFragments;
505 }
506 
507 uint32_t
509  Ptr<const Packet> packet, uint32_t fragmentNumber)
510 {
511  NS_ASSERT (!address.IsGroup ());
512  uint32_t nFragment = GetNFragments (packet);
513  if (fragmentNumber >= nFragment)
514  {
515  return 0;
516  }
517  if (fragmentNumber == nFragment - 1)
518  {
519  uint32_t lastFragmentSize = packet->GetSize () % GetFragmentationThreshold ();
520  return lastFragmentSize;
521  }
522  else
523  {
524  return GetFragmentationThreshold ();
525  }
526 }
527 uint32_t
529  Ptr<const Packet> packet, uint32_t fragmentNumber)
530 {
531  NS_ASSERT (!address.IsGroup ());
532  NS_ASSERT (fragmentNumber < GetNFragments (packet));
533  uint32_t fragmentOffset = fragmentNumber * GetFragmentationThreshold ();
534  return fragmentOffset;
535 }
536 bool
538  Ptr<const Packet> packet, uint32_t fragmentNumber)
539 {
540  NS_ASSERT (!address.IsGroup ());
541  bool isLast = fragmentNumber == (GetNFragments (packet) - 1);
542  return isLast;
543 }
544 WifiMode
546 {
561  WifiMode mode = GetDefaultMode ();
562  bool found = false;
563 
564  // First, search the BSS Basic Rate set
565  for (WifiModeListIterator i = m_bssBasicRateSet.begin ();
566  i != m_bssBasicRateSet.end (); i++)
567  {
568  if ((!found || i->GetPhyRate () > mode.GetPhyRate ())
569  && i->GetPhyRate () <= reqMode.GetPhyRate ()
570  && i->GetModulationClass () == reqMode.GetModulationClass ())
571  {
572  mode = *i;
573  // We've found a potentially-suitable transmit rate, but we
574  // need to continue and consider all the basic rates before
575  // we can be sure we've got the right one.
576  found = true;
577  }
578  }
579 
580  // If we found a suitable rate in the BSSBasicRateSet, then we are
581  // done and can return that mode.
582  if (found)
583  {
584  return mode;
585  }
586 
604  for (uint32_t idx = 0; idx < m_wifiPhy->GetNModes (); idx++)
605  {
606  WifiMode thismode = m_wifiPhy->GetMode (idx);
607 
608  /* If the rate:
609  *
610  * - is a mandatory rate for the PHY, and
611  * - is equal to or faster than our current best choice, and
612  * - is less than or equal to the rate of the received frame, and
613  * - is of the same modulation class as the received frame
614  *
615  * ...then it's our best choice so far.
616  */
617  if (thismode.IsMandatory ()
618  && (!found || thismode.GetPhyRate () > mode.GetPhyRate ())
619  && thismode.GetPhyRate () <= reqMode.GetPhyRate ()
620  && thismode.GetModulationClass () == reqMode.GetModulationClass ())
621  {
622  mode = thismode;
623  // As above; we've found a potentially-suitable transmit
624  // rate, but we need to continue and consider all the
625  // mandatory rates before we can be sure we've got the right
626  // one.
627  found = true;
628  }
629  }
630 
641  if (!found)
642  {
643  NS_FATAL_ERROR ("Can't find response rate for " << reqMode
644  << ". Check standard and selected rates match.");
645  }
646 
647  return mode;
648 }
649 
650 WifiMode
652 {
653  NS_ASSERT (!address.IsGroup ());
654  return GetControlAnswerMode (address, rtsMode);
655 }
656 WifiMode
658 {
659  NS_ASSERT (!address.IsGroup ());
660  return GetControlAnswerMode (address, dataMode);
661 }
662 
665 {
666  WifiRemoteStationState *state = LookupState (address);
667  return state->m_info;
668 }
669 
672 {
673  for (StationStates::const_iterator i = m_states.begin (); i != m_states.end (); i++)
674  {
675  if ((*i)->m_address == address)
676  {
677  return (*i);
678  }
679  }
682  state->m_address = address;
683  state->m_operationalRateSet.push_back (GetDefaultMode ());
684  const_cast<WifiRemoteStationManager *> (this)->m_states.push_back (state);
685  return state;
686 }
689 {
690  uint8_t tid;
691  if (header->IsQosData ())
692  {
693  tid = header->GetQosTid ();
694  }
695  else
696  {
697  tid = 0;
698  }
699  return Lookup (address, tid);
700 }
702 WifiRemoteStationManager::Lookup (Mac48Address address, uint8_t tid) const
703 {
704  for (Stations::const_iterator i = m_stations.begin (); i != m_stations.end (); i++)
705  {
706  if ((*i)->m_tid == tid
707  && (*i)->m_state->m_address == address)
708  {
709  return (*i);
710  }
711  }
712  WifiRemoteStationState *state = LookupState (address);
713 
714  WifiRemoteStation *station = DoCreateStation ();
715  station->m_state = state;
716  station->m_tid = tid;
717  station->m_ssrc = 0;
718  station->m_slrc = 0;
719  // XXX
720  const_cast<WifiRemoteStationManager *> (this)->m_stations.push_back (station);
721  return station;
722 
723 }
724 
725 WifiMode
727 {
728  return m_defaultTxMode;
729 }
730 void
732 {
733  for (Stations::const_iterator i = m_stations.begin (); i != m_stations.end (); i++)
734  {
735  delete (*i);
736  }
737  m_stations.clear ();
738  m_bssBasicRateSet.clear ();
741 }
742 void
744 {
745  for (uint32_t i = 0; i < GetNBasicModes (); i++)
746  {
747  if (GetBasicMode (i) == mode)
748  {
749  return;
750  }
751  }
752  m_bssBasicRateSet.push_back (mode);
753 }
754 uint32_t
756 {
757  return m_bssBasicRateSet.size ();
758 }
759 WifiMode
761 {
762  NS_ASSERT (i < m_bssBasicRateSet.size ());
763  return m_bssBasicRateSet[i];
764 }
765 WifiMode
767 {
768  if (m_nonUnicastMode == WifiMode ())
769  {
770  return GetBasicMode (0);
771  }
772  else
773  {
774  return m_nonUnicastMode;
775  }
776 }
777 
778 bool
780  Ptr<const Packet> packet, bool normally)
781 {
782  return normally;
783 }
784 bool
786  Ptr<const Packet> packet, bool normally)
787 {
788  return normally;
789 }
790 bool
792  Ptr<const Packet> packet, bool normally)
793 {
794  return normally;
795 }
796 bool
798  Ptr<const Packet> packet, bool normally)
799 {
800  return normally;
801 }
802 
803 WifiMode
805 {
806  NS_ASSERT (i < GetNSupported (station));
807  return station->m_state->m_operationalRateSet[i];
808 }
809 uint32_t
811 {
812  return station->m_state->m_operationalRateSet.size ();
813 }
814 
815 //WifiRemoteStationInfo constructor
817  : m_memoryTime (Seconds (1.0)),
818  m_lastUpdate (Seconds (0.0)),
819  m_failAvg (0.0)
820 {
821 }
822 
823 double
825 {
826  double retval = exp ((double)(m_lastUpdate.GetMicroSeconds () - Simulator::Now ().GetMicroSeconds ())
827  / (double)m_memoryTime.GetMicroSeconds ());
829  return retval;
830 }
831 
832 void
834 {
835  double coefficient = CalculateAveragingCoefficient ();
836  m_failAvg = (double)retryCounter / (1 + (double) retryCounter) * (1.0 - coefficient) + coefficient * m_failAvg;
837 }
838 
839 void
841 {
842  double coefficient = CalculateAveragingCoefficient ();
843  m_failAvg = (1.0 - coefficient) + coefficient * m_failAvg;
844 }
845 
846 double
848 {
849  return m_failAvg;
850 }
851 } // namespace ns3