A Discrete-Event Network Simulator
API
lr-wpan-mac-test.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2022 Tokushima University, Japan
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Author: Alberto Gallegos Ramonet <alramonet@is.tokushima-u.ac.jp>
18 */
19
20#include <ns3/constant-position-mobility-model.h>
21#include <ns3/core-module.h>
22#include <ns3/log.h>
23#include <ns3/lr-wpan-module.h>
24#include <ns3/packet.h>
25#include <ns3/propagation-delay-model.h>
26#include <ns3/propagation-loss-model.h>
27#include <ns3/simulator.h>
28#include <ns3/single-model-spectrum-channel.h>
29
30#include <iostream>
31
32using namespace ns3;
33
34NS_LOG_COMPONENT_DEFINE("lr-wpan-mac-test");
35
43{
44 public:
47
48 private:
67 void StateChangeNotificationDev0(std::string context,
68 Time now,
69 LrWpanPhyEnumeration oldState,
70 LrWpanPhyEnumeration newState);
78 void StateChangeNotificationDev2(std::string context,
79 Time now,
80 LrWpanPhyEnumeration oldState,
81 LrWpanPhyEnumeration newState);
82
83 void DoRun() override;
84
86};
87
89 : TestCase("Test PHY going to TRX_OFF state after CSMA failure")
90{
91}
92
94{
95}
96
97void
99{
100 NS_LOG_DEBUG("Received packet of size " << p->GetSize());
101}
102
103void
105{
107 {
108 NS_LOG_DEBUG("LrWpanMcpsDataConfirmStatus = Success");
109 }
111 {
112 NS_LOG_DEBUG("LrWpanMcpsDataConfirmStatus = Channel Access Failure");
113 }
114}
115
116void
118 Time now,
119 LrWpanPhyEnumeration oldState,
120 LrWpanPhyEnumeration newState)
121{
122 NS_LOG_DEBUG(Simulator::Now().As(Time::S)
123 << context << "PHY state change at " << now.As(Time::S) << " from "
124 << LrWpanHelper::LrWpanPhyEnumerationPrinter(oldState) << " to "
125 << LrWpanHelper::LrWpanPhyEnumerationPrinter(newState));
126
127 m_dev0State = newState;
128}
129
130void
132 Time now,
133 LrWpanPhyEnumeration oldState,
134 LrWpanPhyEnumeration newState)
135{
136 NS_LOG_DEBUG(Simulator::Now().As(Time::S)
137 << context << "PHY state change at " << now.As(Time::S) << " from "
138 << LrWpanHelper::LrWpanPhyEnumerationPrinter(oldState) << " to "
139 << LrWpanHelper::LrWpanPhyEnumerationPrinter(newState));
140}
141
142void
144{
145 // [00:01] [00:02] [00:03]
146 // Node 0------>Node1<------Node2 (interferer)
147 //
148 // Test Setup:
149 //
150 // Start the test with a transmission from node 2 to node 1,
151 // soon after, node 0 will attempt to transmit a packet to node 1 as well but
152 // it will fail because node 2 is still transmitting.
153 //
154 // The test confirms that the PHY in node 0 goes to TRX_OFF
155 // after its CSMA failure because its MAC has been previously
156 // set with flag RxOnWhenIdle (false). To ensure that node 0 CSMA
157 // do not attempt to do multiple backoffs delays in its CSMA,
158 // macMinBE and MacMaxCSMABackoffs has been set to 0.
159
161
163 LogComponentEnable("LrWpanCsmaCa", LOG_LEVEL_DEBUG);
164 LogComponentEnable("lr-wpan-mac-test", LOG_LEVEL_DEBUG);
165
166 // Create 3 nodes, and a NetDevice for each one
167 Ptr<Node> n0 = CreateObject<Node>();
168 Ptr<Node> n1 = CreateObject<Node>();
169 Ptr<Node> interferenceNode = CreateObject<Node>();
170
171 Ptr<LrWpanNetDevice> dev0 = CreateObject<LrWpanNetDevice>();
172 Ptr<LrWpanNetDevice> dev1 = CreateObject<LrWpanNetDevice>();
173 Ptr<LrWpanNetDevice> dev2 = CreateObject<LrWpanNetDevice>();
174
175 dev0->SetAddress(Mac16Address("00:01"));
176 dev1->SetAddress(Mac16Address("00:02"));
177 dev2->SetAddress(Mac16Address("00:03"));
178
179 // Each device must be attached to the same channel
180 Ptr<SingleModelSpectrumChannel> channel = CreateObject<SingleModelSpectrumChannel>();
182 CreateObject<LogDistancePropagationLossModel>();
184 CreateObject<ConstantSpeedPropagationDelayModel>();
185 channel->AddPropagationLossModel(propModel);
186 channel->SetPropagationDelayModel(delayModel);
187
188 dev0->SetChannel(channel);
189 dev1->SetChannel(channel);
190 dev2->SetChannel(channel);
191
192 // To complete configuration, a LrWpanNetDevice must be added to a node
193 n0->AddDevice(dev0);
194 n1->AddDevice(dev1);
195 interferenceNode->AddDevice(dev2);
196
197 // Trace state changes in the phy
198 dev0->GetPhy()->TraceConnect(
199 "TrxState",
200 std::string("[address 00:01]"),
202 dev2->GetPhy()->TraceConnect(
203 "TrxState",
204 std::string("[address 00:03]"),
206
207 Ptr<ConstantPositionMobilityModel> sender0Mobility =
208 CreateObject<ConstantPositionMobilityModel>();
209 sender0Mobility->SetPosition(Vector(0, 0, 0));
210 dev0->GetPhy()->SetMobility(sender0Mobility);
211 Ptr<ConstantPositionMobilityModel> sender1Mobility =
212 CreateObject<ConstantPositionMobilityModel>();
213
214 sender1Mobility->SetPosition(Vector(0, 1, 0));
215 dev1->GetPhy()->SetMobility(sender1Mobility);
216
217 Ptr<ConstantPositionMobilityModel> sender3Mobility =
218 CreateObject<ConstantPositionMobilityModel>();
219
220 sender3Mobility->SetPosition(Vector(0, 2, 0));
221 dev2->GetPhy()->SetMobility(sender3Mobility);
222
225 dev0->GetMac()->SetMcpsDataConfirmCallback(cb0);
226
229 dev0->GetMac()->SetMcpsDataIndicationCallback(cb1);
230
233 dev1->GetMac()->SetMcpsDataConfirmCallback(cb2);
234
237 dev1->GetMac()->SetMcpsDataIndicationCallback(cb3);
238
239 dev0->GetMac()->SetRxOnWhenIdle(false);
240 dev1->GetMac()->SetRxOnWhenIdle(false);
241
242 // set CSMA min beacon exponent (BE) to 0 to make all backoff delays == to 0 secs.
243 dev0->GetCsmaCa()->SetMacMinBE(0);
244 dev2->GetCsmaCa()->SetMacMinBE(0);
245
246 // Only try once to do a backoff period before giving up.
247 dev0->GetCsmaCa()->SetMacMaxCSMABackoffs(0);
248 dev2->GetCsmaCa()->SetMacMaxCSMABackoffs(0);
249
250 // The below should trigger two callbacks when end-to-end data is working
251 // 1) DataConfirm callback is called
252 // 2) DataIndication callback is called with value of 50
253 Ptr<Packet> p0 = Create<Packet>(50); // 50 bytes of dummy data
255 params.m_dstPanId = 0;
256
257 params.m_srcAddrMode = SHORT_ADDR;
258 params.m_dstAddrMode = SHORT_ADDR;
259 params.m_dstAddr = Mac16Address("00:02");
260
261 params.m_msduHandle = 0;
262
263 // Send the packet that will be rejected due to channel access failure
264 Simulator::ScheduleWithContext(1,
265 Seconds(0.00033),
266 &LrWpanMac::McpsDataRequest,
267 dev0->GetMac(),
268 params,
269 p0);
270
271 // Send interference packet
272 Ptr<Packet> p2 = Create<Packet>(60); // 60 bytes of dummy data
273 params.m_dstAddr = Mac16Address("00:02");
274
275 Simulator::ScheduleWithContext(2,
276 Seconds(0.0),
277 &LrWpanMac::McpsDataRequest,
278 dev2->GetMac(),
279 params,
280 p2);
281
282 NS_LOG_DEBUG("----------- Start of TestRxOffWhenIdleAfterCsmaFailure -------------------");
283 Simulator::Run();
284
287 "Error, dev0 [00:01] PHY should be in TRX_OFF after CSMA failure");
288
289 Simulator::Destroy();
290}
291
299{
300 public:
303
304 private:
317
318 void DoRun() override;
319
320 std::vector<PanDescriptor> m_panDescriptorList;
324};
325
327 : TestCase("Test the reception of PAN descriptors while performing an active scan")
328{
329}
330
332{
333}
334
335void
337{
338 if (params.m_status == MLMESCAN_SUCCESS)
339 {
340 m_panDescriptorList = params.m_panDescList;
341 }
342}
343
344void
346{
347 g_beaconPayloadSize = params.m_sdu->GetSize();
348}
349
350void
352{
353 /*
354 * [00:01] [00:02] [00:03]
355 * PAN Coordinator 1 (PAN: 5) End Device PAN Coordinator 2 (PAN: 7)
356 *
357 * |--------100 m----------------|----------106 m -----------------------|
358 * Channel 12 (Active Scan channels 11-14) Channel 14
359 *
360 * Test Setup:
361 *
362 * At the beginning of the simulation, PAN coordinators are set to
363 * non-beacon enabled mode and wait for any beacon requests.
364 *
365 * During the simulation, the end device do an Active scan (i.e. send beacon request commands to
366 * the scanned channels). On reception of such commands, coordinators reply with a single beacon
367 * which contains a PAN descriptor. The test makes sure that the PAN descriptors are received (2
368 * PAN descriptors) and because both PAN coordinators are set to a different distance from the
369 * end device, their LQI values should be below 255 but above 0. Likewise, Coordinator 2 LQI
370 * value should be less than Coordinator 1 LQI value. The exact expected value of LQI is not
371 * tested, this is dependable on the LQI implementation.
372 */
373
374 // Create 2 PAN coordinator nodes, and 1 end device
375 Ptr<Node> coord1 = CreateObject<Node>();
376 Ptr<Node> endNode = CreateObject<Node>();
377 Ptr<Node> coord2 = CreateObject<Node>();
378
379 Ptr<LrWpanNetDevice> coord1NetDevice = CreateObject<LrWpanNetDevice>();
380 Ptr<LrWpanNetDevice> endNodeNetDevice = CreateObject<LrWpanNetDevice>();
381 Ptr<LrWpanNetDevice> coord2NetDevice = CreateObject<LrWpanNetDevice>();
382
383 coord1NetDevice->SetAddress(Mac16Address("00:01"));
384 endNodeNetDevice->SetAddress(Mac16Address("00:02"));
385 coord2NetDevice->SetAddress(Mac16Address("00:03"));
386
387 // Configure Spectrum channel
388 Ptr<SingleModelSpectrumChannel> channel = CreateObject<SingleModelSpectrumChannel>();
390 CreateObject<LogDistancePropagationLossModel>();
392 CreateObject<ConstantSpeedPropagationDelayModel>();
393 channel->AddPropagationLossModel(propModel);
394 channel->SetPropagationDelayModel(delayModel);
395
396 coord1NetDevice->SetChannel(channel);
397 endNodeNetDevice->SetChannel(channel);
398 coord2NetDevice->SetChannel(channel);
399
400 coord1->AddDevice(coord1NetDevice);
401 endNode->AddDevice(endNodeNetDevice);
402 coord2->AddDevice(coord2NetDevice);
403
404 // Mobility
406 CreateObject<ConstantPositionMobilityModel>();
407 coord1Mobility->SetPosition(Vector(0, 0, 0));
408 coord1NetDevice->GetPhy()->SetMobility(coord1Mobility);
409
410 Ptr<ConstantPositionMobilityModel> endNodeMobility =
411 CreateObject<ConstantPositionMobilityModel>();
412 endNodeMobility->SetPosition(Vector(100, 0, 0));
413 endNodeNetDevice->GetPhy()->SetMobility(endNodeMobility);
414
416 CreateObject<ConstantPositionMobilityModel>();
417 coord2Mobility->SetPosition(Vector(206, 0, 0));
418 coord2NetDevice->GetPhy()->SetMobility(coord2Mobility);
419
420 // MAC layer Callbacks hooks
423 endNodeNetDevice->GetMac()->SetMlmeScanConfirmCallback(cb0);
424
427 endNodeNetDevice->GetMac()->SetMlmeBeaconNotifyIndicationCallback(cb1);
428
430 // ACTIVE SCAN //
432
433 // PAN coordinator N0 (PAN 5) is set to channel 12 in non-beacon mode but answer to beacon
434 // requests.
436 params.m_panCoor = true;
437 params.m_PanId = 5;
438 params.m_bcnOrd = 15;
439 params.m_sfrmOrd = 15;
440 params.m_logCh = 12;
441 Simulator::ScheduleWithContext(1,
442 Seconds(2.0),
443 &LrWpanMac::MlmeStartRequest,
444 coord1NetDevice->GetMac(),
445 params);
446
447 // PAN coordinator N2 (PAN 7) is set to channel 14 in non-beacon mode but answer to beacon
448 // requests. The second coordinator includes a beacon payload of 25 bytes using the
449 // MLME-SET.request primitive.
450 Ptr<LrWpanMacPibAttributes> pibAttribute = Create<LrWpanMacPibAttributes>();
451 pibAttribute->macBeaconPayload = Create<Packet>(25);
452 coord2NetDevice->GetMac()->MlmeSetRequest(LrWpanMacPibAttributeIdentifier::macBeaconPayload,
453 pibAttribute);
454
456 params2.m_panCoor = true;
457 params2.m_PanId = 7;
458 params2.m_bcnOrd = 15;
459 params2.m_sfrmOrd = 15;
460 params2.m_logCh = 14;
461 Simulator::ScheduleWithContext(2,
462 Seconds(2.0),
463 &LrWpanMac::MlmeStartRequest,
464 coord2NetDevice->GetMac(),
465 params2);
466
467 // End device N1 broadcast a single BEACON REQUEST for each channel (11, 12, 13, and 14).
468 // If a coordinator is present and in range, it will respond with a beacon broadcast.
469 // Scan Channels are represented by bits 0-26 (27 LSB)
470 // ch 14 ch 11
471 // | |
472 // 0x7800 = 0000000000000000111100000000000
473 MlmeScanRequestParams scanParams;
474 scanParams.m_chPage = 0;
475 scanParams.m_scanChannels = 0x7800;
476 scanParams.m_scanDuration = 14;
477 scanParams.m_scanType = MLMESCAN_ACTIVE;
478 Simulator::ScheduleWithContext(1,
479 Seconds(3.0),
480 &LrWpanMac::MlmeScanRequest,
481 endNodeNetDevice->GetMac(),
482 scanParams);
483
484 Simulator::Stop(Seconds(2000));
485 NS_LOG_DEBUG("----------- Start of TestActiveScanPanDescriptors -------------------");
486 Simulator::Run();
487
489 2,
490 "Error, Beacons not received or PAN descriptors not found");
492 255,
493 "Error, Coordinator 1 (PAN 5) LQI value should be less than 255.");
495 255,
496 "Error, Coordinator 2 (PAN 7) LQI value should be less than 255.");
498 0,
499 "Error, Coordinator 1 (PAN 5) LQI value should be greater than 0.");
501 0,
502 "Error, Coordinator 2 (PAN 7) LQI value should be greater than 0.");
503
505 m_panDescriptorList[1].m_linkQuality,
506 m_panDescriptorList[0].m_linkQuality,
507 "Error, Coordinator 2 (PAN 7) LQI value should be less than Coordinator 1 (PAN 5).");
508
510 25,
511 "Error, Beacon Payload not received or incorrect size (25 bytes)");
512
513 Simulator::Destroy();
514}
515
523{
524 public:
526};
527
529 : TestSuite("lr-wpan-mac-test", UNIT)
530{
532 AddTestCase(new TestActiveScanPanDescriptors, TestCase::QUICK);
533}
534
LrWpan MAC TestSuite.
Test MAC Active Scan PAN descriptor reception and check some of its values.
void ScanConfirm(MlmeScanConfirmParams params)
Function called in response to a MAC scan request.
uint32_t g_beaconPayloadSize
The size of the beacon payload received from a coordinator.
void BeaconNotifyIndication(MlmeBeaconNotifyIndicationParams params)
Function used to notify the reception of a beacon with payload.
std::vector< PanDescriptor > m_panDescriptorList
The list of PAN descriptors accumulated during the scan.
void DoRun() override
Implementation to actually run this TestCase.
Test PHY going to TRX_OFF after CSMA failure (MAC->RxOnWhenIdle(false))
void DataConfirm(McpsDataConfirmParams params)
Function called when a Data confirm is invoked (After Tx Attempt)
LrWpanPhyEnumeration m_dev0State
Stores the PHY state of device 0 [00:01].
void StateChangeNotificationDev2(std::string context, Time now, LrWpanPhyEnumeration oldState, LrWpanPhyEnumeration newState)
Function called when a the PHY state changes in Dev2 [00:03].
void DoRun() override
Implementation to actually run this TestCase.
void StateChangeNotificationDev0(std::string context, Time now, LrWpanPhyEnumeration oldState, LrWpanPhyEnumeration newState)
Function called when a the PHY state changes in Dev0 [00:01].
void DataIndication(McpsDataIndicationParams params, Ptr< Packet > p)
Function called when a Data indication is invoked.
void SetChannel(Ptr< SpectrumChannel > channel)
Set the channel to which the NetDevice, and therefore the PHY, should be attached to.
Ptr< LrWpanMac > GetMac() const
Get the MAC used by this NetDevice.
Ptr< LrWpanPhy > GetPhy() const
Get the PHY used by this NetDevice.
void SetAddress(Address address) override
This method indirects to LrWpanMac::SetShortAddress ()
Ptr< LrWpanCsmaCa > GetCsmaCa() const
Get the CSMA/CA implementation used by this NetDevice.
This class can contain 16 bit addresses.
Definition: mac16-address.h:44
uint32_t AddDevice(Ptr< NetDevice > device)
Associate a NetDevice to this node.
Definition: node.cc:138
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:862
encapsulates test code
Definition: test.h:1060
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
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:417
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
LrWpanPhyEnumeration
IEEE802.15.4-2006 PHY Emumerations Table 18 in section 6.2.3.
Definition: lr-wpan-phy.h:109
@ MLMESCAN_ACTIVE
Definition: lr-wpan-mac.h:182
@ IEEE_802_15_4_CHANNEL_ACCESS_FAILURE
Definition: lr-wpan-mac.h:197
@ IEEE_802_15_4_SUCCESS
Definition: lr-wpan-mac.h:194
@ MLMESCAN_SUCCESS
Definition: lr-wpan-mac.h:234
@ IEEE_802_15_4_PHY_TRX_OFF
Definition: lr-wpan-phy.h:118
@ SHORT_ADDR
Definition: lr-wpan-mac.h:156
@ macBeaconPayload
Definition: lr-wpan-mac.h:334
Time Now()
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:296
#define NS_TEST_ASSERT_MSG_LT(actual, limit, msg)
Test that an actual value is less than a limit and report and abort if not.
Definition: test.h:709
#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
#define NS_TEST_ASSERT_MSG_GT(actual, limit, msg)
Test that an actual value is greater than a limit and report and abort if not.
Definition: test.h:874
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1336
static LrWpanMacTestSuite g_lrWpanMacTestSuite
Static variable for test initialization.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void LogComponentEnable(const std::string &name, LogLevel level)
Enable the logging output associated with that log component.
Definition: log.cc:305
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
LogLevel
Logging severity classes and levels.
Definition: log.h:94
@ LOG_PREFIX_FUNC
Prefix all trace prints with function.
Definition: log.h:118
@ LOG_PREFIX_TIME
Prefix all trace prints with simulation time.
Definition: log.h:119
@ LOG_LEVEL_DEBUG
LOG_DEBUG and above.
Definition: log.h:104
void LogComponentEnableAll(LogLevel level)
Enable the logging output for all registered log components.
Definition: log.cc:329
channel
Definition: third.py:81
params
Fit Fluctuating Two Ray model to the 3GPP TR 38.901 using the Anderson-Darling goodness-of-fit ##.
MCPS-DATA.confirm params.
Definition: lr-wpan-mac.h:400
MCPS-DATA.indication params.
Definition: lr-wpan-mac.h:412
MCPS-DATA.request params.
Definition: lr-wpan-mac.h:384
MLME-BEACON-NOTIFY.indication params.
Definition: lr-wpan-mac.h:586
MLME-SCAN.confirm params.
Definition: lr-wpan-mac.h:522
MLME-SCAN.request params.
Definition: lr-wpan-mac.h:507
uint32_t m_scanChannels
The channel numbers to be scanned.
Definition: lr-wpan-mac.h:510
uint32_t m_chPage
The channel page on which to perform scan.
Definition: lr-wpan-mac.h:513
uint8_t m_scanDuration
A value used to calculate the length of time to spend scanning [aBaseSuperframeDuration * (2^m_scanDu...
Definition: lr-wpan-mac.h:511
LrWpanMlmeScanType m_scanType
Indicates the type of scan performed as described in IEEE 802.15.4-2011 (5.1.2.1).
Definition: lr-wpan-mac.h:508
MLME-START.request params.
Definition: lr-wpan-mac.h:457
uint8_t m_logCh
Logical channel on which to start using the new superframe configuration.
Definition: lr-wpan-mac.h:459
bool m_panCoor
On true this device will become coordinator.
Definition: lr-wpan-mac.h:468
uint8_t m_bcnOrd
Beacon Order, Used to calculate the beacon interval, a value of 15 indicates no periodic beacons will...
Definition: lr-wpan-mac.h:465
uint16_t m_PanId
Pan Identifier used by the device.
Definition: lr-wpan-mac.h:458
uint8_t m_sfrmOrd
Superframe Order, indicates the length of the CAP in time slots.
Definition: lr-wpan-mac.h:467