A Discrete-Event Network Simulator
API
channel-coordinator.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  */
18 #include "channel-coordinator.h"
19 #include "ns3/log.h"
20 #include "ns3/simulator.h"
21 
22 namespace ns3 {
23 
24 NS_LOG_COMPONENT_DEFINE ("ChannelCoordinator");
25 
26 /****************************************************************
27  * This destructor is needed.
28  ****************************************************************/
29 
31 {
32 }
33 
34 /****************************************************************/
35 
37 
38 TypeId
40 {
41  static TypeId tid = TypeId ("ns3::ChannelCoordinator")
42  .SetParent<Object> ()
43  .SetGroupName ("Wave")
44  .AddConstructor<ChannelCoordinator> ()
45  .AddAttribute ("CchInterval", "CCH Interval, default value is 50ms.",
48  MakeTimeChecker ())
49  .AddAttribute ("SchInterval", "SCH Interval, default value is 50ms.",
52  MakeTimeChecker ())
53  .AddAttribute ("GuardInterval", "Guard Interval, default value is 4ms.",
56  MakeTimeChecker ())
57  ;
58  return tid;
59 }
60 
62  : m_guardCount (0)
63 {
64  NS_LOG_FUNCTION (this);
65 }
66 
68 {
69  NS_LOG_FUNCTION (this);
70 }
71 
72 void
74 {
75  NS_LOG_FUNCTION (this);
77 }
78 
79 void
81 {
82  NS_LOG_FUNCTION (this);
85 }
86 
87 Time
89 {
91  // refer to Annex H of IEEE 1609.4-2010
92  const static uint8_t DEFAULT_CCH_INTERVAL = 50;
93  return MilliSeconds (DEFAULT_CCH_INTERVAL);
94 }
95 
96 Time
98 {
100  // refer to Annex H of IEEE 1609.4-2010
101  const static uint8_t DEFAULT_SCH_INTERVAL = 50;
102  return MilliSeconds (DEFAULT_SCH_INTERVAL);
103 }
104 
105 Time
107 {
110 }
111 
112 Time
114 {
116  // refer to Annex H of IEEE 1609.4-2010
117  const static uint8_t SyncTolerance = 2;
118  const static uint8_t MaxChSwitchTime = 2;
119  const static uint8_t DEFAULT_GUARD_INTERVAL = SyncTolerance + MaxChSwitchTime;
120  return MilliSeconds (DEFAULT_GUARD_INTERVAL);
121 }
122 
123 void
125 {
126  NS_LOG_FUNCTION (this << cchInterval);
127  m_cchi = cchInterval;
128 }
129 
130 Time
132 {
133  NS_LOG_FUNCTION (this);
134  return m_cchi;
135 }
136 
137 void
139 {
140  NS_LOG_FUNCTION (this << schInterval);
141  m_schi = schInterval;
142 }
143 
144 Time
146 {
147  NS_LOG_FUNCTION (this);
148  return m_schi;
149 }
150 
151 Time
153 {
154  NS_LOG_FUNCTION (this);
155  return GetCchInterval () + GetSchInterval ();
156 }
157 
158 void
160 {
161  NS_LOG_FUNCTION (this);
162  m_gi = guard;
163 }
164 
165 Time
167 {
168  NS_LOG_FUNCTION (this);
169  return m_gi;
170 }
171 
172 Time
174 {
175  NS_LOG_FUNCTION (this);
176  return m_schi - m_gi;
177 }
178 
179 Time
181 {
182  NS_LOG_FUNCTION (this);
183  return m_cchi - m_gi;
184 }
185 
186 bool
188 {
189  NS_LOG_FUNCTION (this << duration);
190  Time future = GetIntervalTime (duration);
191  return (future < m_cchi);
192 }
193 
194 bool
196 {
197  NS_LOG_FUNCTION (this << duration);
198  return !IsCchInterval (duration);
199 }
200 
201 bool
203 {
204  NS_LOG_FUNCTION (this << duration);
205  Time future = GetIntervalTime (duration);
206  // the interval is either in CchInterval or SchInterval
207  Time interval = future < m_cchi ? future : future - m_cchi;
208  return interval < m_gi;
209 }
210 
211 bool
213 {
214  NS_LOG_FUNCTION (this);
215  if (GetCchInterval ().GetMilliSeconds () == 0 || GetSchInterval ().GetMilliSeconds () == 0
216  || GetGuardInterval ().GetMilliSeconds () == 0)
217  {
218  NS_LOG_WARN ("the channel interval should not be zero");
219  return false;
220  }
221  // 1000 is 1000ms which is one UTC second
222  if ((1000 % GetSyncInterval ().GetMilliSeconds ()) != 0)
223  {
224  NS_LOG_WARN ("every UTC second shall be an integer number of SyncInterval");
225  return false;
226  }
227  if (GetCchInterval () <= GetGuardInterval ())
228  {
229  NS_LOG_WARN ("CCH Interval should be large than GuardInterval");
230  return false;
231  }
232  if (GetSchInterval () <= GetGuardInterval ())
233  {
234  NS_LOG_WARN ("SCH Interval should be large than GuardInterval");
235  return false;
236  }
237  // at last, GguardInterval should be larger than real channel switch time of PHY layer.
238  // However there is no method such as GetChannelSwitchTime in the WifiPhy to support test here.
239  return true;
240 }
241 
242 Time
244 {
245  NS_LOG_FUNCTION (this << duration);
246  if (IsCchInterval (duration))
247  {
248  return MilliSeconds (0);
249  }
250  return GetSyncInterval () - GetIntervalTime (duration);
251 }
252 
253 Time
255 {
256  NS_LOG_FUNCTION (this << duration);
257  if (IsSchInterval (duration))
258  {
259  return MilliSeconds (0);
260  }
261  return GetCchInterval () - GetIntervalTime (duration);
262 }
263 
264 Time
266 {
267  NS_LOG_FUNCTION (this << duration);
268  if (IsGuardInterval (duration))
269  {
270  return MilliSeconds (0);
271  }
272  if (IsCchInterval (duration))
273  {
274  // the time to Guard Interval of SCH Interval
275  return (GetCchInterval () - GetIntervalTime (duration));
276  }
277  // the time to Guard Interval of next CCH Interval
278  return (GetSyncInterval () - GetIntervalTime (duration));
279 }
280 
281 Time
283 {
284  NS_LOG_FUNCTION (this << duration);
285  Time future = Now () + duration;
286  Time sync = GetSyncInterval ();
287  uint32_t n = future.GetMilliSeconds () / sync.GetMilliSeconds ();
288  return future - MilliSeconds (n * sync.GetMilliSeconds ());
289 }
290 
291 Time
293 {
294  NS_LOG_FUNCTION (this << duration);
295  return GetSyncInterval () - GetIntervalTime (duration);
296 }
297 
298 void
300 {
301  NS_LOG_FUNCTION (this << listener);
302  NS_ASSERT (listener != 0);
303  m_listeners.push_back (listener);
304 }
305 
306 void
308 {
309  NS_LOG_FUNCTION (this << listener);
310  NS_ASSERT (listener != 0);
311  for (ListenersI i = m_listeners.begin (); i != m_listeners.end (); ++i)
312  {
313  if ((*i) == listener)
314  {
315  m_listeners.erase (i);
316  return;
317  }
318  }
319 }
320 
321 void
323 {
324  NS_LOG_FUNCTION (this);
325  m_listeners.clear ();
326 }
327 
328 void
330 {
331  NS_LOG_FUNCTION (this);
332  Time now = Now ();
333  if ((now.GetMilliSeconds () % 1000) != 0)
334  {
335  // see chapter 5.5.2
336  NS_FATAL_ERROR ("the coordination event order should start with the beginning of 1 second");
337  }
338  if (!IsValidConfig ())
339  {
340  NS_FATAL_ERROR ("the channel intervals configured for channel coordination events are invalid");
341  }
342  m_guardCount = 0;
343  NotifyGuardSlot ();
344 }
345 
346 void
348 {
349  if (!m_coordination.IsExpired ())
350  {
352  }
353  m_guardCount = 0;
354 }
355 
356 void
358 {
359  NS_LOG_FUNCTION (this);
361  for (ListenersI i = m_listeners.begin (); i != m_listeners.end (); ++i)
362  {
363  (*i)->NotifySchSlotStart (GetSchSlot ());
364  }
365 }
366 
367 void
369 {
370  NS_LOG_FUNCTION (this);
372  for (ListenersI i = m_listeners.begin (); i != m_listeners.end (); ++i)
373  {
374  (*i)->NotifyCchSlotStart (GetCchSlot ());
375  }
376 }
377 
378 void
380 {
381  NS_LOG_FUNCTION (this);
382  Time guardSlot = GetGuardInterval ();
383  bool inCchi = ((m_guardCount % 2) == 0);
384  if (inCchi)
385  {
387  }
388  else
389  {
391  }
392  for (ListenersI i = m_listeners.begin (); i != m_listeners.end (); ++i)
393  {
394  (*i)->NotifyGuardSlotStart (guardSlot, inCchi);
395  }
396  m_guardCount++;
397 }
398 
399 } // namespace ns3
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:557
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
Time GetIntervalTime(Time duration=Seconds(0.0)) const
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
ChannelCoordinator deals with channel coordination in data plane (see 1609.4 chapter 5...
Time NeedTimeToCchInterval(Time duration=Seconds(0.0)) const
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
bool IsCchInterval(Time duration=Seconds(0.0)) const
void NotifySchSlot(void)
notify listeners of a SCH slot start
EventId m_coordination
coordination event
Listeners m_listeners
listeners
#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
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1297
Time NeedTimeToGuardInterval(Time duration=Seconds(0.0)) const
uint32_t m_guardCount
guard count
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
bool IsGuardInterval(Time duration=Seconds(0.0)) const
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
bool IsExpired(void) const
This method is syntactic sugar for the ns3::Simulator::IsExpired method.
Definition: event-id.cc:65
void NotifyGuardSlot(void)
notify listeners of a guard slot start
static Time GetDefaultGuardInterval(void)
void UnregisterAllListeners(void)
Remove all listeners.
AttributeValue implementation for Time.
Definition: nstime.h:1353
static Time GetDefaultSchInterval(void)
void StartChannelCoordination(void)
start to make channel coordination events
void RegisterListener(Ptr< ChannelCoordinationListener > listener)
Time m_gi
GuardInterval.
void UnregisterListener(Ptr< ChannelCoordinationListener > listener)
Every class exported by the ns3 library is enclosed in the ns3 namespace.
virtual void DoInitialize(void)
Initialize() implementation.
std::vector< Ptr< ChannelCoordinationListener > >::iterator ListenersI
Listeners iterator typedef.
static Time GetDefaultCchInterval(void)
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:1354
void NotifyCchSlot(void)
notify listeners of a CCH slot start
void StopChannelCoordination(void)
stop channel coordination events
virtual void DoDispose(void)
Destructor implementation.
bool IsSchInterval(Time duration=Seconds(0.0)) const
Time GetRemainTime(Time duration=Seconds(0.0)) const
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:265
int64_t GetMilliSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:384
Time NeedTimeToSchInterval(Time duration=Seconds(0.0)) const
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:53
static TypeId GetTypeId(void)
Get the type ID.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:533
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:287
A base class which provides memory management and object aggregation.
Definition: object.h:87
Time GetSyncInterval(void) const
a unique identifier for an interface.
Definition: type-id.h:58
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:923
Time GetGuardInterval(void) const
void SetGuardInterval(Time guardi)
static Time GetDefaultSyncInterval(void)