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  .AddConstructor<ChannelCoordinator> ()
44  .AddAttribute ("CchInterval", "CCH Interval, default value is 50ms.",
47  MakeTimeChecker ())
48  .AddAttribute ("SchInterval", "SCH Interval, default value is 50ms.",
51  MakeTimeChecker ())
52  .AddAttribute ("GuardInterval", "Guard Interval, default value is 4ms.",
55  MakeTimeChecker ())
56  ;
57  return tid;
58 }
59 
61  : m_guardCount (0)
62 {
63  NS_LOG_FUNCTION (this);
64 }
65 
67 {
68  NS_LOG_FUNCTION (this);
69 }
70 
71 void
73 {
74  NS_LOG_FUNCTION (this);
76 }
77 
78 void
80 {
81  NS_LOG_FUNCTION (this);
84 }
85 
86 Time
88 {
90  // refer to Annex H of IEEE 1609.4-2010
91  const static uint8_t DEFAULT_CCH_INTERVAL = 50;
92  return MilliSeconds (DEFAULT_CCH_INTERVAL);
93 }
94 
95 Time
97 {
99  // refer to Annex H of IEEE 1609.4-2010
100  const static uint8_t DEFAULT_SCH_INTERVAL = 50;
101  return MilliSeconds (DEFAULT_SCH_INTERVAL);
102 }
103 
104 Time
106 {
109 }
110 
111 Time
113 {
115  // refer to Annex H of IEEE 1609.4-2010
116  const static uint8_t SyncTolerance = 2;
117  const static uint8_t MaxChSwitchTime = 2;
118  const static uint8_t DEFAULT_GUARD_INTERVAL = SyncTolerance + MaxChSwitchTime;
119  return MilliSeconds (DEFAULT_GUARD_INTERVAL);
120 }
121 
122 void
124 {
125  NS_LOG_FUNCTION (this << cchInterval);
126  m_cchi = cchInterval;
127 }
128 
129 Time
131 {
132  NS_LOG_FUNCTION (this);
133  return m_cchi;
134 }
135 
136 void
138 {
139  NS_LOG_FUNCTION (this << schInterval);
140  m_schi = schInterval;
141 }
142 
143 Time
145 {
146  NS_LOG_FUNCTION (this);
147  return m_schi;
148 }
149 
150 Time
152 {
153  NS_LOG_FUNCTION (this);
154  return GetCchInterval () + GetSchInterval ();
155 }
156 
157 void
159 {
160  NS_LOG_FUNCTION (this);
161  m_gi = guard;
162 }
163 
164 Time
166 {
167  NS_LOG_FUNCTION (this);
168  return m_gi;
169 }
170 
171 Time
173 {
174  NS_LOG_FUNCTION (this);
175  return m_schi - m_gi;
176 }
177 
178 Time
180 {
181  NS_LOG_FUNCTION (this);
182  return m_cchi - m_gi;
183 }
184 
185 bool
187 {
188  NS_LOG_FUNCTION (this << duration);
189  Time future = GetIntervalTime (duration);
190  return (future < m_cchi);
191 }
192 
193 bool
195 {
196  NS_LOG_FUNCTION (this << duration);
197  return !IsCchInterval (duration);
198 }
199 
200 bool
202 {
203  NS_LOG_FUNCTION (this << duration);
204  Time future = GetIntervalTime (duration);
205  // the interval is either in CchInterval or SchInterval
206  Time interval = future < m_cchi ? future : future - m_cchi;
207  return interval < m_gi;
208 }
209 
210 bool
212 {
213  NS_LOG_FUNCTION (this);
214  if (GetCchInterval ().GetMilliSeconds () == 0 || GetSchInterval ().GetMilliSeconds () == 0
215  || GetGuardInterval ().GetMilliSeconds () == 0)
216  {
217  NS_LOG_WARN ("the channel interval should not be zero");
218  return false;
219  }
220  // 1000 is 1000ms which is one UTC second
221  if ((1000 % GetSyncInterval ().GetMilliSeconds ()) != 0)
222  {
223  NS_LOG_WARN ("every UTC second shall be an integer number of SyncInterval");
224  return false;
225  }
226  if (GetCchInterval () <= GetGuardInterval ())
227  {
228  NS_LOG_WARN ("CCH Interval should be large than GuardInterval");
229  return false;
230  }
231  if (GetSchInterval () <= GetGuardInterval ())
232  {
233  NS_LOG_WARN ("SCH Interval should be large than GuardInterval");
234  return false;
235  }
236  // at last, GguardInterval should be larger than real channel switch time of PHY layer.
237  // However there is no method such as GetChannelSwitchTime in the WifiPhy to support test here.
238  return true;
239 }
240 
241 Time
243 {
244  NS_LOG_FUNCTION (this << duration);
245  if (IsCchInterval (duration))
246  {
247  return MilliSeconds (0);
248  }
249  return GetSyncInterval () - GetIntervalTime (duration);
250 }
251 
252 Time
254 {
255  NS_LOG_FUNCTION (this << duration);
256  if (IsSchInterval (duration))
257  {
258  return MilliSeconds (0);
259  }
260  return GetCchInterval () - GetIntervalTime (duration);
261 }
262 
263 Time
265 {
266  NS_LOG_FUNCTION (this << duration);
267  if (IsGuardInterval (duration))
268  {
269  return MilliSeconds (0);
270  }
271  if (IsCchInterval (duration))
272  {
273  // the time to Guard Interval of SCH Interval
274  return (GetCchInterval () - GetIntervalTime (duration));
275  }
276  // the time to Guard Interval of next CCH Interval
277  return (GetSyncInterval () - GetIntervalTime (duration));
278 }
279 
280 Time
282 {
283  NS_LOG_FUNCTION (this << duration);
284  Time future = Now () + duration;
285  Time sync = GetSyncInterval ();
286  uint32_t n = future.GetMilliSeconds () / sync.GetMilliSeconds ();
287  return future - MilliSeconds (n * sync.GetMilliSeconds ());
288 }
289 
290 Time
292 {
293  NS_LOG_FUNCTION (this << duration);
294  return GetSyncInterval () - GetIntervalTime (duration);
295 }
296 
297 void
299 {
300  NS_LOG_FUNCTION (this << listener);
301  NS_ASSERT (listener != 0);
302  m_listeners.push_back (listener);
303 }
304 
305 void
307 {
308  NS_LOG_FUNCTION (this << listener);
309  NS_ASSERT (listener != 0);
310  for (ListenersI i = m_listeners.begin (); i != m_listeners.end (); ++i)
311  {
312  if ((*i) == listener)
313  {
314  m_listeners.erase (i);
315  return;
316  }
317  }
318 }
319 
320 void
322 {
323  NS_LOG_FUNCTION (this);
324  m_listeners.clear ();
325 }
326 
327 void
329 {
330  NS_LOG_FUNCTION (this);
331  Time now = Now ();
332  if ((now.GetMilliSeconds () % 1000) != 0)
333  {
334  // see chapter 5.5.2
335  NS_FATAL_ERROR ("the coordination event order should start with the beginning of 1 second");
336  }
337  if (!IsValidConfig ())
338  {
339  NS_FATAL_ERROR ("the channel intervals configured for channel coordination events are invalid");
340  }
341  m_guardCount = 0;
342  NotifyGuardSlot ();
343 }
344 
345 void
347 {
348  if (!m_coordination.IsExpired ())
349  {
351  }
352  m_guardCount = 0;
353 }
354 
355 void
357 {
358  NS_LOG_FUNCTION (this);
360  for (ListenersI i = m_listeners.begin (); i != m_listeners.end (); ++i)
361  {
362  (*i)->NotifySchSlotStart (GetSchSlot ());
363  }
364 }
365 
366 void
368 {
369  NS_LOG_FUNCTION (this);
371  for (ListenersI i = m_listeners.begin (); i != m_listeners.end (); ++i)
372  {
373  (*i)->NotifyCchSlotStart (GetCchSlot ());
374  }
375 }
376 
377 void
379 {
380  NS_LOG_FUNCTION (this);
381  Time guardSlot = GetGuardInterval ();
382  bool inCchi = ((m_guardCount % 2) == 0);
383  if (inCchi)
384  {
386  }
387  else
388  {
390  }
391  for (ListenersI i = m_listeners.begin (); i != m_listeners.end (); ++i)
392  {
393  (*i)->NotifyGuardSlotStart (guardSlot, inCchi);
394  }
395  m_guardCount++;
396 }
397 
398 } // namespace ns3
bool IsGuardInterval(Time duration=Seconds(0.0)) const
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:95
#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...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:44
Time GetRemainTime(Time duration=Seconds(0.0)) const
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:61
#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:867
#define NS_FATAL_ERROR(msg)
Fatal error handling.
Definition: fatal-error.h:100
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
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
bool IsSchInterval(Time duration=Seconds(0.0)) const
bool IsValidConfig(void) const
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:439
Time NeedTimeToGuardInterval(Time duration=Seconds(0.0)) const
static Time GetDefaultGuardInterval(void)
void UnregisterAllListeners(void)
Remove all listeners.
AttributeValue implementation for Time.
Definition: nstime.h:921
static Time GetDefaultSchInterval(void)
void StartChannelCoordination(void)
start to make channel coordination events
Time GetGuardInterval(void) const
void RegisterListener(Ptr< ChannelCoordinationListener > listener)
Time NeedTimeToCchInterval(Time duration=Seconds(0.0)) const
bool IsCchInterval(Time duration=Seconds(0.0)) const
void UnregisterListener(Ptr< ChannelCoordinationListener > listener)
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Time GetIntervalTime(Time duration=Seconds(0.0)) const
Time GetCchInterval(void) const
virtual void DoInitialize(void)
Initialize() implementation.
std::vector< Ptr< ChannelCoordinationListener > >::iterator ListenersI
Time NeedTimeToSchInterval(Time duration=Seconds(0.0)) const
static Time GetDefaultCchInterval(void)
Time GetSchInterval(void) const
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:922
void StopChannelCoordination(void)
stop channel coordination events
virtual void DoDispose(void)
Destructor implementation.
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:228
Time GetSyncInterval(void) const
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:53
static TypeId GetTypeId(void)
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:330
A base class which provides memory management and object aggregation.
Definition: object.h:87
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:51
int64_t GetMilliSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:331
TypeId SetParent(TypeId tid)
Definition: type-id.cc:631
void SetGuardInterval(Time guardi)
static Time GetDefaultSyncInterval(void)