A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
spectrum-manager.cc
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License version 2 as
4  * published by the Free Software Foundation;
5  *
6  * This program is distributed in the hope that it will be useful,
7  * but WITHOUT ANY WARRANTY; without even the implied warranty of
8  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9  * GNU General Public License for more details.
10  *
11  * You should have received a copy of the GNU General Public License
12  * along with this program; if not, write to the Free Software
13  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
14  *
15  * Author: Abdulla K. Al-Ali <abdulla.alali@qu.edu.qa>
16  */
17 
18 #include "spectrum-manager.h"
19 #include "ns3/yans-wifi-phy.h"
20 #include "ns3/aodv-routing-protocol.h"
21 
22 NS_LOG_COMPONENT_DEFINE ("CogSpectrumManager");
23 
24 namespace ns3 {
25 
26 //SpectrumManager Initializer
28 
29  m_wifiMac=mac;
30  m_nodeId=id;
31 
32  // State Initialization
33  m_isPuOn=false;
34  m_isSensing=false;
35 
36  // Spectrum Module Definition
37  m_sensingMod=new SpectrumSensing(this);
38  m_decisionMod=new SpectrumDecision(this);
39 
40 }
41 
42 
43 
44 //SpectrumManager Initializer
46  int id, Time sense_time, Time transmit_time) {
47 
48  m_wifiMac=mac;
49  m_nodeId=id;
50  m_wifiPhy = phy;
51  m_isPuOn=false;
52  m_isSensing=false;
53  m_isSwitching = false;
54 
55  // State Initialization
56  m_senseTime=sense_time;
57  m_transmitTime=transmit_time;
58 
59  // Spectrum Module Definition
60  m_sensingMod=new SpectrumSensing(this);
61  m_decisionMod=new SpectrumDecision(this);
62 
63  // Setup sense and handoff ended callback at PHY
66 
67 }
68 
69 SpectrumManager::~SpectrumManager() {
70 
71 }
72 
73 //start: CR starts the sensing/handoff/transmission cycle on the RX iface.
74 void
76  // Start sensing on the current channel for a sense_time_ interval
77  m_isPuOn = m_sensingMod->GetSenseResultsFuture(m_nodeId,m_senseTime,m_transmitTime, m_repository->GetRxChannel(m_nodeId));
78  m_wifiPhy->StartSensing(m_senseTime);
79 
80 }
81 
82 
83 //is_channel_available: return true if CR is NOT doing sensing and is NOT doing spectrum handoff
84 bool
86 
87  bool available= !(m_isSensing || m_isSwitching);
88 
89  return available;
90 
91 }
92 
93 
94 
95 // is_PU_interfering: return true if there is a PU which is transmitting on the same channel and within the tx range of the CR receiving a packet
96 bool
98 
99  // Get the tx time of a packet
100  Time time_tx=txDuration;
101  // Check if a PU is active in the interval [now: now+time_tx]
102  int current_channel=m_repository->GetRxChannel(m_nodeId);
103  bool interference=m_sensingMod->GetSenseResultsFuture(m_nodeId,time_tx,m_transmitTime, current_channel);
104 
105 #ifdef SENSING_VERBOSE_MODE
106  if (interference)
107  {
108  char buffer [50];
109  std::sprintf(buffer, "[SENSING-DBG] Node %d sensed some PU activity on channel %d while receiving data\n", m_nodeId,current_channel);
110  NS_LOG_DEBUG (buffer);
111  }
112 #endif
113  return interference;
114 }
115 
116 
117 
118 /*********************************************************
119  * SETUP METHODS
120  * *******************************************************/
121 
122 //setPUmodel: set the current PU model
123 void
125 
126  m_sensingMod=new SpectrumSensing(this,prob,p);
127 
128 }
129 
130 
131 
132 //setRepository: set the current cross-layer repository
133 void
135 
136  m_repository=rep;
137  m_wifiPhy->SetChannelNumber(m_repository->GetRxChannel(m_nodeId));
138 }
139 
140 
141 /*********************************************************
142  * TIMER METHODS
143  * *******************************************************/
144 
145 //senseHandler: handler for sensing timer.
146 //Check if PU was detected during the last sensing interval, in case ask the spectrumDecision to switch to a new channel.
147 //In case of channel switching, use Spectrum Mobility to perform handoff, and notify the event to the upper layers.
148 void
150 
151  bool need_to_switch=false;
152 
153  int current_channel=m_repository->GetRxChannel(m_nodeId);
154 
155 #ifdef SENSING_VERBOSE_MODE //abdulla
156  char buffer [100];
157  std::sprintf(buffer, "[SENSING-DBG] Node %d is on channel %d and PU activity is %s", m_nodeId, current_channel, (m_isPuOn)?"true":"false");
158  NS_LOG_DEBUG(buffer);
159 #endif
160 
161  // Check if PU was detected
162  if (m_isPuOn) {
163 
164  // Ask the Spectrum Decision if channel switching is needed
165  need_to_switch=m_decisionMod->DecideSwitch();
166 
167  // CR needs to vacate the channel
168  if (need_to_switch) {
169 
170  // Channel allocation is decided at MAC Layer
171 #ifdef CHANNEL_DECISION_MAC_LAYER
172 
173  // Choose next channel and store the information in the shared repository
174  int next_channel=m_decisionMod->DecideSpectrum(current_channel);
175  m_wifiPhy->SetChannelNumber(next_channel);
176  m_repository->SetRxChannel(m_nodeId,next_channel);
177  m_isSwitching = true;
178 
179 #endif
180 
181 #ifdef SENSING_VERBOSE_MODE
182  char buffer [100];
183  std::sprintf(buffer, "[SENSING-DBG] Node %d starts handoff on channel %d to channel %d",m_nodeId,current_channel,next_channel);
184  NS_LOG_DEBUG (buffer);
185 #endif
186 
187  // Sensing Time is off, since the node is performing a spectrum handoff
188  m_isSensing=false;
189 
190  } else { //no need to switch
191 
192  // CR does not vacate the spectrum, but it must not interfere with PU activity
193  // In this case, CR keeps sensing and waits for the channel to be free
194  m_isPuOn = m_sensingMod->GetSenseResultsFuture(m_nodeId,m_senseTime,m_transmitTime, current_channel);
195 
196  NS_LOG_DEBUG ("restarting sensor");
197  m_wifiPhy->StartSensing(m_senseTime);
198 
199  m_isSensing=true;
200 
201  }
202 
203  } else { //if pu is not on. without this else, sensetimer gets scheduled twice
204 
205 
206  // The CR can transmit if PU is not detected
207  if ( !m_isPuOn ) {
208 
209  // Sensing Time is on
210  m_isSensing=false;
211 
212  if (m_isSwitching)
213  {
214 #ifdef ENABLE_SPECTRUM_HANDOFF_NOTIFICATION
215  // Notify the spectrum handoff to the upper layers
216  Ptr<YansWifiPhy> phy = DynamicCast<YansWifiPhy>(m_wifiPhy);
217  Ptr<Ipv4RoutingProtocol> route = phy->GetMobility()->GetObject<Ipv4>()->GetRoutingProtocol();
218  Ptr<aodv::RoutingProtocol> aodv = DynamicCast<aodv::RoutingProtocol>(route);
219  aodv->SendHello();
220  m_isSwitching = false;
221 #endif
222  }
223 
224  // No channel switching, the CR can start transmitting on the current channel
225  Simulator::Schedule (m_transmitTime, &SpectrumManager::TransmitEnded, this);
226  m_wifiMac->RestartAccess();
227 
228 #ifdef SENSING_VERBOSE_MODE
229  char buffer [50];
230  std::sprintf(buffer, "[SENSING-DBG] Node %d starts transmitting on channel %d",m_nodeId,current_channel);
231  NS_LOG_DEBUG (buffer);
232 #endif
233  }
234 
235  }
236 }
237 
238 
239 
240 
241 
242 //TransmitEnded: the CR stops transmitting, and starts sensing for PU detection
243 void
245 
246  int current_channel=m_repository->GetRxChannel(m_nodeId);
247 
248  // Perform sensing on the current channel
249  m_isPuOn= m_sensingMod->GetSenseResultsFuture(m_nodeId,m_senseTime,m_transmitTime, current_channel);
250 
251  // Set the sensing ON
252  m_isSensing=true;
253 
254 #ifdef SENSING_VERBOSE_MODE
255  char buffer [50];
256  std::sprintf(buffer, "[SENSING-DBG] Node %d starts sensing on channel %d",m_nodeId,current_channel);
257  NS_LOG_DEBUG (buffer);
258 #endif
259 
260  m_wifiPhy->StartSensing(m_senseTime);
261 
262 }
263 
264 
265 
266 
267 //HandoffEnded: the CR has performed spectrum handoff to a new channel. Then, it starts sensing on it to detect PU activity.
268 void
270 
271  int current_channel=m_repository->GetRxChannel(m_nodeId);
272 
273  // Perform sensing on the new channel
274  m_isPuOn = m_sensingMod->GetSenseResultsFuture(m_nodeId,m_senseTime,m_transmitTime, current_channel);
275  m_wifiPhy->StartSensing(m_senseTime);
276  m_isSensing = true;
277  //Do not disable m_isSwitching now. We do that after sensing concluded and no PU is there (for aodv to broadcast stuff)
278 
279 #ifdef SENSING_VERBOSE_MODE
280 
281  char buffer [50];
282  std::sprintf(buffer,"[SENSING-DBG] Node %d ends handoff on channel %d",m_nodeId,current_channel);
283  NS_LOG_DEBUG (buffer);
284  std::sprintf(buffer, "[SENSING-DBG] Node %d starts sensing on channel %d",m_nodeId,current_channel);
285  NS_LOG_DEBUG (buffer);
286 
287 #endif
288 
289 }
290 
291 }
292 
SpectrumManager(Ptr< RegularWifiMac > mac, int id)
keep track of time unit.
Definition: nstime.h:149
smart pointer class similar to boost::intrusive_ptr
Definition: ptr.h:59
void SetPuModel(double prob, Ptr< PUModel > p)
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Definition: simulator.h:820
virtual void StartSensing(Time duration)=0
Start sensing on current channel.
virtual void SetHandoffEndedCallback(HandoffEndedCallback callback)=0
bool IsPuInterfering(Time txDuration)
virtual void SetSenseEndedCallback(SnsEndedCallback callback)=0
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:502
Access to the Ipv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:75
virtual void SetChannelNumber(uint16_t id)=0
Set channel number.
void SetRepository(Ptr< Repository > rep)
#define NS_LOG_DEBUG(msg)
Definition: log.h:255
Ptr< T > GetObject(void) const
Definition: object.h:332