A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
wifi-radio-energy-model.cc
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2010 Network Security Lab, University of Washington, Seattle.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Sidharth Nabar <snabar@uw.edu>, He Wu <mdzz@u.washington.edu>
19  */
20 
21 #include "ns3/log.h"
22 #include "ns3/double.h"
23 #include "ns3/simulator.h"
24 #include "ns3/trace-source-accessor.h"
25 #include "energy-source.h"
26 #include "wifi-radio-energy-model.h"
27 
28 NS_LOG_COMPONENT_DEFINE ("WifiRadioEnergyModel");
29 
30 namespace ns3 {
31 
32 NS_OBJECT_ENSURE_REGISTERED (WifiRadioEnergyModel);
33 
34 TypeId
35 WifiRadioEnergyModel::GetTypeId (void)
36 {
37  static TypeId tid = TypeId ("ns3::WifiRadioEnergyModel")
38  .SetParent<DeviceEnergyModel> ()
39  .AddConstructor<WifiRadioEnergyModel> ()
40  .AddAttribute ("IdleCurrentA",
41  "The default radio Idle current in Ampere.",
42  DoubleValue (0.000426), // idle mode = 426uA
43  MakeDoubleAccessor (&WifiRadioEnergyModel::SetIdleCurrentA,
44  &WifiRadioEnergyModel::GetIdleCurrentA),
45  MakeDoubleChecker<double> ())
46  .AddAttribute ("CcaBusyCurrentA",
47  "The default radio CCA Busy State current in Ampere.",
48  DoubleValue (0.000426), // default to be the same as idle mode
49  MakeDoubleAccessor (&WifiRadioEnergyModel::SetCcaBusyCurrentA,
50  &WifiRadioEnergyModel::GetCcaBusyCurrentA),
51  MakeDoubleChecker<double> ())
52  .AddAttribute ("TxCurrentA",
53  "The radio Tx current in Ampere.",
54  DoubleValue (0.0174), // transmit at 0dBm = 17.4mA
55  MakeDoubleAccessor (&WifiRadioEnergyModel::SetTxCurrentA,
56  &WifiRadioEnergyModel::GetTxCurrentA),
57  MakeDoubleChecker<double> ())
58  .AddAttribute ("RxCurrentA",
59  "The radio Rx current in Ampere.",
60  DoubleValue (0.0197), // receive mode = 19.7mA
61  MakeDoubleAccessor (&WifiRadioEnergyModel::SetRxCurrentA,
62  &WifiRadioEnergyModel::GetRxCurrentA),
63  MakeDoubleChecker<double> ())
64  .AddAttribute ("SwitchingCurrentA",
65  "The default radio Channel Switch current in Ampere.",
66  DoubleValue (0.000426), // default to be the same as idle mode
67  MakeDoubleAccessor (&WifiRadioEnergyModel::SetSwitchingCurrentA,
68  &WifiRadioEnergyModel::GetSwitchingCurrentA),
69  MakeDoubleChecker<double> ())
70  .AddTraceSource ("TotalEnergyConsumption",
71  "Total energy consumption of the radio device.",
72  MakeTraceSourceAccessor (&WifiRadioEnergyModel::m_totalEnergyConsumption))
73  ;
74  return tid;
75 }
76 
77 WifiRadioEnergyModel::WifiRadioEnergyModel ()
78 {
79  NS_LOG_FUNCTION (this);
80  m_currentState = WifiPhy::IDLE; // initially IDLE
81  m_lastUpdateTime = Seconds (0.0);
82  m_energyDepletionCallback.Nullify ();
83  m_source = NULL;
84  // set callback for WifiPhy listener
85  m_listener = new WifiRadioEnergyModelPhyListener;
87 }
88 
89 WifiRadioEnergyModel::~WifiRadioEnergyModel ()
90 {
91  NS_LOG_FUNCTION (this);
92  delete m_listener;
93 }
94 
95 void
97 {
98  NS_LOG_FUNCTION (this << source);
99  NS_ASSERT (source != NULL);
100  m_source = source;
101 }
102 
103 double
105 {
106  NS_LOG_FUNCTION (this);
107  return m_totalEnergyConsumption;
108 }
109 
110 double
111 WifiRadioEnergyModel::GetIdleCurrentA (void) const
112 {
113  NS_LOG_FUNCTION (this);
114  return m_idleCurrentA;
115 }
116 
117 void
118 WifiRadioEnergyModel::SetIdleCurrentA (double idleCurrentA)
119 {
120  NS_LOG_FUNCTION (this << idleCurrentA);
121  m_idleCurrentA = idleCurrentA;
122 }
123 
124 double
125 WifiRadioEnergyModel::GetCcaBusyCurrentA (void) const
126 {
127  NS_LOG_FUNCTION (this);
128  return m_ccaBusyCurrentA;
129 }
130 
131 void
132 WifiRadioEnergyModel::SetCcaBusyCurrentA (double CcaBusyCurrentA)
133 {
134  NS_LOG_FUNCTION (this << CcaBusyCurrentA);
135  m_ccaBusyCurrentA = CcaBusyCurrentA;
136 }
137 
138 double
139 WifiRadioEnergyModel::GetTxCurrentA (void) const
140 {
141  NS_LOG_FUNCTION (this);
142  return m_txCurrentA;
143 }
144 
145 void
146 WifiRadioEnergyModel::SetTxCurrentA (double txCurrentA)
147 {
148  NS_LOG_FUNCTION (this << txCurrentA);
149  m_txCurrentA = txCurrentA;
150 }
151 
152 double
153 WifiRadioEnergyModel::GetRxCurrentA (void) const
154 {
155  NS_LOG_FUNCTION (this);
156  return m_rxCurrentA;
157 }
158 
159 void
160 WifiRadioEnergyModel::SetRxCurrentA (double rxCurrentA)
161 {
162  NS_LOG_FUNCTION (this << rxCurrentA);
163  m_rxCurrentA = rxCurrentA;
164 }
165 
166 double
167 WifiRadioEnergyModel::GetSwitchingCurrentA (void) const
168 {
169  NS_LOG_FUNCTION (this);
170  return m_switchingCurrentA;
171 }
172 
173 void
174 WifiRadioEnergyModel::SetSwitchingCurrentA (double switchingCurrentA)
175 {
176  NS_LOG_FUNCTION (this << switchingCurrentA);
177  m_switchingCurrentA = switchingCurrentA;
178 }
179 
180 
183 {
184  NS_LOG_FUNCTION (this);
185  return m_currentState;
186 }
187 
188 void
191 {
192  NS_LOG_FUNCTION (this);
193  if (callback.IsNull ())
194  {
195  NS_LOG_DEBUG ("WifiRadioEnergyModel:Setting NULL energy depletion callback!");
196  }
197  m_energyDepletionCallback = callback;
198 }
199 
200 void
202 {
203  NS_LOG_FUNCTION (this << newState);
204 
205  Time duration = Simulator::Now () - m_lastUpdateTime;
206  NS_ASSERT (duration.GetNanoSeconds () >= 0); // check if duration is valid
207 
208  // energy to decrease = current * voltage * time
209  double energyToDecrease = 0.0;
210  double supplyVoltage = m_source->GetSupplyVoltage ();
211  switch (m_currentState)
212  {
213  case WifiPhy::IDLE:
214  energyToDecrease = duration.GetSeconds () * m_idleCurrentA * supplyVoltage;
215  break;
216  case WifiPhy::CCA_BUSY:
217  energyToDecrease = duration.GetSeconds () * m_ccaBusyCurrentA * supplyVoltage;
218  break;
219  case WifiPhy::TX:
220  energyToDecrease = duration.GetSeconds () * m_txCurrentA * supplyVoltage;
221  break;
222  case WifiPhy::RX:
223  energyToDecrease = duration.GetSeconds () * m_rxCurrentA * supplyVoltage;
224  break;
225  case WifiPhy::SWITCHING:
226  energyToDecrease = duration.GetSeconds () * m_switchingCurrentA * supplyVoltage;
227  break;
228  default:
229  NS_FATAL_ERROR ("WifiRadioEnergyModel:Undefined radio state: " << m_currentState);
230  }
231 
232  // update total energy consumption
233  m_totalEnergyConsumption += energyToDecrease;
234 
235  // update last update time stamp
236  m_lastUpdateTime = Simulator::Now ();
237 
238  // notify energy source
239  m_source->UpdateEnergySource ();
240 
241  // update current state & last update time stamp
242  SetWifiRadioState ((WifiPhy::State) newState);
243 
244  // some debug message
245  NS_LOG_DEBUG ("WifiRadioEnergyModel:Total energy consumption is " <<
246  m_totalEnergyConsumption << "J");
247 }
248 
249 void
251 {
252  NS_LOG_FUNCTION (this);
253  NS_LOG_DEBUG ("WifiRadioEnergyModel:Energy is depleted!");
254  // invoke energy depletion callback, if set.
255  if (!m_energyDepletionCallback.IsNull ())
256  {
257  m_energyDepletionCallback ();
258  }
259 }
260 
263 {
264  NS_LOG_FUNCTION (this);
265  return m_listener;
266 }
267 
268 /*
269  * Private functions start here.
270  */
271 
272 void
274 {
275  NS_LOG_FUNCTION (this);
276  m_source = NULL;
277  m_energyDepletionCallback.Nullify ();
278 }
279 
280 double
282 {
283  NS_LOG_FUNCTION (this);
284  switch (m_currentState)
285  {
286  case WifiPhy::IDLE:
287  return m_idleCurrentA;
288  case WifiPhy::CCA_BUSY:
289  return m_ccaBusyCurrentA;
290  case WifiPhy::TX:
291  return m_txCurrentA;
292  case WifiPhy::RX:
293  return m_rxCurrentA;
294  case WifiPhy::SWITCHING:
295  return m_switchingCurrentA;
296  default:
297  NS_FATAL_ERROR ("WifiRadioEnergyModel:Undefined radio state:" << m_currentState);
298  }
299 }
300 
301 void
303 {
304  NS_LOG_FUNCTION (this << state);
305  m_currentState = state;
306  std::string stateName;
307  switch (state)
308  {
309  case WifiPhy::IDLE:
310  stateName = "IDLE";
311  break;
312  case WifiPhy::CCA_BUSY:
313  stateName = "CCA_BUSY";
314  break;
315  case WifiPhy::TX:
316  stateName = "TX";
317  break;
318  case WifiPhy::RX:
319  stateName = "RX";
320  break;
321  case WifiPhy::SWITCHING:
322  stateName = "SWITCHING";
323  break;
324  case WifiPhy::SENSING:
325  stateName = "SENSING";
326  break;
327  }
328  NS_LOG_DEBUG ("WifiRadioEnergyModel:Switching to state: " << stateName <<
329  " at time = " << Simulator::Now ());
330 }
331 
332 // -------------------------------------------------------------------------- //
333 
334 WifiRadioEnergyModelPhyListener::WifiRadioEnergyModelPhyListener ()
335 {
336  NS_LOG_FUNCTION (this);
337  m_changeStateCallback.Nullify ();
338 }
339 
340 WifiRadioEnergyModelPhyListener::~WifiRadioEnergyModelPhyListener ()
341 {
342  NS_LOG_FUNCTION (this);
343 }
344 
345 void
347 {
348  NS_LOG_FUNCTION (this << &callback);
349  NS_ASSERT (!callback.IsNull ());
350  m_changeStateCallback = callback;
351 }
352 
353 void
355 {
356  NS_LOG_FUNCTION (this << duration);
357  if (m_changeStateCallback.IsNull ())
358  {
359  NS_FATAL_ERROR ("WifiRadioEnergyModelPhyListener:Change state callback not set!");
360  }
362  m_switchToIdleEvent.Cancel ();
363 }
364 
365 void
367 {
368  NS_LOG_FUNCTION (this);
369  if (m_changeStateCallback.IsNull ())
370  {
371  NS_FATAL_ERROR ("WifiRadioEnergyModelPhyListener:Change state callback not set!");
372  }
374 }
375 
376 void
378 {
379  NS_LOG_FUNCTION (this);
380  if (m_changeStateCallback.IsNull ())
381  {
382  NS_FATAL_ERROR ("WifiRadioEnergyModelPhyListener:Change state callback not set!");
383  }
385 }
386 
387 void
389 {
390  NS_LOG_FUNCTION (this << duration);
391  if (m_changeStateCallback.IsNull ())
392  {
393  NS_FATAL_ERROR ("WifiRadioEnergyModelPhyListener:Change state callback not set!");
394  }
396  // schedule changing state back to IDLE after TX duration
397  m_switchToIdleEvent.Cancel ();
398  m_switchToIdleEvent = Simulator::Schedule (duration, &WifiRadioEnergyModelPhyListener::SwitchToIdle, this);
399 }
400 
401 void
403 {
404  NS_LOG_FUNCTION (this << duration);
405  if (m_changeStateCallback.IsNull ())
406  {
407  NS_FATAL_ERROR ("WifiRadioEnergyModelPhyListener:Change state callback not set!");
408  }
410  // schedule changing state back to IDLE after CCA_BUSY duration
411  m_switchToIdleEvent.Cancel ();
412  m_switchToIdleEvent = Simulator::Schedule (duration, &WifiRadioEnergyModelPhyListener::SwitchToIdle, this);
413 }
414 
415 void
417 {
418  NS_LOG_FUNCTION (this << duration);
419  if (m_changeStateCallback.IsNull ())
420  {
421  NS_FATAL_ERROR ("WifiRadioEnergyModelPhyListener:Change state callback not set!");
422  }
424  // schedule changing state back to IDLE after CCA_BUSY duration
425  m_switchToIdleEvent.Cancel ();
426  m_switchToIdleEvent = Simulator::Schedule (duration, &WifiRadioEnergyModelPhyListener::SwitchToIdle, this);
427 }
428 
429 void
431 {
432  NS_LOG_FUNCTION (this << duration);
433  if (m_changeStateCallback.IsNull ())
434  {
435  NS_FATAL_ERROR ("WifiRadioEnergyModelPhyListener:Change state callback not set!");
436  }
438  // schedule changing state back to IDLE after CCA_BUSY duration
439  m_switchToIdleEvent.Cancel ();
440  m_switchToIdleEvent = Simulator::Schedule (duration, &WifiRadioEnergyModelPhyListener::SwitchToIdle, this);
441 }
442 
443 /*
444  * Private function state here.
445  */
446 
447 void
449 {
450  NS_LOG_FUNCTION (this);
451  if (m_changeStateCallback.IsNull ())
452  {
453  NS_FATAL_ERROR ("WifiRadioEnergyModelPhyListener:Change state callback not set!");
454  }
456 }
457 
458 } // namespace ns3
virtual void NotifySwitchingStart(Time duration, uint16_t toChannel)
void SetWifiRadioState(const WifiPhy::State state)
keep track of time unit.
Definition: nstime.h:149
smart pointer class similar to boost::intrusive_ptr
Definition: ptr.h:59
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
#define NS_ASSERT(condition)
Definition: assert.h:64
virtual void NotifySensingStart(Time duration)
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
virtual void ChangeState(int newState)
Changes state of the WifiRadioEnergyMode.
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Definition: simulator.h:820
virtual double GetTotalEnergyConsumption(void) const
virtual void NotifyTxStart(Time duration)
Switches the WifiRadioEnergyModel to TX state and switches back to IDLE after TX duration.
WifiRadioEnergyModelPhyListener * GetPhyListener(void)
virtual void NotifyRxEndOk(void)
Switches the WifiRadioEnergyModel back to IDLE state.
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72
double GetSeconds(void) const
Definition: nstime.h:262
void SetChangeStateCallback(DeviceEnergyModel::ChangeStateCallback callback)
Sets the change state callback. Used by helper class.
virtual void NotifyMaybeCcaBusyStart(Time duration)
virtual void NotifyRxEndError(void)
Switches the WifiRadioEnergyModel back to IDLE state.
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:502
WifiPhy::State GetCurrentState(void) const
DeviceEnergyModel::ChangeStateCallback m_changeStateCallback
virtual void SetEnergySource(Ptr< EnergySource > source)
Sets pointer to EnergySouce installed on node.
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
static Time Now(void)
Definition: simulator.cc:179
virtual void NotifyRxStart(Time duration)
Switches the WifiRadioEnergyModel to RX state.
int64_t GetNanoSeconds(void) const
Definition: nstime.h:287
void SetEnergyDepletionCallback(WifiRadioEnergyDepletionCallback callback)
Time Seconds(double seconds)
create ns3::Time instances in units of seconds.
Definition: nstime.h:586
#define NS_LOG_DEBUG(msg)
Definition: log.h:255
void Cancel(void)
Definition: event-id.cc:47
virtual void ChangeState(int newState)=0
virtual double DoGetCurrentA(void) const
virtual void HandleEnergyDepletion(void)
Handles energy depletion.