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