A Discrete-Event Network Simulator
API
default-channel-scheduler.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License version 2 as
5  * published by the Free Software Foundation;
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software
14  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15  *
16  * Author: Junling Bu <linlinjavaer@gmail.com>
17  */
19 #include "ns3/log.h"
20 #include "ns3/simulator.h"
21 #include "ns3/wifi-phy.h"
22 
23 namespace ns3 {
24 
25 NS_LOG_COMPONENT_DEFINE ("DefaultChannelScheduler");
26 
27 NS_OBJECT_ENSURE_REGISTERED (DefaultChannelScheduler);
28 
34 {
35 public:
42  : m_scheduler (scheduler)
43  {
44  }
46  {
47  }
48  virtual void NotifyCchSlotStart (Time duration)
49  {
50  m_scheduler->NotifyCchSlotStart (duration);
51  }
52  virtual void NotifySchSlotStart (Time duration)
53  {
54  m_scheduler->NotifySchSlotStart (duration);
55  }
56  virtual void NotifyGuardSlotStart (Time duration, bool cchi)
57  {
58  m_scheduler->NotifyGuardSlotStart (duration, cchi);
59  }
60 private:
62 };
63 
64 TypeId
66 {
67  static TypeId tid = TypeId ("ns3::DefaultChannelScheduler")
69  .SetGroupName ("Wave")
70  .AddConstructor<DefaultChannelScheduler> ()
71  ;
72  return tid;
73 }
74 
76  : m_channelNumber (0),
77  m_extend (EXTENDED_CONTINUOUS),
78  m_channelAccess (NoAccess),
79  m_waitChannelNumber (0),
80  m_waitExtend (0),
81  m_coordinationListener (0)
82 {
83  NS_LOG_FUNCTION (this);
84 }
86 {
87  NS_LOG_FUNCTION (this);
88 }
89 
90 void
92 {
93  NS_LOG_FUNCTION (this);
95 }
96 
97 void
99 {
100  NS_LOG_FUNCTION (this);
101  m_coordinator = 0;
102  if (m_coordinationListener != 0)
103  {
105  }
106  if (!m_waitEvent.IsExpired ())
107  {
108  m_waitEvent.Cancel ();
109  }
110  if (!m_extendEvent.IsExpired ())
111  {
112  m_waitEvent.Cancel ();
113  }
115 }
116 
117 void
119 {
120  NS_LOG_FUNCTION (this << device);
122  std::vector<Ptr<WifiPhy> > phys = device->GetPhys ();
123  if (phys.size () > 1)
124  {
125  NS_LOG_WARN ("The class is only in the context of single-PHY device, while there are more than one PHY devices");
126  }
127  // since default channel scheduler is in the context of single-PHY, we only use one phy object.
128  m_phy = device->GetPhy (0);
130  m_coordinationListener = Create<CoordinationListener> (this);
132 }
133 
134 enum ChannelAccess
136 {
137  NS_LOG_FUNCTION (this << channelNumber);
138  if (m_channelAccess == AlternatingAccess && channelNumber == CCH)
139  {
140  return AlternatingAccess;
141  }
142  return (m_channelNumber == channelNumber) ? m_channelAccess : NoAccess;
143 }
144 
145 
146 bool
147 DefaultChannelScheduler::AssignAlternatingAccess (uint32_t channelNumber, bool immediate)
148 {
149  NS_LOG_FUNCTION (this << channelNumber << immediate);
151  uint32_t sch = channelNumber;
152 
154  {
155  return false;
156  }
157 
159  {
160  if (m_channelNumber != sch)
161  {
162  return false;
163  }
164  else
165  {
166  return true;
167  }
168  }
169 
170  // if we need immediately switch to AlternatingAccess,
171  // we switch to specific SCH.
172  if ((immediate && m_coordinator->IsSchInterval ()))
173  {
175  SwitchToNextChannel (CCH, sch);
176  }
177 
178  m_channelNumber = sch;
180  return true;
181 }
182 
183 bool
184 DefaultChannelScheduler::AssignContinuousAccess (uint32_t channelNumber, bool immediate)
185 {
186  NS_LOG_FUNCTION (this << channelNumber << immediate);
188  uint32_t sch = channelNumber;
190  {
191  return false;
192  }
193 
195  {
196  if (m_channelNumber != sch)
197  {
198  return false;
199  }
200  else
201  {
202  return true;
203  }
204  }
205 
206  // if there is already an wait event for previous non-immediate request
207  if (!m_waitEvent.IsExpired ())
208  {
209  if (m_waitChannelNumber != sch)
210  {
211  // then the coming new request will be rejected because of FCFS
212  return false;
213  }
214  else
215  {
216  if (!immediate)
217  {
218  return true;
219  }
220  // then cancel this wait event and assign access for request immediately
221  m_waitEvent.Cancel ();
222  }
223  }
224 
225  if (immediate || m_coordinator->IsSchInterval ())
226  {
228  m_channelNumber = sch;
230  }
231  else
232  {
235  m_waitChannelNumber = sch;
236  }
237 
238  return true;
239 }
240 
241 bool
242 DefaultChannelScheduler::AssignExtendedAccess (uint32_t channelNumber, uint32_t extends, bool immediate)
243 {
244  NS_LOG_FUNCTION (this << channelNumber << extends << immediate);
246  uint32_t sch = channelNumber;
248  {
249  return false;
250  }
251 
253  {
254  if (m_channelNumber != sch)
255  {
256  return false;
257  }
258  else
259  {
260  // if current remain extends cannot fulfill the requirement for extends
262  uint32_t remainExtends = (remainTime / m_coordinator->GetSyncInterval ()).GetHigh ();
263  if (remainExtends > extends)
264  {
265  return true;
266  }
267  else
268  {
269  return false;
270  }
271  }
272  }
273 
274  // if there is already an wait event for previous non-immediate request
275  if (!m_waitEvent.IsExpired ())
276  {
278  if (m_waitChannelNumber != sch)
279  {
280  // then the coming new request will be rejected because of FCFS
281  return false;
282  }
283  else
284  {
285  if (m_waitExtend < extends)
286  {
287  return false;
288  }
289 
290  if (immediate)
291  {
292  // then cancel previous wait event and
293  // go to below code to assign access for request immediately
294  m_waitEvent.Cancel ();
295  }
296  else
297  {
298  return true;
299  }
300  }
301  }
302 
303  if (immediate || m_coordinator->IsSchInterval ())
304  {
306  m_channelNumber = sch;
308  m_extend = extends;
309 
311  // the wait time to proper interval will not be calculated as extended time.
312  Time extendedDuration = m_coordinator->NeedTimeToCchInterval () + MilliSeconds (extends * sync.GetMilliSeconds ());
313  // after end_duration time, DefaultChannelScheduler will release channel access automatically
315  }
316  else
317  {
320  m_waitChannelNumber = sch;
321  m_waitExtend = extends;
322  }
323  return true;
324 }
325 
326 bool
328 {
329  NS_LOG_FUNCTION (this);
331  {
332  return true;
333  }
334  if (m_channelNumber != 0)
335  {
336  // This class does not support preemptive scheduling
337  NS_LOG_DEBUG ("channel access is already assigned for other SCHs, thus cannot assign default CCH access.");
338  return false;
339  }
340  // CCH MAC is to attach single-PHY device and wake up for transmission.
341  Ptr<OcbWifiMac> cchMacEntity = m_device->GetMac (CCH);
342  if (Now ().GetMilliSeconds() != 0)
343  {
345  Time switchTime = m_phy->GetChannelSwitchDelay ();
346  cchMacEntity->MakeVirtualBusy (switchTime);
347  }
348  cchMacEntity->SetWifiPhy (m_phy);
349  cchMacEntity->Resume ();
350 
354  return true;
355 }
356 
357 void
358 DefaultChannelScheduler::SwitchToNextChannel (uint32_t curChannelNumber, uint32_t nextChannelNumber)
359 {
360  NS_LOG_FUNCTION (this << curChannelNumber << curChannelNumber);
361  if (m_phy->GetChannelNumber () == nextChannelNumber)
362  {
363  return;
364  }
365  Ptr<OcbWifiMac> curMacEntity = m_device->GetMac (curChannelNumber);
366  Ptr<OcbWifiMac> nextMacEntity = m_device->GetMac (nextChannelNumber);
367  // Perfect channel switch operation among multiple MAC entities in the context of single PHY device.
368  // first make current MAC entity in sleep mode.
369  curMacEntity->Suspend ();
370  // second unattached current MAC entity from single PHY device
371  curMacEntity->ResetWifiPhy ();
372  // third switch PHY device from current channel to next channel;
373  m_phy->SetChannelNumber (nextChannelNumber);
374  // Here channel switch time is required to notify next MAC entity
375  // that channel access cannot be enabled in channel switch time.
376  Time switchTime = m_phy->GetChannelSwitchDelay ();
377  nextMacEntity->MakeVirtualBusy (switchTime);
378  // four attach next MAC entity to single PHY device
379  nextMacEntity->SetWifiPhy (m_phy);
380  // finally resume next MAC entity from sleep mode
381  nextMacEntity->Resume ();
382 }
383 
384 bool
386 {
387  NS_LOG_FUNCTION (this << channelNumber);
388  NS_ASSERT (m_channelNumber != 0);
389  if (m_channelNumber != channelNumber)
390  {
391  return false;
392  }
393  // cancel current SCH MAC activity and assigned default CCH access.
398  if (!m_waitEvent.IsExpired ())
399  {
400  m_waitEvent.Cancel ();
401  }
402  if (!m_extendEvent.IsExpired ())
403  {
405  }
407  m_waitExtend = 0;
408  return true;
409 }
410 
411 void
413 {
414  NS_LOG_FUNCTION (this << duration);
415 }
416 
417 void
419 {
420  NS_LOG_FUNCTION (this << duration);
421 }
422 
423 void
425 {
426  NS_LOG_FUNCTION (this << duration << cchi);
427  // only alternating access requires channel coordination events
429  {
430  return;
431  }
432 
433  if (cchi)
434  {
437  // see chapter 6.2.5 Sync tolerance
438  // a medium busy shall be declared during the guard interval.
439  mac->MakeVirtualBusy (duration);
440  }
441  else
442  {
445  // see chapter 6.2.5 Sync tolerance
446  // a medium busy shall be declared during the guard interval.
447  mac->MakeVirtualBusy (duration);
448  }
449 }
450 } // namespace ns3
static Time GetDelayLeft(const EventId &id)
Get the remaining time until this event will execute.
Definition: simulator.cc:202
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
CoordinationListener(DefaultChannelScheduler *scheduler)
Constructor.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
Time NeedTimeToCchInterval(Time duration=Seconds(0.0)) const
virtual void DoDispose(void)
Destructor implementation.
CoordinationListener class.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
uint32_t m_waitChannelNumber
wait channel number
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:204
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1070
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:346
#define CCH
bool IsExpired(void) const
This method is syntactic sugar for the ns3::Simulator::IsExpired method.
Definition: event-id.cc:59
virtual void DoInitialize(void)
Initialize() implementation.
virtual void NotifyGuardSlotStart(Time duration, bool cchi)
Ptr< WifiPhy > GetPhy(uint32_t index) const
virtual void SetWaveNetDevice(Ptr< WaveNetDevice > device)
virtual enum ChannelAccess GetAssignedAccessType(uint32_t channelNumber) const
DefaultChannelScheduler * m_scheduler
the scheduler
static EventId Schedule(Time const &delay, MEM mem_ptr, OBJ obj)
Schedule an event to expire after delay.
Definition: simulator.h:1389
static TypeId GetTypeId(void)
Get the type ID.
void NotifySchSlotStart(Time duration)
Notify SCH slot start.
void RegisterListener(Ptr< ChannelCoordinationListener > listener)
mac
Definition: third.py:99
void Suspend(void)
To support MAC extension for multiple channel operation, Suspend the activity in current MAC entity...
virtual void SetWaveNetDevice(Ptr< WaveNetDevice > device)
void MakeVirtualBusy(Time duration)
#define EXTENDED_CONTINUOUS
void ResetWifiPhy(void)
removes attached WifiPhy device from this MAC.
virtual void DoInitialize(void)
Initialize() implementation.
virtual void NotifySchSlotStart(Time duration)
virtual bool AssignDefaultCchAccess(void)
This method will assign default CCH access for CCH.
Ptr< ChannelCoordinator > GetChannelCoordinator(void) const
This class uses a simple mechanism to assign channel access with following features: (1) only in the ...
Time GetChannelSwitchDelay(void) const
Definition: wifi-phy.cc:812
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< ChannelCoordinator > m_coordinator
channel coordinator
void NotifyGuardSlotStart(Time duration, bool cchi)
Notify guard slot start.
virtual bool AssignAlternatingAccess(uint32_t channelNumber, bool immediate)
enum ChannelAccess m_channelAccess
channel access
virtual void SetChannelNumber(uint8_t id)
Set channel number.
Definition: wifi-phy.cc:1455
ChannelAccess
ChannelAccess enumeration.
virtual bool ReleaseAccess(uint32_t channelNumber)
uint8_t GetChannelNumber(void) const
Return current channel number.
Definition: wifi-phy.cc:1509
Ptr< OcbWifiMac > GetMac(uint32_t channelNumber) const
Ptr< WaveNetDevice > m_device
the device
void NotifyCchSlotStart(Time duration)
Notify CCH slot start.
virtual void NotifyCchSlotStart(Time duration)
bool IsSchInterval(Time duration=Seconds(0.0)) const
Ptr< ChannelCoordinationListener > m_coordinationListener
coordination listener
uint32_t m_channelNumber
when m_channelAccess is ContinuousAccess, m_channelNumber is continuous channel number; when m_channe...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:264
int64_t GetMilliSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:359
receive notifications about channel coordination events.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:272
Time NeedTimeToSchInterval(Time duration=Seconds(0.0)) const
virtual bool AssignContinuousAccess(uint32_t channelNumber, bool immediate)
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:53
virtual bool AssignExtendedAccess(uint32_t channelNumber, uint32_t extends, bool immediate)
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:309
std::vector< Ptr< WifiPhy > > GetPhys(void) const
Time GetSyncInterval(void) const
a unique identifier for an interface.
Definition: type-id.h:58
virtual void SetWifiPhy(const Ptr< WifiPhy > phy)
void Resume(void)
To support MAC extension for multiple channel operation, Resume the activity of suspended MAC entity...
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:915
This class will assign channel access for requests from higher layers.
void SwitchToNextChannel(uint32_t curChannelNumber, uint32_t nextChannelNumber)