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 
22 namespace ns3 {
23 
24 NS_LOG_COMPONENT_DEFINE ("DefaultChannelScheduler");
25 
26 NS_OBJECT_ENSURE_REGISTERED (DefaultChannelScheduler);
27 
29 {
30 public:
32  : m_scheduler (scheduler)
33  {
34  }
36  {
37  }
38  virtual void NotifyCchSlotStart (Time duration)
39  {
40  m_scheduler->NotifyCchSlotStart (duration);
41  }
42  virtual void NotifySchSlotStart (Time duration)
43  {
44  m_scheduler->NotifySchSlotStart (duration);
45  }
46  virtual void NotifyGuardSlotStart (Time duration, bool cchi)
47  {
48  m_scheduler->NotifyGuardSlotStart (duration, cchi);
49  }
50 private:
52 };
53 
54 TypeId
56 {
57  static TypeId tid = TypeId ("ns3::DefaultChannelScheduler")
59  .SetGroupName ("Wave")
60  .AddConstructor<DefaultChannelScheduler> ()
61  ;
62  return tid;
63 }
64 
66  : m_channelNumber (0),
67  m_extend (EXTENDED_CONTINUOUS),
68  m_channelAccess (NoAccess),
69  m_waitChannelNumber (0),
70  m_waitExtend (0),
71  m_coordinationListener (0)
72 {
73  NS_LOG_FUNCTION (this);
74 }
76 {
77  NS_LOG_FUNCTION (this);
78 }
79 
80 void
82 {
83  NS_LOG_FUNCTION (this);
85 }
86 
87 void
89 {
90  NS_LOG_FUNCTION (this);
91  m_coordinator = 0;
92  if (m_coordinationListener != 0)
93  {
95  }
96  if (!m_waitEvent.IsExpired ())
97  {
99  }
100  if (!m_extendEvent.IsExpired ())
101  {
102  m_waitEvent.Cancel ();
103  }
105 }
106 
107 void
109 {
110  NS_LOG_FUNCTION (this << device);
112  std::vector<Ptr<WifiPhy> > phys = device->GetPhys ();
113  if (phys.size () > 1)
114  {
115  NS_LOG_WARN ("The class is only in the context of single-PHY device, while there are more than one PHY devices");
116  }
117  // since default channel scheduler is in the context of single-PHY, we only use one phy object.
118  m_phy = device->GetPhy (0);
120  m_coordinationListener = Create<CoordinationListener> (this);
122 }
123 
124 enum ChannelAccess
126 {
127  NS_LOG_FUNCTION (this << channelNumber);
128  if (m_channelAccess == AlternatingAccess && channelNumber == CCH)
129  {
130  return AlternatingAccess;
131  }
132  return (m_channelNumber == channelNumber) ? m_channelAccess : NoAccess;
133 }
134 
135 
136 bool
137 DefaultChannelScheduler::AssignAlternatingAccess (uint32_t channelNumber, bool immediate)
138 {
139  NS_LOG_FUNCTION (this << channelNumber << immediate);
141  uint32_t sch = channelNumber;
142 
144  {
145  return false;
146  }
147 
149  {
150  if (m_channelNumber != sch)
151  {
152  return false;
153  }
154  else
155  {
156  return true;
157  }
158  }
159 
160  // if we need immediately switch SCH in CCHI, or we are in SCHI now,
161  // we switch to specific SCH.
162  if ((immediate || m_coordinator->IsSchInterval ()))
163  {
165  SwitchToNextChannel (CCH, sch);
166  }
167 
168  m_channelNumber = sch;
170  return true;
171 }
172 
173 bool
174 DefaultChannelScheduler::AssignContinuousAccess (uint32_t channelNumber, bool immediate)
175 {
176  NS_LOG_FUNCTION (this << channelNumber << immediate);
178  uint32_t sch = channelNumber;
180  {
181  return false;
182  }
183 
185  {
186  if (m_channelNumber != sch)
187  {
188  return false;
189  }
190  else
191  {
192  return true;
193  }
194  }
195 
196  // if there is already an wait event for previous non-immediate request
197  if (!m_waitEvent.IsExpired ())
198  {
199  if (m_waitChannelNumber != sch)
200  {
201  // then the coming new request will be rejected because of FCFS
202  return false;
203  }
204  else
205  {
206  if (!immediate)
207  {
208  return true;
209  }
210  // then cancel this wait event and assign access for request immediately
211  m_waitEvent.Cancel ();
212  }
213  }
214 
215  if (immediate || m_coordinator->IsSchInterval ())
216  {
218  m_channelNumber = sch;
220  }
221  else
222  {
225  m_waitChannelNumber = sch;
226  }
227 
228  return true;
229 }
230 
231 bool
232 DefaultChannelScheduler::AssignExtendedAccess (uint32_t channelNumber, uint32_t extends, bool immediate)
233 {
234  NS_LOG_FUNCTION (this << channelNumber << extends << immediate);
236  uint32_t sch = channelNumber;
238  {
239  return false;
240  }
241 
243  {
244  if (m_channelNumber != sch)
245  {
246  return false;
247  }
248  else
249  {
250  // if current remain extends cannot fulfill the requirement for extends
252  uint32_t remainExtends = remainTime / m_coordinator->GetSyncInterval ();
253  if (remainExtends > extends)
254  {
255  return true;
256  }
257  else
258  {
259  return false;
260  }
261  }
262  }
263 
264  // if there is already an wait event for previous non-immediate request
265  if (!m_waitEvent.IsExpired ())
266  {
268  if (m_waitChannelNumber != sch)
269  {
270  // then the coming new request will be rejected because of FCFS
271  return false;
272  }
273  else
274  {
275  if (m_waitExtend < extends)
276  {
277  return false;
278  }
279 
280  if (immediate)
281  {
282  // then cancel previous wait event and
283  // go to below code to assign access for request immediately
284  m_waitEvent.Cancel ();
285  }
286  else
287  {
288  return true;
289  }
290  }
291  }
292 
293  if (immediate || m_coordinator->IsSchInterval ())
294  {
296  m_channelNumber = sch;
298  m_extend = extends;
299 
301  // the wait time to proper interval will not be calculated as extended time.
302  Time extendedDuration = m_coordinator->NeedTimeToCchInterval () + MilliSeconds (extends * sync.GetMilliSeconds ());
303  // after end_duration time, DefaultChannelScheduler will release channel access automatically
305  }
306  else
307  {
310  m_waitChannelNumber = sch;
311  m_waitExtend = extends;
312  }
313  return true;
314 }
315 
316 bool
318 {
319  NS_LOG_FUNCTION (this);
321  {
322  return true;
323  }
324  if (m_channelNumber != 0)
325  {
326  // This class does not support preemptive scheduling
327  NS_LOG_DEBUG ("channel access is already assigned for other SCHs, thus cannot assign default CCH access.");
328  return false;
329  }
330  // CCH MAC is to attach single-PHY device and wake up for transmission.
331  Ptr<OcbWifiMac> cchMacEntity = m_device->GetMac (CCH);
333  cchMacEntity->SetWifiPhy (m_phy);
334  cchMacEntity->Resume ();
335 
339  return true;
340 }
341 
342 void
343 DefaultChannelScheduler::SwitchToNextChannel (uint32_t curChannelNumber, uint32_t nextChannelNumber)
344 {
345  NS_LOG_FUNCTION (this << curChannelNumber << curChannelNumber);
346  if (m_phy->GetChannelNumber () == nextChannelNumber)
347  {
348  return;
349  }
350  Ptr<OcbWifiMac> curMacEntity = m_device->GetMac (curChannelNumber);
351  Ptr<OcbWifiMac> nextMacEntity = m_device->GetMac (nextChannelNumber);
352  // Perfect channel switch operation among multiple MAC entities in the context of single PHY device.
353  // first make current MAC entity in sleep mode.
354  curMacEntity->Suspend ();
355  // second unattached current MAC entity from single PHY device
356  curMacEntity->ResetWifiPhy ();
357  // third switch PHY device from current channel to next channel;
358  m_phy->SetChannelNumber (nextChannelNumber);
359  // Here channel switch time is required to notify next MAC entity
360  // that channel access cannot be enabled in channel switch time.
361  Time switchTime = m_phy->GetChannelSwitchDelay ();
362  nextMacEntity->MakeVirtualBusy (switchTime);
363  // four attach next MAC entity to single PHY device
364  nextMacEntity->SetWifiPhy (m_phy);
365  // finally resume next MAC entity from sleep mode
366  nextMacEntity->Resume ();
367 }
368 
369 bool
371 {
372  NS_LOG_FUNCTION (this << channelNumber);
373  NS_ASSERT (m_channelNumber != 0);
374  if (m_channelNumber != channelNumber)
375  {
376  return false;
377  }
378  // cancel current SCH MAC activity and assigned default CCH access.
383  if (!m_waitEvent.IsExpired ())
384  {
385  m_waitEvent.Cancel ();
386  }
387  if (!m_extendEvent.IsExpired ())
388  {
390  }
392  m_waitExtend = 0;
393  return true;
394 }
395 
396 void
398 {
399  NS_LOG_FUNCTION (this << duration);
400 }
401 
402 void
404 {
405  NS_LOG_FUNCTION (this << duration);
406 }
407 
408 void
410 {
411  NS_LOG_FUNCTION (this << duration << cchi);
412  // only alternating access requires channel coordination events
414  {
415  return;
416  }
417 
418  if (cchi)
419  {
422  // see chapter 6.2.5 Sync tolerance
423  // a medium busy shall be declared during the guard interval.
424  mac->MakeVirtualBusy (duration);
425  }
426  else
427  {
430  // see chapter 6.2.5 Sync tolerance
431  // a medium busy shall be declared during the guard interval.
432  mac->MakeVirtualBusy (duration);
433  }
434 }
435 } // namespace ns3
static Time GetDelayLeft(const EventId &id)
Get the remaining time until this event will execute.
Definition: simulator.cc:232
Ptr< WifiPhy > GetPhy(uint32_t index) const
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
CoordinationListener(DefaultChannelScheduler *scheduler)
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
virtual void DoDispose(void)
Destructor implementation.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:44
#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:201
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:874
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:339
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Schedule an event to expire at the relative time "time" is reached.
Definition: simulator.h:819
#define CCH
bool IsSchInterval(Time duration=Seconds(0.0)) const
virtual void DoInitialize(void)
Initialize() implementation.
virtual void NotifyGuardSlotStart(Time duration, bool cchi)
virtual void SetWaveNetDevice(Ptr< WaveNetDevice > device)
Ptr< ChannelCoordinator > GetChannelCoordinator(void) const
DefaultChannelScheduler * m_scheduler
virtual void SetWifiPhy(Ptr< WifiPhy > phy)
void RegisterListener(Ptr< ChannelCoordinationListener > listener)
Time NeedTimeToCchInterval(Time duration=Seconds(0.0)) const
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
virtual 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.
virtual Time GetChannelSwitchDelay(void) const =0
This class uses a simple mechanism to assign channel access with following features: (1) only in the ...
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< ChannelCoordinator > m_coordinator
void NotifyGuardSlotStart(Time duration, bool cchi)
Ptr< OcbWifiMac > GetMac(uint32_t channelNumber) const
virtual bool AssignAlternatingAccess(uint32_t channelNumber, bool immediate)
virtual uint16_t GetChannelNumber(void) const =0
Return current channel number.
Time NeedTimeToSchInterval(Time duration=Seconds(0.0)) const
virtual enum ChannelAccess GetAssignedAccessType(uint32_t channelNumber) const
virtual bool ReleaseAccess(uint32_t channelNumber)
virtual void SetChannelNumber(uint16_t id)=0
Set channel number.
Ptr< WaveNetDevice > m_device
virtual void NotifyCchSlotStart(Time duration)
std::vector< Ptr< WifiPhy > > GetPhys(void) const
Ptr< ChannelCoordinationListener > m_coordinationListener
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:228
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:236
Time GetSyncInterval(void) 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)
bool IsExpired(void) const
This method is syntactic sugar for the ns3::Simulator::IsExpired method.
Definition: event-id.cc:59
a unique identifier for an interface.
Definition: type-id.h:57
void Resume(void)
To support MAC extension for multiple channel operation, Resume the activity of suspended MAC entity...
int64_t GetMilliSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:338
TypeId SetParent(TypeId tid)
Definition: type-id.cc:638
This class will assign channel access for requests from higher layers.
void SwitchToNextChannel(uint32_t curChannelNumber, uint32_t nextChannelNumber)