Dear all, I am kind of stuck at the moment and any help is highly appreciated. My goal is to set the ChannelNumber of a SpetrumWiFiPhy during the runtime of the simulation to dynamically react to changing interference conditions.
Since this is part of a larger project, I am working with snippets in the following. If a minimal example can be helpful, let me know. I am using SpectrumWifiPhy and the MultiModelSpectrumChannel. .... SpectrumWifiPhyHelper spectrumPhy = SpectrumWifiPhyHelper::Default (); Ptr<MultiModelSpectrumChannel> spectrumChannel = CreateObject<MultiModelSpectrumChannel> (); spectrumPhy.SetChannel (spectrumChannel); .... I setup my topology and (everything else) forming a multi-hop WiFi scenario with several nodes. I sort the devices for each link into separate NetDeviceContainer, for example called deviceslink0 for the first link. I have implement the following function to change the channel on two particular WifiNetDevice's of a link: void ChangeFrequencyLocal (NetDeviceContainer deviceslink, uint16_t channel){ for (uint32_t i = 0; i < deviceslink.GetN (); i++) { Ptr<WifiNetDevice> wifidevice = DynamicCast<WifiNetDevice> (deviceslink.Get(i)); Ptr<SpectrumWifiPhy> phy0 = DynamicCast<SpectrumWifiPhy>(wifidevice->GetPhy()); phy0->SetChannelNumber (channel); std::cout << "Changed Frequency to: " << channel << std::endl; } } If I call this function "normally" before the simulation starts:
ChangeFrequencyLocal(deviceslink0, 40);
everything is fine and the channels on that link are changed, really good. If I do the following: Simulator::Schedule(Seconds(1), &ChangeFrequencyLocal, deviceslink0, 40); I get the following assert: assert failed. cond="m_spectrumModel == x.m_spectrumModel", file=../src/spectrum/model/spectrum-value.cc, line=170 I found the AddOperationalChannel function of the SpectrumWifiPhy class.
From the description, it seems to be relevant for WiFi roaming. So I added the desired channels. However, the same assert fires. I am on ns-3.26. With kind regards, Michael
I think I found a hint to the problem, in the description of the SpectrumValue class:
@warning the intended use if that sm points to a static object * which will be there for the whole simulation. This is reasonable * since the set of frequencies which are to be used in the * simulation is normally known before the simulation starts.
However, SpectrumWifiPhy provides a function SpectrumWifiPhy::DoChannelSwitch (uint16_t nch)
This function seems perfectly fine since at some point it conducts a channel switch like this:
m_rxSpectrumModel = WifiSpectrumValueHelper::GetSpectrumModel (GetFrequency (), GetChannelWidth ()); Did somebody successfully used this function during run-time of the simulation?
Hi Tommasso,
Thanks for the answer. I further analyzed the source. Here is what I found out for future reference:
- The SpecrumWiFiPhy differentiates between the receiving and the transmitting channel
- For the receiving channel, there is an “adaptor” class called WifiSpectrumPhyInterface
- The problem is related to the receiving channel
- When the WiFi Device is created a dedicated spectrum model is created:
DEBUG_LOG: 0s 1 SpectrumWifiPhy:GetRxSpectrumModel(): Creating spectrum model from frequency/width pair of (5180, 20)”
- The set channel methods actually calls the SpectrumWifiPhy::DoChannelSwitch () which overwrites a dummy Method in WiFiPhy
- When calling it during run time, the channel switch on the devices is actually conducted:
DEBUG_LOG: 1s -1 SpectrumWifiPhy:DoChannelSwitch(): switching channel 36 -> 40
DEBUG_LOG: 1s -1 WifiPhy:SetChannelNumber(): Setting frequency to 5200; width to 20
- However there is no call to create a new receiving channel on the phy using the new frequency/width
- Therefore, the first attempt to receive on packet on that phy fails since since the spectrum model is not updated
cond="m_spectrumModel == x.m_spectrumModel"
I could try to find implement a fix for this by my own but I am a little afraid that this could be dead-end. I see two different possibilities:
- Creating a SpectrumModel before the start of the simulation for each desired frequency/width combination (computational ineffective, a work-around)
- Creating a new receiving spectrumModel during the channel switch. However, I really do not know if this is conceptional possible.
Perhaps somebody can comment on these two possible fixes? Any hints are more than appreciated.
I will also look into the Bugzilla.
With kind regards,
Michael
Hi Tommasso,
Thanks for the answer. I further analyzed the source. Here is what I found out for future reference:
- The SpecrumWiFiPhy differentiates between the receiving and the transmitting channel
- For the receiving channel, there is an “adaptor” class called WifiSpectrumPhyInterface
- The problem is related to the receiving channel
- When the WiFi Device is created a dedicated spectrum model is created:
DEBUG_LOG: 0s 1 SpectrumWifiPhy:GetRxSpectrumModel(): Creating spectrum model from frequency/width pair of (5180, 20)”
- The set channel methods actually calls the SpectrumWifiPhy::DoChannelSwitch () which overwrites a dummy Method in WiFiPhy
- When calling it during run time, the channel switch on the devices is actually conducted:
DEBUG_LOG: 1s -1 SpectrumWifiPhy:DoChannelSwitch(): switching channel 36 -> 40
DEBUG_LOG: 1s -1 WifiPhy:SetChannelNumber(): Setting frequency to 5200; width to 20
- However there is no call to create a new receiving channel on the phy using the new frequency/width
- Therefore, the first attempt to receive on packet on that phy fails since since the spectrum model is not updated
cond="m_spectrumModel == x.m_spectrumModel"