A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
yans-wifi-phy.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 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  * Author: Ghada Badawy <gbadawy@gmail.com>
20  */
21 
22 #include "yans-wifi-phy.h"
23 #include "yans-wifi-channel.h"
24 #include "wifi-mode.h"
25 #include "wifi-preamble.h"
26 #include "wifi-phy-state-helper.h"
27 #include "error-rate-model.h"
28 #include "ns3/simulator.h"
29 #include "ns3/packet.h"
30 #include "ns3/assert.h"
31 #include "ns3/log.h"
32 #include "ns3/double.h"
33 #include "ns3/uinteger.h"
34 #include "ns3/enum.h"
35 #include "ns3/pointer.h"
36 #include "ns3/net-device.h"
37 #include "ns3/trace-source-accessor.h"
38 #include "ns3/boolean.h"
39 #include <cmath>
40 
41 NS_LOG_COMPONENT_DEFINE ("YansWifiPhy");
42 
43 namespace ns3 {
44 
45 NS_OBJECT_ENSURE_REGISTERED (YansWifiPhy);
46 
47 TypeId
49 {
50  static TypeId tid = TypeId ("ns3::YansWifiPhy")
51  .SetParent<WifiPhy> ()
52  .AddConstructor<YansWifiPhy> ()
53  .AddAttribute ("EnergyDetectionThreshold",
54  "The energy of a received signal should be higher than "
55  "this threshold (dbm) to allow the PHY layer to detect the signal.",
56  DoubleValue (-96.0),
57  MakeDoubleAccessor (&YansWifiPhy::SetEdThreshold,
59  MakeDoubleChecker<double> ())
60  .AddAttribute ("CcaMode1Threshold",
61  "The energy of a received signal should be higher than "
62  "this threshold (dbm) to allow the PHY layer to declare CCA BUSY state",
63  DoubleValue (-99.0),
64  MakeDoubleAccessor (&YansWifiPhy::SetCcaMode1Threshold,
66  MakeDoubleChecker<double> ())
67  .AddAttribute ("TxGain",
68  "Transmission gain (dB).",
69  DoubleValue (1.0),
70  MakeDoubleAccessor (&YansWifiPhy::SetTxGain,
72  MakeDoubleChecker<double> ())
73  .AddAttribute ("RxGain",
74  "Reception gain (dB).",
75  DoubleValue (1.0),
76  MakeDoubleAccessor (&YansWifiPhy::SetRxGain,
78  MakeDoubleChecker<double> ())
79  .AddAttribute ("TxPowerLevels",
80  "Number of transmission power levels available between "
81  "TxPowerStart and TxPowerEnd included.",
82  UintegerValue (1),
83  MakeUintegerAccessor (&YansWifiPhy::m_nTxPower),
84  MakeUintegerChecker<uint32_t> ())
85  .AddAttribute ("TxPowerEnd",
86  "Maximum available transmission level (dbm).",
87  DoubleValue (16.0206),
88  MakeDoubleAccessor (&YansWifiPhy::SetTxPowerEnd,
90  MakeDoubleChecker<double> ())
91  .AddAttribute ("TxPowerStart",
92  "Minimum available transmission level (dbm).",
93  DoubleValue (16.0206),
94  MakeDoubleAccessor (&YansWifiPhy::SetTxPowerStart,
96  MakeDoubleChecker<double> ())
97  .AddAttribute ("RxNoiseFigure",
98  "Loss (dB) in the Signal-to-Noise-Ratio due to non-idealities in the receiver."
99  " According to Wikipedia (http://en.wikipedia.org/wiki/Noise_figure), this is "
100  "\"the difference in decibels (dB) between"
101  " the noise output of the actual receiver to the noise output of an "
102  " ideal receiver with the same overall gain and bandwidth when the receivers "
103  " are connected to sources at the standard noise temperature T0 (usually 290 K)\"."
104  " For",
105  DoubleValue (7),
106  MakeDoubleAccessor (&YansWifiPhy::SetRxNoiseFigure,
108  MakeDoubleChecker<double> ())
109  .AddAttribute ("State", "The state of the PHY layer",
110  PointerValue (),
111  MakePointerAccessor (&YansWifiPhy::m_state),
112  MakePointerChecker<WifiPhyStateHelper> ())
113  .AddAttribute ("ChannelSwitchDelay",
114  "Delay between two short frames transmitted on different frequencies.",
115  TimeValue (MicroSeconds (250)),
116  MakeTimeAccessor (&YansWifiPhy::m_channelSwitchDelay),
117  MakeTimeChecker ())
118  .AddAttribute ("ChannelNumber",
119  "Channel center frequency = Channel starting frequency + 5 MHz * nch",
120  UintegerValue (1),
121  MakeUintegerAccessor (&YansWifiPhy::SetChannelNumber,
123  MakeUintegerChecker<uint16_t> ())
124  .AddAttribute ("Frequency", "The operating frequency.",
125  UintegerValue (2407),
126  MakeUintegerAccessor (&YansWifiPhy::GetFrequency,
128  MakeUintegerChecker<uint32_t> ())
129  .AddAttribute ("Transmitters", "The number of transmitters.",
130  UintegerValue (1),
131  MakeUintegerAccessor (&YansWifiPhy::GetNumberOfTransmitAntennas,
133  MakeUintegerChecker<uint32_t> ())
134  .AddAttribute ("Recievers", "The number of recievers.",
135  UintegerValue (1),
136  MakeUintegerAccessor (&YansWifiPhy::GetNumberOfReceiveAntennas,
138  MakeUintegerChecker<uint32_t> ())
139  .AddAttribute ("ShortGuardEnabled", "Whether or not short guard interval is enabled.",
140  BooleanValue (false),
141  MakeBooleanAccessor (&YansWifiPhy::GetGuardInterval,
143  MakeBooleanChecker ())
144  .AddAttribute ("LdpcEnabled", "Whether or not LDPC is enabled.",
145  BooleanValue (false),
146  MakeBooleanAccessor (&YansWifiPhy::GetLdpc,
148  MakeBooleanChecker ())
149  .AddAttribute ("STBCEnabled", "Whether or not STBC is enabled.",
150  BooleanValue (false),
151  MakeBooleanAccessor (&YansWifiPhy::GetStbc,
153  MakeBooleanChecker ())
154  .AddAttribute ("GreenfieldEnabled", "Whether or not STBC is enabled.",
155  BooleanValue (false),
156  MakeBooleanAccessor (&YansWifiPhy::GetGreenfield,
158  MakeBooleanChecker ())
159  .AddAttribute ("ChannelBonding", "Whether 20MHz or 40MHz.",
160  BooleanValue (false),
161  MakeBooleanAccessor (&YansWifiPhy::GetChannelBonding,
163  MakeBooleanChecker ())
164 
165 
166  ;
167  return tid;
168 }
169 
171  : m_channelNumber (1),
172  m_endRxEvent (),
173  m_channelStartingFrequency (0)
174 {
175  NS_LOG_FUNCTION (this);
176  m_random = CreateObject<UniformRandomVariable> ();
177  m_state = CreateObject<WifiPhyStateHelper> ();
178 }
179 
181 {
182  NS_LOG_FUNCTION (this);
183 }
184 
185 void
187 {
188  NS_LOG_FUNCTION (this);
189  m_channel = 0;
190  m_deviceRateSet.clear ();
191  m_deviceMcsSet.clear();
192  m_device = 0;
193  m_mobility = 0;
194  m_state = 0;
195 }
196 
197 void
199 {
200  NS_LOG_FUNCTION (this << standard);
201  switch (standard)
202  {
204  Configure80211a ();
205  break;
207  Configure80211b ();
208  break;
210  Configure80211g ();
211  break;
214  break;
217  break;
219  ConfigureHolland ();
220  break;
223  break;
226  break;
229  Configure80211n ();
230  break;
233  Configure80211n ();
234  break;
235 
236  default:
237  NS_ASSERT (false);
238  break;
239  }
240 }
241 
242 
243 void
244 YansWifiPhy::SetRxNoiseFigure (double noiseFigureDb)
245 {
246  NS_LOG_FUNCTION (this << noiseFigureDb);
247  m_interference.SetNoiseFigure (DbToRatio (noiseFigureDb));
248 }
249 void
251 {
252  NS_LOG_FUNCTION (this << start);
254 }
255 void
257 {
258  NS_LOG_FUNCTION (this << end);
259  m_txPowerEndDbm = end;
260 }
261 void
263 {
264  NS_LOG_FUNCTION (this << n);
265  m_nTxPower = n;
266 }
267 void
269 {
270  NS_LOG_FUNCTION (this << gain);
271  m_txGainDb = gain;
272 }
273 void
275 {
276  NS_LOG_FUNCTION (this << gain);
277  m_rxGainDb = gain;
278 }
279 void
280 YansWifiPhy::SetEdThreshold (double threshold)
281 {
282  NS_LOG_FUNCTION (this << threshold);
283  m_edThresholdW = DbmToW (threshold);
284 }
285 void
287 {
288  NS_LOG_FUNCTION (this << threshold);
289  m_ccaMode1ThresholdW = DbmToW (threshold);
290 }
291 void
293 {
295 }
296 void
298 {
299  m_device = device;
300 }
301 void
303 {
304  m_mobility = mobility;
305 }
306 
307 double
309 {
311 }
312 double
314 {
315  return m_txPowerBaseDbm;
316 }
317 double
319 {
320  return m_txPowerEndDbm;
321 }
322 double
324 {
325  return m_txGainDb;
326 }
327 double
329 {
330  return m_rxGainDb;
331 }
332 
333 double
335 {
336  return WToDbm (m_edThresholdW);
337 }
338 
339 double
341 {
342  return WToDbm (m_ccaMode1ThresholdW);
343 }
344 
347 {
349 }
352 {
353  return m_device;
354 }
357 {
358  return m_mobility;
359 }
360 
361 double
362 YansWifiPhy::CalculateSnr (WifiMode txMode, double ber) const
363 {
364  return m_interference.GetErrorRateModel ()->CalculateSnr (txMode, ber);
365 }
366 
369 {
370  return m_channel;
371 }
372 void
374 {
375  m_channel = channel;
376  m_channel->Add (this);
377 }
378 
379 void
381 {
382  if (Simulator::Now () == Seconds (0))
383  {
384  // this is not channel switch, this is initialization
385  NS_LOG_DEBUG ("start at channel " << nch);
386  m_channelNumber = nch;
387  return;
388  }
389 
391  switch (m_state->GetState ())
392  {
393  case YansWifiPhy::RX:
394  NS_LOG_DEBUG ("drop packet because of channel switching while reception");
395  m_endRxEvent.Cancel ();
396  goto switchChannel;
397  break;
398  case YansWifiPhy::TX:
399  NS_LOG_DEBUG ("channel switching postponed until end of current transmission");
401  break;
403  case YansWifiPhy::IDLE:
404  goto switchChannel;
405  break;
406  default:
407  NS_ASSERT (false);
408  break;
409  }
410 
411  return;
412 
413 switchChannel:
414 
415  NS_LOG_DEBUG ("switching channel " << m_channelNumber << " -> " << nch);
418  /*
419  * Needed here to be able to correctly sensed the medium for the first
420  * time after the switching. The actual switching is not performed until
421  * after m_channelSwitchDelay. Packets received during the switching
422  * state are added to the event list and are employed later to figure
423  * out the state of the medium after the switching.
424  */
425  m_channelNumber = nch;
426 }
427 
428 uint16_t
430 {
431  return m_channelNumber;
432 }
433 
434 double
436 {
438 }
439 
440 void
442 {
443  m_state->SetReceiveOkCallback (callback);
444 }
445 void
447 {
448  m_state->SetReceiveErrorCallback (callback);
449 }
450 void
452  double rxPowerDbm,
453  WifiTxVector txVector,
454  enum WifiPreamble preamble)
455 {
456  NS_LOG_FUNCTION (this << packet << rxPowerDbm << txVector.GetMode()<< preamble);
457  rxPowerDbm += m_rxGainDb;
458  double rxPowerW = DbmToW (rxPowerDbm);
459  Time rxDuration = CalculateTxDuration (packet->GetSize (), txVector, preamble);
460 WifiMode txMode=txVector.GetMode();
461  Time endRx = Simulator::Now () + rxDuration;
462 
464  event = m_interference.Add (packet->GetSize (),
465  txMode,
466  preamble,
467  rxDuration,
468  rxPowerW,
469  txVector); // we need it to calculate duration of HT training symbols
470 
471  switch (m_state->GetState ())
472  {
474  NS_LOG_DEBUG ("drop packet because of channel switching");
475  NotifyRxDrop (packet);
476  /*
477  * Packets received on the upcoming channel are added to the event list
478  * during the switching state. This way the medium can be correctly sensed
479  * when the device listens to the channel for the first time after the
480  * switching e.g. after channel switching, the channel may be sensed as
481  * busy due to other devices' tramissions started before the end of
482  * the switching.
483  */
484  if (endRx > Simulator::Now () + m_state->GetDelayUntilIdle ())
485  {
486  // that packet will be noise _after_ the completion of the
487  // channel switching.
488  goto maybeCcaBusy;
489  }
490  break;
491  case YansWifiPhy::RX:
492  NS_LOG_DEBUG ("drop packet because already in Rx (power=" <<
493  rxPowerW << "W)");
494  NotifyRxDrop (packet);
495  if (endRx > Simulator::Now () + m_state->GetDelayUntilIdle ())
496  {
497  // that packet will be noise _after_ the reception of the
498  // currently-received packet.
499  goto maybeCcaBusy;
500  }
501  break;
502  case YansWifiPhy::TX:
503  NS_LOG_DEBUG ("drop packet because already in Tx (power=" <<
504  rxPowerW << "W)");
505  NotifyRxDrop (packet);
506  if (endRx > Simulator::Now () + m_state->GetDelayUntilIdle ())
507  {
508  // that packet will be noise _after_ the transmission of the
509  // currently-transmitted packet.
510  goto maybeCcaBusy;
511  }
512  break;
514  case YansWifiPhy::IDLE:
515  if (rxPowerW > m_edThresholdW)
516  {
517  NS_LOG_DEBUG ("sync to signal (power=" << rxPowerW << "W)");
518  // sync to signal
519  m_state->SwitchToRx (rxDuration);
521  NotifyRxBegin (packet);
524  packet,
525  event);
526  }
527  else
528  {
529  NS_LOG_DEBUG ("drop packet because signal power too Small (" <<
530  rxPowerW << "<" << m_edThresholdW << ")");
531  NotifyRxDrop (packet);
532  goto maybeCcaBusy;
533  }
534  break;
535  }
536 
537  return;
538 
539 maybeCcaBusy:
540  // We are here because we have received the first bit of a packet and we are
541  // not going to be able to synchronize on it
542  // In this model, CCA becomes busy when the aggregation of all signals as
543  // tracked by the InterferenceHelper class is higher than the CcaBusyThreshold
544 
546  if (!delayUntilCcaEnd.IsZero ())
547  {
548  m_state->SwitchMaybeToCcaBusy (delayUntilCcaEnd);
549  }
550 }
551 
552 void
554 {
555  NS_LOG_FUNCTION (this << packet << txMode << preamble << (uint32_t)txVector.GetTxPowerLevel());
556  /* Transmission can happen if:
557  * - we are syncing on a packet. It is the responsability of the
558  * MAC layer to avoid doing this but the PHY does nothing to
559  * prevent it.
560  * - we are idle
561  */
563 
564  Time txDuration = CalculateTxDuration (packet->GetSize (), txVector, preamble);
565  if (m_state->IsStateRx ())
566  {
567  m_endRxEvent.Cancel ();
569  }
570  NotifyTxBegin (packet);
571  uint32_t dataRate500KbpsUnits = txVector.GetMode().GetDataRate () * txVector.GetNss() / 500000;
572  bool isShortPreamble = (WIFI_PREAMBLE_SHORT == preamble);
573  NotifyMonitorSniffTx (packet, (uint16_t)GetChannelFrequencyMhz (), GetChannelNumber (), dataRate500KbpsUnits, isShortPreamble, txVector.GetTxPowerLevel());
574  m_state->SwitchToTx (txDuration, packet, txVector.GetMode(), preamble, txVector.GetTxPowerLevel());
575  m_channel->Send (this, packet, GetPowerDbm ( txVector.GetTxPowerLevel()) + m_txGainDb, txVector, preamble);
576 }
577 
578 uint32_t
580 {
581  return m_deviceRateSet.size ();
582 }
583 WifiMode
584 YansWifiPhy::GetMode (uint32_t mode) const
585 {
586  return m_deviceRateSet[mode];
587 }
588 uint32_t
590 {
591  return m_nTxPower;
592 }
593 
594 void
596 {
597  NS_LOG_FUNCTION (this);
598  m_channelStartingFrequency = 5e3; // 5.000 GHz
599 
608 }
609 
610 
611 void
613 {
614  NS_LOG_FUNCTION (this);
615  m_channelStartingFrequency = 2407; // 2.407 GHz
616 
621 }
622 
623 void
625 {
626  NS_LOG_FUNCTION (this);
627  m_channelStartingFrequency = 2407; // 2.407 GHz
628 
641 }
642 
643 void
645 {
646  NS_LOG_FUNCTION (this);
647  m_channelStartingFrequency = 5e3; // 5.000 GHz, suppose 802.11a
648 
657 }
658 
659 void
661 {
662  NS_LOG_FUNCTION (this);
663  m_channelStartingFrequency = 5e3; // 5.000 GHz, suppose 802.11a
664 
673 }
674 
675 void
677 {
678  NS_LOG_FUNCTION (this);
679  m_channelStartingFrequency = 5e3; // 5.000 GHz
685 }
686 
687 void
689 {
690  NS_LOG_FUNCTION (this);
691  m_channelStartingFrequency = 5e3; // 802.11p works over the 5Ghz freq range
692 
701 }
702 
703 void
705 {
706  NS_LOG_FUNCTION (this);
707  m_channelStartingFrequency = 5e3; // 802.11p works over the 5Ghz freq range
708 
717 }
718 
719 void
721 {
722  m_state->RegisterListener (listener);
723 }
724 
725 bool
727 {
728  return m_state->IsStateCcaBusy ();
729 }
730 
731 bool
733 {
734  return m_state->IsStateIdle ();
735 }
736 bool
738 {
739  return m_state->IsStateBusy ();
740 }
741 bool
743 {
744  return m_state->IsStateRx ();
745 }
746 bool
748 {
749  return m_state->IsStateTx ();
750 }
751 bool
753 {
754  return m_state->IsStateSwitching ();
755 }
756 
757 Time
759 {
760  return m_state->GetStateDuration ();
761 }
762 Time
764 {
765  return m_state->GetDelayUntilIdle ();
766 }
767 
768 Time
770 {
771  return m_state->GetLastRxStartTime ();
772 }
773 
774 double
775 YansWifiPhy::DbToRatio (double dB) const
776 {
777  double ratio = std::pow (10.0, dB / 10.0);
778  return ratio;
779 }
780 
781 double
782 YansWifiPhy::DbmToW (double dBm) const
783 {
784  double mW = std::pow (10.0, dBm / 10.0);
785  return mW / 1000.0;
786 }
787 
788 double
789 YansWifiPhy::WToDbm (double w) const
790 {
791  return 10.0 * std::log10 (w * 1000.0);
792 }
793 
794 double
795 YansWifiPhy::RatioToDb (double ratio) const
796 {
797  return 10.0 * std::log10 (ratio);
798 }
799 
800 double
802 {
803  return m_edThresholdW;
804 }
805 
806 double
807 YansWifiPhy::GetPowerDbm (uint8_t power) const
808 {
810  NS_ASSERT (m_nTxPower > 0);
811  double dbm;
812  if (m_nTxPower > 1)
813  {
814  dbm = m_txPowerBaseDbm + power * (m_txPowerEndDbm - m_txPowerBaseDbm) / (m_nTxPower - 1);
815  }
816  else
817  {
818  NS_ASSERT_MSG (m_txPowerBaseDbm == m_txPowerEndDbm, "cannot have TxPowerEnd != TxPowerStart with TxPowerLevels == 1");
819  dbm = m_txPowerBaseDbm;
820  }
821  return dbm;
822 }
823 
824 void
826 {
827  NS_LOG_FUNCTION (this << packet << event);
828  NS_ASSERT (IsStateRx ());
829  NS_ASSERT (event->GetEndTime () == Simulator::Now ());
830 
831  struct InterferenceHelper::SnrPer snrPer;
832  snrPer = m_interference.CalculateSnrPer (event);
834 
835  NS_LOG_DEBUG ("mode=" << (event->GetPayloadMode ().GetDataRate ()) <<
836  ", snr=" << snrPer.snr << ", per=" << snrPer.per << ", size=" << packet->GetSize ());
837  if (m_random->GetValue () > snrPer.per)
838  {
839  NotifyRxEnd (packet);
840  uint32_t dataRate500KbpsUnits = event->GetPayloadMode ().GetDataRate () * event->GetTxVector().GetNss()/ 500000;
841  bool isShortPreamble = (WIFI_PREAMBLE_SHORT == event->GetPreambleType ());
842  double signalDbm = RatioToDb (event->GetRxPowerW ()) + 30;
843  double noiseDbm = RatioToDb (event->GetRxPowerW () / snrPer.snr) - GetRxNoiseFigure () + 30;
844  NotifyMonitorSniffRx (packet, (uint16_t)GetChannelFrequencyMhz (), GetChannelNumber (), dataRate500KbpsUnits, isShortPreamble, signalDbm, noiseDbm);
845  m_state->SwitchFromRxEndOk (packet, snrPer.snr, event->GetPayloadMode (), event->GetPreambleType ());
846  }
847  else
848  {
849  /* failure. */
850  NotifyRxDrop (packet);
851  m_state->SwitchFromRxEndError (packet, snrPer.snr);
852  }
853 }
854 
855 int64_t
857 {
858  NS_LOG_FUNCTION (this << stream);
859  m_random->SetStream (stream);
860  return 1;
861 }
862 
863 void
865 {
867 }
868 
869 void
871 {
873 }
874 void
876 {
877  m_numberOfReceivers = rx;
878 }
879 
880 void
882 {
883  m_ldpc = Ldpc;
884 }
885 
886 void
888 {
889  m_stbc = stbc;
890 }
891 
892 void
893 YansWifiPhy::SetGreenfield (bool greenfield)
894 {
895  m_greenfield = greenfield;
896 }
897 bool
899 {
900  return m_guardInterval;
901 }
902 void
903 YansWifiPhy::SetGuardInterval (bool GuardInterval)
904 {
905  m_guardInterval = GuardInterval;
906 }
907 
908 uint32_t
910 {
912 }
913 
914 uint32_t
916 {
917  return m_numberOfTransmitters;
918 }
919 uint32_t
921 {
922  return m_numberOfReceivers;
923 }
924 
925 bool
927 {
928  return m_ldpc;
929 }
930 bool
932 {
933  return m_stbc;
934 }
935 
936 bool
938 {
939  return m_greenfield;
940 }
941 
942 bool
944 {
945  return m_channelBonding;
946 }
947 
948 void
949 YansWifiPhy::SetChannelBonding(bool channelbonding)
950 {
951  m_channelBonding= channelbonding;
952 }
953 
954 void
956 {
957  NS_LOG_FUNCTION (this);
966  for (uint8_t i=0; i <8; i++)
967  {
968  m_deviceMcsSet.push_back(i);
969  }
970 
971 }
972 uint32_t
974 {
975  return m_bssMembershipSelectorSet.size ();
976 }
977 uint32_t
978 YansWifiPhy::GetBssMembershipSelector (uint32_t selector) const
979 {
980  return m_bssMembershipSelectorSet[selector];
981 }
984 {
985  uint32_t id=GetBssMembershipSelector(selector);
986  WifiModeList supportedmodes;
987  if (id == HT_PHY)
988  {
989  //mandatory MCS 0 to 7
990  supportedmodes.push_back (WifiPhy::GetOfdmRate6_5MbpsBW20MHz ());
991  supportedmodes.push_back (WifiPhy::GetOfdmRate13MbpsBW20MHz ());
992  supportedmodes.push_back (WifiPhy::GetOfdmRate19_5MbpsBW20MHz ());
993  supportedmodes.push_back (WifiPhy::GetOfdmRate26MbpsBW20MHz ());
994  supportedmodes.push_back (WifiPhy::GetOfdmRate39MbpsBW20MHz ());
995  supportedmodes.push_back (WifiPhy::GetOfdmRate52MbpsBW20MHz ());
996  supportedmodes.push_back (WifiPhy::GetOfdmRate58_5MbpsBW20MHz ());
997  supportedmodes.push_back (WifiPhy::GetOfdmRate65MbpsBW20MHz ());
998  }
999  return supportedmodes;
1000 }
1001 uint8_t
1003 {
1004  return m_deviceMcsSet.size ();
1005 }
1006 uint8_t
1007 YansWifiPhy::GetMcs (uint8_t mcs) const
1008 {
1009  return m_deviceMcsSet[mcs];
1010 }
1011 uint32_t
1013 {
1014  uint32_t mcs = 0;
1015  if (mode.GetUniqueName() == "OfdmRate135MbpsBW40MHzShGi" || mode.GetUniqueName() == "OfdmRate65MbpsBW20MHzShGi" )
1016  {
1017  mcs=6;
1018  }
1019  else
1020  {
1021  switch (mode.GetDataRate())
1022  {
1023  case 6500000:
1024  case 7200000:
1025  case 13500000:
1026  case 15000000:
1027  mcs=0;
1028  break;
1029  case 13000000:
1030  case 14400000:
1031  case 27000000:
1032  case 30000000:
1033  mcs=1;
1034  break;
1035  case 19500000:
1036  case 21700000:
1037  case 40500000:
1038  case 45000000:
1039  mcs=2;
1040  break;
1041  case 26000000:
1042  case 28900000:
1043  case 54000000:
1044  case 60000000:
1045  mcs=3;
1046  break;
1047  case 39000000:
1048  case 43300000:
1049  case 81000000:
1050  case 90000000:
1051  mcs=4;
1052  break;
1053  case 52000000:
1054  case 57800000:
1055  case 108000000:
1056  case 120000000:
1057  mcs=5;
1058  break;
1059  case 58500000:
1060  case 121500000:
1061  mcs=6;
1062  break;
1063  case 65000000:
1064  case 72200000:
1065  case 135000000:
1066  case 150000000:
1067  mcs=7;
1068  break;
1069  }
1070  }
1071  return mcs;
1072 }
1073 WifiMode
1075 {
1076  WifiMode mode;
1077  switch (mcs)
1078  {
1079  case 7:
1080  if (!GetGuardInterval() && !GetChannelBonding())
1081  {
1083  }
1084  else if(GetGuardInterval() && !GetChannelBonding())
1085  {
1087  }
1088  else if (!GetGuardInterval() && GetChannelBonding())
1089  {
1091  }
1092  else
1093  {
1095  }
1096  break;
1097  case 6:
1098  if (!GetGuardInterval() && !GetChannelBonding())
1099  {
1101 
1102  }
1103  else if(GetGuardInterval() && !GetChannelBonding())
1104  {
1106 
1107  }
1108  else if (!GetGuardInterval() && GetChannelBonding())
1109  {
1111 
1112  }
1113  else
1114  {
1116 
1117  }
1118  break;
1119  case 5:
1120  if (!GetGuardInterval() && !GetChannelBonding())
1121  {
1123 
1124  }
1125  else if(GetGuardInterval() && !GetChannelBonding())
1126  {
1128  }
1129  else if (!GetGuardInterval() && GetChannelBonding())
1130  {
1132 
1133  }
1134  else
1135  {
1137 
1138  }
1139  break;
1140  case 4:
1141  if (!GetGuardInterval() && !GetChannelBonding())
1142  {
1144  }
1145  else if(GetGuardInterval() && !GetChannelBonding())
1146  {
1148  }
1149  else if (!GetGuardInterval() && GetChannelBonding())
1150  {
1152 
1153  }
1154  else
1155  {
1157 
1158  }
1159  break;
1160  case 3:
1161  if (!GetGuardInterval() && !GetChannelBonding())
1162  {
1164 
1165  }
1166  else if(GetGuardInterval() && !GetChannelBonding())
1167  {
1169 
1170  }
1171  else if (!GetGuardInterval() && GetChannelBonding())
1172  {
1174 
1175  }
1176  else
1177  {
1179  }
1180  break;
1181  case 2:
1182  if (!GetGuardInterval() && !GetChannelBonding())
1183  {
1185 
1186  }
1187  else if(GetGuardInterval() && !GetChannelBonding())
1188  {
1190 
1191  }
1192  else if (!GetGuardInterval() && GetChannelBonding())
1193  {
1195 
1196  }
1197  else
1198  {
1200 
1201  }
1202  break;
1203  case 1:
1204  if (!GetGuardInterval() && !GetChannelBonding())
1205  {
1207 
1208  }
1209  else if(GetGuardInterval() && !GetChannelBonding())
1210  {
1212  }
1213  else if (!GetGuardInterval() && GetChannelBonding())
1214  {
1216 
1217  }
1218  else
1219  {
1221  }
1222  break;
1223  case 0:
1224  default:
1225  if (!GetGuardInterval() && !GetChannelBonding())
1226  {
1228 
1229  }
1230  else if(GetGuardInterval() && !GetChannelBonding())
1231  {
1233  }
1234  else if (!GetGuardInterval() && GetChannelBonding())
1235  {
1237 
1238  }
1239  else
1240  {
1242  }
1243  break;
1244  }
1245  return mode;
1246 }
1247 } // namespace ns3