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  }
114  m_phy = 0;
116 }
117 
118 void
120 {
121  NS_LOG_FUNCTION (this << device);
123  std::vector<Ptr<WifiPhy> > phys = device->GetPhys ();
124  if (phys.size () > 1)
125  {
126  NS_LOG_WARN ("The class is only in the context of single-PHY device, while there are more than one PHY devices");
127  }
128  // since default channel scheduler is in the context of single-PHY, we only use one phy object.
129  m_phy = device->GetPhy (0);
131  m_coordinationListener = Create<CoordinationListener> (this);
133 }
134 
135 enum ChannelAccess
136 DefaultChannelScheduler::GetAssignedAccessType (uint32_t channelNumber) const
137 {
138  NS_LOG_FUNCTION (this << channelNumber);
139  if (m_channelAccess == AlternatingAccess && channelNumber == CCH)
140  {
141  return AlternatingAccess;
142  }
143  return (m_channelNumber == channelNumber) ? m_channelAccess : NoAccess;
144 }
145 
146 
147 bool
148 DefaultChannelScheduler::AssignAlternatingAccess (uint32_t channelNumber, bool immediate)
149 {
150  NS_LOG_FUNCTION (this << channelNumber << immediate);
152  uint32_t sch = channelNumber;
153 
155  {
156  return false;
157  }
158 
160  {
161  if (m_channelNumber != sch)
162  {
163  return false;
164  }
165  else
166  {
167  return true;
168  }
169  }
170 
171  // if we need immediately switch to AlternatingAccess,
172  // we switch to specific SCH.
173  if ((immediate && m_coordinator->IsSchInterval ()))
174  {
176  SwitchToNextChannel (CCH, sch);
177  }
178 
179  m_channelNumber = sch;
181  return true;
182 }
183 
184 bool
185 DefaultChannelScheduler::AssignContinuousAccess (uint32_t channelNumber, bool immediate)
186 {
187  NS_LOG_FUNCTION (this << channelNumber << immediate);
189  uint32_t sch = channelNumber;
191  {
192  return false;
193  }
194 
196  {
197  if (m_channelNumber != sch)
198  {
199  return false;
200  }
201  else
202  {
203  return true;
204  }
205  }
206 
207  // if there is already an wait event for previous non-immediate request
208  if (!m_waitEvent.IsExpired ())
209  {
210  if (m_waitChannelNumber != sch)
211  {
212  // then the coming new request will be rejected because of FCFS
213  return false;
214  }
215  else
216  {
217  if (!immediate)
218  {
219  return true;
220  }
221  // then cancel this wait event and assign access for request immediately
222  m_waitEvent.Cancel ();
223  }
224  }
225 
226  if (immediate || m_coordinator->IsSchInterval ())
227  {
229  m_channelNumber = sch;
231  }
232  else
233  {
236  m_waitChannelNumber = sch;
237  }
238 
239  return true;
240 }
241 
242 bool
243 DefaultChannelScheduler::AssignExtendedAccess (uint32_t channelNumber, uint32_t extends, bool immediate)
244 {
245  NS_LOG_FUNCTION (this << channelNumber << extends << immediate);
247  uint32_t sch = channelNumber;
249  {
250  return false;
251  }
252 
254  {
255  if (m_channelNumber != sch)
256  {
257  return false;
258  }
259  else
260  {
261  // if current remain extends cannot fulfill the requirement for extends
263  uint32_t remainExtends = (remainTime / m_coordinator->GetSyncInterval ()).GetHigh ();
264  if (remainExtends > extends)
265  {
266  return true;
267  }
268  else
269  {
270  return false;
271  }
272  }
273  }
274 
275  // if there is already an wait event for previous non-immediate request
276  if (!m_waitEvent.IsExpired ())
277  {
279  if (m_waitChannelNumber != sch)
280  {
281  // then the coming new request will be rejected because of FCFS
282  return false;
283  }
284  else
285  {
286  if (m_waitExtend < extends)
287  {
288  return false;
289  }
290 
291  if (immediate)
292  {
293  // then cancel previous wait event and
294  // go to below code to assign access for request immediately
295  m_waitEvent.Cancel ();
296  }
297  else
298  {
299  return true;
300  }
301  }
302  }
303 
304  if (immediate || m_coordinator->IsSchInterval ())
305  {
307  m_channelNumber = sch;
309  m_extend = extends;
310 
312  // the wait time to proper interval will not be calculated as extended time.
313  Time extendedDuration = m_coordinator->NeedTimeToCchInterval () + MilliSeconds (extends * sync.GetMilliSeconds ());
314  // after end_duration time, DefaultChannelScheduler will release channel access automatically
316  }
317  else
318  {
321  m_waitChannelNumber = sch;
322  m_waitExtend = extends;
323  }
324  return true;
325 }
326 
327 bool
329 {
330  NS_LOG_FUNCTION (this);
332  {
333  return true;
334  }
335  if (m_channelNumber != 0)
336  {
337  // This class does not support preemptive scheduling
338  NS_LOG_DEBUG ("channel access is already assigned for other SCHs, thus cannot assign default CCH access.");
339  return false;
340  }
341  // CCH MAC is to attach single-PHY device and wake up for transmission.
342  Ptr<OcbWifiMac> cchMacEntity = m_device->GetMac (CCH);
343  if (Now ().GetMilliSeconds() != 0)
344  {
346  Time switchTime = m_phy->GetChannelSwitchDelay ();
347  cchMacEntity->MakeVirtualBusy (switchTime);
348  }
349  cchMacEntity->SetWifiPhy (m_phy);
350  cchMacEntity->Resume ();
351 
355  return true;
356 }
357 
358 void
359 DefaultChannelScheduler::SwitchToNextChannel (uint32_t curChannelNumber, uint32_t nextChannelNumber)
360 {
361  NS_LOG_FUNCTION (this << curChannelNumber << curChannelNumber);
362  if (m_phy->GetChannelNumber () == nextChannelNumber)
363  {
364  return;
365  }
366  Ptr<OcbWifiMac> curMacEntity = m_device->GetMac (curChannelNumber);
367  Ptr<OcbWifiMac> nextMacEntity = m_device->GetMac (nextChannelNumber);
368  // Perfect channel switch operation among multiple MAC entities in the context of single PHY device.
369  // first make current MAC entity in sleep mode.
370  curMacEntity->Suspend ();
371  // second unattached current MAC entity from single PHY device
372  curMacEntity->ResetWifiPhy ();
373  // third switch PHY device from current channel to next channel;
375  // four attach next MAC entity to single PHY device
376  nextMacEntity->SetWifiPhy (m_phy);
377  // Here channel switch time is required to notify next MAC entity
378  // that channel access cannot be enabled in channel switch time.
379  Time switchTime = m_phy->GetChannelSwitchDelay ();
380  nextMacEntity->MakeVirtualBusy (switchTime);
381  // finally resume next MAC entity from sleep mode
382  nextMacEntity->Resume ();
383 }
384 
385 bool
387 {
388  NS_LOG_FUNCTION (this << channelNumber);
389  NS_ASSERT (m_channelNumber != 0);
390  if (m_channelNumber != channelNumber)
391  {
392  return false;
393  }
394  // cancel current SCH MAC activity and assigned default CCH access.
399  if (!m_waitEvent.IsExpired ())
400  {
401  m_waitEvent.Cancel ();
402  }
403  if (!m_extendEvent.IsExpired ())
404  {
406  }
408  m_waitExtend = 0;
409  return true;
410 }
411 
412 void
414 {
415  NS_LOG_FUNCTION (this << duration);
416 }
417 
418 void
420 {
421  NS_LOG_FUNCTION (this << duration);
422 }
423 
424 void
426 {
427  NS_LOG_FUNCTION (this << duration << cchi);
428  // only alternating access requires channel coordination events
430  {
431  return;
432  }
433 
434  if (cchi)
435  {
438  // see chapter 6.2.5 Sync tolerance
439  // a medium busy shall be declared during the guard interval.
440  mac->MakeVirtualBusy (duration);
441  }
442  else
443  {
446  // see chapter 6.2.5 Sync tolerance
447  // a medium busy shall be declared during the guard interval.
448  mac->MakeVirtualBusy (duration);
449  }
450 }
451 } // namespace ns3
#define CCH
#define EXTENDED_CONTINUOUS
receive notifications about channel coordination events.
Time NeedTimeToCchInterval(Time duration=Seconds(0.0)) const
bool IsSchInterval(Time duration=Seconds(0.0)) const
Time GetSyncInterval(void) const
Time NeedTimeToSchInterval(Time duration=Seconds(0.0)) const
void RegisterListener(Ptr< ChannelCoordinationListener > listener)
This class will assign channel access for requests from higher layers.
virtual void DoInitialize(void)
Initialize() implementation.
virtual void DoDispose(void)
Destructor implementation.
virtual void SetWaveNetDevice(Ptr< WaveNetDevice > device)
Ptr< WaveNetDevice > m_device
the device
CoordinationListener class.
CoordinationListener(DefaultChannelScheduler *scheduler)
Constructor.
virtual void NotifyCchSlotStart(Time duration)
DefaultChannelScheduler * m_scheduler
the scheduler
virtual void NotifyGuardSlotStart(Time duration, bool cchi)
virtual void NotifySchSlotStart(Time duration)
This class uses a simple mechanism to assign channel access with following features: (1) only in the ...
static TypeId GetTypeId(void)
Get the type ID.
virtual bool AssignDefaultCchAccess(void)
This method will assign default CCH access for CCH.
enum ChannelAccess m_channelAccess
channel access
virtual void DoInitialize(void)
Initialize() implementation.
virtual void DoDispose(void)
Destructor implementation.
virtual enum ChannelAccess GetAssignedAccessType(uint32_t channelNumber) const
void NotifyGuardSlotStart(Time duration, bool cchi)
Notify guard slot start.
void NotifyCchSlotStart(Time duration)
Notify CCH slot start.
void SwitchToNextChannel(uint32_t curChannelNumber, uint32_t nextChannelNumber)
Ptr< ChannelCoordinator > m_coordinator
channel coordinator
virtual bool AssignAlternatingAccess(uint32_t channelNumber, bool immediate)
virtual bool AssignContinuousAccess(uint32_t channelNumber, bool immediate)
virtual bool AssignExtendedAccess(uint32_t channelNumber, uint32_t extends, bool immediate)
void NotifySchSlotStart(Time duration)
Notify SCH slot start.
uint32_t m_channelNumber
when m_channelAccess is ContinuousAccess, m_channelNumber is continuous channel number; when m_channe...
uint32_t m_waitChannelNumber
wait channel number
Ptr< ChannelCoordinationListener > m_coordinationListener
coordination listener
virtual bool ReleaseAccess(uint32_t channelNumber)
virtual void SetWaveNetDevice(Ptr< WaveNetDevice > device)
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:53
bool IsExpired(void) const
This method is syntactic sugar for the ns3::Simulator::IsExpired method.
Definition: event-id.cc:65
void Suspend(void)
To support MAC extension for multiple channel operation, Suspend the activity in current MAC entity.
void MakeVirtualBusy(Time duration)
void Resume(void)
To support MAC extension for multiple channel operation, Resume the activity of suspended MAC entity.
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:556
static Time GetDelayLeft(const EventId &id)
Get the remaining time until this event will execute.
Definition: simulator.cc:204
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
int64_t GetMilliSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:383
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:922
Ptr< WifiPhy > GetPhy(uint32_t index) const
std::vector< Ptr< WifiPhy > > GetPhys(void) const
Ptr< ChannelCoordinator > GetChannelCoordinator(void) const
Ptr< OcbWifiMac > GetMac(uint32_t channelNumber) const
void ResetWifiPhy(void)
Remove currently attached WifiPhy device from this MAC.
Definition: wifi-mac.cc:783
virtual void SetWifiPhy(Ptr< WifiPhy > phy)
Definition: wifi-mac.cc:763
uint8_t GetChannelNumber(void) const
Return current channel number.
Definition: wifi-phy.cc:912
Time GetChannelSwitchDelay(void) const
Definition: wifi-phy.cc:624
void SetOperatingChannel(const ChannelTuple &channelTuple)
If the standard for this object has not been set yet, store the given channel settings.
Definition: wifi-phy.cc:930
std::tuple< uint8_t, uint16_t, int, uint8_t > ChannelTuple
Tuple identifying an operating channel.
Definition: wifi-phy.h:833
#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:205
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:265
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:287
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1252
@ WIFI_PHY_BAND_5GHZ
The 5 GHz band.
Definition: wifi-phy-band.h:37
Every class exported by the ns3 library is enclosed in the ns3 namespace.
ChannelAccess
ChannelAccess enumeration.
@ AlternatingAccess
@ ContinuousAccess
@ ExtendedAccess
@ DefaultCchAccess
mac
Definition: third.py:99