A Discrete-Event Network Simulator
API
channel-coordinator.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  */
17 #include "channel-coordinator.h"
18 
19 #include "ns3/log.h"
20 #include "ns3/simulator.h"
21 
22 namespace ns3
23 {
24 
25 NS_LOG_COMPONENT_DEFINE("ChannelCoordinator");
26 
27 /****************************************************************
28  * This destructor is needed.
29  ****************************************************************/
30 
32 {
33 }
34 
35 /****************************************************************/
36 
38 
39 TypeId
41 {
42  static TypeId tid = TypeId("ns3::ChannelCoordinator")
43  .SetParent<Object>()
44  .SetGroupName("Wave")
45  .AddConstructor<ChannelCoordinator>()
46  .AddAttribute("CchInterval",
47  "CCH Interval, default value is 50ms.",
51  .AddAttribute("SchInterval",
52  "SCH Interval, default value is 50ms.",
56  .AddAttribute("GuardInterval",
57  "Guard Interval, default value is 4ms.",
60  MakeTimeChecker());
61  return tid;
62 }
63 
65  : m_guardCount(0)
66 {
67  NS_LOG_FUNCTION(this);
68 }
69 
71 {
72  NS_LOG_FUNCTION(this);
73 }
74 
75 void
77 {
78  NS_LOG_FUNCTION(this);
80 }
81 
82 void
84 {
85  NS_LOG_FUNCTION(this);
88 }
89 
90 Time
92 {
94  // refer to Annex H of IEEE 1609.4-2010
95  const static uint8_t DEFAULT_CCH_INTERVAL = 50;
96  return MilliSeconds(DEFAULT_CCH_INTERVAL);
97 }
98 
99 Time
101 {
103  // refer to Annex H of IEEE 1609.4-2010
104  const static uint8_t DEFAULT_SCH_INTERVAL = 50;
105  return MilliSeconds(DEFAULT_SCH_INTERVAL);
106 }
107 
108 Time
110 {
113 }
114 
115 Time
117 {
119  // refer to Annex H of IEEE 1609.4-2010
120  const static uint8_t SyncTolerance = 2;
121  const static uint8_t MaxChSwitchTime = 2;
122  const static uint8_t DEFAULT_GUARD_INTERVAL = SyncTolerance + MaxChSwitchTime;
123  return MilliSeconds(DEFAULT_GUARD_INTERVAL);
124 }
125 
126 void
128 {
129  NS_LOG_FUNCTION(this << cchInterval);
130  m_cchi = cchInterval;
131 }
132 
133 Time
135 {
136  NS_LOG_FUNCTION(this);
137  return m_cchi;
138 }
139 
140 void
142 {
143  NS_LOG_FUNCTION(this << schInterval);
144  m_schi = schInterval;
145 }
146 
147 Time
149 {
150  NS_LOG_FUNCTION(this);
151  return m_schi;
152 }
153 
154 Time
156 {
157  NS_LOG_FUNCTION(this);
158  return GetCchInterval() + GetSchInterval();
159 }
160 
161 void
163 {
164  NS_LOG_FUNCTION(this);
165  m_gi = guard;
166 }
167 
168 Time
170 {
171  NS_LOG_FUNCTION(this);
172  return m_gi;
173 }
174 
175 Time
177 {
178  NS_LOG_FUNCTION(this);
179  return m_schi - m_gi;
180 }
181 
182 Time
184 {
185  NS_LOG_FUNCTION(this);
186  return m_cchi - m_gi;
187 }
188 
189 bool
191 {
192  NS_LOG_FUNCTION(this << duration);
193  Time future = GetIntervalTime(duration);
194  return (future < m_cchi);
195 }
196 
197 bool
199 {
200  NS_LOG_FUNCTION(this << duration);
201  return !IsCchInterval(duration);
202 }
203 
204 bool
206 {
207  NS_LOG_FUNCTION(this << duration);
208  Time future = GetIntervalTime(duration);
209  // the interval is either in CchInterval or SchInterval
210  Time interval = future < m_cchi ? future : future - m_cchi;
211  return interval < m_gi;
212 }
213 
214 bool
216 {
217  NS_LOG_FUNCTION(this);
218  if (GetCchInterval().GetMilliSeconds() == 0 || GetSchInterval().GetMilliSeconds() == 0 ||
219  GetGuardInterval().GetMilliSeconds() == 0)
220  {
221  NS_LOG_WARN("the channel interval should not be zero");
222  return false;
223  }
224  // 1000 is 1000ms which is one UTC second
225  if ((1000 % GetSyncInterval().GetMilliSeconds()) != 0)
226  {
227  NS_LOG_WARN("every UTC second shall be an integer number of SyncInterval");
228  return false;
229  }
230  if (GetCchInterval() <= GetGuardInterval())
231  {
232  NS_LOG_WARN("CCH Interval should be large than GuardInterval");
233  return false;
234  }
235  if (GetSchInterval() <= GetGuardInterval())
236  {
237  NS_LOG_WARN("SCH Interval should be large than GuardInterval");
238  return false;
239  }
240  // at last, GguardInterval should be larger than real channel switch time of PHY layer.
241  // However there is no method such as GetChannelSwitchTime in the WifiPhy to support test here.
242  return true;
243 }
244 
245 Time
247 {
248  NS_LOG_FUNCTION(this << duration);
249  if (IsCchInterval(duration))
250  {
251  return MilliSeconds(0);
252  }
253  return GetSyncInterval() - GetIntervalTime(duration);
254 }
255 
256 Time
258 {
259  NS_LOG_FUNCTION(this << duration);
260  if (IsSchInterval(duration))
261  {
262  return MilliSeconds(0);
263  }
264  return GetCchInterval() - GetIntervalTime(duration);
265 }
266 
267 Time
269 {
270  NS_LOG_FUNCTION(this << duration);
271  if (IsGuardInterval(duration))
272  {
273  return MilliSeconds(0);
274  }
275  if (IsCchInterval(duration))
276  {
277  // the time to Guard Interval of SCH Interval
278  return (GetCchInterval() - GetIntervalTime(duration));
279  }
280  // the time to Guard Interval of next CCH Interval
281  return (GetSyncInterval() - GetIntervalTime(duration));
282 }
283 
284 Time
286 {
287  NS_LOG_FUNCTION(this << duration);
288  Time future = Now() + duration;
289  Time sync = GetSyncInterval();
290  uint32_t n = future.GetMilliSeconds() / sync.GetMilliSeconds();
291  return future - MilliSeconds(n * sync.GetMilliSeconds());
292 }
293 
294 Time
296 {
297  NS_LOG_FUNCTION(this << duration);
298  return GetSyncInterval() - GetIntervalTime(duration);
299 }
300 
301 void
303 {
304  NS_LOG_FUNCTION(this << listener);
305  NS_ASSERT(listener);
306  m_listeners.push_back(listener);
307 }
308 
309 void
311 {
312  NS_LOG_FUNCTION(this << listener);
313  NS_ASSERT(listener);
314  for (ListenersI i = m_listeners.begin(); i != m_listeners.end(); ++i)
315  {
316  if ((*i) == listener)
317  {
318  m_listeners.erase(i);
319  return;
320  }
321  }
322 }
323 
324 void
326 {
327  NS_LOG_FUNCTION(this);
328  m_listeners.clear();
329 }
330 
331 void
333 {
334  NS_LOG_FUNCTION(this);
335  Time now = Now();
336  if ((now.GetMilliSeconds() % 1000) != 0)
337  {
338  // see chapter 5.5.2
339  NS_FATAL_ERROR("the coordination event order should start with the beginning of 1 second");
340  }
341  if (!IsValidConfig())
342  {
344  "the channel intervals configured for channel coordination events are invalid");
345  }
346  m_guardCount = 0;
347  NotifyGuardSlot();
348 }
349 
350 void
352 {
353  if (!m_coordination.IsExpired())
354  {
356  }
357  m_guardCount = 0;
358 }
359 
360 void
362 {
363  NS_LOG_FUNCTION(this);
365  for (ListenersI i = m_listeners.begin(); i != m_listeners.end(); ++i)
366  {
367  (*i)->NotifySchSlotStart(GetSchSlot());
368  }
369 }
370 
371 void
373 {
374  NS_LOG_FUNCTION(this);
376  for (ListenersI i = m_listeners.begin(); i != m_listeners.end(); ++i)
377  {
378  (*i)->NotifyCchSlotStart(GetCchSlot());
379  }
380 }
381 
382 void
384 {
385  NS_LOG_FUNCTION(this);
386  Time guardSlot = GetGuardInterval();
387  bool inCchi = ((m_guardCount % 2) == 0);
388  if (inCchi)
389  {
391  }
392  else
393  {
395  }
396  for (ListenersI i = m_listeners.begin(); i != m_listeners.end(); ++i)
397  {
398  (*i)->NotifyGuardSlotStart(guardSlot, inCchi);
399  }
400  m_guardCount++;
401 }
402 
403 } // namespace ns3
ChannelCoordinator deals with channel coordination in data plane (see 1609.4 chapter 5....
static TypeId GetTypeId()
Get the type ID.
void StartChannelCoordination()
start to make channel coordination events
Listeners m_listeners
listeners
Time NeedTimeToCchInterval(Time duration=Seconds(0.0)) const
std::vector< Ptr< ChannelCoordinationListener > >::iterator ListenersI
Listeners iterator typedef.
bool IsSchInterval(Time duration=Seconds(0.0)) const
bool IsGuardInterval(Time duration=Seconds(0.0)) const
uint32_t m_guardCount
guard count
void SetGuardInterval(Time guardi)
void UnregisterAllListeners()
Remove all listeners.
void StopChannelCoordination()
stop channel coordination events
void NotifySchSlot()
notify listeners of a SCH slot start
EventId m_coordination
coordination event
Time NeedTimeToSchInterval(Time duration=Seconds(0.0)) const
void DoInitialize() override
Initialize() implementation.
Time NeedTimeToGuardInterval(Time duration=Seconds(0.0)) const
void UnregisterListener(Ptr< ChannelCoordinationListener > listener)
void NotifyCchSlot()
notify listeners of a CCH slot start
void DoDispose() override
Destructor implementation.
void NotifyGuardSlot()
notify listeners of a guard slot start
Time GetRemainTime(Time duration=Seconds(0.0)) const
Time GetIntervalTime(Time duration=Seconds(0.0)) const
bool IsCchInterval(Time duration=Seconds(0.0)) const
void RegisterListener(Ptr< ChannelCoordinationListener > 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
A base class which provides memory management and object aggregation.
Definition: object.h:89
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:568
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
AttributeValue implementation for Time.
Definition: nstime.h:1423
a unique identifier for an interface.
Definition: type-id.h:60
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
#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
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: nstime.h:1424
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
#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
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:535