From dae8a0debb1b54d23af4340888b11bf27ab0d123 Mon Sep 17 00:00:00 2001 From: Pavel Boyko Date: Thu, 16 Jul 2009 15:56:42 +0400 Subject: [PATCH] Initial multichannel support in Yans Wifi PHY. --- src/devices/wifi/wifi-phy.h | 14 +++++++- src/devices/wifi/yans-wifi-channel.cc | 9 +++-- src/devices/wifi/yans-wifi-phy.cc | 52 ++++++++++++++++++++++----- src/devices/wifi/yans-wifi-phy.h | 23 +++++++++++- 4 files changed, 85 insertions(+), 13 deletions(-) diff --git a/src/devices/wifi/wifi-phy.h b/src/devices/wifi/wifi-phy.h index 2da58de60..f17adac2c 100644 --- a/src/devices/wifi/wifi-phy.h +++ b/src/devices/wifi/wifi-phy.h @@ -241,7 +241,19 @@ public: * the requested ber for the specified transmission mode. (W/W) */ virtual double CalculateSnr (WifiMode txMode, double ber) const = 0; - + + /** + * \brief Set channel number. + * + * Channel center frequency = Channel starting frequency + 5 MHz * (nch - 1) + * + * where Starting channel frequency is standard-dependent, see SetStandard() + * as defined in IEEE 802.11-2007 17.3.8.3.2. + */ + virtual void SetChannelNumber (uint16_t id) = 0; + /// Return current channel number, see SetChannelNumber() + virtual uint16_t GetChannelNumber () const = 0; + virtual Ptr GetChannel (void) const = 0; static WifiMode Get6mba (void); diff --git a/src/devices/wifi/yans-wifi-channel.cc b/src/devices/wifi/yans-wifi-channel.cc index 2bbc4559b..52ce25527 100644 --- a/src/devices/wifi/yans-wifi-channel.cc +++ b/src/devices/wifi/yans-wifi-channel.cc @@ -77,10 +77,14 @@ YansWifiChannel::Send (Ptr sender, Ptr packet, double Ptr senderMobility = sender->GetMobility ()->GetObject (); NS_ASSERT (senderMobility != 0); uint32_t j = 0; - for (PhyList::const_iterator i = m_phyList.begin (); i != m_phyList.end (); i++) - { + for (PhyList::const_iterator i = m_phyList.begin (); i != m_phyList.end (); i++, j++) + { if (sender != (*i)) { + // For now don't account for inter channel interference + if ((*i)->GetChannelNumber() != sender->GetChannelNumber()) + continue; + Ptr receiverMobility = (*i)->GetMobility ()->GetObject (); Time delay = m_delay->GetDelay (senderMobility, receiverMobility); double rxPowerDbm = m_loss->CalcRxPower (txPowerDbm, senderMobility, receiverMobility); @@ -90,7 +94,6 @@ YansWifiChannel::Send (Ptr sender, Ptr packet, double Simulator::Schedule (delay, &YansWifiChannel::Receive, this, j, copy, rxPowerDbm, wifiMode, preamble); } - j++; } } diff --git a/src/devices/wifi/yans-wifi-phy.cc b/src/devices/wifi/yans-wifi-phy.cc index 40b1599e3..75024b1c2 100644 --- a/src/devices/wifi/yans-wifi-phy.cc +++ b/src/devices/wifi/yans-wifi-phy.cc @@ -112,21 +112,25 @@ YansWifiPhy::GetTypeId (void) MakeEnumChecker (WIFI_PHY_STANDARD_80211a, "802.11a", WIFI_PHY_STANDARD_80211b, "802.11b", WIFI_PHY_STANDARD_80211_10Mhz,"802.11_10Mhz", - WIFI_PHY_STANDARD_80211_5Mhz,"802-11_5Mhz", + WIFI_PHY_STANDARD_80211_5Mhz,"802.11_5Mhz", WIFI_PHY_STANDARD_holland, "holland")) .AddAttribute ("State", "The state of the PHY layer", PointerValue (), MakePointerAccessor (&YansWifiPhy::m_state), MakePointerChecker ()) + .AddAttribute ("ChannelSwitchDelay", + "Delay between two short frames transmitted on different frequencies. NOTE: Unused now.", + TimeValue (MicroSeconds (250)), + MakeTimeAccessor (&YansWifiPhy::m_channelSwitchDelay), + MakeTimeChecker ()) ; return tid; } YansWifiPhy::YansWifiPhy () - : m_channelFreqMhz(2437), - m_endSyncEvent (), - m_random (0.0, 1.0) - + : m_endSyncEvent (), + m_random (0.0, 1.0), + m_channelStartingFrequency (0) { NS_LOG_FUNCTION (this); m_state = CreateObject (); @@ -163,7 +167,7 @@ YansWifiPhy::SetStandard (enum WifiPhyStandard standard) break; case WIFI_PHY_STANDARD_80211_5Mhz: Configure80211_5Mhz (); - break; + break; case WIFI_PHY_STANDARD_holland: ConfigureHolland (); break; @@ -308,6 +312,33 @@ YansWifiPhy::SetChannel (Ptr channel) { m_channel = channel; m_channel->Add (this); + m_channelId = 1; // always start on channel starting frequency (channel 1) +} + +void +YansWifiPhy::SetChannelNumber (uint16_t nch) +{ + // TODO implement channel switching state machine here + DoSetChannelNumber (nch); +} + +void +YansWifiPhy::DoSetChannelNumber (uint16_t nch) +{ + NS_LOG_DEBUG("switching channel " << m_channelId << " -> " << nch); + m_channelId = nch; +} + +uint16_t +YansWifiPhy::GetChannelNumber() const +{ + return m_channelId; +} + +double +YansWifiPhy::GetChannelFrequencyMhz() const +{ + return m_channelStartingFrequency + 5 * (GetChannelNumber() - 1); } void @@ -420,7 +451,7 @@ YansWifiPhy::SendPacket (Ptr packet, WifiMode txMode, WifiPreamble NotifyTxBegin (packet); uint32_t dataRate500KbpsUnits = txMode.GetDataRate () / 500000; bool isShortPreamble = (WIFI_PREAMBLE_SHORT == preamble); - NotifyPromiscSniffTx (packet, m_channelFreqMhz, dataRate500KbpsUnits, isShortPreamble); + NotifyPromiscSniffTx (packet, (uint16_t)GetChannelFrequencyMhz(), dataRate500KbpsUnits, isShortPreamble); m_state->SwitchToTx (txDuration, packet, txMode, preamble, txPower); m_channel->Send (this, packet, GetPowerDbm (txPower) + m_txGainDb, txMode, preamble); } @@ -445,6 +476,7 @@ void YansWifiPhy::Configure80211a (void) { NS_LOG_FUNCTION (this); + m_channelStartingFrequency = 5e3; // 5.000 GHz m_modes.push_back (WifiPhy::Get6mba ()); m_modes.push_back (WifiPhy::Get9mba ()); m_modes.push_back (WifiPhy::Get12mba ()); @@ -460,6 +492,7 @@ void YansWifiPhy::Configure80211b (void) { NS_LOG_FUNCTION (this); + m_channelStartingFrequency = 2412; // 2.412 GHz m_modes.push_back (WifiPhy::Get1mbb ()); m_modes.push_back (WifiPhy::Get2mbb ()); m_modes.push_back (WifiPhy::Get5_5mbb ()); @@ -470,6 +503,7 @@ void YansWifiPhy::Configure80211_10Mhz (void) { NS_LOG_FUNCTION (this); + m_channelStartingFrequency = 5e3; // 5.000 GHz, suppose 802.11a m_modes.push_back (WifiPhy::Get3mb10Mhz ()); m_modes.push_back (WifiPhy::Get4_5mb10Mhz ()); m_modes.push_back (WifiPhy::Get6mb10Mhz ()); @@ -484,6 +518,7 @@ void YansWifiPhy::Configure80211_5Mhz (void) { NS_LOG_FUNCTION (this); + m_channelStartingFrequency = 5e3; // 5.000 GHz, suppose 802.11a m_modes.push_back (WifiPhy::Get1_5mb5Mhz ()); m_modes.push_back (WifiPhy::Get2_25mb5Mhz ()); m_modes.push_back (WifiPhy::Get3mb5Mhz ()); @@ -498,6 +533,7 @@ void YansWifiPhy::ConfigureHolland (void) { NS_LOG_FUNCTION (this); + m_channelStartingFrequency = 5e3; // 5.000 GHz m_modes.push_back (WifiPhy::Get6mba ()); m_modes.push_back (WifiPhy::Get12mba ()); m_modes.push_back (WifiPhy::Get18mba ()); @@ -621,7 +657,7 @@ YansWifiPhy::EndSync (Ptr packet, Ptr event) 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); + NotifyPromiscSniffRx (packet, (uint16_t)GetChannelFrequencyMhz(), dataRate500KbpsUnits, isShortPreamble, signalDbm, noiseDbm); m_state->SwitchFromSyncEndOk (packet, snrPer.snr, event->GetPayloadMode (), event->GetPreambleType ()); } else diff --git a/src/devices/wifi/yans-wifi-phy.h b/src/devices/wifi/yans-wifi-phy.h index 56357177a..a2efeba4e 100644 --- a/src/devices/wifi/yans-wifi-phy.h +++ b/src/devices/wifi/yans-wifi-phy.h @@ -69,6 +69,21 @@ public: virtual ~YansWifiPhy (); void SetChannel (Ptr channel); + + /** + * \brief Set channel number. + * + * Channel center frequency = Channel starting frequency + 5 MHz * (nch - 1) + * + * where Starting channel frequency is standard-dependent, see SetStandard() + * as defined in IEEE 802.11-2007 17.3.8.3.2. + */ + void SetChannelNumber (uint16_t id); + /// Return current channel number, see SetChannelNumber() + uint16_t GetChannelNumber () const; + /// Return current center channel frequency in MHz, see SetСhannelNumber() + double GetChannelFrequencyMhz() const; + void StartReceivePacket (Ptr packet, double rxPowerDbm, WifiMode mode, @@ -94,6 +109,8 @@ public: Ptr GetErrorRateModel (void) const; Ptr GetDevice (void) const; Ptr GetMobility (void); + + virtual double GetTxPowerStart (void) const; @@ -135,6 +152,7 @@ private: double RatioToDb (double ratio) const; double GetPowerDbm (uint8_t power) const; void EndSync (Ptr packet, Ptr event); + void DoSetChannelNumber(uint16_t id); private: double m_edThresholdW; @@ -144,17 +162,20 @@ private: double m_txPowerBaseDbm; double m_txPowerEndDbm; uint32_t m_nTxPower; - uint16_t m_channelFreqMhz; Ptr m_channel; + uint16_t m_channelId; Ptr m_device; Ptr m_mobility; Modes m_modes; EventId m_endSyncEvent; UniformVariable m_random; WifiPhyStandard m_standard; + /// Standard-dependent center frequency of 0-th channel, MHz + double m_channelStartingFrequency; Ptr m_state; InterferenceHelper m_interference; + Time m_channelSwitchDelay; };