src/devices/wifi/wifi-phy.cc
changeset 3888 a15618dcd0eb
parent 3882 05de3d432860
child 3906 01acc159ffb1
equal deleted inserted replaced
3887:51e9f5ef0963 3888:a15618dcd0eb
    35 
    35 
    36 NS_LOG_COMPONENT_DEFINE ("WifiPhy");
    36 NS_LOG_COMPONENT_DEFINE ("WifiPhy");
    37 
    37 
    38 namespace ns3 {
    38 namespace ns3 {
    39 
    39 
    40   // Define all the WifiMode needed for 802.11a
    40 // Define all the WifiMode needed for 802.11a
    41 static WifiMode g_6mba = WifiModeFactory::CreateBpsk ("wifia-6mbs",
    41 WifiMode WifiPhy::g_6mba = WifiModeFactory::CreateBpsk ("wifia-6mbs",
    42                                                       true,
    42                                                         true,
    43                                                       20000000, 6000000, 12000000);
    43                                                         20000000, 6000000, 12000000);
    44 static WifiMode g_9mba = WifiModeFactory::CreateBpsk ("wifia-9mbs",
    44 WifiMode WifiPhy::g_9mba = WifiModeFactory::CreateBpsk ("wifia-9mbs",
    45                                                       false,
    45                                                         false,
    46                                                       20000000, 9000000, 12000000);
    46                                                         20000000, 9000000, 12000000);
    47 // XXX explain why Bpsk rather than Qpsk
    47 // XXX explain why Bpsk rather than Qpsk
    48 static WifiMode g_12mba = WifiModeFactory::CreateBpsk ("wifia-12mbs",
    48 WifiMode WifiPhy::g_12mba = WifiModeFactory::CreateBpsk ("wifia-12mbs",
    49                                                        true,
    49                                                          true,
    50                                                        20000000, 12000000, 24000000);
    50                                                          20000000, 12000000, 24000000);
    51 static WifiMode g_18mba = WifiModeFactory::CreateBpsk ("wifia-18mbs",
    51 WifiMode WifiPhy::g_18mba = WifiModeFactory::CreateBpsk ("wifia-18mbs",
    52                                                        false,
    52                                                          false,
    53                                                        20000000, 18000000, 24000000);
    53                                                          20000000, 18000000, 24000000);
    54 static WifiMode g_24mba = WifiModeFactory::CreateBpsk ("wifia-24mbs",
    54 WifiMode WifiPhy::g_24mba = WifiModeFactory::CreateBpsk ("wifia-24mbs",
    55                                                        true,
    55                                                          true,
    56                                                        20000000, 24000000, 48000000);
    56                                                          20000000, 24000000, 48000000);
    57 static WifiMode g_36mba = WifiModeFactory::CreateBpsk ("wifia-36mbs",
    57 WifiMode WifiPhy::g_36mba = WifiModeFactory::CreateBpsk ("wifia-36mbs",
    58                                                        false,
    58                                                          false,
    59                                                        20000000, 36000000, 48000000);
    59                                                          20000000, 36000000, 48000000);
    60 static WifiMode g_48mba = WifiModeFactory::CreateBpsk ("wifia-48mbs",
    60 WifiMode WifiPhy::g_48mba = WifiModeFactory::CreateBpsk ("wifia-48mbs",
    61                                                        false,
    61                                                          false,
    62                                                        20000000, 48000000, 72000000);
    62                                                          20000000, 48000000, 72000000);
    63 static WifiMode g_54mba = WifiModeFactory::CreateBpsk ("wifia-54mbs",
    63 WifiMode WifiPhy::g_54mba = WifiModeFactory::CreateBpsk ("wifia-54mbs",
    64                                                        false,
    64                                                          false,
    65                                                        20000000, 54000000, 72000000);
    65                                                          20000000, 54000000, 72000000);
    66 
    66 
    67 
    67 
    68 /****************************************************************
    68 /****************************************************************
    69  *       This destructor is needed.
    69  *       This destructor is needed.
    70  ****************************************************************/
    70  ****************************************************************/
    71 
    71 
    72 WifiPhyListener::~WifiPhyListener ()
    72 WifiPhyListener::~WifiPhyListener ()
    73 {}
    73 {}
    74 
       
    75 
       
    76 /****************************************************************
       
    77  *       Phy event class
       
    78  ****************************************************************/
       
    79 
       
    80 class RxEvent
       
    81 {
       
    82 public:
       
    83   RxEvent (uint32_t size, WifiMode payloadMode, 
       
    84            enum WifiPreamble preamble,
       
    85            Time duration, double rxPower)
       
    86     : m_size (size),
       
    87       m_payloadMode (payloadMode),
       
    88       m_preamble (preamble),
       
    89       m_startTime (Simulator::Now ()),
       
    90       m_endTime (m_startTime + duration),
       
    91       m_rxPowerW (rxPower),
       
    92       m_refCount (1)
       
    93   {}
       
    94   ~RxEvent ()
       
    95   {
       
    96     NS_ASSERT (m_refCount == 0);
       
    97   }
       
    98   
       
    99   void Ref (void) const {
       
   100     m_refCount++;
       
   101   }
       
   102   void Unref (void) const {
       
   103     m_refCount--;
       
   104     if (m_refCount == 0) {
       
   105       delete this;
       
   106     }
       
   107   }
       
   108   Time GetDuration (void) const {
       
   109     return m_endTime - m_startTime;
       
   110   }
       
   111   Time GetStartTime (void) const {
       
   112     return m_startTime;
       
   113   }
       
   114   Time GetEndTime (void) const {
       
   115     return m_endTime;
       
   116   }
       
   117   bool Overlaps (Time time) const {
       
   118     if (m_startTime <= time &&
       
   119         m_endTime >= time) {
       
   120       return true;
       
   121     } else {
       
   122       return false;
       
   123     }
       
   124   }
       
   125   double GetRxPowerW (void) const {
       
   126     return m_rxPowerW;
       
   127   }
       
   128   uint32_t GetSize (void) const {
       
   129     return m_size;
       
   130   }
       
   131   WifiMode GetPayloadMode (void) const {
       
   132     return m_payloadMode;
       
   133   }
       
   134   enum WifiPreamble GetPreambleType (void) const {
       
   135     return m_preamble;
       
   136   }
       
   137 
       
   138 private:
       
   139   uint32_t m_size;
       
   140   WifiMode m_payloadMode;
       
   141   enum WifiPreamble m_preamble;
       
   142   Time m_startTime;
       
   143   Time m_endTime;
       
   144   double m_rxPowerW;
       
   145   mutable int m_refCount;
       
   146 };
       
   147 
       
   148 
       
   149 /****************************************************************
       
   150  *       Class which records SNIR change events for a 
       
   151  *       short period of time.
       
   152  ****************************************************************/
       
   153 
       
   154 WifiPhy::NiChange::NiChange (Time time, double delta)
       
   155   : m_time (time), m_delta (delta) 
       
   156 {}
       
   157 Time
       
   158 WifiPhy::NiChange::GetTime (void) const
       
   159 {
       
   160   return m_time;
       
   161 }
       
   162 double 
       
   163 WifiPhy::NiChange::GetDelta (void) const
       
   164 {
       
   165   return m_delta;
       
   166 }
       
   167 bool 
       
   168 WifiPhy::NiChange::operator < (WifiPhy::NiChange const &o) const
       
   169 {
       
   170   return (m_time < o.m_time)?true:false;
       
   171 }
       
   172 
       
   173 
       
   174 
    74 
   175 /****************************************************************
    75 /****************************************************************
   176  *       The actual WifiPhy class
    76  *       The actual WifiPhy class
   177  ****************************************************************/
    77  ****************************************************************/
   178 
    78 
   181 TypeId 
    81 TypeId 
   182 WifiPhy::GetTypeId (void)
    82 WifiPhy::GetTypeId (void)
   183 {
    83 {
   184   static TypeId tid = TypeId ("ns3::WifiPhy")
    84   static TypeId tid = TypeId ("ns3::WifiPhy")
   185     .SetParent<Object> ()
    85     .SetParent<Object> ()
   186     .AddConstructor<WifiPhy> ()
       
   187     .AddAttribute ("EnergyDetectionThreshold",
       
   188                    "The energy of a received signal should be higher than "
       
   189                    "this threshold (dbm) to allow the PHY layer to detect the signal.",
       
   190                    DoubleValue (-140.0),
       
   191                    MakeDoubleAccessor (&WifiPhy::SetEdThreshold,
       
   192                                        &WifiPhy::GetEdThreshold),
       
   193                    MakeDoubleChecker<double> ())
       
   194     .AddAttribute ("TxGain",
       
   195                    "Transmission gain (dB).",
       
   196                    DoubleValue (1.0),
       
   197                    MakeDoubleAccessor (&WifiPhy::SetTxGain,
       
   198                                        &WifiPhy::GetTxGain),
       
   199                    MakeDoubleChecker<double> ())
       
   200     .AddAttribute ("RxGain",
       
   201                    "Reception gain (dB).",
       
   202                    DoubleValue (1.0),
       
   203                    MakeDoubleAccessor (&WifiPhy::SetRxGain,
       
   204                                        &WifiPhy::GetRxGain),
       
   205                    MakeDoubleChecker<double> ())
       
   206     .AddAttribute ("TxPowerLevels",
       
   207                    "Number of transmission power levels available between "
       
   208                    "TxPowerBase and TxPowerEnd included.",
       
   209                    UintegerValue (1),
       
   210                    MakeUintegerAccessor (&WifiPhy::m_nTxPower),
       
   211                    MakeUintegerChecker<uint32_t> ())
       
   212     .AddAttribute ("TxPowerEnd",
       
   213                    "Maximum available transmission level (dbm).",
       
   214                    DoubleValue (16.0206),
       
   215                    MakeDoubleAccessor (&WifiPhy::SetTxPowerEnd, 
       
   216                                        &WifiPhy::GetTxPowerEnd),
       
   217                    MakeDoubleChecker<double> ())
       
   218     .AddAttribute ("TxPowerStart",
       
   219                    "Minimum available transmission level (dbm).",
       
   220                    DoubleValue (16.0206),
       
   221                    MakeDoubleAccessor (&WifiPhy::SetTxPowerStart, 
       
   222                                        &WifiPhy::GetTxPowerStart),
       
   223                    MakeDoubleChecker<double> ())
       
   224     .AddAttribute ("RxNoise",
       
   225                    "Ratio of energy lost by receiver (dB).",
       
   226                    DoubleValue (7),
       
   227                    MakeDoubleAccessor (&WifiPhy::SetRxNoise,
       
   228                                        &WifiPhy::GetRxNoise),
       
   229                    MakeDoubleChecker<double> ())
       
   230     .AddAttribute ("Standard", "The standard chosen configures a set of transmission modes"
       
   231                    " and some PHY-specific constants.",
       
   232                    EnumValue (WIFI_PHY_STANDARD_80211a),
       
   233                    MakeEnumAccessor (&WifiPhy::SetStandard),
       
   234                    MakeEnumChecker (WIFI_PHY_STANDARD_80211a, "802.11a",
       
   235                                     WIFI_PHY_STANDARD_holland, "holland"))
       
   236     .AddTraceSource ("State",
       
   237                      "The WifiPhy state",
       
   238                      MakeTraceSourceAccessor (&WifiPhy::m_stateLogger))
       
   239     .AddTraceSource ("RxOk",
       
   240                      "A packet has been received successfully.",
       
   241                      MakeTraceSourceAccessor (&WifiPhy::m_rxOkTrace))
       
   242     .AddTraceSource ("RxError",
       
   243                      "A packet has been received unsuccessfully.",
       
   244                      MakeTraceSourceAccessor (&WifiPhy::m_rxErrorTrace))
       
   245     .AddTraceSource ("Tx", "Packet transmission is starting.",
       
   246                      MakeTraceSourceAccessor (&WifiPhy::m_txTrace))
       
   247     ;
    86     ;
   248   return tid;
    87   return tid;
   249 }
    88 }
   250 
    89 
   251 WifiPhy::WifiPhy ()
    90 WifiPhy::WifiPhy ()
   252   : m_syncing (false),
       
   253     m_endTx (Seconds (0)),
       
   254     m_endSync (Seconds (0)),
       
   255     m_endCcaBusy (Seconds (0)),
       
   256     m_startTx (Seconds (0)),
       
   257     m_startSync (Seconds (0)),
       
   258     m_startCcaBusy (Seconds (0)),
       
   259     m_previousStateChangeTime (Seconds (0)),
       
   260     m_endSyncEvent (),
       
   261     m_random (0.0, 1.0)
       
   262 {
    91 {
   263   NS_LOG_FUNCTION (this);
    92   NS_LOG_FUNCTION (this);
   264 }
    93 }
   265 
    94 
   266 WifiPhy::~WifiPhy ()
    95 WifiPhy::~WifiPhy ()
   267 {
    96 {
   268   NS_LOG_FUNCTION (this);
    97   NS_LOG_FUNCTION (this);
   269 }
    98 }
   270 
    99 
   271 void
       
   272 WifiPhy::DoDispose (void)
       
   273 {
       
   274   NS_LOG_FUNCTION (this);
       
   275   m_channel = 0;
       
   276   m_events.clear ();
       
   277   m_modes.clear ();
       
   278 }
       
   279 
       
   280 void
       
   281 WifiPhy::SetStandard (enum WifiPhyStandard standard)
       
   282 {
       
   283   NS_LOG_FUNCTION (this << standard);
       
   284   m_standard = standard;
       
   285   switch (standard) {
       
   286   case WIFI_PHY_STANDARD_80211a:
       
   287     Configure80211a ();
       
   288     break;
       
   289   case WIFI_PHY_STANDARD_holland:
       
   290     ConfigureHolland ();
       
   291     break;
       
   292   default:
       
   293     NS_ASSERT (false);
       
   294     break;
       
   295   }
       
   296 }
       
   297 
       
   298 
       
   299 void 
       
   300 WifiPhy::SetRxNoise (double db)
       
   301 {
       
   302   NS_LOG_FUNCTION (this << db);
       
   303   m_rxNoiseRatio = DbToRatio (db);
       
   304 }
       
   305 void 
       
   306 WifiPhy::SetTxPowerStart (double start)
       
   307 {
       
   308   NS_LOG_FUNCTION (this << start);
       
   309   m_txPowerBaseDbm = start;
       
   310 }
       
   311 void 
       
   312 WifiPhy::SetTxPowerEnd (double end)
       
   313 {
       
   314   NS_LOG_FUNCTION (this << end);
       
   315   m_txPowerEndDbm = end;
       
   316 }
       
   317 void 
       
   318 WifiPhy::SetNTxPower (uint32_t n)
       
   319 {
       
   320   NS_LOG_FUNCTION (this << n);
       
   321   m_nTxPower = n;
       
   322 }
       
   323 void 
       
   324 WifiPhy::SetTxGain (double gain)
       
   325 {
       
   326   NS_LOG_FUNCTION (this << gain);
       
   327   m_txGainDb = gain;
       
   328 }
       
   329 void 
       
   330 WifiPhy::SetRxGain (double gain)
       
   331 {
       
   332   NS_LOG_FUNCTION (this << gain);
       
   333   m_rxGainDb = gain;
       
   334 }
       
   335 void 
       
   336 WifiPhy::SetEdThreshold (double threshold)
       
   337 {
       
   338   NS_LOG_FUNCTION (this << threshold);
       
   339   m_edThresholdW = DbmToW (threshold);
       
   340 }
       
   341 double 
       
   342 WifiPhy::GetRxNoise (void) const
       
   343 {
       
   344   return RatioToDb (m_rxNoiseRatio);
       
   345 }
       
   346 double 
       
   347 WifiPhy::GetTxPowerStart (void) const
       
   348 {
       
   349   return m_txPowerBaseDbm;
       
   350 }
       
   351 double 
       
   352 WifiPhy::GetTxPowerEnd (void) const
       
   353 {
       
   354   return m_txPowerEndDbm;
       
   355 }
       
   356 double 
       
   357 WifiPhy::GetTxGain (void) const
       
   358 {
       
   359   return m_txGainDb;
       
   360 }
       
   361 double 
       
   362 WifiPhy::GetRxGain (void) const
       
   363 {
       
   364   return m_rxGainDb;
       
   365 }
       
   366 
       
   367 double 
       
   368 WifiPhy::GetEdThreshold (void) const
       
   369 {
       
   370   return WToDbm (m_edThresholdW);
       
   371 }
       
   372 
       
   373 Ptr<WifiChannel> 
       
   374 WifiPhy::GetChannel (void) const
       
   375 {
       
   376   return m_channel;
       
   377 }
       
   378 
       
   379 void 
       
   380 WifiPhy::SetChannel (Ptr<WifiChannel> channel)
       
   381 {
       
   382   m_channel = channel;
       
   383 }
       
   384 
       
   385 void 
       
   386 WifiPhy::SetReceiveOkCallback (SyncOkCallback callback)
       
   387 {
       
   388   m_syncOkCallback = callback;
       
   389 }
       
   390 void 
       
   391 WifiPhy::SetReceiveErrorCallback (SyncErrorCallback callback)
       
   392 {
       
   393   m_syncErrorCallback = callback;
       
   394 }
       
   395 void 
       
   396 WifiPhy::StartReceivePacket (Ptr<Packet> packet, 
       
   397                              double rxPowerDbm,
       
   398                              WifiMode txMode,
       
   399                              enum WifiPreamble preamble)
       
   400 {
       
   401   NS_LOG_FUNCTION (this << packet << rxPowerDbm << txMode << preamble);
       
   402   rxPowerDbm += m_rxGainDb;
       
   403   double rxPowerW = DbmToW (rxPowerDbm);
       
   404   Time rxDuration = CalculateTxDuration (packet->GetSize (), txMode, preamble);
       
   405   Time endRx = Simulator::Now () + rxDuration;
       
   406 
       
   407   Ptr<RxEvent> event = Create<RxEvent> (packet->GetSize (), 
       
   408                                         txMode,
       
   409                                         preamble,
       
   410                                         rxDuration,
       
   411                                         rxPowerW);
       
   412   AppendEvent (event);
       
   413 
       
   414   switch (GetState ()) {
       
   415   case WifiPhy::SYNC:
       
   416     NS_LOG_DEBUG ("drop packet because already in Sync (power="<<
       
   417                   rxPowerW<<"W)");
       
   418     if (endRx > m_endSync) 
       
   419       {
       
   420         goto maybeCcaBusy;
       
   421       }
       
   422     break;
       
   423   case WifiPhy::TX:
       
   424     NS_LOG_DEBUG ("drop packet because already in Tx (power="<<
       
   425                   rxPowerW<<"W)");
       
   426     if (endRx > m_endTx) 
       
   427       {
       
   428         goto maybeCcaBusy;
       
   429       }
       
   430     break;
       
   431   case WifiPhy::CCA_BUSY:
       
   432   case WifiPhy::IDLE:
       
   433     if (rxPowerW > m_edThresholdW) 
       
   434       {
       
   435         NS_LOG_DEBUG ("sync (power="<<rxPowerW<<"W)");
       
   436         // sync to signal
       
   437         NotifySyncStart (rxDuration);
       
   438         SwitchToSync (rxDuration);
       
   439         NS_ASSERT (m_endSyncEvent.IsExpired ());
       
   440         m_endSyncEvent = Simulator::Schedule (rxDuration, &WifiPhy::EndSync, this, 
       
   441                                               packet,
       
   442                                               event);
       
   443       }
       
   444     else 
       
   445       {
       
   446         NS_LOG_DEBUG ("drop packet because signal power too Small ("<<
       
   447                       rxPowerW<<"<"<<m_edThresholdW<<")");
       
   448         goto maybeCcaBusy;
       
   449       }
       
   450     break;
       
   451   }
       
   452 
       
   453   return;
       
   454 
       
   455  maybeCcaBusy:
       
   456 
       
   457   if (rxPowerW > m_edThresholdW) 
       
   458     {
       
   459       SwitchMaybeToCcaBusy (rxDuration);
       
   460       NotifyCcaBusyStart (rxDuration);
       
   461     } 
       
   462   else 
       
   463     {
       
   464       double threshold = m_edThresholdW - rxPowerW;
       
   465       NiChanges ni;
       
   466       CalculateNoiseInterferenceW (event, &ni);
       
   467       double noiseInterferenceW = 0.0;
       
   468       Time end = Simulator::Now ();
       
   469       for (NiChanges::const_iterator i = ni.begin (); i != ni.end (); i++) 
       
   470         {
       
   471           noiseInterferenceW += i->GetDelta ();
       
   472           if (noiseInterferenceW < threshold) 
       
   473             {
       
   474               break;
       
   475             }
       
   476           end = i->GetTime ();
       
   477         }
       
   478       if (end > Simulator::Now ()) 
       
   479         {
       
   480           Time delta = end - Simulator::Now ();
       
   481           SwitchMaybeToCcaBusy (delta);
       
   482           NotifyCcaBusyStart (delta);
       
   483         }
       
   484     }
       
   485 
       
   486 }
       
   487 void 
       
   488 WifiPhy::SendPacket (Ptr<const Packet> packet, WifiMode txMode, WifiPreamble preamble, uint8_t txPower)
       
   489 {
       
   490   NS_LOG_FUNCTION (this << packet << txMode << preamble << (uint32_t)txPower);
       
   491   /* Transmission can happen if:
       
   492    *  - we are syncing on a packet. It is the responsability of the
       
   493    *    MAC layer to avoid doing this but the PHY does nothing to 
       
   494    *    prevent it.
       
   495    *  - we are idle
       
   496    */
       
   497   NS_ASSERT (!IsStateTx ());
       
   498 
       
   499   m_txTrace (packet, txMode, preamble, txPower);
       
   500   Time txDuration = CalculateTxDuration (packet->GetSize (), txMode, preamble);
       
   501   NotifyTxStart (txDuration);
       
   502   SwitchToTx (txDuration);
       
   503   m_channel->Send (this, packet, GetPowerDbm (txPower) + m_txGainDb, txMode, preamble);
       
   504 }
       
   505 
       
   506 uint32_t 
       
   507 WifiPhy::GetNModes (void) const
       
   508 {
       
   509   return m_modes.size ();
       
   510 }
       
   511 WifiMode 
       
   512 WifiPhy::GetMode (uint32_t mode) const
       
   513 {
       
   514   return m_modes[mode];
       
   515 }
       
   516 uint32_t 
       
   517 WifiPhy::GetNTxPower (void) const
       
   518 {
       
   519   return m_nTxPower;
       
   520 }
       
   521 
       
   522 double 
       
   523 WifiPhy::CalculateSnr (WifiMode txMode, double ber) const
       
   524 {
       
   525   double low, high, precision;
       
   526   low = 1e-25;
       
   527   high = 1e25;
       
   528   precision = 1e-12;
       
   529   while (high - low > precision) 
       
   530     {
       
   531       NS_ASSERT (high >= low);
       
   532       double middle = low + (high - low) / 2;
       
   533       if ((1 - GetChunkSuccessRate (txMode, middle, 1)) > ber) 
       
   534         {
       
   535           low = middle;
       
   536         } 
       
   537       else 
       
   538         {
       
   539           high = middle;
       
   540         }
       
   541     }
       
   542   return low;
       
   543 }
       
   544 
       
   545 void
       
   546 WifiPhy::Configure80211aParameters (void)
       
   547 {
       
   548   NS_LOG_FUNCTION (this);
       
   549   m_plcpLongPreambleDelayUs = 16;
       
   550   m_plcpShortPreambleDelayUs = 16;
       
   551   m_longPlcpHeaderMode = g_6mba;
       
   552   m_shortPlcpHeaderMode = g_6mba;
       
   553   m_plcpHeaderLength = 4 + 1 + 12 + 1 + 6;
       
   554   /* 4095 bytes at a 6Mb/s rate with a 1/2 coding rate. */
       
   555   m_maxPacketDuration = CalculateTxDuration (4095, g_6mba, WIFI_PREAMBLE_LONG);
       
   556 }
       
   557 
       
   558 void
       
   559 WifiPhy::PrintModes (void) const
       
   560 {
       
   561 #if 0
       
   562   for (double db = -10; db < 30; db+= 0.5) {
       
   563     double snr = DbToRatio (db);
       
   564     std::cout <<snr<<" ";
       
   565     for (uint8_t i = 0; i < GetNModes (); i++) {
       
   566       WifiMode mode = GetMode (i);
       
   567       double ber = 1-GetChunkSuccessRate (mode,snr, 2000*8);
       
   568       std::cout <<ber<< " ";
       
   569     }
       
   570     std::cout << std::endl;
       
   571   }
       
   572 #endif
       
   573 }
       
   574 
       
   575 void
       
   576 WifiPhy::Configure80211a (void)
       
   577 {
       
   578   NS_LOG_FUNCTION (this);
       
   579   Configure80211aParameters ();
       
   580   m_modes.push_back (g_6mba);
       
   581   m_modes.push_back (g_9mba);
       
   582   m_modes.push_back (g_12mba);
       
   583   m_modes.push_back (g_18mba);
       
   584   m_modes.push_back (g_24mba);
       
   585   m_modes.push_back (g_36mba);
       
   586   m_modes.push_back (g_48mba);
       
   587   m_modes.push_back (g_54mba);
       
   588 
       
   589   PrintModes ();
       
   590 }
       
   591 
       
   592 void
       
   593 WifiPhy::ConfigureHolland (void)
       
   594 {
       
   595   NS_LOG_FUNCTION (this);
       
   596   Configure80211aParameters ();
       
   597   m_modes.push_back (g_6mba);
       
   598   m_modes.push_back (g_12mba);
       
   599   m_modes.push_back (g_18mba);
       
   600   m_modes.push_back (g_36mba);
       
   601   m_modes.push_back (g_54mba);
       
   602 
       
   603   PrintModes ();
       
   604 }
       
   605 
       
   606 void 
       
   607 WifiPhy::RegisterListener (WifiPhyListener *listener)
       
   608 {
       
   609   m_listeners.push_back (listener);
       
   610 }
       
   611 
       
   612 bool 
       
   613 WifiPhy::IsStateCcaBusy (void)
       
   614 {
       
   615   return GetState () == CCA_BUSY;
       
   616 }
       
   617 
       
   618 bool 
       
   619 WifiPhy::IsStateIdle (void)
       
   620 {
       
   621   return (GetState () == IDLE)?true:false;
       
   622 }
       
   623 bool 
       
   624 WifiPhy::IsStateBusy (void)
       
   625 {
       
   626   return (GetState () != IDLE)?true:false;
       
   627 }
       
   628 bool 
       
   629 WifiPhy::IsStateSync (void)
       
   630 {
       
   631   return (GetState () == SYNC)?true:false;
       
   632 }
       
   633 bool 
       
   634 WifiPhy::IsStateTx (void)
       
   635 {
       
   636   return (GetState () == TX)?true:false;
       
   637 }
       
   638 
       
   639 Time
       
   640 WifiPhy::GetStateDuration (void)
       
   641 {
       
   642   return Simulator::Now () - m_previousStateChangeTime;
       
   643 }
       
   644 Time
       
   645 WifiPhy::GetDelayUntilIdle (void)
       
   646 {
       
   647   Time retval;
       
   648 
       
   649   switch (GetState ()) {
       
   650   case SYNC:
       
   651     retval = m_endSync - Simulator::Now ();
       
   652     break;
       
   653   case TX:
       
   654     retval = m_endTx - Simulator::Now ();
       
   655     break;
       
   656   case CCA_BUSY:
       
   657     retval = m_endCcaBusy - Simulator::Now ();
       
   658     break;
       
   659   case IDLE:
       
   660     retval = Seconds (0);
       
   661     break;
       
   662   default:
       
   663     NS_ASSERT (false);
       
   664     // NOTREACHED
       
   665     retval = Seconds (0);
       
   666     break;
       
   667   }
       
   668   retval = Max (retval, Seconds (0));
       
   669   return retval;
       
   670 }
       
   671 
       
   672 Time 
       
   673 WifiPhy::GetLastRxStartTime (void) const
       
   674 {
       
   675   return m_startSync;
       
   676 }
       
   677 
       
   678 
       
   679 Time
       
   680 WifiPhy::CalculateTxDuration (uint32_t size, WifiMode payloadMode, WifiPreamble preamble) const
       
   681 {
       
   682   uint64_t delay = 0;
       
   683   switch (m_standard) {
       
   684   case WIFI_PHY_STANDARD_80211a:
       
   685   case WIFI_PHY_STANDARD_holland: {
       
   686     delay += m_plcpLongPreambleDelayUs;
       
   687     // symbol duration is 4us
       
   688     delay += 4;
       
   689     delay += lrint (ceil ((size * 8.0 + 16.0 + 6.0) / payloadMode.GetDataRate () / 4e-6) * 4);
       
   690   } break;
       
   691   default:
       
   692     // quiet compiler.
       
   693     NS_ASSERT (false);
       
   694     break;
       
   695   }
       
   696   return MicroSeconds (delay);
       
   697 }
       
   698 
       
   699 char const *
       
   700 WifiPhy::StateToString (enum State state)
       
   701 {
       
   702   switch (state) {
       
   703   case TX:
       
   704     return "TX";
       
   705     break;
       
   706   case CCA_BUSY:
       
   707     return "CCA_BUSY";
       
   708     break;
       
   709   case IDLE:
       
   710     return "IDLE";
       
   711     break;
       
   712   case SYNC:
       
   713     return "SYNC";
       
   714     break;
       
   715   default:
       
   716     NS_ASSERT (false);
       
   717     // quiet compiler
       
   718     return "INVALID";
       
   719     break;
       
   720   }
       
   721 }
       
   722 enum WifiPhy::State 
       
   723 WifiPhy::GetState (void)
       
   724 {
       
   725   if (m_endTx > Simulator::Now ()) 
       
   726     {
       
   727       return WifiPhy::TX;
       
   728     } 
       
   729   else if (m_syncing) 
       
   730     {
       
   731       return WifiPhy::SYNC;
       
   732     } 
       
   733   else if (m_endCcaBusy > Simulator::Now ()) 
       
   734     {
       
   735       return WifiPhy::CCA_BUSY;
       
   736     } 
       
   737   else 
       
   738     {
       
   739       return WifiPhy::IDLE;
       
   740     }
       
   741 }
       
   742 
       
   743 double 
       
   744 WifiPhy::DbToRatio (double dB) const
       
   745 {
       
   746   double ratio = pow(10.0,dB/10.0);
       
   747   return ratio;
       
   748 }
       
   749 
       
   750 double 
       
   751 WifiPhy::DbmToW (double dBm) const
       
   752 {
       
   753   double mW = pow(10.0,dBm/10.0);
       
   754   return mW / 1000.0;
       
   755 }
       
   756 
       
   757 double
       
   758 WifiPhy::WToDbm (double w) const
       
   759 {
       
   760   return 10.0 * log10(w * 1000.0);
       
   761 }
       
   762 
       
   763 double
       
   764 WifiPhy::RatioToDb (double ratio) const
       
   765 {
       
   766   return 10.0 * log10(ratio);
       
   767 }
       
   768 
       
   769 double
       
   770 WifiPhy::GetEdThresholdW (void) const
       
   771 {
       
   772   return m_edThresholdW;
       
   773 }
       
   774 
       
   775 Time
       
   776 WifiPhy::GetMaxPacketDuration (void) const
       
   777 {
       
   778   return m_maxPacketDuration;
       
   779 }
       
   780 
       
   781 double 
       
   782 WifiPhy::GetPowerDbm (uint8_t power) const
       
   783 {
       
   784   NS_ASSERT (m_txPowerBaseDbm <= m_txPowerEndDbm);
       
   785   NS_ASSERT (m_nTxPower > 0);
       
   786   double dbm = m_txPowerBaseDbm + power * (m_txPowerEndDbm - m_txPowerBaseDbm) / m_nTxPower;
       
   787   return dbm;
       
   788 }
       
   789 
       
   790 void 
       
   791 WifiPhy::NotifyTxStart (Time duration)
       
   792 {
       
   793   for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++) {
       
   794     (*i)->NotifyTxStart (duration);
       
   795   }
       
   796 }
       
   797 void 
       
   798 WifiPhy::NotifySyncStart (Time duration)
       
   799 {
       
   800   for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++) {
       
   801     (*i)->NotifyRxStart (duration);
       
   802   }
       
   803 }
       
   804 void 
       
   805 WifiPhy::NotifySyncEndOk (void)
       
   806 {
       
   807   for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++) {
       
   808     (*i)->NotifyRxEndOk ();
       
   809   }
       
   810 }
       
   811 void 
       
   812 WifiPhy::NotifySyncEndError (void)
       
   813 {
       
   814   for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++) {
       
   815     (*i)->NotifyRxEndError ();
       
   816   }
       
   817 }
       
   818 void 
       
   819 WifiPhy::NotifyCcaBusyStart (Time duration)
       
   820 {
       
   821   for (Listeners::const_iterator i = m_listeners.begin (); i != m_listeners.end (); i++) {
       
   822     (*i)->NotifyCcaBusyStart (duration);
       
   823   }
       
   824 }
       
   825 
       
   826 void
       
   827 WifiPhy::LogPreviousIdleAndCcaBusyStates (void)
       
   828 {
       
   829   Time now = Simulator::Now ();
       
   830   Time idleStart = Max (m_endCcaBusy, m_endSync);
       
   831   idleStart = Max (idleStart, m_endTx);
       
   832   NS_ASSERT (idleStart <= now);
       
   833   if (m_endCcaBusy > m_endSync && 
       
   834       m_endCcaBusy > m_endTx) {
       
   835     Time ccaBusyStart = Max (m_endTx, m_endSync);
       
   836     ccaBusyStart = Max (ccaBusyStart, m_startCcaBusy);
       
   837     m_stateLogger (ccaBusyStart, idleStart - ccaBusyStart, WifiPhy::CCA_BUSY);
       
   838   }
       
   839   m_stateLogger (idleStart, now - idleStart, WifiPhy::IDLE);
       
   840 }
       
   841 
       
   842 void
       
   843 WifiPhy::SwitchToTx (Time txDuration)
       
   844 {
       
   845   Time now = Simulator::Now ();
       
   846   switch (GetState ()) {
       
   847   case WifiPhy::SYNC:
       
   848     /* The packet which is being received as well
       
   849      * as its endSync event are cancelled by the caller.
       
   850      */
       
   851     m_syncing = false;
       
   852     m_stateLogger (m_startSync, now - m_startSync, WifiPhy::SYNC);
       
   853     m_endSyncEvent.Cancel ();
       
   854     m_endSync = now;
       
   855     break;
       
   856   case WifiPhy::CCA_BUSY: {
       
   857     Time ccaStart = Max (m_endSync, m_endTx);
       
   858     ccaStart = Max (ccaStart, m_startCcaBusy);
       
   859     m_stateLogger (ccaStart, now - ccaStart, WifiPhy::CCA_BUSY);
       
   860   } break;
       
   861   case WifiPhy::IDLE:
       
   862     LogPreviousIdleAndCcaBusyStates ();
       
   863     break;
       
   864   default:
       
   865     NS_ASSERT (false);
       
   866     break;
       
   867   }
       
   868   m_stateLogger (now, txDuration, WifiPhy::TX);
       
   869   m_previousStateChangeTime = now;
       
   870   m_endTx = now + txDuration;
       
   871   m_startTx = now;
       
   872 }
       
   873 void
       
   874 WifiPhy::SwitchToSync (Time rxDuration)
       
   875 {
       
   876   NS_ASSERT (IsStateIdle () || IsStateCcaBusy ());
       
   877   NS_ASSERT (!m_syncing);
       
   878   Time now = Simulator::Now ();
       
   879   switch (GetState ()) {
       
   880   case WifiPhy::IDLE:
       
   881     LogPreviousIdleAndCcaBusyStates ();
       
   882     break;
       
   883   case WifiPhy::CCA_BUSY: {
       
   884     Time ccaStart = Max (m_endSync, m_endTx);
       
   885     ccaStart = Max (ccaStart, m_startCcaBusy);
       
   886     m_stateLogger (ccaStart, now - ccaStart, WifiPhy::CCA_BUSY);
       
   887   } break;
       
   888   case WifiPhy::SYNC:
       
   889   case WifiPhy::TX:
       
   890     NS_ASSERT (false);
       
   891     break;
       
   892   }
       
   893   m_previousStateChangeTime = now;
       
   894   m_syncing = true;
       
   895   m_startSync = now;
       
   896   m_endSync = now + rxDuration;
       
   897   NS_ASSERT (IsStateSync ());
       
   898 }
       
   899 void
       
   900 WifiPhy::SwitchFromSync (void)
       
   901 {
       
   902   NS_ASSERT (IsStateSync ());
       
   903   NS_ASSERT (m_syncing);
       
   904 
       
   905   Time now = Simulator::Now ();
       
   906   m_stateLogger (m_startSync, now - m_startSync, WifiPhy::SYNC);
       
   907   m_previousStateChangeTime = now;
       
   908   m_syncing = false;
       
   909 
       
   910   NS_ASSERT (IsStateIdle () || IsStateCcaBusy ());
       
   911 }
       
   912 void
       
   913 WifiPhy::SwitchMaybeToCcaBusy (Time duration)
       
   914 {
       
   915   Time now = Simulator::Now ();
       
   916   switch (GetState ()) {
       
   917   case WifiPhy::IDLE:
       
   918     LogPreviousIdleAndCcaBusyStates ();
       
   919   break;
       
   920   case WifiPhy::CCA_BUSY:
       
   921     break;
       
   922   case WifiPhy::SYNC:
       
   923     break;
       
   924   case WifiPhy::TX:
       
   925     break;
       
   926   }
       
   927   m_startCcaBusy = now;
       
   928   m_endCcaBusy = Max (m_endCcaBusy, now + duration);
       
   929 }
       
   930 
       
   931 void 
       
   932 WifiPhy::AppendEvent (Ptr<RxEvent> event)
       
   933 {
       
   934   /* attempt to remove the events which are 
       
   935    * not useful anymore. 
       
   936    * i.e.: all events which end _before_
       
   937    *       now - m_maxPacketDuration
       
   938    */
       
   939   
       
   940   if (Simulator::Now () > GetMaxPacketDuration ())
       
   941     {
       
   942       Time end = Simulator::Now () - GetMaxPacketDuration ();
       
   943       Events::iterator i = m_events.begin ();
       
   944       while (i != m_events.end () &&
       
   945              (*i)->GetEndTime () <= end) 
       
   946         {
       
   947           i++;
       
   948         }
       
   949       m_events.erase (m_events.begin (), i);
       
   950     } 
       
   951   m_events.push_back (event);
       
   952 }
       
   953 
       
   954 
       
   955 
       
   956 /**
       
   957  * Stuff specific to the BER model here.
       
   958  */
       
   959 double 
       
   960 WifiPhy::Log2 (double val) const
       
   961 {
       
   962   return log(val) / log(2.0);
       
   963 }
       
   964 double 
       
   965 WifiPhy::GetBpskBer (double snr, uint32_t signalSpread, uint32_t phyRate) const
       
   966 {
       
   967   double EbNo = snr * signalSpread / phyRate;
       
   968   double z = sqrt(EbNo);
       
   969   double ber = 0.5 * erfc(z);
       
   970   NS_LOG_INFO ("bpsk snr="<<snr<<" ber="<<ber);
       
   971   return ber;
       
   972 }
       
   973 double 
       
   974 WifiPhy::GetQamBer (double snr, unsigned int m, uint32_t signalSpread, uint32_t phyRate) const
       
   975 {
       
   976   double EbNo = snr * signalSpread / phyRate;
       
   977   double z = sqrt ((1.5 * Log2 (m) * EbNo) / (m - 1.0));
       
   978   double z1 = ((1.0 - 1.0 / sqrt (m)) * erfc (z)) ;
       
   979   double z2 = 1 - pow ((1-z1), 2.0);
       
   980   double ber = z2 / Log2 (m);
       
   981   NS_LOG_INFO ("Qam m="<<m<<" rate=" << phyRate << " snr="<<snr<<" ber="<<ber);
       
   982   return ber;
       
   983 }
       
   984 uint32_t
       
   985 WifiPhy::Factorial (uint32_t k) const
       
   986 {
       
   987   uint32_t fact = 1;
       
   988   while (k > 0) 
       
   989     {
       
   990       fact *= k;
       
   991       k--;
       
   992     }
       
   993   return fact;
       
   994 }
       
   995 double 
       
   996 WifiPhy::Binomial (uint32_t k, double p, uint32_t n) const
       
   997 {
       
   998   double retval = Factorial (n) / (Factorial (k) * Factorial (n-k)) * pow (p, k) * pow (1-p, n-k);
       
   999   return retval;
       
  1000 }
       
  1001 double 
       
  1002 WifiPhy::CalculatePdOdd (double ber, unsigned int d) const
       
  1003 {
       
  1004   NS_ASSERT ((d % 2) == 1);
       
  1005   unsigned int dstart = (d + 1) / 2;
       
  1006   unsigned int dend = d;
       
  1007   double pd = 0;
       
  1008 
       
  1009   for (unsigned int i = dstart; i < dend; i++) 
       
  1010     {
       
  1011       pd += Binomial (i, ber, d);
       
  1012     }
       
  1013   return pd;
       
  1014 }
       
  1015 double 
       
  1016 WifiPhy::CalculatePdEven (double ber, unsigned int d) const
       
  1017 {
       
  1018   NS_ASSERT ((d % 2) == 0);
       
  1019   unsigned int dstart = d / 2 + 1;
       
  1020   unsigned int dend = d;
       
  1021   double pd = 0;
       
  1022 
       
  1023   for (unsigned int i = dstart; i < dend; i++)
       
  1024     {
       
  1025       pd +=  Binomial (i, ber, d);
       
  1026     }
       
  1027   pd += 0.5 * Binomial (d / 2, ber, d);
       
  1028 
       
  1029   return pd;
       
  1030 }
       
  1031 
       
  1032 double 
       
  1033 WifiPhy::CalculatePd (double ber, unsigned int d) const
       
  1034 {
       
  1035   double pd;
       
  1036   if ((d % 2) == 0) 
       
  1037     {
       
  1038       pd = CalculatePdEven (ber, d);
       
  1039     } 
       
  1040   else 
       
  1041     {
       
  1042       pd = CalculatePdOdd (ber, d);
       
  1043     }
       
  1044   return pd;
       
  1045 }
       
  1046 
       
  1047 double
       
  1048 WifiPhy::GetFecBpskBer (double snr, double nbits, 
       
  1049                          uint32_t signalSpread, uint32_t phyRate,
       
  1050                          uint32_t dFree, uint32_t adFree) const
       
  1051 {
       
  1052   double ber = GetBpskBer (snr, signalSpread, phyRate);
       
  1053   if (ber == 0.0) 
       
  1054     {
       
  1055       return 1.0;
       
  1056     }
       
  1057   double pd = CalculatePd (ber, dFree);
       
  1058   double pmu = adFree * pd;
       
  1059   pmu = std::min (pmu, 1.0);
       
  1060   double pms = pow (1 - pmu, nbits);
       
  1061   return pms;
       
  1062 }
       
  1063 
       
  1064 double
       
  1065 WifiPhy::GetFecQamBer (double snr, uint32_t nbits, 
       
  1066                        uint32_t signalSpread,
       
  1067                        uint32_t phyRate,
       
  1068                        uint32_t m, uint32_t dFree,
       
  1069                        uint32_t adFree, uint32_t adFreePlusOne) const
       
  1070 {
       
  1071   double ber = GetQamBer (snr, m, signalSpread, phyRate);
       
  1072   if (ber == 0.0) 
       
  1073     {
       
  1074       return 1.0;
       
  1075     }
       
  1076   /* first term */
       
  1077   double pd = CalculatePd (ber, dFree);
       
  1078   double pmu = adFree * pd;
       
  1079   /* second term */
       
  1080   pd = CalculatePd (ber, dFree + 1);
       
  1081   pmu += adFreePlusOne * pd;
       
  1082   pmu = std::min (pmu, 1.0);
       
  1083   double pms = pow (1 - pmu, nbits);
       
  1084   return pms;
       
  1085 }
       
  1086 
       
  1087 double 
       
  1088 WifiPhy::GetChunkSuccessRate (WifiMode mode, double snr, uint32_t nbits) const
       
  1089 {
       
  1090   if (mode.GetUid () == g_6mba.GetUid ())
       
  1091     {
       
  1092       return GetFecBpskBer (snr, 
       
  1093                             nbits,
       
  1094                             mode.GetBandwidth (), // signal spread
       
  1095                             mode.GetPhyRate (), // phy rate
       
  1096                             10, // dFree
       
  1097                             11 // adFree
       
  1098                             );      
       
  1099     }
       
  1100   else if (mode.GetUid () == g_9mba.GetUid ())
       
  1101     {
       
  1102       return GetFecBpskBer (snr, 
       
  1103                             nbits,
       
  1104                             mode.GetBandwidth (), // signal spread
       
  1105                             mode.GetPhyRate (), // phy rate
       
  1106                             5, // dFree
       
  1107                             8 // adFree
       
  1108                             );
       
  1109     }
       
  1110   else if (mode.GetUid () == g_12mba.GetUid ())
       
  1111     {
       
  1112       return GetFecQamBer (snr, 
       
  1113                            nbits,
       
  1114                            mode.GetBandwidth (), // signal spread
       
  1115                            mode.GetPhyRate (), // phy rate
       
  1116                            4,  // m 
       
  1117                            10, // dFree
       
  1118                            11, // adFree
       
  1119                            0   // adFreePlusOne
       
  1120                            );
       
  1121     }
       
  1122   else if (mode.GetUid () == g_18mba.GetUid ())
       
  1123     {
       
  1124       return GetFecQamBer (snr, 
       
  1125                            nbits,
       
  1126                            mode.GetBandwidth (), // signal spread
       
  1127                            mode.GetPhyRate (), // phy rate
       
  1128                            4, // m
       
  1129                            5, // dFree
       
  1130                            8, // adFree
       
  1131                            31 // adFreePlusOne
       
  1132                            );
       
  1133     }
       
  1134   else if (mode.GetUid () == g_24mba.GetUid ())
       
  1135     {
       
  1136       return GetFecQamBer (snr, 
       
  1137                            nbits,
       
  1138                            mode.GetBandwidth (), // signal spread
       
  1139                            mode.GetPhyRate (), // phy rate
       
  1140                            16, // m
       
  1141                            10, // dFree
       
  1142                            11, // adFree
       
  1143                            0   // adFreePlusOne
       
  1144                            );
       
  1145     }
       
  1146   else if (mode.GetUid () == g_36mba.GetUid ())
       
  1147     {
       
  1148       return GetFecQamBer (snr, 
       
  1149                            nbits,
       
  1150                            mode.GetBandwidth (), // signal spread
       
  1151                            mode.GetPhyRate (), // phy rate
       
  1152                            16, // m
       
  1153                            5,  // dFree
       
  1154                            8,  // adFree
       
  1155                            31  // adFreePlusOne
       
  1156                            );
       
  1157     }
       
  1158   else if (mode.GetUid () == g_48mba.GetUid ())
       
  1159     {
       
  1160       return GetFecQamBer (snr, 
       
  1161                            nbits,
       
  1162                            mode.GetBandwidth (), // signal spread
       
  1163                            mode.GetPhyRate (), // phy rate
       
  1164                            64, // m
       
  1165                            6,  // dFree
       
  1166                            1,  // adFree
       
  1167                            16  // adFreePlusOne
       
  1168                            );
       
  1169     }
       
  1170   else if (mode.GetUid () == g_54mba.GetUid ())
       
  1171     {
       
  1172       return GetFecQamBer (snr, 
       
  1173                            nbits,
       
  1174                            mode.GetBandwidth (), // signal spread
       
  1175                            mode.GetPhyRate (), // phy rate
       
  1176                            64, // m
       
  1177                            5,  // dFree
       
  1178                            8,  // adFree
       
  1179                            31  // adFreePlusOne
       
  1180                            );
       
  1181     }
       
  1182   return 0;
       
  1183 }
       
  1184 
       
  1185 double
       
  1186 WifiPhy::CalculateSnr (double signal, double noiseInterference, WifiMode mode) const
       
  1187 {
       
  1188   // thermal noise at 290K in J/s = W
       
  1189   static const double BOLTZMANN = 1.3803e-23;
       
  1190   double Nt = BOLTZMANN * 290.0 * mode.GetBandwidth ();
       
  1191   // receiver noise Floor (W)
       
  1192   double noiseFloor = m_rxNoiseRatio * Nt;
       
  1193   double noise = noiseFloor + noiseInterference;
       
  1194   double snr = signal / noise;
       
  1195   return snr;
       
  1196 }
       
  1197 
       
  1198 double
       
  1199 WifiPhy::CalculateNoiseInterferenceW (Ptr<RxEvent> event, NiChanges *ni) const
       
  1200 {
       
  1201   Events::const_iterator i = m_events.begin ();
       
  1202   double noiseInterference = 0.0;
       
  1203   while (i != m_events.end ()) 
       
  1204     {
       
  1205       if (event == (*i)) 
       
  1206         {
       
  1207           i++;
       
  1208           continue;
       
  1209         }
       
  1210       if (event->Overlaps ((*i)->GetStartTime ())) 
       
  1211         {
       
  1212           ni->push_back (NiChange ((*i)->GetStartTime (), (*i)->GetRxPowerW ()));
       
  1213         }
       
  1214       if (event->Overlaps ((*i)->GetEndTime ())) 
       
  1215         {
       
  1216           ni->push_back (NiChange ((*i)->GetEndTime (), -(*i)->GetRxPowerW ()));
       
  1217         }
       
  1218       if ((*i)->Overlaps (event->GetStartTime ())) 
       
  1219         {
       
  1220           noiseInterference += (*i)->GetRxPowerW ();
       
  1221         }
       
  1222       i++;
       
  1223     }
       
  1224   ni->push_back (NiChange (event->GetStartTime (), noiseInterference));
       
  1225   ni->push_back (NiChange (event->GetEndTime (), 0));
       
  1226 
       
  1227   /* quicksort vector of NI changes by time. */
       
  1228   std::sort (ni->begin (), ni->end (), std::less<NiChange> ());
       
  1229 
       
  1230   return noiseInterference;
       
  1231 }
       
  1232 
       
  1233 double
       
  1234 WifiPhy::CalculateChunkSuccessRate (double snir, Time duration, WifiMode mode) const
       
  1235 {
       
  1236   if (duration == NanoSeconds (0)) {
       
  1237     return 1.0;
       
  1238   }
       
  1239   uint32_t rate = mode.GetPhyRate ();
       
  1240   uint64_t nbits = (uint64_t)(rate * duration.GetSeconds ());
       
  1241   double csr = GetChunkSuccessRate (mode, snir, (uint32_t)nbits);
       
  1242   return csr;
       
  1243 }
       
  1244 
       
  1245 double 
       
  1246 WifiPhy::CalculatePer (Ptr<const RxEvent> event, NiChanges *ni) const
       
  1247 {  
       
  1248   double psr = 1.0; /* Packet Success Rate */
       
  1249   NiChanges::iterator j = ni->begin ();
       
  1250   Time previous = (*j).GetTime ();
       
  1251   uint64_t plcpPreambleDelayUs;
       
  1252   WifiMode payloadMode = event->GetPayloadMode ();
       
  1253   WifiMode headerMode;
       
  1254   switch (event->GetPreambleType ()) {
       
  1255   case WIFI_PREAMBLE_LONG:
       
  1256     plcpPreambleDelayUs = m_plcpLongPreambleDelayUs;
       
  1257     headerMode = m_longPlcpHeaderMode;
       
  1258     break;
       
  1259   case WIFI_PREAMBLE_SHORT:
       
  1260     plcpPreambleDelayUs = m_plcpShortPreambleDelayUs;
       
  1261     headerMode = m_shortPlcpHeaderMode;
       
  1262     break;
       
  1263   default:
       
  1264     NS_ASSERT (false);
       
  1265     // only to quiet compiler. Really stupid.
       
  1266     plcpPreambleDelayUs = 0;
       
  1267     headerMode = m_shortPlcpHeaderMode;
       
  1268     break;
       
  1269   }
       
  1270   Time plcpHeaderStart = (*j).GetTime () + MicroSeconds (plcpPreambleDelayUs);
       
  1271   Time plcpPayloadStart = plcpHeaderStart + 
       
  1272     Seconds ((m_plcpHeaderLength + 0.0) / headerMode.GetDataRate ());
       
  1273   double noiseInterferenceW = (*j).GetDelta ();
       
  1274   double powerW = event->GetRxPowerW ();
       
  1275 
       
  1276   j++;
       
  1277   while (ni->end () != j) 
       
  1278     {
       
  1279       Time current = (*j).GetTime ();
       
  1280       NS_ASSERT (current >= previous);
       
  1281     
       
  1282       if (previous >= plcpPayloadStart) 
       
  1283         {
       
  1284           psr *= CalculateChunkSuccessRate (CalculateSnr (powerW, 
       
  1285                                                           noiseInterferenceW, 
       
  1286                                                           payloadMode), 
       
  1287                                             current - previous,
       
  1288                                             payloadMode);
       
  1289         } 
       
  1290       else if (previous >= plcpHeaderStart) 
       
  1291         {
       
  1292           if (current >= plcpPayloadStart) 
       
  1293             {
       
  1294               psr *= CalculateChunkSuccessRate (CalculateSnr (powerW, 
       
  1295                                                               noiseInterferenceW, 
       
  1296                                                               headerMode), 
       
  1297                                                 plcpPayloadStart - previous,
       
  1298                                                 headerMode);
       
  1299               psr *= CalculateChunkSuccessRate (CalculateSnr (powerW, 
       
  1300                                                               noiseInterferenceW, 
       
  1301                                                               payloadMode),
       
  1302                                                 current - plcpPayloadStart,
       
  1303                                                 payloadMode);
       
  1304             } 
       
  1305           else 
       
  1306             {
       
  1307               NS_ASSERT (current >= plcpHeaderStart);
       
  1308               psr *= CalculateChunkSuccessRate (CalculateSnr (powerW, 
       
  1309                                                               noiseInterferenceW, 
       
  1310                                                               headerMode), 
       
  1311                                                 current - previous,
       
  1312                                                 headerMode);
       
  1313             }
       
  1314         } 
       
  1315       else 
       
  1316         {
       
  1317           if (current >= plcpPayloadStart) 
       
  1318             {
       
  1319               psr *= CalculateChunkSuccessRate (CalculateSnr (powerW, 
       
  1320                                                               noiseInterferenceW, 
       
  1321                                                               headerMode), 
       
  1322                                                 plcpPayloadStart - plcpHeaderStart,
       
  1323                                                 headerMode);
       
  1324               psr *= CalculateChunkSuccessRate (CalculateSnr (powerW, 
       
  1325                                                               noiseInterferenceW, 
       
  1326                                                               payloadMode), 
       
  1327                                                 current - plcpPayloadStart,
       
  1328                                                 payloadMode);
       
  1329             } 
       
  1330           else if (current >= plcpHeaderStart) 
       
  1331             {
       
  1332               psr *= CalculateChunkSuccessRate (CalculateSnr (powerW, 
       
  1333                                                               noiseInterferenceW, 
       
  1334                                                               headerMode), 
       
  1335                                                 current - plcpHeaderStart,
       
  1336                                                 headerMode);
       
  1337             }
       
  1338         }
       
  1339 
       
  1340       noiseInterferenceW += (*j).GetDelta ();
       
  1341       previous = (*j).GetTime ();
       
  1342       j++;
       
  1343     }
       
  1344 
       
  1345   double per = 1 - psr;
       
  1346   return per;
       
  1347 }
       
  1348 
       
  1349 
       
  1350 void
       
  1351 WifiPhy::EndSync (Ptr<Packet> packet, Ptr<RxEvent> event)
       
  1352 {
       
  1353   NS_LOG_FUNCTION (this << packet << event);
       
  1354   NS_ASSERT (IsStateSync ());
       
  1355   NS_ASSERT (event->GetEndTime () == Simulator::Now ());
       
  1356 
       
  1357   NiChanges ni;
       
  1358   double noiseInterferenceW = CalculateNoiseInterferenceW (event, &ni);
       
  1359   double snr = CalculateSnr (event->GetRxPowerW (),
       
  1360                              noiseInterferenceW,
       
  1361                              event->GetPayloadMode ());
       
  1362   
       
  1363   /* calculate the SNIR at the start of the packet and accumulate
       
  1364    * all SNIR changes in the snir vector.
       
  1365    */
       
  1366   double per = CalculatePer (event, &ni);
       
  1367   NS_LOG_DEBUG ("mode="<<(event->GetPayloadMode ().GetDataRate ())<<
       
  1368                 ", ber="<<(1-GetChunkSuccessRate (event->GetPayloadMode (), snr, 1))<<
       
  1369                 ", snr="<<snr<<", per="<<per<<", size="<<packet->GetSize ());
       
  1370   
       
  1371   if (m_random.GetValue () > per) 
       
  1372     {
       
  1373       NotifySyncEndOk ();
       
  1374       SwitchFromSync ();
       
  1375       m_rxOkTrace (packet, snr, event->GetPayloadMode (), event->GetPreambleType ());
       
  1376       if (!m_syncOkCallback.IsNull ())
       
  1377         {
       
  1378           m_syncOkCallback (packet, snr, event->GetPayloadMode (), event->GetPreambleType ());
       
  1379         }
       
  1380     } 
       
  1381   else 
       
  1382     {
       
  1383       /* failure. */
       
  1384       NotifySyncEndError ();
       
  1385       SwitchFromSync ();
       
  1386       m_rxErrorTrace (packet, snr);
       
  1387       if (!m_syncErrorCallback.IsNull ())
       
  1388         {
       
  1389           m_syncErrorCallback (packet, snr);
       
  1390         }
       
  1391     }
       
  1392 }
       
  1393 
       
  1394 
       
  1395 
       
  1396 
       
  1397 } // namespace ns3
   100 } // namespace ns3