A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
zigbee-rreq-test.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2024 Tokushima University, Tokushima, Japan
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author:
7 * Alberto Gallegos Ramonet <alramonet@is.tokushima-u.ac.jp>
8 */
9
10#include "ns3/constant-position-mobility-model.h"
11#include "ns3/core-module.h"
12#include "ns3/log.h"
13#include "ns3/lr-wpan-module.h"
14#include "ns3/packet.h"
15#include "ns3/propagation-delay-model.h"
16#include "ns3/propagation-loss-model.h"
17#include "ns3/rng-seed-manager.h"
18#include "ns3/simulator.h"
19#include "ns3/single-model-spectrum-channel.h"
20#include "ns3/zigbee-module.h"
21
22#include <iomanip>
23#include <iostream>
24
25using namespace ns3;
26using namespace ns3::lrwpan;
27using namespace ns3::zigbee;
28
29NS_LOG_COMPONENT_DEFINE("zigbee-rreq-test");
30
31/**
32 * @ingroup zigbee-test
33 * @ingroup tests
34 *
35 * Zigbee RREQ transmission retries test case
36 */
38{
39 public:
41 ~ZigbeeRreqRetryTestCase() override;
42
43 private:
44 /**
45 * Called in response to a NLME-NETWORK-DISCOVERY.request
46 *
47 * @param testcase The pointer to the testcase
48 * @param stack The zigbee stack of the device originating the callback
49 * @param params The NLME-NETWORK-DISCOVERY.confirm parameters
50 */
52 Ptr<ZigbeeStack> stack,
54
55 /**
56 * Called in response to a NLME-JOIN.request
57 *
58 * @param testcase The pointer to the testcase
59 * @param stack The zigbee stack of the device originating the callback
60 * @param params The NLME-JOIN.confirm parameters
61 */
62 static void NwkJoinConfirm(ZigbeeRreqRetryTestCase* testcase,
63 Ptr<ZigbeeStack> stack,
65
66 /**
67 * Called when a maximum RREQ retries are reached
68 *
69 * @param testcase The pointer to the testcase
70 * @param stack The zigbee stack of the device originating the callback
71 * @param rreqid The RREQ ID
72 * @param dst The destination Mac16Address of the RREQ
73 * @param rreqRetriesNum Maximum number of retries reached
74 */
76 Ptr<ZigbeeStack> stack,
77 uint8_t rreqid,
78 Mac16Address dst,
79 uint8_t rreqRetriesNum);
80 void DoRun() override;
81
82 std::vector<std::pair<uint32_t, uint32_t>>
83 m_rreqRetriesExhaustedList; //!< A list containing
84 //!< the RREQ ID and the allowed max retries every time the
85 //!< maximum RREQ retries are reached
86};
87
89 : TestCase("Zigbee: RREQ retries test")
90{
91}
92
96
97void
99 Ptr<ZigbeeStack> stack,
101{
102 // See Zigbee Specification r22.1.0, 3.6.1.4.1
103 // This method implements a simplistic version of the method implemented
104 // in a zigbee APL layer. In this layer a candidate Extended PAN Id must
105 // be selected and a NLME-JOIN.request must be issued.
106
107 if (params.m_status == NwkStatus::SUCCESS)
108 {
109 std::cout << " Network discovery confirm Received. Networks found ("
110 << params.m_netDescList.size() << "):\n";
111
112 for (const auto& netDescriptor : params.m_netDescList)
113 {
114 std::cout << " ExtPanID: 0x" << std::hex << netDescriptor.m_extPanId << "\n"
115 << std::dec << " CH: " << static_cast<uint32_t>(netDescriptor.m_logCh)
116 << "\n"
117 << std::hex << " Pan ID: 0x" << netDescriptor.m_panId << "\n"
118 << " Stack profile: " << std::dec
119 << static_cast<uint32_t>(netDescriptor.m_stackProfile) << "\n"
120 << "--------------------\n";
121 }
122
123 NlmeJoinRequestParams joinParams;
124
126 capaInfo.SetDeviceType(ROUTER);
127 capaInfo.SetAllocateAddrOn(true);
128
129 joinParams.m_rejoinNetwork = zigbee::JoiningMethod::ASSOCIATION;
130 joinParams.m_capabilityInfo = capaInfo.GetCapability();
131 joinParams.m_extendedPanId = params.m_netDescList[0].m_extPanId;
132
133 Simulator::ScheduleNow(&ZigbeeNwk::NlmeJoinRequest, stack->GetNwk(), joinParams);
134 }
135 else
136 {
137 NS_ABORT_MSG("Unable to discover networks | status: " << params.m_status);
138 }
139}
140
141void
143 Ptr<ZigbeeStack> stack,
145{
146 if (params.m_status == NwkStatus::SUCCESS)
147 {
148 std::cout << Simulator::Now().As(Time::S)
149 << " The device joined the network SUCCESSFULLY with short address " << std::hex
150 << params.m_networkAddress << " on the Extended PAN Id: " << std::hex
151 << params.m_extendedPanId << "\n"
152 << std::dec;
153
154 // 3 - After dev 1 is associated, it should be started as a router
155 // (i.e. it becomes able to accept request from other devices to join the network)
156 NlmeStartRouterRequestParams startRouterParams;
158 stack->GetNwk(),
159 startRouterParams);
160 }
161 else
162 {
163 std::cout << " The device FAILED to join the network with status " << params.m_status
164 << "\n";
165 }
166}
167
168void
170 Ptr<ZigbeeStack> stack,
171 uint8_t rreqid,
172 Mac16Address dst,
173 uint8_t rreqRetriesNum)
174{
175 NS_LOG_DEBUG("RREQ retries (" << static_cast<uint32_t>(rreqRetriesNum)
176 << ") exhausted for destination [" << dst << "] and RREQ ID "
177 << static_cast<uint32_t>(rreqid));
178
179 testcase->m_rreqRetriesExhaustedList.emplace_back(
180 std::pair(stack->GetNode()->GetId(), rreqRetriesNum));
181}
182
183void
185{
186 // RREQ retries exhaustion test
187 // This test verifies that the necessary number of Route Requests are issued during
188 // zigbee's route discovery process in which a Route Reply (RREP) is not received.
189 // In this test, a coordinator and 2 routers are set in a line.
190 // The coordinator issues a route discovery primitive (NLME-ROUTE-DISCOVERY.request)
191 // to a non-existent destination (0d:10). Route request are retried a number of times
192 // depending on the origin of the request (initial request or relayed request)
193 // Topology:
194 //
195 // ========= RREQ(x3) =====> ======== RREQ(x2) ===> ==== RREQ(x2) ====>
196 // ZC--------------------------ZR1-------------------------ZR2
197 // (Node 0) (Node 1) (Node 2)
198 //
199 // The number of retries depend on the NWK layer constants:
200 // nwkcInitialRREQRetries (Default: 3)
201 // nwkcRREQRetries (Default: 2)
202
204 LogComponentEnable("zigbee-rreq-test", LOG_LEVEL_DEBUG);
205
208
210 nodes.Create(3);
211
212 //// Configure MAC
213
214 LrWpanHelper lrWpanHelper;
215 NetDeviceContainer lrwpanDevices = lrWpanHelper.Install(nodes);
216 Ptr<LrWpanNetDevice> dev0 = lrwpanDevices.Get(0)->GetObject<LrWpanNetDevice>();
217 Ptr<LrWpanNetDevice> dev1 = lrwpanDevices.Get(1)->GetObject<LrWpanNetDevice>();
218 Ptr<LrWpanNetDevice> dev2 = lrwpanDevices.Get(2)->GetObject<LrWpanNetDevice>();
219
220 dev0->GetMac()->SetExtendedAddress("00:00:00:00:00:00:CA:FE");
221 dev1->GetMac()->SetExtendedAddress("00:00:00:00:00:00:00:01");
222 dev2->GetMac()->SetExtendedAddress("00:00:00:00:00:00:00:02");
223
227
230
231 channel->AddPropagationLossModel(propModel);
232 channel->SetPropagationDelayModel(delayModel);
233
234 dev0->SetChannel(channel);
235 dev1->SetChannel(channel);
236 dev2->SetChannel(channel);
237
238 //// Configure NWK
239
240 ZigbeeHelper zigbee;
241 zigbee.SetNwkLayerOnly();
242 ZigbeeStackContainer zigbeeStackContainer = zigbee.Install(lrwpanDevices);
243
244 Ptr<ZigbeeStack> zstack0 = zigbeeStackContainer.Get(0)->GetObject<ZigbeeStack>();
245 Ptr<ZigbeeStack> zstack1 = zigbeeStackContainer.Get(1)->GetObject<ZigbeeStack>();
246 Ptr<ZigbeeStack> zstack2 = zigbeeStackContainer.Get(2)->GetObject<ZigbeeStack>();
247
248 //// Configure Nodes Mobility
249
251 dev0Mobility->SetPosition(Vector(0, 0, 0));
252 dev0->GetPhy()->SetMobility(dev0Mobility);
253
255 dev1Mobility->SetPosition(Vector(90, 0, 0)); // 110 ,0,0
256 dev1->GetPhy()->SetMobility(dev1Mobility);
257
259 dev2Mobility->SetPosition(Vector(170, 0, 0)); // 190,0,0
260 dev2->GetPhy()->SetMobility(dev2Mobility);
261
262 // NWK callbacks hooks, these hooks are usually directly connected to the APS layer
263 // where all these calls inform the result of a request originated the APS layer.
264 // In this test these are used to complete the Join process and router initialization
265 zstack1->GetNwk()->SetNlmeNetworkDiscoveryConfirmCallback(
267 zstack2->GetNwk()->SetNlmeNetworkDiscoveryConfirmCallback(
269
270 zstack1->GetNwk()->SetNlmeJoinConfirmCallback(
272 zstack2->GetNwk()->SetNlmeJoinConfirmCallback(
274
275 // Connect to traces in the NWK layer
276 zstack0->GetNwk()->TraceConnectWithoutContext(
277 "rreqRetriesExhausted",
279
280 zstack1->GetNwk()->TraceConnectWithoutContext(
281 "rreqRetriesExhausted",
283
284 zstack2->GetNwk()->TraceConnectWithoutContext(
285 "rreqRetriesExhausted",
287
288 // 1 - Initiate the Zigbee coordinator, start the network
290 netFormParams.m_scanChannelList.channelPageCount = 1;
292 netFormParams.m_scanDuration = 0;
293 netFormParams.m_superFrameOrder = 15;
294 netFormParams.m_beaconOrder = 15;
295
296 Simulator::ScheduleWithContext(zstack0->GetNode()->GetId(),
297 Seconds(1),
299 zstack0->GetNwk(),
300 netFormParams);
301
302 // 2- Let the dev1 (Router) discovery the coordinator and join the network, after
303 // this, it will become router itself(call to NLME-START-ROUTER.request). We
304 // continue doing the same with the rest of the devices which will discover the
305 // previously added routers and join the network
307 netDiscParams.m_scanChannelList.channelPageCount = 1;
308 netDiscParams.m_scanChannelList.channelsField[0] = 0x00007800; // 0x00000800;
309 netDiscParams.m_scanDuration = 2;
310 Simulator::ScheduleWithContext(zstack1->GetNode()->GetId(),
311 Seconds(3),
313 zstack1->GetNwk(),
314 netDiscParams);
315
317 netDiscParams2.m_scanChannelList.channelPageCount = 1;
318 netDiscParams2.m_scanChannelList.channelsField[0] = 0x00007800; // 0x00000800;
319 netDiscParams2.m_scanDuration = 2;
320 Simulator::ScheduleWithContext(zstack2->GetNode()->GetId(),
321 Seconds(4),
323 zstack2->GetNwk(),
324 netDiscParams2);
325
326 // 5- Find a route to the given device short address
327 NlmeRouteDiscoveryRequestParams routeDiscParams;
328 routeDiscParams.m_dstAddr = Mac16Address("0d:10");
329 Simulator::ScheduleWithContext(zstack0->GetNode()->GetId(),
330 Seconds(8),
332 zstack0->GetNwk(),
333 routeDiscParams);
335
336 for (auto rreqRetriesExhaustedElement : m_rreqRetriesExhaustedList)
337 {
338 if (rreqRetriesExhaustedElement.first == 0)
339 {
340 // For Node with id 0 (Coordinator/RREQ originator) the number of retries is
341 // nwkcInitialRREQRetries (Default: 3)
342 NS_TEST_EXPECT_MSG_EQ(rreqRetriesExhaustedElement.second,
343 3,
344 "The number of RREQ retries from an originator should be 3");
345 }
346 else
347 {
348 // For other node other that the RREQ originator the number of retries is
349 // nwkcRREQRetries (Default: 2)
350 NS_TEST_EXPECT_MSG_EQ(rreqRetriesExhaustedElement.second,
351 2,
352 "The number of RREQ retries from a relaying node should be 2");
353 }
354 }
355
357}
358
359/**
360 * @ingroup zigbee-test
361 * @ingroup tests
362 *
363 * Zigbee RREQ TestSuite
364 */
366{
367 public:
369};
370
372 : TestSuite("zigbee-rreq-test", Type::UNIT)
373{
374 AddTestCase(new ZigbeeRreqRetryTestCase, TestCase::Duration::QUICK);
375}
376
377static ZigbeeRreqTestSuite zigbeeRreqTestSuite; //!< Static variable for test initialization
Zigbee RREQ transmission retries test case.
static void NwkNetworkDiscoveryConfirm(ZigbeeRreqRetryTestCase *testcase, Ptr< ZigbeeStack > stack, NlmeNetworkDiscoveryConfirmParams params)
Called in response to a NLME-NETWORK-DISCOVERY.request.
void DoRun() override
Implementation to actually run this TestCase.
static void RreqRetriesExhausted(ZigbeeRreqRetryTestCase *testcase, Ptr< ZigbeeStack > stack, uint8_t rreqid, Mac16Address dst, uint8_t rreqRetriesNum)
Called when a maximum RREQ retries are reached.
std::vector< std::pair< uint32_t, uint32_t > > m_rreqRetriesExhaustedList
A list containing the RREQ ID and the allowed max retries every time the maximum RREQ retries are rea...
static void NwkJoinConfirm(ZigbeeRreqRetryTestCase *testcase, Ptr< ZigbeeStack > stack, NlmeJoinConfirmParams params)
Called in response to a NLME-JOIN.request.
Zigbee RREQ TestSuite.
helps to manage and create IEEE 802.15.4 NetDevice objects
NetDeviceContainer Install(NodeContainer c)
Install a LrWpanNetDevice and the associated structures (e.g., channel) in the nodes.
This class can contain 16 bit addresses.
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.
Smart pointer class similar to boost::intrusive_ptr.
static void SetRun(uint64_t run)
Set the run number of simulation.
static void SetSeed(uint32_t seed)
Set the seed.
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:131
static void ScheduleWithContext(uint32_t context, const Time &delay, FUNC f, Ts &&... args)
Schedule an event with the given context.
Definition simulator.h:578
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:197
static void Run()
Run the simulation.
Definition simulator.cc:167
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition simulator.h:595
encapsulates test code
Definition test.h:1050
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition test.cc:292
A suite of tests to run.
Definition test.h:1267
Type
Type of test.
Definition test.h:1274
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition time.cc:403
@ S
second
Definition nstime.h:105
Setup a Zigbee stack to be used with LrWpanNetDevice.
zigbee::ZigbeeStackContainer Install(NetDeviceContainer c)
Install the Zigbee stack on top of an existing LrWpanNetDevice.
void SetNwkLayerOnly()
If this is set, the helper will only create Zigbee stacks that contain only the NWK layer.
Network layer to device interface.
Represent the the Capability Information Bit fields See zigbe Specification r22.1....
uint8_t GetCapability() const
Used to obtain the complete capability information bit map.
void SetDeviceType(MacDeviceType devType)
Set the device type bit for the capability information field.
void SetAllocateAddrOn(bool value)
Set the Allocate Addr On for the capability information field.
void NlmeStartRouterRequest(NlmeStartRouterRequestParams params)
Zigbee Specification r22.1.0, section 3.2.2.9 NLME-START-ROUTER.request This primitive allows the nex...
void NlmeNetworkDiscoveryRequest(NlmeNetworkDiscoveryRequestParams params)
Zigbee Specification r22.1.0, section 3.2.2.3 NLME-NETWORK-DISCOVERY.request Allows the next higher l...
void NlmeJoinRequest(NlmeJoinRequestParams params)
Zigbee Specification r22.1.0, section 3.2.2.13 NLME-JOIN.request This primitive allows the next highe...
void NlmeNetworkFormationRequest(NlmeNetworkFormationRequestParams params)
Zigbee Specification r22.1.0, Section 3.2.2.5 and 3.6.1.1 NLME-NETWORK-FORMATION.request Request the ...
void NlmeRouteDiscoveryRequest(NlmeRouteDiscoveryRequestParams params)
Zigbee Specification r22.1.0, section 3.2.2.33.3 and 3.6.3.5 NLME-ROUTE-DISCOVERY....
Holds a vector of ns3::ZigbeeStack pointers.
Ptr< ZigbeeStack > Get(uint32_t i) const
Get a stack element from the container.
Zigbee protocol stack to device interface.
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition abort.h:38
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
auto MakeBoundCallback(R(*fnPtr)(Args...), BArgs &&... bargs)
Make Callbacks with varying number of bound arguments.
Definition callback.h:745
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
#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:241
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1345
@ ROUTER
Router device.
NodeContainer nodes
static constexpr uint32_t ALL_CHANNELS
Bitmap representing all channels (11~26) LSB b0-b26, b27-b31 MSB Page 0 in Zigbee (250kbps O-QPSK)
Definition zigbee-nwk.h:47
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:284
LogLevel
Logging severity classes and levels.
Definition log.h:83
@ LOG_PREFIX_FUNC
Prefix all trace prints with function.
Definition log.h:107
@ LOG_PREFIX_TIME
Prefix all trace prints with simulation time.
Definition log.h:108
@ LOG_LEVEL_DEBUG
LOG_DEBUG and above.
Definition log.h:102
@ LOG_PREFIX_NODE
Prefix all trace prints with simulation node.
Definition log.h:109
void LogComponentEnableAll(LogLevel level)
Enable the logging output for all registered log components.
Definition log.cc:302
uint8_t channelPageCount
The number of the channel page structures contained in the channel list structure.
Definition zigbee-nwk.h:274
std::vector< uint32_t > channelsField
The set of channels for a given page.
Definition zigbee-nwk.h:276
NLME-JOIN.confirm params.
Definition zigbee-nwk.h:537
NLME-JOIN.request params.
Definition zigbee-nwk.h:515
JoiningMethod m_rejoinNetwork
This parameter controls the method of joining the network.
Definition zigbee-nwk.h:518
uint8_t m_capabilityInfo
The operating capabilities of the device being directly joined (Bit map).
Definition zigbee-nwk.h:524
uint64_t m_extendedPanId
The 64 bit PAN identifier of the the network to join.
Definition zigbee-nwk.h:516
NLME-NETWORK-DISCOVERY.confirm params.
Definition zigbee-nwk.h:500
NLME-NETWORK-DISCOVERY.request params.
Definition zigbee-nwk.h:461
uint8_t m_scanDuration
A value used to calculate the length of time to spend.
Definition zigbee-nwk.h:464
ChannelList m_scanChannelList
The list of all channel pages and the associated channels that shall be scanned.
Definition zigbee-nwk.h:462
NLME-NETWORK-FORMATION.request params.
Definition zigbee-nwk.h:348
uint8_t m_superFrameOrder
The superframe order.
Definition zigbee-nwk.h:355
ChannelList m_scanChannelList
A structure that contain a description on the pages and their channels to be scanned.
Definition zigbee-nwk.h:349
uint8_t m_scanDuration
The time spent of each channel in symbols: aBaseSuperframeDuriantion * (2n+1).
Definition zigbee-nwk.h:352
NLME-ROUTE-DISCOVERY.request params.
Definition zigbee-nwk.h:404
Mac16Address m_dstAddr
The destination of the route discovery.
Definition zigbee-nwk.h:406
NLME-START-ROUTER.request params.
Definition zigbee-nwk.h:588
static ZigbeeRreqTestSuite zigbeeRreqTestSuite
Static variable for test initialization.