A Discrete-Event Network Simulator
API
default-channel-scheduler.cc
Go to the documentation of this file.
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: Junling Bu <linlinjavaer@gmail.com>
16  */
18 
19 #include "ns3/log.h"
20 #include "ns3/simulator.h"
21 #include "ns3/wifi-phy.h"
22 
23 namespace ns3
24 {
25 
26 NS_LOG_COMPONENT_DEFINE("DefaultChannelScheduler");
27 
28 NS_OBJECT_ENSURE_REGISTERED(DefaultChannelScheduler);
29 
35 {
36  public:
43  : m_scheduler(scheduler)
44  {
45  }
46 
47  void NotifyCchSlotStart(Time duration) override
48  {
50  }
51 
52  void NotifySchSlotStart(Time duration) override
53  {
55  }
56 
57  void NotifyGuardSlotStart(Time duration, bool cchi) override
58  {
59  m_scheduler->NotifyGuardSlotStart(duration, cchi);
60  }
61 
62  private:
64 };
65 
66 TypeId
68 {
69  static TypeId tid = TypeId("ns3::DefaultChannelScheduler")
71  .SetGroupName("Wave")
72  .AddConstructor<DefaultChannelScheduler>();
73  return tid;
74 }
75 
77  : m_channelNumber(0),
78  m_extend(EXTENDED_CONTINUOUS),
79  m_channelAccess(NoAccess),
80  m_waitChannelNumber(0),
81  m_waitExtend(0),
82  m_coordinationListener(nullptr)
83 {
84  NS_LOG_FUNCTION(this);
85 }
86 
88 {
89  NS_LOG_FUNCTION(this);
90 }
91 
92 void
94 {
95  NS_LOG_FUNCTION(this);
97 }
98 
99 void
101 {
102  NS_LOG_FUNCTION(this);
103  m_coordinator = nullptr;
105  {
106  m_coordinationListener = nullptr;
107  }
108  if (!m_waitEvent.IsExpired())
109  {
111  }
112  if (!m_extendEvent.IsExpired())
113  {
115  }
116  m_phy = nullptr;
118 }
119 
120 void
122 {
123  NS_LOG_FUNCTION(this << device);
125  std::vector<Ptr<WifiPhy>> phys = device->GetPhys();
126  if (phys.size() > 1)
127  {
128  NS_LOG_WARN("The class is only in the context of single-PHY device, while there are more "
129  "than one PHY devices");
130  }
131  // since default channel scheduler is in the context of single-PHY, we only use one phy object.
132  m_phy = device->GetPhy(0);
134  m_coordinationListener = Create<CoordinationListener>(this);
136 }
137 
138 enum ChannelAccess
139 DefaultChannelScheduler::GetAssignedAccessType(uint32_t channelNumber) const
140 {
141  NS_LOG_FUNCTION(this << channelNumber);
142  if (m_channelAccess == AlternatingAccess && channelNumber == CCH)
143  {
144  return AlternatingAccess;
145  }
146  return (m_channelNumber == channelNumber) ? m_channelAccess : NoAccess;
147 }
148 
149 bool
150 DefaultChannelScheduler::AssignAlternatingAccess(uint32_t channelNumber, bool immediate)
151 {
152  NS_LOG_FUNCTION(this << channelNumber << immediate);
154  uint32_t sch = channelNumber;
155 
157  {
158  return false;
159  }
160 
162  {
163  if (m_channelNumber != sch)
164  {
165  return false;
166  }
167  else
168  {
169  return true;
170  }
171  }
172 
173  // if we need immediately switch to AlternatingAccess,
174  // we switch to specific SCH.
175  if ((immediate && m_coordinator->IsSchInterval()))
176  {
178  SwitchToNextChannel(CCH, sch);
179  }
180 
181  m_channelNumber = sch;
183  return true;
184 }
185 
186 bool
187 DefaultChannelScheduler::AssignContinuousAccess(uint32_t channelNumber, bool immediate)
188 {
189  NS_LOG_FUNCTION(this << channelNumber << immediate);
191  uint32_t sch = channelNumber;
193  {
194  return false;
195  }
196 
198  {
199  if (m_channelNumber != sch)
200  {
201  return false;
202  }
203  else
204  {
205  return true;
206  }
207  }
208 
209  // if there is already an wait event for previous non-immediate request
210  if (!m_waitEvent.IsExpired())
211  {
212  if (m_waitChannelNumber != sch)
213  {
214  // then the coming new request will be rejected because of FCFS
215  return false;
216  }
217  else
218  {
219  if (!immediate)
220  {
221  return true;
222  }
223  // then cancel this wait event and assign access for request immediately
225  }
226  }
227 
228  if (immediate || m_coordinator->IsSchInterval())
229  {
231  m_channelNumber = sch;
233  }
234  else
235  {
239  this,
240  sch,
241  false);
242  m_waitChannelNumber = sch;
243  }
244 
245  return true;
246 }
247 
248 bool
250  uint32_t extends,
251  bool immediate)
252 {
253  NS_LOG_FUNCTION(this << channelNumber << extends << immediate);
255  uint32_t sch = channelNumber;
257  {
258  return false;
259  }
260 
262  {
263  if (m_channelNumber != sch)
264  {
265  return false;
266  }
267  else
268  {
269  // if current remain extends cannot fulfill the requirement for extends
271  uint32_t remainExtends = (remainTime / m_coordinator->GetSyncInterval()).GetHigh();
272  if (remainExtends > extends)
273  {
274  return true;
275  }
276  else
277  {
278  return false;
279  }
280  }
281  }
282 
283  // if there is already an wait event for previous non-immediate request
284  if (!m_waitEvent.IsExpired())
285  {
287  if (m_waitChannelNumber != sch)
288  {
289  // then the coming new request will be rejected because of FCFS
290  return false;
291  }
292  else
293  {
294  if (m_waitExtend < extends)
295  {
296  return false;
297  }
298 
299  if (immediate)
300  {
301  // then cancel previous wait event and
302  // go to below code to assign access for request immediately
304  }
305  else
306  {
307  return true;
308  }
309  }
310  }
311 
312  if (immediate || m_coordinator->IsSchInterval())
313  {
315  m_channelNumber = sch;
317  m_extend = extends;
318 
320  // the wait time to proper interval will not be calculated as extended time.
321  Time extendedDuration =
323  // after end_duration time, DefaultChannelScheduler will release channel access
324  // automatically
325  m_extendEvent = Simulator::Schedule(extendedDuration,
327  this,
328  sch);
329  }
330  else
331  {
335  this,
336  sch,
337  extends,
338  false);
339  m_waitChannelNumber = sch;
340  m_waitExtend = extends;
341  }
342  return true;
343 }
344 
345 bool
347 {
348  NS_LOG_FUNCTION(this);
350  {
351  return true;
352  }
353  if (m_channelNumber != 0)
354  {
355  // This class does not support preemptive scheduling
356  NS_LOG_DEBUG("channel access is already assigned for other SCHs, thus cannot assign "
357  "default CCH access.");
358  return false;
359  }
360  // CCH MAC is to attach single-PHY device and wake up for transmission.
361  Ptr<OcbWifiMac> cchMacEntity = m_device->GetMac(CCH);
362  if (Now().GetMilliSeconds() != 0)
363  {
365  Time switchTime = m_phy->GetChannelSwitchDelay();
366  cchMacEntity->MakeVirtualBusy(switchTime);
367  }
368  cchMacEntity->SetWifiPhy(m_phy);
369  cchMacEntity->Resume();
370 
374  return true;
375 }
376 
377 void
378 DefaultChannelScheduler::SwitchToNextChannel(uint32_t curChannelNumber, uint32_t nextChannelNumber)
379 {
380  NS_LOG_FUNCTION(this << curChannelNumber << curChannelNumber);
381  if (m_phy->GetChannelNumber() == nextChannelNumber)
382  {
383  return;
384  }
385  Ptr<OcbWifiMac> curMacEntity = m_device->GetMac(curChannelNumber);
386  Ptr<OcbWifiMac> nextMacEntity = m_device->GetMac(nextChannelNumber);
387  // Perfect channel switch operation among multiple MAC entities in the context of single PHY
388  // device. first make current MAC entity in sleep mode.
389  curMacEntity->Suspend();
390  // second unattached current MAC entity from single PHY device
391  curMacEntity->ResetWifiPhys();
392  // third switch PHY device from current channel to next channel;
394  // four attach next MAC entity to single PHY device
395  nextMacEntity->SetWifiPhy(m_phy);
396  // Here channel switch time is required to notify next MAC entity
397  // that channel access cannot be enabled in channel switch time.
398  Time switchTime = m_phy->GetChannelSwitchDelay();
399  nextMacEntity->MakeVirtualBusy(switchTime);
400  // finally resume next MAC entity from sleep mode
401  nextMacEntity->Resume();
402 }
403 
404 bool
406 {
407  NS_LOG_FUNCTION(this << channelNumber);
409  if (m_channelNumber != channelNumber)
410  {
411  return false;
412  }
413  // cancel current SCH MAC activity and assigned default CCH access.
418  if (!m_waitEvent.IsExpired())
419  {
421  }
422  if (!m_extendEvent.IsExpired())
423  {
425  }
427  m_waitExtend = 0;
428  return true;
429 }
430 
431 void
433 {
434  NS_LOG_FUNCTION(this << duration);
435 }
436 
437 void
439 {
440  NS_LOG_FUNCTION(this << duration);
441 }
442 
443 void
445 {
446  NS_LOG_FUNCTION(this << duration << cchi);
447  // only alternating access requires channel coordination events
449  {
450  return;
451  }
452 
453  if (cchi)
454  {
457  // see chapter 6.2.5 Sync tolerance
458  // a medium busy shall be declared during the guard interval.
459  mac->MakeVirtualBusy(duration);
460  }
461  else
462  {
465  // see chapter 6.2.5 Sync tolerance
466  // a medium busy shall be declared during the guard interval.
467  mac->MakeVirtualBusy(duration);
468  }
469 }
470 } // 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 NeedTimeToSchInterval(Time duration=Seconds(0.0)) const
void RegisterListener(Ptr< ChannelCoordinationListener > listener)
This class will assign channel access for requests from higher layers.
void DoDispose() override
Destructor implementation.
virtual void SetWaveNetDevice(Ptr< WaveNetDevice > device)
Ptr< WaveNetDevice > m_device
the device
void DoInitialize() override
Initialize() implementation.
CoordinationListener class.
CoordinationListener(DefaultChannelScheduler *scheduler)
Constructor.
DefaultChannelScheduler * m_scheduler
the scheduler
void NotifyCchSlotStart(Time duration) override
void NotifyGuardSlotStart(Time duration, bool cchi) override
void NotifySchSlotStart(Time duration) override
This class uses a simple mechanism to assign channel access with following features: (1) only in the ...
bool ReleaseAccess(uint32_t channelNumber) override
void DoDispose() override
Destructor implementation.
void NotifyGuardSlotStart(Time duration, bool cchi)
Notify guard slot start.
static TypeId GetTypeId()
Get the type ID.
void NotifyCchSlotStart(Time duration)
Notify CCH slot start.
void SwitchToNextChannel(uint32_t curChannelNumber, uint32_t nextChannelNumber)
bool AssignContinuousAccess(uint32_t channelNumber, bool immediate) override
Ptr< ChannelCoordinator > m_coordinator
channel coordinator
bool AssignDefaultCchAccess() override
This method will assign default CCH access for CCH.
bool AssignAlternatingAccess(uint32_t channelNumber, bool immediate) override
bool AssignExtendedAccess(uint32_t channelNumber, uint32_t extends, bool immediate) override
void NotifySchSlotStart(Time duration)
Notify SCH slot start.
void SetWaveNetDevice(Ptr< WaveNetDevice > device) override
ChannelAccess GetAssignedAccessType(uint32_t channelNumber) const override
uint32_t m_channelNumber
when m_channelAccess is ContinuousAccess, m_channelNumber is continuous channel number; when m_channe...
ChannelAccess m_channelAccess
channel access
uint32_t m_waitChannelNumber
wait channel number
void DoInitialize() override
Initialize() implementation.
Ptr< ChannelCoordinationListener > m_coordinationListener
coordination listener
void Cancel()
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:55
bool IsExpired() const
This method is syntactic sugar for the ns3::Simulator::IsExpired method.
Definition: event-id.cc:69
void SetWifiPhy(Ptr< WifiPhy > phy)
Set the PHY.
void Suspend()
To support MAC extension for multiple channel operation, Suspend the activity in current MAC entity.
void Resume()
To support MAC extension for multiple channel operation, Resume the activity of suspended MAC entity.
void MakeVirtualBusy(Time duration)
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:568
static Time GetDelayLeft(const EventId &id)
Get the remaining time until this event will execute.
Definition: simulator.cc:208
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
int64_t GetMilliSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:407
a unique identifier for an interface.
Definition: type-id.h:60
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
Ptr< WifiPhy > GetPhy(uint8_t index) const override
const std::vector< Ptr< WifiPhy > > & GetPhys() const override
Ptr< ChannelCoordinator > GetChannelCoordinator() const
Ptr< OcbWifiMac > GetMac(uint32_t channelNumber) const
void ResetWifiPhys()
Remove currently attached WifiPhy objects from this MAC.
Definition: wifi-mac.cc:961
Time GetChannelSwitchDelay() const
Definition: wifi-phy.cc:683
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:1062
uint8_t GetChannelNumber() const
Return current channel number.
Definition: wifi-phy.cc:1020
std::tuple< uint8_t, uint16_t, int, uint8_t > ChannelTuple
Tuple identifying an operating channel.
Definition: wifi-phy.h:870
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#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:261
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Time Now()
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:296
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1348
@ 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:85