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
23namespace ns3 {
24
25NS_LOG_COMPONENT_DEFINE ("DefaultChannelScheduler");
26
27NS_OBJECT_ENSURE_REGISTERED (DefaultChannelScheduler);
28
34{
35public:
42 : m_scheduler (scheduler)
43 {
44 }
46 {
47 }
48 virtual void NotifyCchSlotStart (Time duration)
49 {
51 }
52 virtual void NotifySchSlotStart (Time duration)
53 {
55 }
56 virtual void NotifyGuardSlotStart (Time duration, bool cchi)
57 {
58 m_scheduler->NotifyGuardSlotStart (duration, cchi);
59 }
60private:
62};
63
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
90void
92{
93 NS_LOG_FUNCTION (this);
95}
96
97void
99{
100 NS_LOG_FUNCTION (this);
101 m_coordinator = 0;
102 if (m_coordinationListener != 0)
103 {
105 }
106 if (!m_waitEvent.IsExpired ())
107 {
109 }
110 if (!m_extendEvent.IsExpired ())
111 {
113 }
114 m_phy = 0;
116}
117
118void
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
135enum ChannelAccess
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
147bool
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 {
177 }
178
179 m_channelNumber = sch;
181 return true;
182}
183
184bool
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
223 }
224 }
225
226 if (immediate || m_coordinator->IsSchInterval ())
227 {
229 m_channelNumber = sch;
231 }
232 else
233 {
237 }
238
239 return true;
240}
241
242bool
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
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 {
322 m_waitExtend = extends;
323 }
324 return true;
325}
326
327bool
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
358void
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
385bool
387{
388 NS_LOG_FUNCTION (this << channelNumber);
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 {
402 }
403 if (!m_extendEvent.IsExpired ())
404 {
406 }
408 m_waitExtend = 0;
409 return true;
410}
411
412void
414{
415 NS_LOG_FUNCTION (this << duration);
416}
417
418void
420{
421 NS_LOG_FUNCTION (this << duration);
422}
423
424void
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:895
Time GetChannelSwitchDelay(void) const
Definition: wifi-phy.cc:607
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:913
std::tuple< uint8_t, uint16_t, int, uint8_t > ChannelTuple
Tuple identifying an operating channel.
Definition: wifi-phy.h:832
#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:96