00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "ns2ext-wifi-phy.h"
00023 #include "ns2ext-wifi-channel.h"
00024 #include "wifi-mode.h"
00025 #include "wifi-preamble.h"
00026 #include "ns2ext-wifi-phy-state-helper.h"
00027 #include "ns3/simulator.h"
00028 #include "ns3/packet.h"
00029 #include "ns3/random-variable.h"
00030 #include "ns3/assert.h"
00031 #include "ns3/log.h"
00032 #include "ns3/boolean.h"
00033 #include "ns3/double.h"
00034 #include "ns3/uinteger.h"
00035 #include "ns3/enum.h"
00036 #include "ns3/pointer.h"
00037 #include "ns3/net-device.h"
00038 #include <math.h>
00039
00040 NS_LOG_COMPONENT_DEFINE ("Ns2ExtWifiPhy");
00041
00042 namespace ns3 {
00043
00044 NS_OBJECT_ENSURE_REGISTERED (Ns2ExtWifiPhy);
00045
00046 TypeId
00047 Ns2ExtWifiPhy::GetTypeId (void)
00048 {
00049 static TypeId tid = TypeId ("ns3::Ns2ExtWifiPhy")
00050 .SetParent<WifiPhy> ()
00051 .AddConstructor<Ns2ExtWifiPhy> ()
00052 .AddAttribute ("TxGain",
00053 "Transmission gain (dB).",
00054 DoubleValue (0.0),
00055 MakeDoubleAccessor (&Ns2ExtWifiPhy::SetTxGain,
00056 &Ns2ExtWifiPhy::GetTxGain),
00057 MakeDoubleChecker<double> ())
00058 .AddAttribute ("RxGain",
00059 "Reception gain (dB).",
00060 DoubleValue (0.0),
00061 MakeDoubleAccessor (&Ns2ExtWifiPhy::SetRxGain,
00062 &Ns2ExtWifiPhy::GetRxGain),
00063 MakeDoubleChecker<double> ())
00064 .AddAttribute ("TxPowerLevels",
00065 "Number of transmission power levels available between "
00066 "TxPowerBase and TxPowerEnd included.",
00067 UintegerValue (1),
00068 MakeUintegerAccessor (&Ns2ExtWifiPhy::m_nTxPower),
00069 MakeUintegerChecker<uint32_t> ())
00070 .AddAttribute ("TxPowerEnd",
00071 "Maximum available transmission level (dbm).",
00072 DoubleValue (20.0),
00073 MakeDoubleAccessor (&Ns2ExtWifiPhy::SetTxPowerEnd,
00074 &Ns2ExtWifiPhy::GetTxPowerEnd),
00075 MakeDoubleChecker<double> ())
00076 .AddAttribute ("TxPowerStart",
00077 "Minimum available transmission level (dbm).",
00078 DoubleValue (20.0),
00079 MakeDoubleAccessor (&Ns2ExtWifiPhy::SetTxPowerStart,
00080 &Ns2ExtWifiPhy::GetTxPowerStart),
00081 MakeDoubleChecker<double> ())
00082 .AddAttribute ("RxNoise",
00083 "Ratio of energy lost by receiver (dB).",
00084 DoubleValue (7),
00085 MakeDoubleAccessor (&Ns2ExtWifiPhy::SetRxNoise,
00086 &Ns2ExtWifiPhy::GetRxNoise),
00087 MakeDoubleChecker<double> ())
00088 .AddAttribute ("UseConstantNoiseFloor",
00089 "If false calculate noise floor, if true use ConstantNoiseFloor as noise floor.",
00090 BooleanValue (false),
00091 MakeBooleanAccessor (&Ns2ExtWifiPhy::SetUseConstantNoiseFloor,
00092 &Ns2ExtWifiPhy::GetUseConstantNoiseFloor),
00093 MakeBooleanChecker ())
00094 .AddAttribute ("ConstantNoiseFloor",
00095 "Override receiver noise energy calculation with a constant noise floor (dBm).",
00096 DoubleValue (-101.0),
00097 MakeDoubleAccessor (&Ns2ExtWifiPhy::SetConstantNoiseFloor,
00098 &Ns2ExtWifiPhy::GetConstantNoiseFloor),
00099 MakeDoubleChecker<double> ())
00100 .AddAttribute ("CarrierSenseThreshold",
00101 "Carrier-sense threshold in dBm.",
00102 DoubleValue (-94.0),
00103 MakeDoubleAccessor (&Ns2ExtWifiPhy::SetCarrierSenseThreshold,
00104 &Ns2ExtWifiPhy::GetCarrierSenseThreshold),
00105 MakeDoubleChecker<double> ())
00106 .AddAttribute ("SINRReceive",
00107 "Signal-and-Noise-Interference ratio (in dB) required to receive a packet. TODO: This should depend on the datarate.",
00108 DoubleValue (4.0),
00109 MakeDoubleAccessor (&Ns2ExtWifiPhy::m_sinrReceive),
00110 MakeDoubleChecker<double> ())
00111 .AddAttribute ("Standard", "The standard chosen configures a set of transmission modes"
00112 " and some PHY-specific constants.",
00113 EnumValue (WIFI_PHY_STANDARD_80211a),
00114 MakeEnumAccessor (&Ns2ExtWifiPhy::SetStandard),
00115 MakeEnumChecker (WIFI_PHY_STANDARD_80211a, "802.11a",
00116 WIFI_PHY_STANDARD_holland, "holland"))
00117 .AddAttribute ("State", "The state of the PHY layer",
00118 PointerValue (),
00119 MakePointerAccessor (&Ns2ExtWifiPhy::m_state),
00120 MakePointerChecker<Ns2ExtWifiPhyStateHelper> ())
00121 ;
00122 return tid;
00123 }
00124
00125 Ns2ExtWifiPhy::Ns2ExtWifiPhy ()
00126 : m_endRxEvent ()
00127 {
00128 NS_LOG_FUNCTION (this);
00129 m_state = CreateObject<Ns2ExtWifiPhyStateHelper> ();
00130 }
00131
00132 Ns2ExtWifiPhy::~Ns2ExtWifiPhy ()
00133 {
00134 NS_LOG_FUNCTION (this);
00135 }
00136
00137 void
00138 Ns2ExtWifiPhy::DoDispose (void)
00139 {
00140 NS_LOG_FUNCTION (this);
00141 m_channel = 0;
00142 m_modes.clear ();
00143 m_device = 0;
00144 }
00145
00146 void
00147 Ns2ExtWifiPhy::SetStandard (enum WifiPhyStandard standard)
00148 {
00149 NS_LOG_FUNCTION (this << standard);
00150 m_standard = standard;
00151 switch (standard) {
00152 case WIFI_PHY_STANDARD_80211a:
00153 Configure80211a ();
00154 break;
00155 case WIFI_PHY_STANDARD_holland:
00156 ConfigureHolland ();
00157 break;
00158 default:
00159 NS_ASSERT (false);
00160 break;
00161 }
00162 }
00163
00164
00165 void
00166 Ns2ExtWifiPhy::SetRxNoise (double db)
00167 {
00168 NS_LOG_FUNCTION (this << db);
00169 m_interference.SetRxNoiseRatio (DbToRatio (db));
00170 }
00171 double
00172 Ns2ExtWifiPhy::GetRxNoise (void) const
00173 {
00174 return RatioToDb (m_interference.GetRxNoiseRatio ());
00175 }
00176
00177 void
00178 Ns2ExtWifiPhy::SetUseConstantNoiseFloor (bool value)
00179 {
00180 NS_LOG_FUNCTION (this << value);
00181 m_interference.SetUseConstantNoiseFloor (value);
00182 }
00183 bool
00184 Ns2ExtWifiPhy::GetUseConstantNoiseFloor () const
00185 {
00186 return m_interference.GetUseConstantNoiseFloor ();
00187 }
00188
00189 void
00190 Ns2ExtWifiPhy::SetConstantNoiseFloor (double dbm)
00191 {
00192 NS_LOG_FUNCTION (this << dbm);
00193 m_interference.SetConstantNoiseFloorW (DbmToW (dbm));
00194 }
00195 double
00196 Ns2ExtWifiPhy::GetConstantNoiseFloor (void) const
00197 {
00198 return WToDbm (m_interference.GetConstantNoiseFloorW ());
00199 }
00200
00201 void
00202 Ns2ExtWifiPhy::SetTxPowerStart (double start)
00203 {
00204 NS_LOG_FUNCTION (this << start);
00205 m_txPowerBaseDbm = start;
00206 }
00207 void
00208 Ns2ExtWifiPhy::SetTxPowerEnd (double end)
00209 {
00210 NS_LOG_FUNCTION (this << end);
00211 m_txPowerEndDbm = end;
00212 }
00213 void
00214 Ns2ExtWifiPhy::SetNTxPower (uint32_t n)
00215 {
00216 NS_LOG_FUNCTION (this << n);
00217 m_nTxPower = n;
00218 }
00219 void
00220 Ns2ExtWifiPhy::SetTxGain (double gain)
00221 {
00222 NS_LOG_FUNCTION (this << gain);
00223 m_txGainDb = gain;
00224 }
00225 void
00226 Ns2ExtWifiPhy::SetRxGain (double gain)
00227 {
00228 NS_LOG_FUNCTION (this << gain);
00229 m_rxGainDb = gain;
00230 }
00231 void
00232 Ns2ExtWifiPhy::SetDevice (Ptr<Object> device)
00233 {
00234 m_device = device;
00235 }
00236 void
00237 Ns2ExtWifiPhy::SetMobility (Ptr<Object> mobility)
00238 {
00239 m_mobility = mobility;
00240 }
00241
00242 double
00243 Ns2ExtWifiPhy::GetTxPowerStart (void) const
00244 {
00245 return m_txPowerBaseDbm;
00246 }
00247 double
00248 Ns2ExtWifiPhy::GetTxPowerEnd (void) const
00249 {
00250 return m_txPowerEndDbm;
00251 }
00252 double
00253 Ns2ExtWifiPhy::GetTxGain (void) const
00254 {
00255 return m_txGainDb;
00256 }
00257 double
00258 Ns2ExtWifiPhy::GetRxGain (void) const
00259 {
00260 return m_rxGainDb;
00261 }
00262
00263 Ptr<Object>
00264 Ns2ExtWifiPhy::GetDevice (void) const
00265 {
00266 return m_device;
00267 }
00268 Ptr<Object>
00269 Ns2ExtWifiPhy::GetMobility (void)
00270 {
00271 return m_mobility;
00272 }
00273
00274 void
00275 Ns2ExtWifiPhy::SetCarrierSenseThreshold (double dbm)
00276 {
00277 NS_LOG_FUNCTION (this << dbm);
00278 m_carrierSenseThresholdW = DbmToW (dbm);
00279 }
00280 double
00281 Ns2ExtWifiPhy::GetCarrierSenseThreshold () const
00282 {
00283 return WToDbm (m_carrierSenseThresholdW);
00284 }
00285
00286 double
00287 Ns2ExtWifiPhy::CalculateSnr (WifiMode txMode, double ber) const
00288 {
00289 return m_sinrReceive;
00290 }
00291
00292 Ptr<WifiChannel>
00293 Ns2ExtWifiPhy::GetChannel (void) const
00294 {
00295 return m_channel;
00296 }
00297 void
00298 Ns2ExtWifiPhy::SetChannel (Ptr<Ns2ExtWifiChannel> channel)
00299 {
00300 m_channel = channel;
00301 m_channel->Add (this);
00302 }
00303
00304 void
00305 Ns2ExtWifiPhy::SetReceiveOkCallback (RxOkCallback callback)
00306 {
00307 m_state->SetReceiveOkCallback (callback);
00308 }
00309 void
00310 Ns2ExtWifiPhy::SetReceiveErrorCallback (RxErrorCallback callback)
00311 {
00312 m_state->SetReceiveErrorCallback (callback);
00313 }
00314 void
00315 Ns2ExtWifiPhy::StartReceivePacket (Ptr<Packet> packet,
00316 double rxPowerDbm,
00317 WifiMode txMode,
00318 enum WifiPreamble preamble)
00319 {
00320 NS_LOG_FUNCTION (this << packet << rxPowerDbm << txMode << preamble);
00321 rxPowerDbm += m_rxGainDb;
00322 double rxPowerW = DbmToW (rxPowerDbm);
00323 Time rxDuration = CalculateTxDuration (packet->GetSize (), txMode, preamble);
00324 Time endRx = Simulator::Now () + rxDuration;
00325
00326 Ptr<InterferenceHelper::Event> event;
00327 event = m_interference.Add (packet->GetSize (),
00328 txMode,
00329 preamble,
00330 rxDuration,
00331 rxPowerW);
00332
00333 double snr = m_interference.CalculateSnr (event);
00334
00335 switch (m_state->GetState ()) {
00336 case Ns2ExtWifiPhy::RX:
00337 NS_LOG_DEBUG ("drop packet because already receiving (power="<<
00338 rxPowerW<<"W)");
00339
00340 packet->AddTag(WifiPhyRxTag( rxPowerDbm, snr, 0 ));
00341
00342 m_state->CallRxErrorTrace(packet, RXERROR_ALREADY_RXING);
00343
00344 if (endRx > Simulator::Now () + m_state->GetDelayUntilIdle ())
00345 {
00346
00347
00348 goto maybeCcaBusy;
00349 }
00350 break;
00351 case Ns2ExtWifiPhy::TX:
00352 NS_LOG_DEBUG ("drop packet because already in Tx (power="<<
00353 rxPowerW<<"W)");
00354
00355 packet->AddTag(WifiPhyRxTag( rxPowerDbm, snr, 0 ));
00356
00357 m_state->CallRxErrorTrace(packet, RXERROR_IN_TX);
00358
00359 if (endRx > Simulator::Now () + m_state->GetDelayUntilIdle ())
00360 {
00361
00362
00363 goto maybeCcaBusy;
00364 }
00365 break;
00366 case Ns2ExtWifiPhy::CCA_BUSY:
00367 case Ns2ExtWifiPhy::IDLE:
00368 if (rxPowerW > m_carrierSenseThresholdW)
00369 {
00370 NS_LOG_DEBUG ("sync (power="<<rxPowerW<<"W)");
00371
00372 WifiPhyRxTag rxTag( rxPowerDbm, snr, 0 );
00373 m_state->CallRxStartTrace(packet, rxTag);
00374
00375
00376 m_state->SwitchToRx (rxDuration);
00377 NS_ASSERT (m_endRxEvent.IsExpired ());
00378 m_endRxEvent = Simulator::Schedule (rxDuration, &Ns2ExtWifiPhy::EndReceivePacket, this,
00379 packet,
00380 event);
00381 }
00382 else
00383 {
00384 NS_LOG_DEBUG ("drop packet because signal power too Small ("<<
00385 rxPowerW<<"<"<<m_carrierSenseThresholdW<<")");
00386
00387 packet->AddTag(WifiPhyRxTag( rxPowerDbm, snr, 0 ));
00388
00389 m_state->CallRxErrorTrace(packet, RXERROR_LOW_SIGNAL);
00390
00391 goto maybeCcaBusy;
00392 }
00393 break;
00394 default:
00395 NS_ASSERT (false);
00396 break;
00397 }
00398
00399 return;
00400
00401 maybeCcaBusy:
00402
00403
00404
00405
00406
00407 Time delayUntilCcaEnd = m_interference.GetEnergyDuration (m_carrierSenseThresholdW);
00408 if (!delayUntilCcaEnd.IsZero ())
00409 {
00410 m_state->SwitchMaybeToCcaBusy (delayUntilCcaEnd);
00411 }
00412 }
00413 void
00414 Ns2ExtWifiPhy::SendPacket (Ptr<const Packet> packet, WifiMode txMode, WifiPreamble preamble, uint8_t txPower)
00415 {
00416 NS_LOG_FUNCTION (this << packet << txMode << preamble << (uint32_t)txPower);
00417
00418
00419
00420
00421
00422
00423 NS_ASSERT (!m_state->IsStateTx ());
00424
00425 Time txDuration = CalculateTxDuration (packet->GetSize (), txMode, preamble);
00426 if (m_state->IsStateRx ())
00427 {
00428 m_endRxEvent.Cancel ();
00429 }
00430
00431 double txPowerDbm = GetPowerDbm (txPower) + m_txGainDb;
00432
00433 packet->AddTag( WifiPhyTxTag(preamble, txMode, txPower, txPowerDbm, txDuration) );
00434
00435 m_state->SwitchToTx (packet, txDuration);
00436 m_channel->Send (this, packet, txPowerDbm, txMode, preamble);
00437 }
00438
00439 uint32_t
00440 Ns2ExtWifiPhy::GetNModes (void) const
00441 {
00442 return m_modes.size ();
00443 }
00444 WifiMode
00445 Ns2ExtWifiPhy::GetMode (uint32_t mode) const
00446 {
00447 return m_modes[mode];
00448 }
00449 uint32_t
00450 Ns2ExtWifiPhy::GetNTxPower (void) const
00451 {
00452 return m_nTxPower;
00453 }
00454
00455 void
00456 Ns2ExtWifiPhy::Configure80211a (void)
00457 {
00458 NS_LOG_FUNCTION (this);
00459 m_interference.Configure80211aParameters ();
00460 m_modes.push_back (WifiPhy::Get6mba ());
00461 m_modes.push_back (WifiPhy::Get9mba ());
00462 m_modes.push_back (WifiPhy::Get12mba ());
00463 m_modes.push_back (WifiPhy::Get18mba ());
00464 m_modes.push_back (WifiPhy::Get24mba ());
00465 m_modes.push_back (WifiPhy::Get36mba ());
00466 m_modes.push_back (WifiPhy::Get48mba ());
00467 m_modes.push_back (WifiPhy::Get54mba ());
00468 }
00469
00470 void
00471 Ns2ExtWifiPhy::ConfigureHolland (void)
00472 {
00473 NS_LOG_FUNCTION (this);
00474 m_interference.Configure80211aParameters ();
00475 m_modes.push_back (WifiPhy::Get6mba ());
00476 m_modes.push_back (WifiPhy::Get12mba ());
00477 m_modes.push_back (WifiPhy::Get18mba ());
00478 m_modes.push_back (WifiPhy::Get36mba ());
00479 m_modes.push_back (WifiPhy::Get54mba ());
00480 }
00481
00482 void
00483 Ns2ExtWifiPhy::RegisterListener (WifiPhyListener *listener)
00484 {
00485 m_state->RegisterListener (listener);
00486 }
00487
00488 bool
00489 Ns2ExtWifiPhy::IsStateCcaBusy (void)
00490 {
00491 return m_state->IsStateCcaBusy ();
00492 }
00493
00494 bool
00495 Ns2ExtWifiPhy::IsStateIdle (void)
00496 {
00497 return m_state->IsStateIdle ();
00498 }
00499 bool
00500 Ns2ExtWifiPhy::IsStateBusy (void)
00501 {
00502 return m_state->IsStateBusy ();
00503 }
00504 bool
00505 Ns2ExtWifiPhy::IsStateSyncing (void)
00506 {
00507 return m_state->IsStateSyncing ();
00508 }
00509 bool
00510 Ns2ExtWifiPhy::IsStateRx (void)
00511 {
00512 return m_state->IsStateRx ();
00513 }
00514 bool
00515 Ns2ExtWifiPhy::IsStateTx (void)
00516 {
00517 return m_state->IsStateTx ();
00518 }
00519
00520 Time
00521 Ns2ExtWifiPhy::GetStateDuration (void)
00522 {
00523 return m_state->GetStateDuration ();
00524 }
00525 Time
00526 Ns2ExtWifiPhy::GetDelayUntilIdle (void)
00527 {
00528 return m_state->GetDelayUntilIdle ();
00529 }
00530
00531 Time
00532 Ns2ExtWifiPhy::GetLastRxStartTime (void) const
00533 {
00534 return m_state->GetLastRxStartTime ();
00535 }
00536
00537 Time
00538 Ns2ExtWifiPhy::CalculateTxDuration (uint32_t size, WifiMode payloadMode, enum WifiPreamble preamble) const
00539 {
00540 return m_interference.CalculateTxDuration (size, payloadMode, preamble);
00541 }
00542
00543 double
00544 Ns2ExtWifiPhy::DbToRatio (double dB) const
00545 {
00546 double ratio = pow(10.0,dB/10.0);
00547 return ratio;
00548 }
00549
00550 double
00551 Ns2ExtWifiPhy::DbmToW (double dBm) const
00552 {
00553 double mW = pow(10.0,dBm/10.0);
00554 return mW / 1000.0;
00555 }
00556
00557 double
00558 Ns2ExtWifiPhy::WToDbm (double w) const
00559 {
00560 return 10.0 * log10(w * 1000.0);
00561 }
00562
00563 double
00564 Ns2ExtWifiPhy::RatioToDb (double ratio) const
00565 {
00566 return 10.0 * log10(ratio);
00567 }
00568
00569 double
00570 Ns2ExtWifiPhy::GetPowerDbm (uint8_t power) const
00571 {
00572 NS_ASSERT (m_txPowerBaseDbm <= m_txPowerEndDbm);
00573 NS_ASSERT (m_nTxPower > 0);
00574 double dbm = m_txPowerBaseDbm + power * (m_txPowerEndDbm - m_txPowerBaseDbm) / m_nTxPower;
00575 return dbm;
00576 }
00577
00578 void
00579 Ns2ExtWifiPhy::EndReceivePacket (Ptr<Packet> packet, Ptr<InterferenceHelper::Event> event)
00580 {
00581 NS_LOG_FUNCTION (this << packet << event);
00582 NS_ASSERT (IsStateRx ());
00583 NS_ASSERT (event->GetEndTime () == Simulator::Now ());
00584
00585
00586
00587 double snr = m_interference.CalculateSnr (event);
00588
00589 NS_LOG_DEBUG ("pr=" << WToDbm(event->GetRxPowerW()) << "dBm, " <<
00590 "csThr=" << WToDbm(m_carrierSenseThresholdW) << "dBm, " <<
00591 "snr=" << snr << ", " <<
00592 "snrRecv=" << m_sinrReceive << ", " <<
00593 "size=" << packet->GetSize());
00594
00595 packet->AddTag(WifiPhyRxTag( WToDbm(event->GetRxPowerW()), snr, 0 ));
00596
00597 bool rxOk = (snr > m_sinrReceive && event->GetRxPowerW () >= m_carrierSenseThresholdW);
00598
00599 if (rxOk)
00600 {
00601
00602 m_state->SwitchFromRxEndOk (packet);
00603 }
00604 else
00605 {
00606
00607 m_state->SwitchFromRxEndError (packet);
00608 }
00609 }
00610
00611
00612
00613
00614 }