A Discrete-Event Network Simulator
API
mac-extension-test-suite.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 <cmath>
19 #include "ns3/test.h"
20 #include "ns3/config.h"
21 #include "ns3/string.h"
22 #include "ns3/node-list.h"
23 #include "ns3/mobility-model.h"
24 #include "ns3/yans-wifi-helper.h"
25 #include "ns3/mobility-helper.h"
26 #include "ns3/seq-ts-header.h"
27 #include "ns3/wave-net-device.h"
28 #include "ns3/wave-mac-helper.h"
29 #include "ns3/wave-helper.h"
30 
31 using namespace ns3;
32 
33 // This test case tests the channel coordination.
34 // In particular, it checks the following:
35 // - channel interval calculation including CCH Interval, SCH Interval,
36 // Guard Interval and Sync Interval
37 // - current interval state for current time and future time
38 // - channel coordination events notified at the correct time.
40 {
41 public:
43  virtual ~ChannelCoordinationTestCase (void);
44 
45  // below three methods are used in CoordinationTestListener
46  void NotifyCchStartNow (Time duration);
47  void NotifySchStartNow (Time duration);
48  void NotifyGuardStartNow (Time duration, bool inCchInterval);
49 private:
50  void TestIntervalAfter (bool cchi, bool schi, bool guardi);
51  virtual void DoRun (void);
53 
54 };
55 
56 // CoordinationTestListener is used to test channel coordination events
58 {
59 public:
61  : m_coordinatorTest (coordinatorTest)
62  {
63  }
65  {
66  }
67  virtual void NotifyCchSlotStart (Time duration)
68  {
69  m_coordinatorTest->NotifyCchStartNow (duration);
70  }
71  virtual void NotifySchSlotStart (Time duration)
72  {
73  m_coordinatorTest->NotifySchStartNow (duration);
74  }
75  virtual void NotifyGuardSlotStart (Time duration, bool cchi)
76  {
77  m_coordinatorTest->NotifyGuardStartNow (duration, cchi);
78  }
80 };
81 
83  : TestCase ("channel-coordination")
84 {
85 }
87 {
88 }
89 
90 void
91 ChannelCoordinationTestCase::TestIntervalAfter (bool cchi, bool schi, bool guardi)
92 {
93  uint32_t now = Now ().GetMilliSeconds ();
94  NS_TEST_EXPECT_MSG_EQ (m_coordinator->IsCchInterval (), cchi, "now is " << now << "ms "
95  "check whether is CCH interval");
96  NS_TEST_EXPECT_MSG_EQ (m_coordinator->IsSchInterval (), schi, "now is " << now << "ms "
97  "check whether is SCH interval");
98  NS_TEST_EXPECT_MSG_EQ (m_coordinator->IsGuardInterval (), guardi, "now is " << now << "ms "
99  "check whether is Guard interval");
100 }
101 void
103 {
104  // this method shall be called at 4ms, 104ms, ... synci * n + guardi
105  // synci is sync interval with default value 100ms
106  // guardi is guard interval with default value 4ms
107  // n is sequence number
108  int64_t now = Now ().GetMilliSeconds ();
109  int64_t synci = m_coordinator->GetSyncInterval ().GetMilliSeconds ();
110  int64_t guardi = m_coordinator->GetGuardInterval ().GetMilliSeconds ();
111  bool test = (((now - guardi) % synci) == 0);
112  NS_TEST_EXPECT_MSG_EQ (test, true, "the time of now shall be synci * n + guardi");
113 
114  // besides that, the argument duration shall be cchi - guardi
116  NS_TEST_EXPECT_MSG_EQ ((duration == d), true, "the duration shall be cchi - guardi");
117 }
118 
119 void
121 {
122  // this method shall be called at 54ms, 154ms, ... synci * n + cchi + guardi
123  // synci is sync interval with default value 100ms
124  // cchi is CCH interval with default value 50ms
125  // guardi is guard interval with default value 4ms
126  // n is sequence number
127  int64_t now = Now ().GetMilliSeconds ();
128  int64_t synci = m_coordinator->GetSyncInterval ().GetMilliSeconds ();
129  int64_t cchi = m_coordinator->GetCchInterval ().GetMilliSeconds ();
130  int64_t guardi = m_coordinator->GetGuardInterval ().GetMilliSeconds ();
131  bool test = ((now - guardi - cchi) % synci == 0);
132  NS_TEST_EXPECT_MSG_EQ (test, true, "the time of now shall be synci * n + cchi + guardi");
133 
134  // besides that, the argument duration shall be schi - guardi
136  NS_TEST_EXPECT_MSG_EQ ((duration == d), true, "the duration shall be schi - guardi");
137 }
138 
139 void
141 {
142  int64_t now = Now ().GetMilliSeconds ();
143  int64_t sync = m_coordinator->GetSyncInterval ().GetMilliSeconds ();
144  int64_t cchi = m_coordinator->GetCchInterval ().GetMilliSeconds ();
145  bool test = false;
146  if (inCchInterval)
147  {
148  // if cchi, this method will be called at 0ms, 100ms, sync * n
149  test = ((now % sync) == 0);
150  NS_TEST_EXPECT_MSG_EQ (test, true, "the time of now shall be sync * n");
151  }
152  else
153  {
154  // if schi, this method will be called at 50ms, 150ms, sync * n + cchi
155  test = (((now - cchi) % sync) == 0);
156  NS_TEST_EXPECT_MSG_EQ (test, true, "the time of now shall be sync * n");
157  }
158  // the duration shall be guardi
159  test = (duration == m_coordinator->GetGuardInterval ());
160  NS_TEST_EXPECT_MSG_EQ (test, true, "the duration shall be guard interval");
161 }
162 
163 void
165 {
166  // first test configure method
167  m_coordinator = CreateObject<ChannelCoordinator> ();
168  NS_TEST_EXPECT_MSG_EQ (m_coordinator->GetCchInterval (), MilliSeconds (50), "normally CCH interval is 50ms");
169  NS_TEST_EXPECT_MSG_EQ (m_coordinator->GetSchInterval (), MilliSeconds (50), "normally SCH interval is 50ms");
170  NS_TEST_EXPECT_MSG_EQ (m_coordinator->GetSyncInterval (), MilliSeconds (100), "normally Sync interval is 50ms");
171  NS_TEST_EXPECT_MSG_EQ (m_coordinator->GetGuardInterval (), MilliSeconds (4), "normally Guard interval is 50ms");
174  NS_TEST_EXPECT_MSG_EQ (m_coordinator->IsValidConfig (), true, "valid configuration of channel intervals");
177  NS_TEST_EXPECT_MSG_EQ (m_coordinator->IsValidConfig (), false, "invalid configuration of channel intervals");
181  NS_TEST_EXPECT_MSG_EQ (m_coordinator->IsValidConfig (), false, "invalid configuration of channel intervals");
182 
183  // second test member method
184  m_coordinator = CreateObject<ChannelCoordinator> ();
185  Simulator::Schedule (MilliSeconds (0), &ChannelCoordinationTestCase::TestIntervalAfter, this, true, false, true);
186  Simulator::Schedule (MilliSeconds (1), &ChannelCoordinationTestCase::TestIntervalAfter, this, true, false, true);
187  Simulator::Schedule (MilliSeconds (3), &ChannelCoordinationTestCase::TestIntervalAfter, this, true, false, true);
188  Simulator::Schedule (MilliSeconds (4), &ChannelCoordinationTestCase::TestIntervalAfter, this, true, false, false);
189  Simulator::Schedule (MilliSeconds (5), &ChannelCoordinationTestCase::TestIntervalAfter, this, true, false, false);
190  Simulator::Schedule (MilliSeconds (50), &ChannelCoordinationTestCase::TestIntervalAfter, this, false, true, true);
191  Simulator::Schedule (MilliSeconds (51), &ChannelCoordinationTestCase::TestIntervalAfter, this, false, true, true);
192  Simulator::Schedule (MilliSeconds (53), &ChannelCoordinationTestCase:: TestIntervalAfter, this, false, true, true);
193  Simulator::Schedule (MilliSeconds (54), &ChannelCoordinationTestCase::TestIntervalAfter, this, false, true, false);
194  Simulator::Schedule (MilliSeconds (55), &ChannelCoordinationTestCase::TestIntervalAfter, this, false, true, false);
195  Simulator::Schedule (MilliSeconds (100), &ChannelCoordinationTestCase::TestIntervalAfter, this, true, false, true);
196  Simulator::Schedule (MilliSeconds (200), &ChannelCoordinationTestCase::TestIntervalAfter, this, true, false, true);
197  Simulator::Schedule (MilliSeconds (201), &ChannelCoordinationTestCase::TestIntervalAfter, this, true, false, true);
198  Simulator::Schedule (MilliSeconds (203), &ChannelCoordinationTestCase::TestIntervalAfter, this, true, false, true);
199  Simulator::Schedule (MilliSeconds (204), &ChannelCoordinationTestCase::TestIntervalAfter, this, true, false, false);
200  Simulator::Schedule (MilliSeconds (205), &ChannelCoordinationTestCase::TestIntervalAfter, this, true, false, false);
201  Simulator::Schedule (MilliSeconds (250), &ChannelCoordinationTestCase::TestIntervalAfter, this, false, true, true);
202  Simulator::Schedule (MilliSeconds (251), &ChannelCoordinationTestCase::TestIntervalAfter, this, false, true, true);
203  Simulator::Schedule (MilliSeconds (253), &ChannelCoordinationTestCase:: TestIntervalAfter, this, false, true, true);
204  Simulator::Schedule (MilliSeconds (254), &ChannelCoordinationTestCase::TestIntervalAfter, this, false, true, false);
205  Simulator::Schedule (MilliSeconds (255), &ChannelCoordinationTestCase::TestIntervalAfter, this, false, true, false);
206  Simulator::Schedule (MilliSeconds (300), &ChannelCoordinationTestCase::TestIntervalAfter, this, true, false, true);
207  Simulator::Stop (Seconds (1.0));
208  Simulator::Run ();
209  Simulator::Destroy ();
210 
211  m_coordinator = CreateObject<ChannelCoordinator> ();
212  // third test channel coordination events
213  Ptr<CoordinationTestListener> ptr = Create<CoordinationTestListener> (this);
214  m_coordinator->RegisterListener (ptr);
215  Simulator::Stop (Seconds (100.0));
216  Simulator::Run ();
217  Simulator::Destroy ();
218 }
219 
221 {
222 public:
223  static NetDeviceContainer CreatWaveDevice (uint32_t nodesNumber = 2);
224 };
225 
226 #define PI 3.14159265
227 
229 TestCaseHelper::CreatWaveDevice (uint32_t nodesNumber)
230 {
232  nodes.Create (nodesNumber);
233 
234  MobilityHelper mobility;
235  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
236  mobility.Install (nodes);
237  // this is a circle with radius 10
238  Ptr<MobilityModel> model = NodeList::GetNode (0)->GetObject<MobilityModel> ();
239  model->SetPosition (Vector (0, 0, 0));
240  for (uint32_t n = 1; n != nodesNumber; ++n)
241  {
242  double angle = (PI / 180) * (360 / (nodesNumber - 1) * n);
243  double x = cos (angle) * 10;
244  double y = sin (angle) * 10;
245  Ptr<MobilityModel> model = NodeList::GetNode (n)->GetObject<MobilityModel> ();
246  model->SetPosition (Vector (x, y,0));
247  }
248 
249  YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default ();
250  YansWavePhyHelper wifiPhy = YansWavePhyHelper::Default ();
251  wifiPhy.SetChannel (wifiChannel.Create ());
252  QosWaveMacHelper waveMac = QosWaveMacHelper::Default ();
253  WaveHelper waveHelper = WaveHelper::Default ();
254  NetDeviceContainer devices = waveHelper.Install (wifiPhy, waveMac, nodes);
255  return devices;
256 }
257 
263 {
264 public:
265  ChannelRoutingTestCase (void);
266  virtual ~ChannelRoutingTestCase (void);
267 
268  // send IP-based packets
269  // shouldSuccess is used to check whether packet sent should be successful.
270  void SendIp (bool shouldSucceed, bool ipv6);
271  // send WSMP or other packets
272  // shouldSuccess is used to check whether packet sent should be successful.
273  void SendWsmp (bool shouldSucceed, const TxInfo &txInfo);
274  // send VSA management frames
275  // shouldSuccess is used to check whether packet sent should be successful.
276  void SendWsa (bool shouldSucceed, const VsaInfo &vsaInfo);
277 
278 private:
279  virtual void DoRun (void);
280  bool Receive (Ptr<NetDevice> dev, Ptr<const Packet> pkt, uint16_t mode, const Address &sender);
281  bool ReceiveVsa (Ptr<const Packet>,const Address &, uint32_t, uint32_t);
282 
284 };
285 
287  : TestCase ("channel-routing")
288 {
289 
290 }
292 {
293 
294 }
295 void
296 ChannelRoutingTestCase::SendWsmp (bool shouldSucceed, const TxInfo &txInfo)
297 {
298  Ptr<Packet> packet = Create<Packet> (100);
299  const Address dest = Mac48Address::GetBroadcast ();
300  uint16_t protocol = 0x80dd; // any number is OK even ipv4 and ipv6
301  bool result = m_sender->SendX (packet, dest, protocol, txInfo);
302  NS_TEST_EXPECT_MSG_EQ (result, shouldSucceed, "test SendWsmp method error");
303 }
304 void
305 ChannelRoutingTestCase::SendIp (bool shouldSucceed, bool ipv6)
306 {
307  Ptr<Packet> packet = Create<Packet> (100);
308  const Address dest = Mac48Address::GetBroadcast ();
309  const static uint16_t IPv4_PROT_NUMBER = 0x0800;
310  const static uint16_t IPv6_PROT_NUMBER = 0x86DD;
311  uint16_t protocol = ipv6 ? IPv6_PROT_NUMBER : IPv4_PROT_NUMBER;
312  bool result = m_sender->Send (packet, dest, protocol);
313  NS_TEST_EXPECT_MSG_EQ (result, shouldSucceed, "test SendIp method error");
314 }
315 
316 void
317 ChannelRoutingTestCase::SendWsa (bool shouldSucceed, const VsaInfo &vsaInfo)
318 {
319  bool result = m_sender->StartVsa (vsaInfo);
320  NS_TEST_EXPECT_MSG_EQ (result, shouldSucceed, "test SendWsa method error");
321 }
322 
323 void
325 {
326  // check SendX method for WSMP packets
327  {
329  m_sender = DynamicCast<WaveNetDevice> (devices.Get (0));
330 
331  Simulator::Schedule (Seconds (0.1), &ChannelRoutingTestCase::SendWsmp, this, true, TxInfo (CCH));
332  Simulator::Schedule (Seconds (0.1), &ChannelRoutingTestCase::SendWsmp, this, false, TxInfo (SCH1));
333  Simulator::Schedule (Seconds (0.1), &ChannelRoutingTestCase::SendWsmp, this, false, TxInfo (SCH2));
334 
335  const SchInfo schInfo = SchInfo (SCH1, false, EXTENDED_ALTERNATING);
336  Simulator::Schedule (Seconds (0.2), &WaveNetDevice::StartSch, m_sender, schInfo);
337 
338  Simulator::Schedule (Seconds (0.3), &ChannelRoutingTestCase::SendWsmp, this, true, TxInfo (CCH));
339  Simulator::Schedule (Seconds (0.3), &ChannelRoutingTestCase::SendWsmp, this, true, TxInfo (SCH1));
340  Simulator::Schedule (Seconds (0.3), &ChannelRoutingTestCase::SendWsmp, this, false, TxInfo (SCH2));
341  Simulator::Schedule (Seconds (0.3), &ChannelRoutingTestCase::SendWsmp, this, false, TxInfo (SCH3));
342  Simulator::Schedule (Seconds (0.3), &ChannelRoutingTestCase::SendWsmp, this, false, TxInfo (SCH4));
343  Simulator::Schedule (Seconds (0.3), &ChannelRoutingTestCase::SendWsmp, this, false, TxInfo (SCH5));
344  Simulator::Schedule (Seconds (0.3), &ChannelRoutingTestCase::SendWsmp, this, false, TxInfo (SCH6));
345 
346  // invalid channel number
347  Simulator::Schedule (Seconds (0.4), &ChannelRoutingTestCase::SendWsmp, this, false, TxInfo (0));
348  // invalid user priority
349  Simulator::Schedule (Seconds (0.4), &ChannelRoutingTestCase::SendWsmp, this, false, TxInfo (CCH, 8));
350  // invalid tx parameters
351  Simulator::Schedule (Seconds (0.4), &ChannelRoutingTestCase::SendWsmp, this, false, TxInfo (CCH, 7, WifiMode ("OfdmRate6Mbps"), 7));
352  Simulator::Schedule (Seconds (0.4), &ChannelRoutingTestCase::SendWsmp, this, false, TxInfo (CCH, 7, WifiMode ("OfdmRate3MbpsBW10MHz"), 10));
353  // valid tx parameters
354  Simulator::Schedule (Seconds (0.4), &ChannelRoutingTestCase::SendWsmp, this, true, TxInfo (CCH, 7, WifiMode ("OfdmRate3MbpsBW10MHz"), 7));
355  Simulator::Schedule (Seconds (0.4), &ChannelRoutingTestCase::SendWsmp, this, true, TxInfo (CCH, 7, WifiMode (), 8));
356 
357  // release channel access at 0.6s
358  Simulator::Schedule (Seconds (0.5), &WaveNetDevice::StopSch, m_sender, SCH1);
359 
360  // the packet will be dropped because channel access is not assigned again
361  Simulator::Schedule (Seconds (0.6), &ChannelRoutingTestCase::SendWsmp, this, true, TxInfo (CCH));
362  Simulator::Schedule (Seconds (0.6), &ChannelRoutingTestCase::SendWsmp, this, false, TxInfo (SCH1));
363  Simulator::Schedule (Seconds (0.6), &ChannelRoutingTestCase::SendWsmp, this, false, TxInfo (SCH2));
364 
365  Simulator::Stop (Seconds (1.0));
366  Simulator::Run ();
367  Simulator::Destroy ();
368  }
369 
370  // check Send method for IP-based packets
371  {
373  m_sender = DynamicCast<WaveNetDevice> (devices.Get (0));
374 
375  bool ipv6 = true, ipv4 = false;
376  Simulator::Schedule (Seconds (0.1), &ChannelRoutingTestCase::SendIp, this, false, ipv6);
377  Simulator::Schedule (Seconds (0.1), &ChannelRoutingTestCase::SendIp, this, false, ipv4);
378 
379  const SchInfo schInfo = SchInfo (SCH1, false, EXTENDED_ALTERNATING);
380  Simulator::Schedule (Seconds (0.2), &WaveNetDevice::StartSch, m_sender, schInfo);
381 
382  Simulator::Schedule (Seconds (0.3), &ChannelRoutingTestCase::SendIp, this, false, ipv6);
383  Simulator::Schedule (Seconds (0.3), &ChannelRoutingTestCase::SendIp, this, false, ipv4);
384 
385  TxProfile txProfile = TxProfile (SCH1);
386  Simulator::Schedule (Seconds (0.4), &WaveNetDevice::RegisterTxProfile, m_sender, txProfile);
387 
388  Simulator::Schedule (Seconds (0.5), &ChannelRoutingTestCase::SendIp, this, true, ipv6);
389  Simulator::Schedule (Seconds (0.5), &ChannelRoutingTestCase::SendIp, this, true, ipv4);
390 
391  // unregister txprofile
392  Simulator::Schedule (Seconds (0.5), &WaveNetDevice::DeleteTxProfile, m_sender,SCH1);
393 
394  Simulator::Schedule (Seconds (0.6), &ChannelRoutingTestCase::SendIp, this, false, ipv6);
395  Simulator::Schedule (Seconds (0.6), &ChannelRoutingTestCase::SendIp, this, false, ipv4);
396 
397  // release channel access
398  // mac entities have no channel resource even phy device has ability to send
399  Simulator::Schedule (Seconds (0.7),&WaveNetDevice::StopSch, m_sender, SCH1);
400 
401  Simulator::Schedule (Seconds (0.8), &ChannelRoutingTestCase::SendIp, this, false, ipv6);
402  Simulator::Schedule (Seconds (0.8), &ChannelRoutingTestCase::SendIp, this, false, ipv4);
403 
404  Simulator::Stop (Seconds (1.0));
405  Simulator::Run ();
406  Simulator::Destroy ();
407  }
408 
409  // check StartVsa method for WSA management frames
410  {
412  m_sender = DynamicCast<WaveNetDevice> (devices.Get (0));
413 
414  Ptr<Packet> packet = Create<Packet> (100);
415  const Mac48Address dest = Mac48Address::GetBroadcast ();
416  VsaInfo vsaInfo = VsaInfo (dest, OrganizationIdentifier (), 3, packet, SCH1, 50, VSA_TRANSMIT_IN_BOTHI);
417  Simulator::Schedule (Seconds (0.1), &ChannelRoutingTestCase::SendWsa, this, false, vsaInfo);
418 
419  vsaInfo.channelNumber = 0;
420  Simulator::Schedule (Seconds (0.2), &ChannelRoutingTestCase::SendWsa, this, false, vsaInfo);
421 
422  vsaInfo.channelNumber = CCH;
423  Simulator::Schedule (Seconds (0.3), &ChannelRoutingTestCase::SendWsa, this, true, vsaInfo);
424  Simulator::Schedule (Seconds (0.39), &WaveNetDevice::StopVsa, m_sender, CCH);
425 
426  const SchInfo schInfo = SchInfo (SCH1, false, EXTENDED_ALTERNATING);
427  Simulator::Schedule (Seconds (0.4), &WaveNetDevice::StartSch, m_sender, schInfo);
428  vsaInfo.channelNumber = CCH;
429  Simulator::Schedule (Seconds (0.4), &ChannelRoutingTestCase::SendWsa, this, true, vsaInfo);
430  vsaInfo.channelNumber = SCH1;
431  Simulator::Schedule (Seconds (0.4), &ChannelRoutingTestCase::SendWsa, this, true, vsaInfo);
432  vsaInfo.channelNumber = SCH2;
433  Simulator::Schedule (Seconds (0.4), &ChannelRoutingTestCase::SendWsa, this, false, vsaInfo);
434 
435  Simulator::Schedule (Seconds (0.49), &WaveNetDevice::StopVsa, m_sender, CCH);
436  Simulator::Schedule (Seconds (0.49), &WaveNetDevice::StopVsa, m_sender, SCH1);
437  Simulator::Schedule (Seconds (0.49),&WaveNetDevice::StopSch, m_sender, SCH1);
438 
439  vsaInfo.channelNumber = CCH;
440  Simulator::Schedule (Seconds (0.5), &ChannelRoutingTestCase::SendWsa, this, true, vsaInfo);
441  vsaInfo.channelNumber = SCH1;
442  Simulator::Schedule (Seconds (0.5), &ChannelRoutingTestCase::SendWsa, this, false, vsaInfo);
443  vsaInfo.channelNumber = SCH2;
444  Simulator::Schedule (Seconds (0.5), &ChannelRoutingTestCase::SendWsa, this, false, vsaInfo);
445 
446  Simulator::Stop (Seconds (1.0));
447  Simulator::Run ();
448  Simulator::Destroy ();
449  }
450 }
451 
452 // This test case tests channel access assignments which is done by
453 // StartSch and StopSch method of WaveNetDevice.
454 // channel access assignments include ContinuousAccess, ExtendedAccess,
455 // and AlternatingAccess.
456 // The results of this test case depend on the implementation of ChannelScheduler
457 // In this case, the results depend on class "DefaultChannelScheduler".
459 {
460 public:
461  ChannelAccessTestCase (void);
462  virtual ~ChannelAccessTestCase (void);
463 private:
464  void TestContinuous (SchInfo &info, bool shouldSuccceed);
465  void TestContinuousAfter (uint32_t channelNumber, bool isAccessAssigned);
466  void TestExtended (SchInfo &info, bool shouldSuccceed);
467  void TestExtendedAfter (uint32_t channelNumber, bool isAccessAssigned);
468  void TestAlternating (SchInfo &info, bool shouldSuccceed);
469  void TestAlternatingAfter (uint32_t channelNumber, bool isAccessAssigned);
470 
471  void SendX (uint32_t channel, uint32_t receiverId);
472  bool Receive (Ptr<NetDevice> dev, Ptr<const Packet> pkt, uint16_t mode, const Address &sender);
473 
474  virtual void DoRun (void);
475 
478  uint32_t m_received;
479 };
480 
482  : TestCase ("channel-access")
483 {
484 }
486 {
487 
488 }
489 void
490 ChannelAccessTestCase::TestContinuous (SchInfo &info, bool shouldSuccceed)
491 {
492  bool result = m_sender->StartSch (info);
493  NS_TEST_EXPECT_MSG_EQ (result, shouldSuccceed, "TestContinuous fail at " << Now ().GetSeconds ());
494 }
495 void
496 ChannelAccessTestCase::TestContinuousAfter (uint32_t channelNumber, bool isAccessAssigned)
497 {
498  bool result = m_sender->GetChannelScheduler ()->IsContinuousAccessAssigned (channelNumber);
499  NS_TEST_EXPECT_MSG_EQ (result, isAccessAssigned, "TestContinuousAfter fail at " << Now ().GetSeconds ());
500 }
501 void
502 ChannelAccessTestCase::TestExtended (SchInfo &info, bool shouldSuccceed)
503 {
504  bool result = m_sender->StartSch (info);
505  NS_TEST_EXPECT_MSG_EQ (result, shouldSuccceed, "TestExtended fail at " << Now ().GetSeconds ());
506 }
507 void
508 ChannelAccessTestCase::TestExtendedAfter (uint32_t channelNumber, bool isAccessAssigned)
509 {
510  bool result = m_sender->GetChannelScheduler ()->IsExtendedAccessAssigned (channelNumber);
511  NS_TEST_EXPECT_MSG_EQ (result, isAccessAssigned, "TestExtendedAfter fail at " << Now ().GetSeconds ());
512 }
513 
514 void
516 {
517  bool result = m_sender->StartSch (info);
518  NS_TEST_EXPECT_MSG_EQ (result, shouldSuccceed, "TestAlternating fail at " << Now ().GetSeconds ());
519 }
520 void
521 ChannelAccessTestCase::TestAlternatingAfter (uint32_t channelNumber, bool isAccessAssigned)
522 {
523  bool result = m_sender->GetChannelScheduler ()->IsAlternatingAccessAssigned (channelNumber);
524  NS_TEST_EXPECT_MSG_EQ (result, isAccessAssigned, "TestAlternating fail at " << Now ().GetSeconds ());
525 }
526 
527 void
528 ChannelAccessTestCase::SendX (uint32_t channel, uint32_t receiverId)
529 {
530  const static uint16_t WSMP_PROT_NUMBER = 0x88DC;
531  const Mac48Address dest = Mac48Address::GetBroadcast ();
532  const TxInfo txInfo = TxInfo (channel);
533  Ptr<Packet> p = Create<Packet> (100);
534  // the sequence here indicates the node id which should receive transmitted packets.
535  SeqTsHeader seqTs;
536  seqTs.SetSeq (receiverId);
537  p->AddHeader (seqTs);
538  m_sender->SendX (p, dest, WSMP_PROT_NUMBER, txInfo);
539 }
540 
541 bool
543 {
544  SeqTsHeader seqTs;
545  ConstCast<Packet> (pkt)->RemoveHeader (seqTs);
546  uint32_t curNodeId = dev->GetNode ()->GetId ();
547  NS_TEST_EXPECT_MSG_EQ (curNodeId, seqTs.GetSeq (), "fail to assign channel access");
548  m_received++;
549  return true;
550 }
551 
552 void
554 {
555  // test ContinuousAccess in the sender side
556  {
558  m_sender = DynamicCast<WaveNetDevice> (m_devices.Get (0));
559 
560  // there is no need for assigning CCH continuous access.
561  SchInfo info = SchInfo (CCH, false, EXTENDED_CONTINUOUS);
562  Simulator::Schedule (Seconds (1), &ChannelAccessTestCase::TestContinuous, this, info, false);
563 
564  info = SchInfo (SCH1, false, EXTENDED_CONTINUOUS);
565  Simulator::Schedule (Seconds (2), &ChannelAccessTestCase::TestContinuous, this, info, true);
566 
567  // BE ATTENTION !!!
568  // because channel access is assigned in non-immediate mode, the first CCH Interval will be
569  // the wait time with DefaultCchAccess assigned, thus there is no ContinuousAccess assigned.
570  Simulator::Schedule (Seconds (2), &ChannelAccessTestCase::TestContinuousAfter, this, SCH1, false);
571  Simulator::Schedule (Seconds (2.01), &ChannelAccessTestCase::TestContinuousAfter, this, SCH1, false);
572  Simulator::Schedule (Seconds (2.049), &ChannelAccessTestCase::TestContinuousAfter, this, SCH1, false);
573  Simulator::Schedule (Seconds (2.05), &ChannelAccessTestCase::TestContinuousAfter, this, SCH1, false);
574  Simulator::Schedule (Seconds (2.051), &ChannelAccessTestCase::TestContinuousAfter, this, SCH1, true);
575  Simulator::Schedule (Seconds (2.99), &ChannelAccessTestCase::TestContinuousAfter, this, SCH1, true);
576 
577  // it's OK to assign same access again,
578  Simulator::Schedule (Seconds (3), &ChannelAccessTestCase::TestContinuous, this, info, true);
579  // fail to assign continuous access for other SCH if current channel is assigned
580  info = SchInfo (SCH2, false, EXTENDED_CONTINUOUS);
581  Simulator::Schedule (Seconds (4), &ChannelAccessTestCase::TestContinuous, this, info, false);
582 
583  // then we release channel access at 0.5s
584  Simulator::Schedule (Seconds (5), &WaveNetDevice::StopSch, m_sender, SCH1);
585 
586  info = SchInfo (SCH2, false, EXTENDED_CONTINUOUS);
587  // succeed to assign access for other SCH is previous SCH access is released
588  Simulator::Schedule (Seconds (6), &ChannelAccessTestCase::TestContinuous, this, info, true);
589 
590  Simulator::Stop (Seconds (7.0));
591  Simulator::Run ();
592  Simulator::Destroy ();
593  }
594 
595  // test ContinuousAccess again in the receiver side
596  {
598  m_sender = DynamicCast<WaveNetDevice> (m_devices.Get (0));
599  m_received = 0;
600 
601  for (uint32_t i = 1; i != 8; ++i)
602  {
603  Ptr<WaveNetDevice> device = DynamicCast<WaveNetDevice> (m_devices.Get (i));
605 
606  // at 0s, receivers are assigned ContinuousAccess from CCH, SCH1 to SCH6
607  static std::vector<uint32_t> WaveChannels = ChannelManager::GetWaveChannels ();
608  uint32_t channel = WaveChannels[i - 1];
609  const SchInfo info = SchInfo (channel, false, EXTENDED_CONTINUOUS);
610  Simulator::Schedule (Seconds (0), &WaveNetDevice::StartSch, device, info);
611  }
612 
613  // at 0s, the sender is assigned DefaultCchAccess, so only node-1 can receive packets.
614  Simulator::Schedule (Seconds (0.1), &ChannelAccessTestCase::SendX, this, CCH, 1);
615  // if receivers assigned for SCH access can receive packets, there shall be crashed
616  Simulator::Schedule (Seconds (0.1), &ChannelAccessTestCase::SendX, this, SCH1, 0);
617  Simulator::Schedule (Seconds (0.1), &ChannelAccessTestCase::SendX, this, SCH2, 0);
618  Simulator::Schedule (Seconds (0.1), &ChannelAccessTestCase::SendX, this, SCH3, 0);
619  Simulator::Schedule (Seconds (0.1), &ChannelAccessTestCase::SendX, this, SCH4, 0);
620  Simulator::Schedule (Seconds (0.1), &ChannelAccessTestCase::SendX, this, SCH5, 0);
621  Simulator::Schedule (Seconds (0.1), &ChannelAccessTestCase::SendX, this, SCH6, 0);
622 
623  // at 1s, the sender is assigned ContinuousAccess for SCH1, so only node-2 can receive packets.
624  SchInfo info = SchInfo (SCH1, false, EXTENDED_CONTINUOUS);
625  Simulator::Schedule (Seconds (1), &WaveNetDevice::StartSch, m_sender, info);
626  Simulator::Schedule (Seconds (1.1), &ChannelAccessTestCase::SendX, this, SCH1, 2);
627  // other channel access cannot receive packets
628  Simulator::Schedule (Seconds (1.1), &ChannelAccessTestCase::SendX, this, CCH, 0);
629  Simulator::Schedule (Seconds (1.1), &ChannelAccessTestCase::SendX, this, SCH2, 0);
630  Simulator::Schedule (Seconds (1.1), &ChannelAccessTestCase::SendX, this, SCH3, 0);
631  Simulator::Schedule (Seconds (1.1), &ChannelAccessTestCase::SendX, this, SCH4, 0);
632  Simulator::Schedule (Seconds (1.1), &ChannelAccessTestCase::SendX, this, SCH5, 0);
633  Simulator::Schedule (Seconds (1.1), &ChannelAccessTestCase::SendX, this, SCH6, 0);
634 
635  Simulator::Stop (Seconds (10.0));
636  Simulator::Run ();
637  Simulator::Destroy ();
638 
639  NS_TEST_EXPECT_MSG_EQ (m_received, 2, "test ContinuousAccess fail in receive side");
640  }
641 
642  // test ExtendedAccess in the sender side
643  {
645  m_sender = DynamicCast<WaveNetDevice> (m_devices.Get (0));
646 
647  // there is no need for assigning CCH extended access.
648  SchInfo info = SchInfo (CCH, false, 10);
649  Simulator::Schedule (Seconds (1), &ChannelAccessTestCase::TestExtended, this, info, false);
650 
651  info = SchInfo (SCH1, false, 10);
652  Simulator::Schedule (Seconds (2), &ChannelAccessTestCase::TestExtended, this, info, true);
653  // succeed because request for extends 8 can be fulfilled by previous extends 10..
654  info = SchInfo (SCH1, false, 8);
655  Simulator::Schedule (Seconds (2), &ChannelAccessTestCase::TestExtended, this, info, true);
656  // fail because request for extends 12 cannot be fulfilled by previous extends 10..
657  info = SchInfo (SCH1, false, 12);
658  Simulator::Schedule (Seconds (2), &ChannelAccessTestCase::TestExtended, this, info, false);
659 
660  // BE ATTENTION !!!
661  // because channel access is assigned in non-immediate mode, the first CCH Interval will be
662  // the wait time with DefaultCchAccess assigned, while there is no ExtendedAccess assigned.
663  Simulator::Schedule (Seconds (2), &ChannelAccessTestCase::TestExtendedAfter, this, SCH1, false);
664  Simulator::Schedule (Seconds (2.01), &ChannelAccessTestCase::TestExtendedAfter, this, SCH1, false);
665  Simulator::Schedule (Seconds (2.049), &ChannelAccessTestCase::TestExtendedAfter, this, SCH1, false);
666  Simulator::Schedule (Seconds (2.05), &ChannelAccessTestCase::TestExtendedAfter, this, SCH1, false);
667  Simulator::Schedule (Seconds (2.051), &ChannelAccessTestCase::TestExtendedAfter, this, SCH1, true);
668  Simulator::Schedule (Seconds (2.99), &ChannelAccessTestCase::TestExtendedAfter, this, SCH1, true);
669 
670  // the end of extended access is (2s + 100ms + 100ms * 10) = 3.1s
671  Simulator::Schedule (Seconds (3), &ChannelAccessTestCase::TestExtendedAfter, this, SCH1, true);
672  Simulator::Schedule (Seconds (3.1), &ChannelAccessTestCase::TestExtendedAfter, this, SCH1, true);
673  Simulator::Schedule (Seconds (3.2), &ChannelAccessTestCase::TestExtendedAfter, this, SCH1, false);
674  Simulator::Schedule (Seconds (3.3), &ChannelAccessTestCase::TestExtendedAfter, this, SCH1, false);
675 
676  // succeed to assign extended access for other SCH since previous extended access is released automatically
677  info = SchInfo (SCH2, false, 10);
678  Simulator::Schedule (Seconds (4), &ChannelAccessTestCase::TestExtended, this, info, true);
679 
680  // stop it at 5s even the end of extended access is (4s + 100ms + 100ms * 10) = 5.1s
681  Simulator::Schedule (Seconds (5), &WaveNetDevice::StopSch, m_sender, SCH2);
682 
683  Simulator::Schedule (Seconds (5), &ChannelAccessTestCase::TestExtendedAfter, this, SCH2, false);
684  Simulator::Schedule (Seconds (5.1), &ChannelAccessTestCase::TestExtendedAfter, this, SCH2, false);
685  Simulator::Schedule (Seconds (5.2), &ChannelAccessTestCase::TestExtendedAfter, this, SCH2, false);
686 
687  Simulator::Stop (Seconds (6.0));
688  Simulator::Run ();
689  Simulator::Destroy ();
690  }
691 
692  // test ExtendedAccess again in the receiver side
693  {
695  m_sender = DynamicCast<WaveNetDevice> (m_devices.Get (0));
696  m_received = 0;
697 
698  for (uint32_t i = 1; i != 8; ++i)
699  {
700  Ptr<WaveNetDevice> device = DynamicCast<WaveNetDevice> (m_devices.Get (i));
702 
703  // at 0s, receivers are assigned ContinuosAccess from CCH, SCH1 to SCH6
704  static std::vector<uint32_t> WaveChannels = ChannelManager::GetWaveChannels ();
705  uint32_t channel = WaveChannels[i - 1];
706  const SchInfo info = SchInfo (channel, false, EXTENDED_CONTINUOUS);
707  Simulator::Schedule (Seconds (0), &WaveNetDevice::StartSch, device, info);
708  }
709 
710  // at 0s, the sender is assigned DefaultCchAccess, so only node-1 can receive packets.
711  Simulator::Schedule (Seconds (0.1), &ChannelAccessTestCase::SendX, this, CCH, 1);
712  // if receivers assigned for SCH access can receive packets, there shall be crashed
713  Simulator::Schedule (Seconds (0.1), &ChannelAccessTestCase::SendX, this, SCH1, 0);
714  Simulator::Schedule (Seconds (0.1), &ChannelAccessTestCase::SendX, this, SCH2, 0);
715  Simulator::Schedule (Seconds (0.1), &ChannelAccessTestCase::SendX, this, SCH3, 0);
716  Simulator::Schedule (Seconds (0.1), &ChannelAccessTestCase::SendX, this, SCH4, 0);
717  Simulator::Schedule (Seconds (0.1), &ChannelAccessTestCase::SendX, this, SCH5, 0);
718  Simulator::Schedule (Seconds (0.1), &ChannelAccessTestCase::SendX, this, SCH6, 0);
719 
720  // at 1s, the sender is assigned ExtendedAccess for SCH1 with extends 10,
721  //, so only node-2 can receive packets from 1s - 2.1s ( 1s + 100ms + 100ms * 10)
722  SchInfo info = SchInfo (SCH1, false, 10);
723  Simulator::Schedule (Seconds (1), &WaveNetDevice::StartSch, m_sender, info);
724  Simulator::Schedule (Seconds (1.1), &ChannelAccessTestCase::SendX, this, SCH1, 2);
725  // other channel access cannot receive packets
726  Simulator::Schedule (Seconds (1.1), &ChannelAccessTestCase::SendX, this, CCH, 0);
727  Simulator::Schedule (Seconds (1.1), &ChannelAccessTestCase::SendX, this, SCH2, 0);
728  Simulator::Schedule (Seconds (1.1), &ChannelAccessTestCase::SendX, this, SCH3, 0);
729  Simulator::Schedule (Seconds (1.1), &ChannelAccessTestCase::SendX, this, SCH4, 0);
730  Simulator::Schedule (Seconds (1.1), &ChannelAccessTestCase::SendX, this, SCH5, 0);
731  Simulator::Schedule (Seconds (1.1), &ChannelAccessTestCase::SendX, this, SCH6, 0);
732  // at 2.2s the node-2 cannot receive this packet because of extended access released in node-0
733  // but sended is assigned DefaultCchAccess again, thus node-1 can receive broadcasted packets.
734  Simulator::Schedule (Seconds (2.2), &ChannelAccessTestCase::SendX, this, CCH, 1);
735  Simulator::Schedule (Seconds (2.2), &ChannelAccessTestCase::SendX, this, SCH1, 0);
736  Simulator::Schedule (Seconds (2.2), &ChannelAccessTestCase::SendX, this, SCH2, 0);
737  Simulator::Schedule (Seconds (2.2), &ChannelAccessTestCase::SendX, this, SCH3, 0);
738  Simulator::Schedule (Seconds (2.2), &ChannelAccessTestCase::SendX, this, SCH4, 0);
739  Simulator::Schedule (Seconds (2.2), &ChannelAccessTestCase::SendX, this, SCH5, 0);
740  Simulator::Schedule (Seconds (2.2), &ChannelAccessTestCase::SendX, this, SCH6, 0);
741 
742  Simulator::Stop (Seconds (10.0));
743  Simulator::Run ();
744  Simulator::Destroy ();
745 
746  NS_TEST_EXPECT_MSG_EQ (m_received, 3, "test ExtendedAccess fail in receive side");
747  }
748 
749  // test AlternatingAccess in the sender side
750  {
752  m_sender = DynamicCast<WaveNetDevice> (m_devices.Get (0));
753 
754  // there is no need for assigning CCH alternating access.
755  SchInfo info = SchInfo (CCH, false, EXTENDED_ALTERNATING);
756  Simulator::Schedule (Seconds (1), &ChannelAccessTestCase::TestAlternating, this, info, false);
757 
758  info = SchInfo (SCH1, false, EXTENDED_ALTERNATING);
759  Simulator::Schedule (Seconds (2), &ChannelAccessTestCase::TestAlternating, this, info, true);
760 
761  // BE ATTENTION !!!
762  // No matter whether channel access is assigned in immediate mode or non-immediate mode,
763  // the channel access will assigned immediately which is different from the test results in
764  // ExtendedAccess assignment and ContinuousAccess assignment.
765  Simulator::Schedule (Seconds (2), &ChannelAccessTestCase::TestAlternatingAfter, this, SCH1, true);
766  Simulator::Schedule (Seconds (2.01), &ChannelAccessTestCase::TestAlternatingAfter, this, SCH1, true);
767  Simulator::Schedule (Seconds (2.049), &ChannelAccessTestCase::TestAlternatingAfter, this, SCH1, true);
768  Simulator::Schedule (Seconds (2.05), &ChannelAccessTestCase::TestAlternatingAfter, this, SCH1, true);
769  Simulator::Schedule (Seconds (2.051), &ChannelAccessTestCase::TestAlternatingAfter, this, SCH1, true);
770  Simulator::Schedule (Seconds (2.99), &ChannelAccessTestCase::TestAlternatingAfter, this, SCH1, true);
771 
772  Simulator::Schedule (Seconds (3), &ChannelAccessTestCase::TestAlternating, this, info, true);
773  info = SchInfo (SCH2, false, EXTENDED_ALTERNATING);
774  Simulator::Schedule (Seconds (3), &ChannelAccessTestCase::TestAlternating, this, info, false);
775  info = SchInfo (0, false, EXTENDED_ALTERNATING);
776  Simulator::Schedule (Seconds (3), &ChannelAccessTestCase::TestAlternating, this, info, false);
777 
778  // then we release channel access at 0.5s
779  Simulator::Schedule (Seconds (4), &WaveNetDevice::StopSch, m_sender, SCH1);
780 
781  info = SchInfo (SCH2, false, EXTENDED_ALTERNATING);
782  // succeed to assign access for other SCH is previous SCH access is released
783  Simulator::Schedule (Seconds (5), &ChannelAccessTestCase::TestAlternating, this, info, true);
784 
785  Simulator::Stop (Seconds (6.0));
786  Simulator::Run ();
787  Simulator::Destroy ();
788  }
789 
790  // test AlternatingAccess again in the receiver side
791  {
793  m_sender = DynamicCast<WaveNetDevice> (m_devices.Get (0));
794  m_received = 0;
795 
796  for (uint32_t i = 1; i != 8; ++i)
797  {
798  Ptr<WaveNetDevice> device = DynamicCast<WaveNetDevice> (m_devices.Get (i));
800 
801  // at 0s, receivers are assigned ContinuosAccess from CCH, SCH1 to SCH6
802  static std::vector<uint32_t> WaveChannels = ChannelManager::GetWaveChannels ();
803  uint32_t channel = WaveChannels[i - 1];
804  const SchInfo info = SchInfo (channel, false, EXTENDED_CONTINUOUS);
805  Simulator::Schedule (Seconds (0), &WaveNetDevice::StartSch, device, info);
806  }
807 
808  // at 0s, the sender is assigned DefaultCchAccess, so only node-1 can receive packets.
809  Simulator::Schedule (Seconds (0.1), &ChannelAccessTestCase::SendX, this, CCH, 1);
810  // if receivers assigned for SCH access can receive packets, there shall be crashed
811  Simulator::Schedule (Seconds (0.1), &ChannelAccessTestCase::SendX, this, SCH1, 0);
812  Simulator::Schedule (Seconds (0.1), &ChannelAccessTestCase::SendX, this, SCH2, 0);
813  Simulator::Schedule (Seconds (0.1), &ChannelAccessTestCase::SendX, this, SCH3, 0);
814  Simulator::Schedule (Seconds (0.1), &ChannelAccessTestCase::SendX, this, SCH4, 0);
815  Simulator::Schedule (Seconds (0.1), &ChannelAccessTestCase::SendX, this, SCH5, 0);
816  Simulator::Schedule (Seconds (0.1), &ChannelAccessTestCase::SendX, this, SCH6, 0);
817 
818  // at 1s, the sender is assigned ContinuosAccess for SCH1, so only node-2 can receive packets.
819  SchInfo info = SchInfo (SCH1, false, EXTENDED_ALTERNATING);
820  Simulator::Schedule (Seconds (1), &WaveNetDevice::StartSch, m_sender, info);
821  // node-1 (assigned CCH access) and node-2 (assigned SCH1 access) can receive packets
822  // in different channel interval
823  Simulator::Schedule (Seconds (1.1), &ChannelAccessTestCase::SendX, this, SCH1, 2);
824  Simulator::Schedule (Seconds (1.1), &ChannelAccessTestCase::SendX, this, CCH, 1);
825  // other channel access cannot receive packets
826  Simulator::Schedule (Seconds (1.1), &ChannelAccessTestCase::SendX, this, SCH2, 0);
827  Simulator::Schedule (Seconds (1.1), &ChannelAccessTestCase::SendX, this, SCH3, 0);
828  Simulator::Schedule (Seconds (1.1), &ChannelAccessTestCase::SendX, this, SCH4, 0);
829  Simulator::Schedule (Seconds (1.1), &ChannelAccessTestCase::SendX, this, SCH5, 0);
830  Simulator::Schedule (Seconds (1.1), &ChannelAccessTestCase::SendX, this, SCH6, 0);
831 
832  Simulator::Schedule (Seconds (2), &WaveNetDevice::StopSch, m_sender, SCH1);
833  // if ContinuousAccess for SCH1 is released, node-2 cannot receive packets again
834  Simulator::Schedule (Seconds (2.1), &ChannelAccessTestCase::SendX, this, CCH, 1);
835  Simulator::Schedule (Seconds (2.1), &ChannelAccessTestCase::SendX, this, SCH1, 0);
836  Simulator::Schedule (Seconds (2.1), &ChannelAccessTestCase::SendX, this, SCH2, 0);
837  Simulator::Schedule (Seconds (2.1), &ChannelAccessTestCase::SendX, this, SCH3, 0);
838  Simulator::Schedule (Seconds (2.1), &ChannelAccessTestCase::SendX, this, SCH4, 0);
839  Simulator::Schedule (Seconds (2.1), &ChannelAccessTestCase::SendX, this, SCH5, 0);
840  Simulator::Schedule (Seconds (2.1), &ChannelAccessTestCase::SendX, this, SCH6, 0);
841 
842  Simulator::Stop (Seconds (10.0));
843  Simulator::Run ();
844  Simulator::Destroy ();
845 
846  NS_TEST_EXPECT_MSG_EQ (m_received, 4, "test AlternatingAccess fail in receive side");
847  }
848 }
849 
850 // The Annex C of IEEE 1609.4 : "Avoiding transmission at scheduled guard intervals"
851 // This feature is implemented in WaveMacLow::StartTransmission method
852 class AnnexC_TestCase : public TestCase
853 {
854 public:
855  AnnexC_TestCase ();
856  virtual ~AnnexC_TestCase ();
857 private:
858  virtual void DoRun (void);
859 
860  void SendPacket (uint32_t packetSize, const TxInfo & txInfo, uint32_t sequence);
861  bool Receive (Ptr<NetDevice> dev, Ptr<const Packet> pkt, uint16_t mode, const Address &sender);
862 
866 };
867 
869  : TestCase ("annex-c")
870 {
871 }
872 
874 {
875 }
876 
877 void
878 AnnexC_TestCase::SendPacket (uint32_t packetSize, const TxInfo & txInfo, uint32_t sequence)
879 {
880  const static uint16_t WSMP_PROT_NUMBER = 0x88DC;
881  const Mac48Address dest = Mac48Address::ConvertFrom (m_receiver->GetAddress ());
882 // const Mac48Address dest = Mac48Address::GetBroadcast();
883 
884 
885  Ptr<Packet> p = Create<Packet> (packetSize - (8 + 4)); // 8+4 : the size of the seqTs header
886  // the sequence here indicates whether the node id which should receive transmitted packets.
887  SeqTsHeader seqTs;
888  seqTs.SetSeq (sequence);
889  p->AddHeader (seqTs);
890  m_sender->SendX (p, dest, WSMP_PROT_NUMBER, txInfo);
891 }
892 
893 bool
894 AnnexC_TestCase::Receive (Ptr<NetDevice> dev, Ptr<const Packet> pkt, uint16_t mode, const Address &sender)
895 {
896  SeqTsHeader seqTs;
897  ConstCast<Packet> (pkt)->RemoveHeader (seqTs);
898  uint32_t seq = seqTs.GetSeq ();
899  Time sendTime = seqTs.GetTs ();
900  Time curTime = Now ();
901  Time duration = curTime - sendTime;
902 
903  if (seq == 1)
904  {
905  NS_TEST_EXPECT_MSG_GT (duration, ChannelCoordinator::GetDefaultSchInterval (), "fail to test Annex C when packet sequence is " << seq);
906  }
907  else if (seq == 2)
908  {
909  NS_TEST_EXPECT_MSG_LT (duration, ChannelCoordinator::GetDefaultSchInterval (), "fail to test Annex C when packet sequence is " << seq);
910  }
911  else if (seq == 3)
912  {
913  NS_TEST_EXPECT_MSG_GT (duration, ChannelCoordinator::GetDefaultCchInterval (), "fail to test Annex C when packet sequence is " << seq);
914  }
915  else if (seq == 4)
916  {
917  NS_TEST_EXPECT_MSG_LT (duration, ChannelCoordinator::GetDefaultCchInterval (), "fail to test Annex C when packet sequence is " << seq);
918  }
919  return true;
920 }
921 
922 void
924 {
926  m_sender = DynamicCast<WaveNetDevice> (m_devices.Get (0));
927  m_receiver = DynamicCast<WaveNetDevice> (m_devices.Get (1));
929 
930  // at 0s, the receiver is assigned AlternatingAccess for SCH1
931  SchInfo infoReceiver = SchInfo (SCH1, false, EXTENDED_ALTERNATING);
932  Simulator::Schedule (MilliSeconds (0), &WaveNetDevice::StartSch, m_receiver, infoReceiver);
933 
934  // at 0s, the sender is assigned AlternatingAccess for SCH1
935  SchInfo infoSender = SchInfo (SCH1, false, EXTENDED_ALTERNATING);
936  Simulator::Schedule (MilliSeconds (0), &WaveNetDevice::StartSch, m_sender, infoSender);
937 
938  TxInfo txInfo = TxInfo (CCH, 0, WifiMode ("OfdmRate3MbpsBW10MHz"), 0);
939  // the packet size with 2312 bytes costs 6.42s, which will cancel this transmission in the CCH Interval
940  // so the receiver will receive this packet in next CCH Interval
941  Simulator::Schedule (MilliSeconds (45), &AnnexC_TestCase::SendPacket, this, 2304, txInfo, 1);
942 
943  // the packet size with 312 bytes costs 1.104ms, which will not cancel transmission in the CCH Interval
944  // so the receiver can this packet is this CCH Interval
945  Simulator::Schedule (MilliSeconds (145), &AnnexC_TestCase::SendPacket, this, 312, txInfo, 2);
946 
947  txInfo = TxInfo (SCH1, 0, WifiMode ("OfdmRate3MbpsBW10MHz"), 0);
948  // the packet size with 2312 bytes costs 6.42ms, which will cancel this transmission in the SCH Interval
949  // so the receiver will receive this packet in next SCH Interval
950  Simulator::Schedule (MilliSeconds (295), &AnnexC_TestCase::SendPacket, this, 2304, txInfo, 3);
951 
952  // the packet size with 312 bytes costs 1.104ms, which will not cancel transmission in the SCH Interval
953  // so the receiver can this packet is this SCH Interval
954  Simulator::Schedule (MilliSeconds (395), &AnnexC_TestCase::SendPacket, this, 312, txInfo, 4);
955 
956  Simulator::Stop (Seconds (1.0));
957  Simulator::Run ();
958  Simulator::Destroy ();
959 }
960 
962 {
963 public:
964  WaveMacTestSuite ();
965 };
966 
968  : TestSuite ("wave-mac-extension", UNIT)
969 {
970  // TestDuration for TestCase can be QUICK, EXTENSIVE or TAKES_FOREVER
971  AddTestCase (new ChannelCoordinationTestCase, TestCase::QUICK);
972  AddTestCase (new ChannelRoutingTestCase, TestCase::QUICK);
973  AddTestCase (new ChannelAccessTestCase, TestCase::QUICK);
974  AddTestCase (new AnnexC_TestCase, TestCase::QUICK);
975 }
976 
977 // Do not forget to allocate an instance of this TestSuite
virtual Address GetAddress(void) const
void SendX(uint32_t channel, uint32_t receiverId)
bool IsGuardInterval(Time duration=Seconds(0.0)) const
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:95
virtual void NotifyGuardSlotStart(Time duration, bool cchi)
uint32_t GetSeq(void) const
tuple devices
Definition: first.py:32
bool StartSch(const SchInfo &schInfo)
void TestContinuousAfter(uint32_t channelNumber, bool isAccessAssigned)
Ptr< YansWifiChannel > Create(void) const
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr stored in this container at a given index.
A suite of tests to run.
Definition: test.h:1270
bool Receive(Ptr< NetDevice > dev, Ptr< const Packet > pkt, uint16_t mode, const Address &sender)
virtual Ptr< Node > GetNode(void) const =0
bool SendX(Ptr< Packet > packet, const Address &dest, uint32_t protocol, const TxInfo &txInfo)
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:867
static NetDeviceContainer CreatWaveDevice(uint32_t nodesNumber=2)
#define NS_TEST_EXPECT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report if not.
Definition: test.h:267
virtual void DoRun(void)
Implementation to actually run this TestCase.
Ptr< ChannelCoordinator > m_coordinator
encapsulates test code
Definition: test.h:1102
void SendWsmp(bool shouldSucceed, const TxInfo &txInfo)
virtual NetDeviceContainer Install(const WifiPhyHelper &phy, const WifiMacHelper &mac, NodeContainer c) const
Definition: wave-helper.cc:482
#define CCH
represent a single transmission modeA WifiMode is implemented by a single integer which is used to lo...
Definition: wifi-mode.h:93
virtual void DoRun(void)
Implementation to actually run this TestCase.
void TestContinuous(SchInfo &info, bool shouldSuccceed)
virtual void SetReceiveCallback(NetDevice::ReceiveCallback cb)
bool IsSchInterval(Time duration=Seconds(0.0)) const
a polymophic address class
Definition: address.h:90
bool IsValidConfig(void) const
tuple nodes
Definition: first.py:25
Keep track of the current position and velocity of an object.
void SetChannel(Ptr< YansWifiChannel > channel)
#define PI
void Install(Ptr< Node > node) const
"Layout" a single node according to the current position allocator type.
void AddTestCase(TestCase *testCase, enum TestDuration duration)
Add an individual child TestCase to this test suite.
Definition: test.cc:184
#define EXTENDED_ALTERNATING
the organization identifier is a public organizationally unique identifier assigned by the IEEE...
helps to create WaveNetDevice objects
Definition: wave-helper.h:110
Time GetGuardInterval(void) const
holds a vector of ns3::NetDevice pointers
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1290
#define EXTENDED_CONTINUOUS
#define SCH2
void SendPacket(uint32_t packetSize, const TxInfo &txInfo, uint32_t sequence)
NetDeviceContainer m_devices
Introspection did not find any typical Config paths.
Definition: seq-ts-header.h:36
void SendIp(bool shouldSucceed, bool ipv6)
bool IsCchInterval(Time duration=Seconds(0.0)) const
CoordinationTestListener(ChannelCoordinationTestCase *coordinatorTest)
Every class exported by the ns3 library is enclosed in the ns3 namespace.
keep track of a set of node pointers.
void NotifyGuardStartNow(Time duration, bool inCchInterval)
uint32_t channelNumber
Definition: vsa-manager.h:65
Time GetCchInterval(void) const
void SendWsa(bool shouldSucceed, const VsaInfo &vsaInfo)
void SetMobilityModel(std::string type, std::string n1="", const AttributeValue &v1=EmptyAttributeValue(), std::string n2="", const AttributeValue &v2=EmptyAttributeValue(), std::string n3="", const AttributeValue &v3=EmptyAttributeValue(), std::string n4="", const AttributeValue &v4=EmptyAttributeValue(), std::string n5="", const AttributeValue &v5=EmptyAttributeValue(), std::string n6="", const AttributeValue &v6=EmptyAttributeValue(), std::string n7="", const AttributeValue &v7=EmptyAttributeValue(), std::string n8="", const AttributeValue &v8=EmptyAttributeValue(), std::string n9="", const AttributeValue &v9=EmptyAttributeValue())
route packets or frames in different approaches see 1609.4-2010 chapter 5.3.4
an EUI-48 address
Definition: mac48-address.h:43
bool Receive(Ptr< NetDevice > dev, Ptr< const Packet > pkt, uint16_t mode, const Address &sender)
void TestExtended(SchInfo &info, bool shouldSuccceed)
manage and create wifi channel objects for the yans model.
Time GetSchInterval(void) const
To trace WaveNetDevice, we have to overwrite the trace functions of class YansWifiPhyHelper.
Definition: wave-helper.h:39
ChannelCoordinationTestCase * m_coordinatorTest
#define NS_TEST_EXPECT_MSG_GT(actual, limit, msg)
Test that an actual value is greater than a limit and report if not.
Definition: test.h:1044
void SetPosition(const Vector &position)
virtual void NotifySchSlotStart(Time duration)
virtual void DoRun(void)
Implementation to actually run this TestCase.
void TestAlternatingAfter(uint32_t channelNumber, bool isAccessAssigned)
Helper class used to assign positions and mobility models to nodes.
bool StartVsa(const VsaInfo &vsaInfo)
Ptr< WaveNetDevice > m_sender
Time GetTs(void) const
#define SCH5
#define SCH3
uint32_t GetId(void) const
Definition: node.cc:106
void TestExtendedAfter(uint32_t channelNumber, bool isAccessAssigned)
receive notifications about channel coordination events.
void SetSeq(uint32_t seq)
bool ReceiveVsa(Ptr< const Packet >, const Address &, uint32_t, uint32_t)
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:859
void TestAlternating(SchInfo &info, bool shouldSuccceed)
Time GetSyncInterval(void) const
#define NS_TEST_EXPECT_MSG_LT(actual, limit, msg)
Test that an actual value is less than a limit and report if not.
Definition: test.h:862
virtual void DoRun(void)
Implementation to actually run this TestCase.
bool Receive(Ptr< NetDevice > dev, Ptr< const Packet > pkt, uint16_t mode, const Address &sender)
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:330
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
static const uint32_t packetSize
static WaveMacTestSuite waveMacTestSuite
void TestIntervalAfter(bool cchi, bool schi, bool guardi)
Ptr< ChannelScheduler > GetChannelScheduler(void) const
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:455
#define SCH4
int64_t GetMilliSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:331
void test(void)
Example use of ns3::SystemThread.
virtual void NotifyCchSlotStart(Time duration)
Ptr< WaveNetDevice > m_receiver
#define SCH1
virtual bool Send(Ptr< Packet > packet, const Address &dest, uint16_t protocolNumber)
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:253
void SetGuardInterval(Time guardi)
#define SCH6