A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
mac-extension-test-suite.cc
Go to the documentation of this file.
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License version 2 as
4 * published by the Free Software Foundation;
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
14 *
15 * Author: Junling Bu <linlinjavaer@gmail.com>
16 */
17#include "ns3/config.h"
18#include "ns3/mobility-helper.h"
19#include "ns3/mobility-model.h"
20#include "ns3/node-list.h"
21#include "ns3/string.h"
22#include "ns3/test.h"
23#include "ns3/wave-helper.h"
24#include "ns3/wave-mac-helper.h"
25#include "ns3/wave-net-device.h"
26#include "ns3/yans-wifi-helper.h"
27
28#include <cmath>
29
30using namespace ns3;
31
49{
50 public:
53
54 // below three methods are used in CoordinationTestListener
59 void NotifyCchStartNow(Time duration);
64 void NotifySchStartNow(Time duration);
70 void NotifyGuardStartNow(Time duration, bool inCchInterval);
71
72 private:
79 void TestIntervalAfter(bool cchi, bool schi, bool guardi);
80 void DoRun() override;
82};
83
91{
92 public:
99 : m_coordinatorTest(coordinatorTest)
100 {
101 }
102
104 {
105 }
106
107 void NotifyCchSlotStart(Time duration) override
108 {
110 }
111
112 void NotifySchSlotStart(Time duration) override
113 {
115 }
116
117 void NotifyGuardSlotStart(Time duration, bool cchi) override
118 {
119 m_coordinatorTest->NotifyGuardStartNow(duration, cchi);
120 }
121
123};
124
126 : TestCase("channel-coordination")
127{
128}
129
131{
132}
133
134void
135ChannelCoordinationTestCase::TestIntervalAfter(bool cchi, bool schi, bool guardi)
136{
137 uint32_t now = Now().GetMilliSeconds();
139 cchi,
140 "now is " << now
141 << "ms "
142 "check whether is CCH interval");
144 schi,
145 "now is " << now
146 << "ms "
147 "check whether is SCH interval");
149 guardi,
150 "now is " << now
151 << "ms "
152 "check whether is Guard interval");
153}
154
155void
157{
158 // this method shall be called at 4ms, 104ms, ... synci * n + guardi
159 // synci is sync interval with default value 100ms
160 // guardi is guard interval with default value 4ms
161 // n is sequence number
162 int64_t now = Now().GetMilliSeconds();
163 int64_t synci = m_coordinator->GetSyncInterval().GetMilliSeconds();
164 int64_t guardi = m_coordinator->GetGuardInterval().GetMilliSeconds();
165 bool test = (((now - guardi) % synci) == 0);
166 NS_TEST_EXPECT_MSG_EQ(test, true, "the time of now shall be synci * n + guardi");
167
168 // besides that, the argument duration shall be cchi - guardi
170 NS_TEST_EXPECT_MSG_EQ((duration == d), true, "the duration shall be cchi - guardi");
171}
172
173void
175{
176 // this method shall be called at 54ms, 154ms, ... synci * n + cchi + guardi
177 // synci is sync interval with default value 100ms
178 // cchi is CCH interval with default value 50ms
179 // guardi is guard interval with default value 4ms
180 // n is sequence number
181 int64_t now = Now().GetMilliSeconds();
182 int64_t synci = m_coordinator->GetSyncInterval().GetMilliSeconds();
183 int64_t cchi = m_coordinator->GetCchInterval().GetMilliSeconds();
184 int64_t guardi = m_coordinator->GetGuardInterval().GetMilliSeconds();
185 bool test = ((now - guardi - cchi) % synci == 0);
186 NS_TEST_EXPECT_MSG_EQ(test, true, "the time of now shall be synci * n + cchi + guardi");
187
188 // besides that, the argument duration shall be schi - guardi
190 NS_TEST_EXPECT_MSG_EQ((duration == d), true, "the duration shall be schi - guardi");
191}
192
193void
195{
196 int64_t now = Now().GetMilliSeconds();
198 int64_t cchi = m_coordinator->GetCchInterval().GetMilliSeconds();
199 bool test = false;
200 if (inCchInterval)
201 {
202 // if cchi, this method will be called at 0ms, 100ms, sync * n
203 test = ((now % sync) == 0);
204 NS_TEST_EXPECT_MSG_EQ(test, true, "the time of now shall be sync * n");
205 }
206 else
207 {
208 // if schi, this method will be called at 50ms, 150ms, sync * n + cchi
209 test = (((now - cchi) % sync) == 0);
210 NS_TEST_EXPECT_MSG_EQ(test, true, "the time of now shall be sync * n");
211 }
212 // the duration shall be guardi
213 test = (duration == m_coordinator->GetGuardInterval());
214 NS_TEST_EXPECT_MSG_EQ(test, true, "the duration shall be guard interval");
215}
216
217void
219{
220 // first test configure method
221 m_coordinator = CreateObject<ChannelCoordinator>();
223 MilliSeconds(50),
224 "normally CCH interval is 50ms");
226 MilliSeconds(50),
227 "normally SCH interval is 50ms");
229 MilliSeconds(100),
230 "normally Sync interval is 50ms");
232 MilliSeconds(4),
233 "normally Guard interval is 50ms");
237 true,
238 "valid configuration of channel intervals");
242 false,
243 "invalid configuration of channel intervals");
248 false,
249 "invalid configuration of channel intervals");
250
251 // second test member method
252 m_coordinator = CreateObject<ChannelCoordinator>();
255 this,
256 true,
257 false,
258 true);
261 this,
262 true,
263 false,
264 true);
267 this,
268 true,
269 false,
270 true);
273 this,
274 true,
275 false,
276 false);
279 this,
280 true,
281 false,
282 false);
285 this,
286 false,
287 true,
288 true);
291 this,
292 false,
293 true,
294 true);
297 this,
298 false,
299 true,
300 true);
303 this,
304 false,
305 true,
306 false);
309 this,
310 false,
311 true,
312 false);
315 this,
316 true,
317 false,
318 true);
321 this,
322 true,
323 false,
324 true);
327 this,
328 true,
329 false,
330 true);
333 this,
334 true,
335 false,
336 true);
339 this,
340 true,
341 false,
342 false);
345 this,
346 true,
347 false,
348 false);
351 this,
352 false,
353 true,
354 true);
357 this,
358 false,
359 true,
360 true);
363 this,
364 false,
365 true,
366 true);
369 this,
370 false,
371 true,
372 false);
375 this,
376 false,
377 true,
378 false);
381 this,
382 true,
383 false,
384 true);
388
389 m_coordinator = CreateObject<ChannelCoordinator>();
390 // third test channel coordination events
391 Ptr<CoordinationTestListener> ptr = Create<CoordinationTestListener>(this);
393 Simulator::Stop(Seconds(100.0));
396}
397
405{
406 public:
412 static NetDeviceContainer CreatWaveDevice(uint32_t nodesNumber = 2);
413};
414
415#define PI 3.14159265
416
419{
421 nodes.Create(nodesNumber);
422
423 MobilityHelper mobility;
424 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
425 mobility.Install(nodes);
426 // this is a circle with radius 10
428 model->SetPosition(Vector(0, 0, 0));
429 for (uint32_t n = 1; n != nodesNumber; ++n)
430 {
431 double angle = (PI / 180) * (360 / (nodesNumber - 1) * n);
432 double x = cos(angle) * 10;
433 double y = sin(angle) * 10;
435 model->SetPosition(Vector(x, y, 0));
436 }
437
440 wifiPhy.SetChannel(wifiChannel.Create());
442 WaveHelper waveHelper = WaveHelper::Default();
443 NetDeviceContainer devices = waveHelper.Install(wifiPhy, waveMac, nodes);
444 return devices;
445}
446
452{
453 public:
455 ~ChannelRoutingTestCase() override;
456
463 void SendIp(bool shouldSucceed, bool ipv6);
469 void SendWsmp(bool shouldSucceed, const TxInfo& txInfo);
475 void SendWsa(bool shouldSucceed, const VsaInfo& vsaInfo);
476
477 private:
478 void DoRun() override;
487 bool Receive(Ptr<NetDevice> dev, Ptr<const Packet> pkt, uint16_t mode, const Address& sender);
495
497};
498
500 : TestCase("channel-routing")
501{
502}
503
505{
506}
507
508void
509ChannelRoutingTestCase::SendWsmp(bool shouldSucceed, const TxInfo& txInfo)
510{
511 Ptr<Packet> packet = Create<Packet>(100);
512 const Address dest = Mac48Address::GetBroadcast();
513 uint16_t protocol = 0x80dd; // any number is OK even ipv4 and ipv6
514 bool result = m_sender->SendX(packet, dest, protocol, txInfo);
515 NS_TEST_EXPECT_MSG_EQ(result, shouldSucceed, "test SendWsmp method error");
516}
517
518void
519ChannelRoutingTestCase::SendIp(bool shouldSucceed, bool ipv6)
520{
521 Ptr<Packet> packet = Create<Packet>(100);
522 const Address dest = Mac48Address::GetBroadcast();
523 const static uint16_t IPv4_PROT_NUMBER = 0x0800;
524 const static uint16_t IPv6_PROT_NUMBER = 0x86DD;
525 uint16_t protocol = ipv6 ? IPv6_PROT_NUMBER : IPv4_PROT_NUMBER;
526 bool result = m_sender->Send(packet, dest, protocol);
527 NS_TEST_EXPECT_MSG_EQ(result, shouldSucceed, "test SendIp method error");
528}
529
530void
531ChannelRoutingTestCase::SendWsa(bool shouldSucceed, const VsaInfo& vsaInfo)
532{
533 bool result = m_sender->StartVsa(vsaInfo);
534 NS_TEST_EXPECT_MSG_EQ(result, shouldSucceed, "test SendWsa method error");
535}
536
537void
539{
540 // check SendX method for WSMP packets
541 {
543 m_sender = DynamicCast<WaveNetDevice>(devices.Get(0));
544
547 this,
548 true,
549 TxInfo(CCH));
552 this,
553 false,
554 TxInfo(SCH1));
557 this,
558 false,
559 TxInfo(SCH2));
560
561 const SchInfo schInfo = SchInfo(SCH1, false, EXTENDED_ALTERNATING);
563
566 this,
567 true,
568 TxInfo(CCH));
571 this,
572 true,
573 TxInfo(SCH1));
576 this,
577 false,
578 TxInfo(SCH2));
581 this,
582 false,
583 TxInfo(SCH3));
586 this,
587 false,
588 TxInfo(SCH4));
591 this,
592 false,
593 TxInfo(SCH5));
596 this,
597 false,
598 TxInfo(SCH6));
599
600 // invalid channel number
603 this,
604 false,
605 TxInfo(0));
606 // invalid user priority
609 this,
610 false,
611 TxInfo(CCH, 8));
612 // invalid tx parameters
615 this,
616 false,
617 TxInfo(CCH, 7, WifiMode("OfdmRate6Mbps"), WIFI_PREAMBLE_LONG, 7));
619 Seconds(0.4),
621 this,
622 false,
623 TxInfo(CCH, 7, WifiMode("OfdmRate3MbpsBW10MHz"), WIFI_PREAMBLE_LONG, 10));
624 // valid tx parameters
626 Seconds(0.4),
628 this,
629 true,
630 TxInfo(CCH, 7, WifiMode("OfdmRate3MbpsBW10MHz"), WIFI_PREAMBLE_LONG, 7));
633 this,
634 true,
636
637 // release channel access at 0.6s
639
640 // the packet will be dropped because channel access is not assigned again
643 this,
644 true,
645 TxInfo(CCH));
648 this,
649 false,
650 TxInfo(SCH1));
653 this,
654 false,
655 TxInfo(SCH2));
656
660 }
661
662 // check Send method for IP-based packets
663 {
665 m_sender = DynamicCast<WaveNetDevice>(devices.Get(0));
666
667 bool ipv6 = true;
668 bool ipv4 = false;
671
672 const SchInfo schInfo = SchInfo(SCH1, false, EXTENDED_ALTERNATING);
674
677
678 TxProfile txProfile = TxProfile(SCH1);
680
683
684 // unregister txprofile
686
689
690 // release channel access
691 // mac entities have no channel resource even phy device has ability to send
693
696
700 }
701
702 // check StartVsa method for WSA management frames
703 {
705 m_sender = DynamicCast<WaveNetDevice>(devices.Get(0));
706
707 Ptr<Packet> packet = Create<Packet>(100);
709 VsaInfo vsaInfo =
711 Simulator::Schedule(Seconds(0.1), &ChannelRoutingTestCase::SendWsa, this, false, vsaInfo);
712
713 vsaInfo.channelNumber = 0;
714 Simulator::Schedule(Seconds(0.2), &ChannelRoutingTestCase::SendWsa, this, false, vsaInfo);
715
716 vsaInfo.channelNumber = CCH;
719
720 const SchInfo schInfo = SchInfo(SCH1, false, EXTENDED_ALTERNATING);
722 vsaInfo.channelNumber = CCH;
724 vsaInfo.channelNumber = SCH1;
726 vsaInfo.channelNumber = SCH2;
727 Simulator::Schedule(Seconds(0.4), &ChannelRoutingTestCase::SendWsa, this, false, vsaInfo);
728
732
733 vsaInfo.channelNumber = CCH;
735 vsaInfo.channelNumber = SCH1;
736 Simulator::Schedule(Seconds(0.5), &ChannelRoutingTestCase::SendWsa, this, false, vsaInfo);
737 vsaInfo.channelNumber = SCH2;
738 Simulator::Schedule(Seconds(0.5), &ChannelRoutingTestCase::SendWsa, this, false, vsaInfo);
739
743 }
744}
745
755{
756 public:
758 ~ChannelAccessTestCase() override;
759
760 private:
766 void TestContinuous(SchInfo& info, bool shouldSucceed);
772 void TestContinuousAfter(uint32_t channelNumber, bool isAccessAssigned);
778 void TestExtended(SchInfo& info, bool shouldSucceed);
784 void TestExtendedAfter(uint32_t channelNumber, bool isAccessAssigned);
790 void TestAlternating(SchInfo& info, bool shouldSucceed);
796 void TestAlternatingAfter(uint32_t channelNumber, bool isAccessAssigned);
797
803 void SendX(uint32_t channel, uint32_t receiverId);
812 bool Receive(Ptr<NetDevice> dev, Ptr<const Packet> pkt, uint16_t mode, const Address& sender);
813
814 void DoRun() override;
815
819};
820
822 : TestCase("channel-access")
823{
824}
825
827{
828}
829
830void
832{
833 bool result = m_sender->StartSch(info);
834 NS_TEST_EXPECT_MSG_EQ(result, shouldSucceed, "TestContinuous fail at " << Now().As(Time::S));
835}
836
837void
838ChannelAccessTestCase::TestContinuousAfter(uint32_t channelNumber, bool isAccessAssigned)
839{
840 bool result = m_sender->GetChannelScheduler()->IsContinuousAccessAssigned(channelNumber);
842 isAccessAssigned,
843 "TestContinuousAfter fail at " << Now().As(Time::S));
844}
845
846void
848{
849 bool result = m_sender->StartSch(info);
850 NS_TEST_EXPECT_MSG_EQ(result, shouldSucceed, "TestExtended fail at " << Now().As(Time::S));
851}
852
853void
854ChannelAccessTestCase::TestExtendedAfter(uint32_t channelNumber, bool isAccessAssigned)
855{
856 bool result = m_sender->GetChannelScheduler()->IsExtendedAccessAssigned(channelNumber);
858 isAccessAssigned,
859 "TestExtendedAfter fail at " << Now().As(Time::S));
860}
861
862void
864{
865 bool result = m_sender->StartSch(info);
866 NS_TEST_EXPECT_MSG_EQ(result, shouldSucceed, "TestAlternating fail at " << Now().As(Time::S));
867}
868
869void
870ChannelAccessTestCase::TestAlternatingAfter(uint32_t channelNumber, bool isAccessAssigned)
871{
872 bool result = m_sender->GetChannelScheduler()->IsAlternatingAccessAssigned(channelNumber);
874 isAccessAssigned,
875 "TestAlternating fail at " << Now().As(Time::S));
876}
877
878void
880{
881 const static uint16_t WSMP_PROT_NUMBER = 0x88DC;
883 const TxInfo txInfo = TxInfo(channel);
884
885 uint8_t* data = new uint8_t[112];
886 data[0] = (receiverId >> 24) & 0xFF;
887 data[1] = (receiverId >> 16) & 0xFF;
888 data[2] = (receiverId >> 8) & 0xFF;
889 data[3] = (receiverId >> 0) & 0xFF;
890
891 uint64_t ts = Simulator::Now().GetTimeStep();
892 data[4] = (ts >> 56) & 0xFF;
893 data[5] = (ts >> 48) & 0xFF;
894 data[6] = (ts >> 40) & 0xFF;
895 data[7] = (ts >> 32) & 0xFF;
896 data[8] = (ts >> 24) & 0xFF;
897 data[9] = (ts >> 16) & 0xFF;
898 data[10] = (ts >> 8) & 0xFF;
899 data[11] = (ts >> 0) & 0xFF;
900
901 Ptr<Packet> p = Create<Packet>(data, 112);
902
903 m_sender->SendX(p, dest, WSMP_PROT_NUMBER, txInfo);
904
905 delete[] data;
906}
907
908bool
911 uint16_t mode,
912 const Address& sender)
913{
914 uint8_t* data = new uint8_t[pkt->GetSize()];
915 pkt->CopyData(data, pkt->GetSize());
916
917 uint32_t seq = data[0];
918 seq <<= 8;
919 seq |= data[1];
920 seq <<= 8;
921 seq |= data[2];
922 seq <<= 8;
923 seq |= data[3];
924
925 uint64_t ts = data[4];
926 ts <<= 8;
927 ts |= data[5];
928 ts <<= 8;
929 ts |= data[6];
930 ts <<= 8;
931 ts |= data[7];
932 ts <<= 8;
933 ts |= data[8];
934 ts <<= 8;
935 ts |= data[9];
936 ts <<= 8;
937 ts |= data[10];
938 ts <<= 8;
939 ts |= data[11];
940 Time sendTime = TimeStep(ts);
941
942 delete[] data;
943
944 // SeqTsHeader seqTs;
945 // ConstCast<Packet> (pkt)->RemoveHeader (seqTs);
946 uint32_t curNodeId = dev->GetNode()->GetId();
947 NS_TEST_EXPECT_MSG_EQ(curNodeId, seq, "fail to assign channel access");
948 m_received++;
949 return true;
950}
951
952void
954{
955 // test ContinuousAccess in the sender side
956 {
958 m_sender = DynamicCast<WaveNetDevice>(m_devices.Get(0));
959
960 // there is no need for assigning CCH continuous access.
961 SchInfo info = SchInfo(CCH, false, EXTENDED_CONTINUOUS);
963
964 info = SchInfo(SCH1, false, EXTENDED_CONTINUOUS);
966
967 // BE ATTENTION !!!
968 // because channel access is assigned in non-immediate mode, the first CCH Interval will be
969 // the wait time with DefaultCchAccess assigned, thus there is no ContinuousAccess assigned.
972 this,
973 SCH1,
974 false);
977 this,
978 SCH1,
979 false);
982 this,
983 SCH1,
984 false);
987 this,
988 SCH1,
989 false);
992 this,
993 SCH1,
994 true);
997 this,
998 SCH1,
999 true);
1000
1001 // it's OK to assign same access again,
1003 // fail to assign continuous access for other SCH if current channel is assigned
1004 info = SchInfo(SCH2, false, EXTENDED_CONTINUOUS);
1006
1007 // then we release channel access at 0.5s
1009
1010 info = SchInfo(SCH2, false, EXTENDED_CONTINUOUS);
1011 // succeed to assign access for other SCH is previous SCH access is released
1013
1017 }
1018
1019 // test ContinuousAccess again in the receiver side
1020 {
1022 m_sender = DynamicCast<WaveNetDevice>(m_devices.Get(0));
1023 m_received = 0;
1024
1025 for (uint32_t i = 1; i != 8; ++i)
1026 {
1027 Ptr<WaveNetDevice> device = DynamicCast<WaveNetDevice>(m_devices.Get(i));
1028 device->SetReceiveCallback(MakeCallback(&ChannelAccessTestCase::Receive, this));
1029
1030 // at 0s, receivers are assigned ContinuousAccess from CCH, SCH1 to SCH6
1031 static std::vector<uint32_t> WaveChannels = ChannelManager::GetWaveChannels();
1032 uint32_t channel = WaveChannels[i - 1];
1033 const SchInfo info = SchInfo(channel, false, EXTENDED_CONTINUOUS);
1035 }
1036
1037 // at 0s, the sender is assigned DefaultCchAccess, so only node-1 can receive packets.
1039 // if receivers assigned for SCH access can receive packets, there shall be crashed
1046
1047 // at 1s, the sender is assigned ContinuousAccess for SCH1, so only node-2 can receive
1048 // packets.
1049 SchInfo info = SchInfo(SCH1, false, EXTENDED_CONTINUOUS);
1052 // other channel access cannot receive packets
1059
1060 Simulator::Stop(Seconds(10.0));
1063
1064 NS_TEST_EXPECT_MSG_EQ(m_received, 2, "test ContinuousAccess fail in receive side");
1065 }
1066
1067 // test ExtendedAccess in the sender side
1068 {
1070 m_sender = DynamicCast<WaveNetDevice>(m_devices.Get(0));
1071
1072 // there is no need for assigning CCH extended access.
1073 SchInfo info = SchInfo(CCH, false, 10);
1075
1076 info = SchInfo(SCH1, false, 10);
1078 // succeed because request for extends 8 can be fulfilled by previous extends 10..
1079 info = SchInfo(SCH1, false, 8);
1081 // fail because request for extends 12 cannot be fulfilled by previous extends 10..
1082 info = SchInfo(SCH1, false, 12);
1084
1085 // BE ATTENTION !!!
1086 // because channel access is assigned in non-immediate mode, the first CCH Interval will be
1087 // the wait time with DefaultCchAccess assigned, while there is no ExtendedAccess assigned.
1090 this,
1091 SCH1,
1092 false);
1095 this,
1096 SCH1,
1097 false);
1100 this,
1101 SCH1,
1102 false);
1105 this,
1106 SCH1,
1107 false);
1110 this,
1111 SCH1,
1112 true);
1115 this,
1116 SCH1,
1117 true);
1118
1119 // the end of extended access is (2s + 100ms + 100ms * 10) = 3.1s
1122 this,
1123 SCH1,
1124 true);
1127 this,
1128 SCH1,
1129 true);
1132 this,
1133 SCH1,
1134 false);
1137 this,
1138 SCH1,
1139 false);
1140
1141 // succeed to assign extended access for other SCH since previous extended access is
1142 // released automatically
1143 info = SchInfo(SCH2, false, 10);
1145
1146 // stop it at 5s even the end of extended access is (4s + 100ms + 100ms * 10) = 5.1s
1148
1151 this,
1152 SCH2,
1153 false);
1156 this,
1157 SCH2,
1158 false);
1161 this,
1162 SCH2,
1163 false);
1164
1168 }
1169
1170 // test ExtendedAccess again in the receiver side
1171 {
1173 m_sender = DynamicCast<WaveNetDevice>(m_devices.Get(0));
1174 m_received = 0;
1175
1176 for (uint32_t i = 1; i != 8; ++i)
1177 {
1178 Ptr<WaveNetDevice> device = DynamicCast<WaveNetDevice>(m_devices.Get(i));
1179 device->SetReceiveCallback(MakeCallback(&ChannelAccessTestCase::Receive, this));
1180
1181 // at 0s, receivers are assigned ContinuosAccess from CCH, SCH1 to SCH6
1182 static std::vector<uint32_t> WaveChannels = ChannelManager::GetWaveChannels();
1183 uint32_t channel = WaveChannels[i - 1];
1184 const SchInfo info = SchInfo(channel, false, EXTENDED_CONTINUOUS);
1186 }
1187
1188 // at 0s, the sender is assigned DefaultCchAccess, so only node-1 can receive packets.
1190 // if receivers assigned for SCH access can receive packets, there shall be crashed
1197
1198 // at 1s, the sender is assigned ExtendedAccess for SCH1 with extends 10,
1199 //, so only node-2 can receive packets from 1s - 2.1s ( 1s + 100ms + 100ms * 10)
1200 SchInfo info = SchInfo(SCH1, false, 10);
1203 // other channel access cannot receive packets
1210 // at 2.2s the node-2 cannot receive this packet because of extended access released in
1211 // node-0 but sended is assigned DefaultCchAccess again, thus node-1 can receive broadcasted
1212 // packets.
1220
1221 Simulator::Stop(Seconds(10.0));
1224
1225 NS_TEST_EXPECT_MSG_EQ(m_received, 3, "test ExtendedAccess fail in receive side");
1226 }
1227
1228 // test AlternatingAccess in the sender side
1229 {
1231 m_sender = DynamicCast<WaveNetDevice>(m_devices.Get(0));
1232
1233 // there is no need for assigning CCH alternating access.
1234 SchInfo info = SchInfo(CCH, false, EXTENDED_ALTERNATING);
1236
1237 info = SchInfo(SCH1, false, EXTENDED_ALTERNATING);
1239
1240 // BE ATTENTION !!!
1241 // No matter whether channel access is assigned in immediate mode or non-immediate mode,
1242 // the channel access will assigned immediately which is different from the test results in
1243 // ExtendedAccess assignment and ContinuousAccess assignment.
1246 this,
1247 SCH1,
1248 true);
1251 this,
1252 SCH1,
1253 true);
1256 this,
1257 SCH1,
1258 true);
1261 this,
1262 SCH1,
1263 true);
1266 this,
1267 SCH1,
1268 true);
1271 this,
1272 SCH1,
1273 true);
1274
1276 info = SchInfo(SCH2, false, EXTENDED_ALTERNATING);
1278 info = SchInfo(0, false, EXTENDED_ALTERNATING);
1280
1281 // then we release channel access at 0.5s
1283
1284 info = SchInfo(SCH2, false, EXTENDED_ALTERNATING);
1285 // succeed to assign access for other SCH is previous SCH access is released
1287
1291 }
1292
1293 // test AlternatingAccess again in the receiver side
1294 {
1296 m_sender = DynamicCast<WaveNetDevice>(m_devices.Get(0));
1297 m_received = 0;
1298
1299 for (uint32_t i = 1; i != 8; ++i)
1300 {
1301 Ptr<WaveNetDevice> device = DynamicCast<WaveNetDevice>(m_devices.Get(i));
1302 device->SetReceiveCallback(MakeCallback(&ChannelAccessTestCase::Receive, this));
1303
1304 // at 0s, receivers are assigned ContinuosAccess from CCH, SCH1 to SCH6
1305 static std::vector<uint32_t> WaveChannels = ChannelManager::GetWaveChannels();
1306 uint32_t channel = WaveChannels[i - 1];
1307 const SchInfo info = SchInfo(channel, false, EXTENDED_CONTINUOUS);
1309 }
1310
1311 // at 0s, the sender is assigned DefaultCchAccess, so only node-1 can receive packets.
1313 // if receivers assigned for SCH access can receive packets, there shall be crashed
1320
1321 // at 1s, the sender is assigned ContinuosAccess for SCH1, so only node-2 can receive
1322 // packets.
1323 SchInfo info = SchInfo(SCH1, false, EXTENDED_ALTERNATING);
1325 // node-1 (assigned CCH access) and node-2 (assigned SCH1 access) can receive packets
1326 // in different channel interval
1329 // other channel access cannot receive packets
1335
1337 // if ContinuousAccess for SCH1 is released, node-2 cannot receive packets again
1345
1346 Simulator::Stop(Seconds(10.0));
1349
1350 NS_TEST_EXPECT_MSG_EQ(m_received, 4, "test AlternatingAccess fail in receive side");
1351 }
1352}
1353
1362{
1363 public:
1365 ~AnnexC_TestCase() override;
1366
1367 private:
1368 void DoRun() override;
1369
1376 void SendPacket(uint32_t packetSize, const TxInfo& txInfo, uint32_t sequence);
1385 bool Receive(Ptr<NetDevice> dev, Ptr<const Packet> pkt, uint16_t mode, const Address& sender);
1386
1390};
1391
1393 : TestCase("annex-c")
1394{
1395}
1396
1398{
1399}
1400
1401void
1403{
1404 const static uint16_t WSMP_PROT_NUMBER = 0x88DC;
1406
1407 uint8_t* data = new uint8_t[packetSize];
1408 data[0] = (sequence >> 24) & 0xFF;
1409 data[1] = (sequence >> 16) & 0xFF;
1410 data[2] = (sequence >> 8) & 0xFF;
1411 data[3] = (sequence >> 0) & 0xFF;
1412
1413 uint64_t ts = Simulator::Now().GetTimeStep();
1414 data[4] = (ts >> 56) & 0xFF;
1415 data[5] = (ts >> 48) & 0xFF;
1416 data[6] = (ts >> 40) & 0xFF;
1417 data[7] = (ts >> 32) & 0xFF;
1418 data[8] = (ts >> 24) & 0xFF;
1419 data[9] = (ts >> 16) & 0xFF;
1420 data[10] = (ts >> 8) & 0xFF;
1421 data[11] = (ts >> 0) & 0xFF;
1422
1423 Ptr<Packet> p = Create<Packet>(data, packetSize);
1424
1425 m_sender->SendX(p, dest, WSMP_PROT_NUMBER, txInfo);
1426
1427 delete[] data;
1428}
1429
1430bool
1433 uint16_t mode,
1434 const Address& sender)
1435{
1436 uint8_t* data = new uint8_t[pkt->GetSize()];
1437 pkt->CopyData(data, pkt->GetSize());
1438
1439 uint32_t seq = data[0];
1440 seq <<= 8;
1441 seq |= data[1];
1442 seq <<= 8;
1443 seq |= data[2];
1444 seq <<= 8;
1445 seq |= data[3];
1446
1447 uint64_t ts = data[4];
1448 ts <<= 8;
1449 ts |= data[5];
1450 ts <<= 8;
1451 ts |= data[6];
1452 ts <<= 8;
1453 ts |= data[7];
1454 ts <<= 8;
1455 ts |= data[8];
1456 ts <<= 8;
1457 ts |= data[9];
1458 ts <<= 8;
1459 ts |= data[10];
1460 ts <<= 8;
1461 ts |= data[11];
1462 Time sendTime = TimeStep(ts);
1463
1464 delete[] data;
1465
1466 Time curTime = Now();
1467 Time duration = curTime - sendTime;
1468
1469 if (seq == 1)
1470 {
1471 NS_TEST_EXPECT_MSG_GT(duration,
1473 "fail to test Annex C when packet sequence is " << seq);
1474 }
1475 else if (seq == 2)
1476 {
1477 NS_TEST_EXPECT_MSG_LT(duration,
1479 "fail to test Annex C when packet sequence is " << seq);
1480 }
1481 else if (seq == 3)
1482 {
1483 NS_TEST_EXPECT_MSG_GT(duration,
1485 "fail to test Annex C when packet sequence is " << seq);
1486 }
1487 else if (seq == 4)
1488 {
1489 NS_TEST_EXPECT_MSG_LT(duration,
1491 "fail to test Annex C when packet sequence is " << seq);
1492 }
1493 return true;
1494}
1495
1496void
1498{
1500 m_sender = DynamicCast<WaveNetDevice>(m_devices.Get(0));
1501 m_receiver = DynamicCast<WaveNetDevice>(m_devices.Get(1));
1503
1504 // at 0s, the receiver is assigned AlternatingAccess for SCH1
1505 SchInfo infoReceiver = SchInfo(SCH1, false, EXTENDED_ALTERNATING);
1507
1508 // at 0s, the sender is assigned AlternatingAccess for SCH1
1509 SchInfo infoSender = SchInfo(SCH1, false, EXTENDED_ALTERNATING);
1511
1512 TxInfo txInfo = TxInfo(CCH, 0, WifiMode("OfdmRate3MbpsBW10MHz"), WIFI_PREAMBLE_LONG, 0);
1513 // the packet size with 2312 bytes costs 6.42s, which will cancel this transmission in the CCH
1514 // Interval so the receiver will receive this packet in next CCH Interval
1515 Simulator::Schedule(MilliSeconds(45), &AnnexC_TestCase::SendPacket, this, 2304, txInfo, 1);
1516
1517 // the packet size with 312 bytes costs 1.104ms, which will not cancel transmission in the CCH
1518 // Interval so the receiver can this packet is this CCH Interval
1519 Simulator::Schedule(MilliSeconds(145), &AnnexC_TestCase::SendPacket, this, 312, txInfo, 2);
1520
1521 txInfo = TxInfo(SCH1, 0, WifiMode("OfdmRate3MbpsBW10MHz"), WIFI_PREAMBLE_LONG, 0);
1522 // the packet size with 2312 bytes costs 6.42ms, which will cancel this transmission in the SCH
1523 // Interval so the receiver will receive this packet in next SCH Interval
1524 Simulator::Schedule(MilliSeconds(295), &AnnexC_TestCase::SendPacket, this, 2304, txInfo, 3);
1525
1526 // the packet size with 312 bytes costs 1.104ms, which will not cancel transmission in the SCH
1527 // Interval so the receiver can this packet is this SCH Interval
1528 Simulator::Schedule(MilliSeconds(395), &AnnexC_TestCase::SendPacket, this, 312, txInfo, 4);
1529
1533}
1534
1542{
1543 public:
1545};
1546
1548 : TestSuite("wave-mac-extension", UNIT)
1549{
1550 // TestDuration for TestCase can be QUICK, EXTENSIVE or TAKES_FOREVER
1555}
1556
1557// Do not forget to allocate an instance of this TestSuite
#define SCH2
#define SCH5
#define SCH1
#define CCH
#define SCH6
#define SCH4
#define SCH3
#define EXTENDED_ALTERNATING
#define EXTENDED_CONTINUOUS
The Annex C of IEEE 1609.4 : "Avoiding transmission at scheduled guard intervals" This feature is imp...
bool Receive(Ptr< NetDevice > dev, Ptr< const Packet > pkt, uint16_t mode, const Address &sender)
Receive function.
Ptr< WaveNetDevice > m_sender
sender
Ptr< WaveNetDevice > m_receiver
receiver
void DoRun() override
Implementation to actually run this TestCase.
void SendPacket(uint32_t packetSize, const TxInfo &txInfo, uint32_t sequence)
Send packet function.
NetDeviceContainer m_devices
devices
This test case tests channel access assignments which is done by StartSch and StopSch method of WaveN...
void TestAlternating(SchInfo &info, bool shouldSucceed)
Test aternating function.
void TestAlternatingAfter(uint32_t channelNumber, bool isAccessAssigned)
Test alternating after function.
NetDeviceContainer m_devices
the devices
void SendX(uint32_t channel, uint32_t receiverId)
Send X function.
void DoRun() override
Implementation to actually run this TestCase.
void TestExtendedAfter(uint32_t channelNumber, bool isAccessAssigned)
Test extended after function.
void TestContinuousAfter(uint32_t channelNumber, bool isAccessAssigned)
Test continuous after function.
bool Receive(Ptr< NetDevice > dev, Ptr< const Packet > pkt, uint16_t mode, const Address &sender)
Receive function.
void TestContinuous(SchInfo &info, bool shouldSucceed)
Test continuous function.
void TestExtended(SchInfo &info, bool shouldSucceed)
Test extended function.
Ptr< WaveNetDevice > m_sender
sender
This test case tests the channel coordination.
void NotifySchStartNow(Time duration)
Notify SCH start now function.
void TestIntervalAfter(bool cchi, bool schi, bool guardi)
Test interval after function.
void DoRun() override
Implementation to actually run this TestCase.
void NotifyGuardStartNow(Time duration, bool inCchInterval)
Notify guard start now function.
void NotifyCchStartNow(Time duration)
Notify CCS start now function.
Ptr< ChannelCoordinator > m_coordinator
coordinator
route packets or frames in different approaches see 1609.4-2010 chapter 5.3.4
Ptr< WaveNetDevice > m_sender
sender
void SendWsa(bool shouldSucceed, const VsaInfo &vsaInfo)
Send VSA management frames.
void SendWsmp(bool shouldSucceed, const TxInfo &txInfo)
Send WSMP or other packets.
void SendIp(bool shouldSucceed, bool ipv6)
Send IP-based packets.
void DoRun() override
Implementation to actually run this TestCase.
bool ReceiveVsa(Ptr< const Packet > pkt, const Address &address, uint32_t, uint32_t)
Receive VSA function.
bool Receive(Ptr< NetDevice > dev, Ptr< const Packet > pkt, uint16_t mode, const Address &sender)
Receive function.
CoordinationTestListener is used to test channel coordination events.
void NotifyCchSlotStart(Time duration) override
ChannelCoordinationTestCase * m_coordinatorTest
coordinator test
void NotifySchSlotStart(Time duration) override
CoordinationTestListener(ChannelCoordinationTestCase *coordinatorTest)
Constructor.
void NotifyGuardSlotStart(Time duration, bool cchi) override
static NetDeviceContainer CreatWaveDevice(uint32_t nodesNumber=2)
Create WAVE device function.
Wave Mac Test Suite.
a polymophic address class
Definition: address.h:100
receive notifications about channel coordination events.
bool IsSchInterval(Time duration=Seconds(0.0)) const
bool IsGuardInterval(Time duration=Seconds(0.0)) const
void SetGuardInterval(Time guardi)
bool IsCchInterval(Time duration=Seconds(0.0)) const
void RegisterListener(Ptr< ChannelCoordinationListener > listener)
static std::vector< uint32_t > GetWaveChannels()
an EUI-48 address
Definition: mac48-address.h:46
static Mac48Address ConvertFrom(const Address &address)
static Mac48Address GetBroadcast()
Helper class used to assign positions and mobility models to nodes.
Keep track of the current position and velocity of an object.
holds a vector of ns3::NetDevice pointers
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
keep track of a set of node pointers.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
static Ptr< Node > GetNode(uint32_t n)
Definition: node-list.cc:251
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:471
the organization identifier is a public organizationally unique identifier assigned by the IEEE.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
Qos Wave Mac Helper class.
static QosWaveMacHelper Default()
Create a mac helper in a default working state.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:568
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:140
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:199
static void Run()
Run the simulation.
Definition: simulator.cc:176
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:184
encapsulates test code
Definition: test.h:1060
@ QUICK
Fast test.
Definition: test.h:1065
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:305
A suite of tests to run.
Definition: test.h:1256
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
int64_t GetMilliSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:407
@ S
second
Definition: nstime.h:116
int64_t GetTimeStep() const
Get the raw time value, in the current resolution unit.
Definition: nstime.h:444
helps to create WaveNetDevice objects
Definition: wave-helper.h:116
virtual NetDeviceContainer Install(const WifiPhyHelper &phy, const WifiMacHelper &mac, NodeContainer c) const
Definition: wave-helper.cc:335
static WaveHelper Default()
Definition: wave-helper.cc:285
bool Send(Ptr< Packet > packet, const Address &dest, uint16_t protocolNumber) override
bool StartSch(const SchInfo &schInfo)
bool DeleteTxProfile(uint32_t channelNumber)
Address GetAddress() const override
Ptr< ChannelScheduler > GetChannelScheduler() const
void SetReceiveCallback(NetDevice::ReceiveCallback cb) override
bool StopVsa(uint32_t channelNumber)
bool SendX(Ptr< Packet > packet, const Address &dest, uint32_t protocol, const TxInfo &txInfo)
bool RegisterTxProfile(const TxProfile &txprofile)
bool StartVsa(const VsaInfo &vsaInfo)
bool StopSch(uint32_t channelNumber)
represent a single transmission mode
Definition: wifi-mode.h:50
To trace WaveNetDevice, we have to overwrite the trace functions of class YansWifiPhyHelper.
Definition: wave-helper.h:42
static YansWavePhyHelper Default()
Create a phy helper in a default working state.
Definition: wave-helper.cc:122
manage and create wifi channel objects for the YANS model.
static YansWifiChannelHelper Default()
Create a channel helper in a default working state.
Ptr< YansWifiChannel > Create() const
void SetChannel(Ptr< YansWifiChannel > channel)
Time Now()
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:296
#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:790
#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:956
#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:251
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1336
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1348
@ VSA_TRANSMIT_IN_BOTHI
Definition: vsa-manager.h:39
@ WIFI_PREAMBLE_LONG
NodeContainer nodes
static WaveMacTestSuite waveMacTestSuite
the test suite
#define PI
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:707
-ns3 Test suite for the ns3 wrapper script
uint8_t data[writeSize]
uint32_t channelNumber
channel number
Definition: vsa-manager.h:69
static const uint32_t packetSize
Packet size generated at the AP.