Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(1501)

Unified Diff: src/devices/wifi/spectrum-yans-wifi-phy.cc

Issue 1869054: LTE module for ns-3
Patch Set: Created 13 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/devices/wifi/spectrum-yans-wifi-phy.cc
===================================================================
new file mode 100644
--- /dev/null
+++ b/src/devices/wifi/spectrum-yans-wifi-phy.cc
@@ -0,0 +1,615 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005,2006 INRIA
+ * Copyright (c) 2009 CTTC
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Original Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Ported to the Spectrum framework by Nicola Baldo <nbaldo@cttc.es> on June 2009
+ */
+
+#include<ns3/spectrum-channel.h>
+#include"wifi-channel.h"
+#include "spectrum-yans-wifi-phy.h"
+#include "wifi-mode.h"
+#include "wifi-preamble.h"
+#include "wifi-phy-tag.h"
+#include "wifi-phy-state-helper.h"
+#include "error-rate-model.h"
+#include "ns3/simulator.h"
+#include "ns3/packet.h"
+#include "ns3/random-variable.h"
+#include "ns3/assert.h"
+#include "ns3/log.h"
+#include "ns3/double.h"
+#include "ns3/uinteger.h"
+#include "ns3/enum.h"
+#include "ns3/pointer.h"
+#include "ns3/net-device.h"
+#include "ns3/trace-source-accessor.h"
+#include "ns3/spectrum-value.h"
+#include <math.h>
+
+
+NS_LOG_COMPONENT_DEFINE ("SpectrumYansWifiPhy");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (SpectrumYansWifiPhy);
+
+TypeId
+SpectrumYansWifiPhy::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::SpectrumYansWifiPhy")
+ .SetParent<WifiPhy> ()
+ .AddConstructor<SpectrumYansWifiPhy> ()
+ .AddAttribute ("EnergyDetectionThreshold",
+ "The energy of a received signal should be higher than "
+ "this threshold (dbm) to allow the PHY layer to detect the signal.",
+ DoubleValue (-140.0),
+ MakeDoubleAccessor (&SpectrumYansWifiPhy::SetEdThreshold,
+ &SpectrumYansWifiPhy::GetEdThreshold),
+ MakeDoubleChecker<double> ())
+ .AddAttribute ("CcaMode1Threshold",
+ "The energy of a received signal should be higher than "
+ "this threshold (dbm) to allow the PHY layer to declare CCA BUSY state",
+ DoubleValue (-140.0),
+ MakeDoubleAccessor (&SpectrumYansWifiPhy::SetCcaMode1Threshold,
+ &SpectrumYansWifiPhy::GetCcaMode1Threshold),
+ MakeDoubleChecker<double> ())
+ .AddAttribute ("TxPowerLevels",
+ "Number of transmission power levels available between "
+ "TxPowerBase and TxPowerEnd included.",
+ UintegerValue (1),
+ MakeUintegerAccessor (&SpectrumYansWifiPhy::m_nTxPower),
+ MakeUintegerChecker<uint32_t> ())
+ .AddAttribute ("TxPowerEnd",
+ "Maximum available transmission level (dbm).",
+ DoubleValue (16.0206),
+ MakeDoubleAccessor (&SpectrumYansWifiPhy::SetTxPowerEnd,
+ &SpectrumYansWifiPhy::GetTxPowerEnd),
+ MakeDoubleChecker<double> ())
+ .AddAttribute ("TxPowerStart",
+ "Minimum available transmission level (dbm).",
+ DoubleValue (16.0206),
+ MakeDoubleAccessor (&SpectrumYansWifiPhy::SetTxPowerStart,
+ &SpectrumYansWifiPhy::GetTxPowerStart),
+ MakeDoubleChecker<double> ())
+ .AddAttribute ("RxNoiseFigure",
+ "Loss (dB) in the Signal-to-Noise-Ratio due to non-idealities in the receiver."
+ " According to Wikipedia (http://en.wikipedia.org/wiki/Noise_figure), this is "
+ "\"the difference in decibels (dB) between"
+ " the noise output of the actual receiver to the noise output of an "
+ " ideal receiver with the same overall gain and bandwidth when the receivers "
+ " are connected to sources at the standard noise temperature T0 (usually 290 K)\"."
+ " For",
+ DoubleValue (7),
+ MakeDoubleAccessor (&SpectrumYansWifiPhy::SetRxNoiseFigure,
+ &SpectrumYansWifiPhy::GetRxNoiseFigure),
+ MakeDoubleChecker<double> ())
+ .AddAttribute ("Standard", "The standard chosen configures a set of transmission modes"
+ " and some PHY-specific constants.",
+ EnumValue (WIFI_PHY_STANDARD_80211a),
+ MakeEnumAccessor (&SpectrumYansWifiPhy::SetStandard),
+ MakeEnumChecker (WIFI_PHY_STANDARD_80211a, "802.11a",
+ WIFI_PHY_STANDARD_80211b, "802.11b",
+ WIFI_PHY_STANDARD_holland, "holland"))
+ .AddAttribute ("State", "The state of the PHY layer",
+ PointerValue (),
+ MakePointerAccessor (&SpectrumYansWifiPhy::m_state),
+ MakePointerChecker<WifiPhyStateHelper> ())
+ ;
+ return tid;
+}
+
+SpectrumYansWifiPhy::SpectrumYansWifiPhy ()
+ : m_channelFreqMhz(2437),
+ m_endSyncEvent (),
+ m_random (0.0, 1.0),
+ m_txSpectralMask(0),
+ m_rxSpectralMask(0)
+{
+ NS_LOG_FUNCTION (this);
+ m_state = CreateObject<WifiPhyStateHelper> ();
+ m_wifiSpectrumPhyInterface = CreateObject<WifiSpectrumPhyInterface> ();
+ m_wifiSpectrumPhyInterface->SetSpectrumYansWifiPhy(this);
+}
+
+SpectrumYansWifiPhy::~SpectrumYansWifiPhy ()
+{
+ NS_LOG_FUNCTION (this);
+}
+
+void
+SpectrumYansWifiPhy::DoDispose (void)
+{
+ NS_LOG_FUNCTION (this);
+ m_channel = 0;
+ m_modes.clear ();
+ m_device = 0;
+}
+
+void
+SpectrumYansWifiPhy::SetStandard (enum WifiPhyStandard standard)
+{
+ NS_LOG_FUNCTION (this << standard);
+ m_standard = standard;
+ switch (standard) {
+ case WIFI_PHY_STANDARD_80211a:
+ Configure80211a ();
+ break;
+ case WIFI_PHY_STANDARD_80211b:
+ Configure80211b ();
+ break;
+ case WIFI_PHY_STANDARD_holland:
+ ConfigureHolland ();
+ break;
+ default:
+ NS_ASSERT (false);
+ break;
+ }
+}
+
+
+void
+SpectrumYansWifiPhy::SetRxNoiseFigure (double noiseFigureDb)
+{
+ NS_LOG_FUNCTION (this << noiseFigureDb);
+ m_interference.SetNoiseFigure (DbToRatio (noiseFigureDb));
+}
+void
+SpectrumYansWifiPhy::SetTxPowerStart (double start)
+{
+ NS_LOG_FUNCTION (this << start);
+ m_txPowerBaseDbm = start;
+}
+void
+SpectrumYansWifiPhy::SetTxPowerEnd (double end)
+{
+ NS_LOG_FUNCTION (this << end);
+ m_txPowerEndDbm = end;
+}
+void
+SpectrumYansWifiPhy::SetNTxPower (uint32_t n)
+{
+ NS_LOG_FUNCTION (this << n);
+ m_nTxPower = n;
+}
+
+
+void
+SpectrumYansWifiPhy::SetTxSpectralMask (Ptr<SpectrumValue> mask)
+{
+ m_txSpectralMask = mask;
+}
+
+void
+SpectrumYansWifiPhy::SetRxSpectralMask (Ptr<SpectrumValue> mask)
+{
+ m_rxSpectralMask = mask;
+}
+
+
+void
+SpectrumYansWifiPhy::SetEdThreshold (double threshold)
+{
+ NS_LOG_FUNCTION (this << threshold);
+ m_edThresholdW = DbmToW (threshold);
+}
+void
+SpectrumYansWifiPhy::SetCcaMode1Threshold (double threshold)
+{
+ NS_LOG_FUNCTION (this << threshold);
+ m_ccaMode1ThresholdW = DbmToW (threshold);
+}
+void
+SpectrumYansWifiPhy::SetErrorRateModel (Ptr<ErrorRateModel> rate)
+{
+ m_interference.SetErrorRateModel (rate);
+}
+void
+SpectrumYansWifiPhy::SetDevice (Ptr<Object> device)
+{
+ m_device = device;
+}
+void
+SpectrumYansWifiPhy::SetMobility (Ptr<Object> mobility)
+{
+ m_mobility = mobility;
+}
+
+double
+SpectrumYansWifiPhy::GetRxNoiseFigure (void) const
+{
+ return RatioToDb (m_interference.GetNoiseFigure ());
+}
+double
+SpectrumYansWifiPhy::GetTxPowerStart (void) const
+{
+ return m_txPowerBaseDbm;
+}
+double
+SpectrumYansWifiPhy::GetTxPowerEnd (void) const
+{
+ return m_txPowerEndDbm;
+}
+
+double
+SpectrumYansWifiPhy::GetEdThreshold (void) const
+{
+ return WToDbm (m_edThresholdW);
+}
+
+double
+SpectrumYansWifiPhy::GetCcaMode1Threshold (void) const
+{
+ return WToDbm (m_ccaMode1ThresholdW);
+}
+
+Ptr<ErrorRateModel>
+SpectrumYansWifiPhy::GetErrorRateModel (void) const
+{
+ return m_interference.GetErrorRateModel ();
+}
+Ptr<Object>
+SpectrumYansWifiPhy::GetDevice (void) const
+{
+ return m_device;
+}
+Ptr<Object>
+SpectrumYansWifiPhy::GetMobility (void)
+{
+ return m_mobility;
+}
+
+Ptr<SpectrumPhy>
+SpectrumYansWifiPhy::GetSpectrumPhy (void)
+{
+ return (m_wifiSpectrumPhyInterface->GetObject<SpectrumPhy> ());
+}
+
+
+double
+SpectrumYansWifiPhy::CalculateSnr (WifiMode txMode, double ber) const
+{
+ return m_interference.GetErrorRateModel ()->CalculateSnr (txMode, ber);
+}
+
+Ptr<WifiChannel>
+SpectrumYansWifiPhy::GetChannel (void) const
+{
+ return Ptr<WifiChannel>(0);
+}
+void
+SpectrumYansWifiPhy::SetChannel (Ptr<SpectrumChannel> channel)
+{
+ m_channel = channel;
+}
+
+void
+SpectrumYansWifiPhy::SetReceiveOkCallback (SyncOkCallback callback)
+{
+ m_state->SetReceiveOkCallback (callback);
+}
+void
+SpectrumYansWifiPhy::SetReceiveErrorCallback (SyncErrorCallback callback)
+{
+ m_state->SetReceiveErrorCallback (callback);
+}
+
+void
+SpectrumYansWifiPhy:: StartRx(Ptr<Packet> packet,
+ Ptr <const SpectrumValue> rxPowerSpectrum,
+ Time rxDuration,
+ Ptr<SpectrumPhy> sender)
+{
+ NS_LOG_FUNCTION (this);
+
+ WifiPhyTag tag;
+ packet->PeekPacketTag(tag);
+ WifiMode txMode = tag.GetWifiMode ();
+ enum WifiPreamble preamble = tag.GetWifiPreamble ();
+ double rxPowerW = Norm((*rxPowerSpectrum) * (*m_rxSpectralMask));
+ Time endRx = Simulator::Now () + rxDuration;
+
+ Ptr<InterferenceHelper::Event> event;
+ event = m_interference.Add (packet->GetSize (),
+ txMode,
+ preamble,
+ rxDuration,
+ rxPowerW);
+
+ switch (m_state->GetState ()) {
+ case SpectrumYansWifiPhy::SYNC:
+ NS_LOG_DEBUG ("drop packet because already in Sync (power="<<
+ rxPowerW<<"W)");
+ NotifyRxDrop (packet);
+ if (endRx > Simulator::Now () + m_state->GetDelayUntilIdle ())
+ {
+ // that packet will be noise _after_ the reception of the
+ // currently-received packet.
+ goto maybeCcaBusy;
+ }
+ break;
+ case SpectrumYansWifiPhy::TX:
+ NS_LOG_DEBUG ("drop packet because already in Tx (power="<<
+ rxPowerW<<"W)");
+ NotifyRxDrop (packet);
+ if (endRx > Simulator::Now () + m_state->GetDelayUntilIdle ())
+ {
+ // that packet will be noise _after_ the transmission of the
+ // currently-transmitted packet.
+ goto maybeCcaBusy;
+ }
+ break;
+ case SpectrumYansWifiPhy::CCA_BUSY:
+ case SpectrumYansWifiPhy::IDLE:
+ if (rxPowerW > m_edThresholdW)
+ {
+ NS_LOG_DEBUG ("sync (power="<<rxPowerW<<"W)");
+ // sync to signal
+ m_state->SwitchToSync (rxDuration);
+ NS_ASSERT (m_endSyncEvent.IsExpired ());
+ NotifyRxBegin (packet);
+ m_endSyncEvent = Simulator::Schedule (rxDuration, &SpectrumYansWifiPhy::EndSync, this,
+ packet,
+ event);
+ }
+ else
+ {
+ NS_LOG_DEBUG ("drop packet because signal power too Small ("<<
+ rxPowerW<<"<"<<m_edThresholdW<<")");
+ NotifyRxDrop (packet);
+ goto maybeCcaBusy;
+ }
+ break;
+ }
+
+ return;
+
+ maybeCcaBusy:
+ // We are here because we have received the first bit of a packet and we are
+ // not going to be able to synchronize on it
+ // In this model, CCA becomes busy when the aggregation of all signals as
+ // tracked by the InterferenceHelper class is higher than the CcaBusyThreshold
+
+ Time delayUntilCcaEnd = m_interference.GetEnergyDuration (m_ccaMode1ThresholdW);
+ if (!delayUntilCcaEnd.IsZero ())
+ {
+ m_state->SwitchMaybeToCcaBusy (delayUntilCcaEnd);
+ }
+}
+
+void
+SpectrumYansWifiPhy::SendPacket (Ptr<Packet> packet, WifiMode txMode, WifiPreamble preamble, uint8_t txPower)
+{
+ NS_LOG_FUNCTION (this << packet << txMode << preamble << (uint32_t)txPower);
+ /* Transmission can happen if:
+ * - we are syncing on a packet. It is the responsability of the
+ * MAC layer to avoid doing this but the PHY does nothing to
+ * prevent it.
+ * - we are idle
+ */
+ NS_ASSERT (!m_state->IsStateTx ());
+
+ Time txDuration = CalculateTxDuration (packet->GetSize (), txMode, preamble);
+ if (m_state->IsStateSync ())
+ {
+ m_endSyncEvent.Cancel ();
+ }
+ NotifyTxBegin (packet);
+ uint32_t dataRate500KbpsUnits = txMode.GetDataRate () / 500000;
+ bool isShortPreamble = (WIFI_PREAMBLE_SHORT == preamble);
+ NotifyPromiscSniffTx (packet, m_channelFreqMhz, dataRate500KbpsUnits, isShortPreamble);
+ m_state->SwitchToTx (txDuration, packet, txMode, preamble, txPower);
+
+
+ //m_channel->StartTx (this, packet, GetPowerDbm (txPower) , txMode, preamble);
+
+ WifiPhyTag oldtag;
+ packet->RemovePacketTag(oldtag);
+ WifiPhyTag tag(txMode, preamble);
+ packet->AddPacketTag(tag);
+
+ double txPowerWatts = DbmToW (GetPowerDbm (txPower));
+ Ptr<SpectrumValue> txPowerSpectrum = Create<SpectrumValue> (m_txSpectralMask->GetSpectrumModel ());
+ *txPowerSpectrum = *m_txSpectralMask * txPowerWatts;
+
+ m_channel->StartTx (packet, txPowerSpectrum, txDuration, GetSpectrumPhy ());
+
+}
+
+uint32_t
+SpectrumYansWifiPhy::GetNModes (void) const
+{
+ return m_modes.size ();
+}
+WifiMode
+SpectrumYansWifiPhy::GetMode (uint32_t mode) const
+{
+ return m_modes[mode];
+}
+uint32_t
+SpectrumYansWifiPhy::GetNTxPower (void) const
+{
+ return m_nTxPower;
+}
+
+void
+SpectrumYansWifiPhy::Configure80211a (void)
+{
+ NS_LOG_FUNCTION (this);
+ m_interference.Configure80211aParameters ();
+ m_modes.push_back (WifiPhy::Get6mba ());
+ m_modes.push_back (WifiPhy::Get9mba ());
+ m_modes.push_back (WifiPhy::Get12mba ());
+ m_modes.push_back (WifiPhy::Get18mba ());
+ m_modes.push_back (WifiPhy::Get24mba ());
+ m_modes.push_back (WifiPhy::Get36mba ());
+ m_modes.push_back (WifiPhy::Get48mba ());
+ m_modes.push_back (WifiPhy::Get54mba ());
+}
+
+
+void
+SpectrumYansWifiPhy::Configure80211b (void)
+{
+ NS_LOG_FUNCTION (this);
+ m_interference.Configure80211bParameters ();
+ m_modes.push_back (WifiPhy::Get1mbb ());
+ m_modes.push_back (WifiPhy::Get2mbb ());
+ m_modes.push_back (WifiPhy::Get5_5mbb ());
+ m_modes.push_back (WifiPhy::Get11mbb ());
+}
+
+void
+SpectrumYansWifiPhy::ConfigureHolland (void)
+{
+ NS_LOG_FUNCTION (this);
+ m_interference.Configure80211aParameters ();
+ m_modes.push_back (WifiPhy::Get6mba ());
+ m_modes.push_back (WifiPhy::Get12mba ());
+ m_modes.push_back (WifiPhy::Get18mba ());
+ m_modes.push_back (WifiPhy::Get36mba ());
+ m_modes.push_back (WifiPhy::Get54mba ());
+}
+
+void
+SpectrumYansWifiPhy::RegisterListener (WifiPhyListener *listener)
+{
+ m_state->RegisterListener (listener);
+}
+
+bool
+SpectrumYansWifiPhy::IsStateCcaBusy (void)
+{
+ return m_state->IsStateCcaBusy ();
+}
+
+bool
+SpectrumYansWifiPhy::IsStateIdle (void)
+{
+ return m_state->IsStateIdle ();
+}
+bool
+SpectrumYansWifiPhy::IsStateBusy (void)
+{
+ return m_state->IsStateBusy ();
+}
+bool
+SpectrumYansWifiPhy::IsStateSync (void)
+{
+ return m_state->IsStateSync ();
+}
+bool
+SpectrumYansWifiPhy::IsStateTx (void)
+{
+ return m_state->IsStateTx ();
+}
+
+Time
+SpectrumYansWifiPhy::GetStateDuration (void)
+{
+ return m_state->GetStateDuration ();
+}
+Time
+SpectrumYansWifiPhy::GetDelayUntilIdle (void)
+{
+ return m_state->GetDelayUntilIdle ();
+}
+
+Time
+SpectrumYansWifiPhy::GetLastRxStartTime (void) const
+{
+ return m_state->GetLastRxStartTime ();
+}
+
+Time
+SpectrumYansWifiPhy::CalculateTxDuration (uint32_t size, WifiMode payloadMode, enum WifiPreamble preamble) const
+{
+ return m_interference.CalculateTxDuration (size, payloadMode, preamble);
+}
+
+double
+SpectrumYansWifiPhy::DbToRatio (double dB) const
+{
+ double ratio = pow(10.0,dB/10.0);
+ return ratio;
+}
+
+double
+SpectrumYansWifiPhy::DbmToW (double dBm) const
+{
+ double mW = pow(10.0,dBm/10.0);
+ return mW / 1000.0;
+}
+
+double
+SpectrumYansWifiPhy::WToDbm (double w) const
+{
+ return 10.0 * log10(w * 1000.0);
+}
+
+double
+SpectrumYansWifiPhy::RatioToDb (double ratio) const
+{
+ return 10.0 * log10(ratio);
+}
+
+double
+SpectrumYansWifiPhy::GetEdThresholdW (void) const
+{
+ return m_edThresholdW;
+}
+
+double
+SpectrumYansWifiPhy::GetPowerDbm (uint8_t power) const
+{
+ NS_ASSERT (m_txPowerBaseDbm <= m_txPowerEndDbm);
+ NS_ASSERT (m_nTxPower > 0);
+ double dbm = m_txPowerBaseDbm + power * (m_txPowerEndDbm - m_txPowerBaseDbm) / m_nTxPower;
+ return dbm;
+}
+
+void
+SpectrumYansWifiPhy::EndSync (Ptr<Packet> packet, Ptr<InterferenceHelper::Event> event)
+{
+ NS_LOG_FUNCTION (this << packet << event);
+ NS_ASSERT (IsStateSync ());
+ NS_ASSERT (event->GetEndTime () == Simulator::Now ());
+
+ struct InterferenceHelper::SnrPer snrPer;
+ snrPer = m_interference.CalculateSnrPer (event);
+
+ NS_LOG_DEBUG ("mode="<<(event->GetPayloadMode ().GetDataRate ())<<
+ ", snr="<<snrPer.snr<<", per="<<snrPer.per<<", size="<<packet->GetSize ());
+ if (m_random.GetValue () > snrPer.per)
+ {
+ NotifyRxEnd (packet);
+ uint32_t dataRate500KbpsUnits = event->GetPayloadMode ().GetDataRate () / 500000;
+ bool isShortPreamble = (WIFI_PREAMBLE_SHORT == event->GetPreambleType ());
+ double signalDbm = RatioToDb (event->GetRxPowerW ()) + 30;
+ double noiseDbm = RatioToDb(event->GetRxPowerW() / snrPer.snr) - GetRxNoiseFigure() + 30 ;
+ NotifyPromiscSniffRx (packet, m_channelFreqMhz, dataRate500KbpsUnits, isShortPreamble, signalDbm, noiseDbm);
+ m_state->SwitchFromSyncEndOk (packet, snrPer.snr, event->GetPayloadMode (), event->GetPreambleType ());
+ }
+ else
+ {
+ /* failure. */
+ NotifyRxDrop (packet);
+ m_state->SwitchFromSyncEndError (packet, snrPer.snr);
+ }
+}
+} // namespace ns3

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b