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