A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
lr-wpan-ifs-test.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2019 Ritsumeikan University, Shiga, Japan
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author:
7 * Alberto Gallegos Ramonet <ramonet@fc.ritsumei.ac.jp>
8 */
9
10#include "ns3/rng-seed-manager.h"
11#include <ns3/constant-position-mobility-model.h>
12#include <ns3/core-module.h>
13#include <ns3/log.h>
14#include <ns3/lr-wpan-module.h>
15#include <ns3/packet.h>
16#include <ns3/propagation-delay-model.h>
17#include <ns3/propagation-loss-model.h>
18#include <ns3/simulator.h>
19#include <ns3/single-model-spectrum-channel.h>
20
21#include <iomanip>
22#include <iostream>
23
24using namespace ns3;
25using namespace ns3::lrwpan;
26
27NS_LOG_COMPONENT_DEFINE("lr-wpan-ifs-test");
28
29/**
30 * \ingroup lr-wpan-test
31 * \ingroup tests
32 *
33 * \brief LrWpan Dataframe transmission with Interframe Space
34 */
36{
37 public:
39 ~LrWpanDataIfsTestCase() override;
40
41 private:
42 /**
43 * \brief Function called when DataConfirm is hit.
44 * \param testcase pointer to the testcase
45 * \param dev originating NetDevice
46 * \param params the MCPS params
47 */
48 static void DataConfirm(LrWpanDataIfsTestCase* testcase,
51
52 /**
53 * \brief Function called when DataReceived is hit.
54 * \param testcase pointer to the testcase
55 * \param dev originating NetDevice
56 * \param p packet
57 */
58 static void DataReceivedDev0(LrWpanDataIfsTestCase* testcase,
61
62 /**
63 * \brief Function called when PhyDataRxStart is hit.
64 * \param testcase pointer to the testcase
65 * \param dev originating NetDevice
66 * \param p packet
67 */
68 static void PhyDataRxStart(LrWpanDataIfsTestCase* testcase,
71
72 /**
73 * \brief Function called when DataConfirm is hit.
74 * \param testcase pointer to the testcase
75 * \param dev originating NetDevice
76 * \param p packet
77 */
78 static void DataReceivedDev1(LrWpanDataIfsTestCase* testcase,
81
82 /**
83 * \brief Function called when the IFS ends.
84 * \param testcase pointer to the testcase
85 * \param dev originating NetDevice
86 * \param IfsTime the IFS time
87 */
88 static void IfsEnd(LrWpanDataIfsTestCase* testcase, Ptr<LrWpanNetDevice> dev, Time IfsTime);
89
90 void DoRun() override;
91 Time m_lastTxTime; //!< The time of the last transmitted packet
92 Time m_ackRxTime; //!< The time of the received acknowledgment.
93 Time m_endIfs; //!< The time where the Interframe Space ended.
94 Time m_phyStartRx; //!< The time the phy start receiving a packet.
95};
96
98 : TestCase("Lrwpan: IFS tests")
99{
100}
101
105
106void
110{
111 // get the end time of transmission
112 testcase->m_lastTxTime = Simulator::Now();
113}
114
115void
119{
120 // Callback for Data received in the Dev0
121 Ptr<Packet> RxPacket = p->Copy();
122 LrWpanMacHeader receivedMacHdr;
123 RxPacket->RemoveHeader(receivedMacHdr);
124
125 if (receivedMacHdr.IsAcknowledgment())
126 {
127 testcase->m_ackRxTime = Simulator::Now();
128 std::cout << Simulator::Now().GetSeconds() << " | Dev0 (Node 0) received Acknowledgment.\n";
129 }
130 else if (receivedMacHdr.GetShortDstAddr().IsBroadcast())
131 {
132 std::cout << Simulator::Now().GetSeconds() << " | Dev0 (Node 0) received Broadcast. \n";
133 }
134}
135
136void
140{
141 // get the start time the phy in dev 0 ( Node 0) start receiving a frame
142 testcase->m_phyStartRx = Simulator::Now();
143}
144
145void
149{
150 // Callback for Data received in the Dev1
151 Ptr<Packet> RxPacket = p->Copy();
152 LrWpanMacHeader receivedMacHdr;
153 RxPacket->RemoveHeader(receivedMacHdr);
154
155 if (receivedMacHdr.GetShortDstAddr().IsBroadcast())
156 {
157 std::cout << Simulator::Now().GetSeconds() << " | Dev1 (Node 1) received Broadcast. \n";
158
159 // Bcst received, respond with another bcst
160
161 Ptr<Packet> p0 = Create<Packet>(50); // 50 bytes of dummy data
162 McpsDataRequestParams params1;
163 params1.m_dstPanId = 0;
164 params1.m_srcAddrMode = SHORT_ADDR;
165 params1.m_dstAddrMode = SHORT_ADDR;
166 params1.m_dstAddr = Mac16Address("ff:ff");
167 params1.m_msduHandle = 0;
168
169 Simulator::ScheduleNow(&LrWpanMac::McpsDataRequest, dev->GetMac(), params1, p0);
170 }
171}
172
173void
176 Time IfsTime)
177{
178 // take the time of the end of the IFS
179 testcase->m_endIfs = Simulator::Now();
180}
181
182void
184{
185 // Test of Interframe Spaces (IFS)
186
187 // The MAC layer needs a finite amount of time to process the data received from the PHY.
188 // To allow this, to successive transmitted frames must be separated for at least one IFS.
189 // The IFS size depends on the transmitted frame. This test verifies that the IFS is correctly
190 // implemented and its size correspond to the situations described by the standard.
191 // For more info see IEEE 802.15.4-2011 Section 5.1.1.3
192
197 LogComponentEnable("LrWpanCsmaCa", LOG_LEVEL_DEBUG);
198
199 // Create 2 nodes, and a NetDevice for each one
202
205
206 dev0->SetAddress(Mac16Address("00:01"));
207 dev1->SetAddress(Mac16Address("00:02"));
208
209 // Each device must be attached to the same channel
215 channel->AddPropagationLossModel(propModel);
216 channel->SetPropagationDelayModel(delayModel);
217
218 dev0->SetChannel(channel);
219 dev1->SetChannel(channel);
220
221 // To complete configuration, a LrWpanNetDevice must be added to a node
222 n0->AddDevice(dev0);
223 n1->AddDevice(dev1);
224
225 // Connect to trace files in the MAC layer
226 dev0->GetMac()->TraceConnectWithoutContext(
227 "IfsEnd",
229 dev0->GetMac()->TraceConnectWithoutContext(
230 "MacRx",
232 dev0->GetPhy()->TraceConnectWithoutContext(
233 "PhyRxBegin",
235 dev1->GetMac()->TraceConnectWithoutContext(
236 "MacRx",
238
239 Ptr<ConstantPositionMobilityModel> sender0Mobility =
241 sender0Mobility->SetPosition(Vector(0, 0, 0));
242 dev0->GetPhy()->SetMobility(sender0Mobility);
243 Ptr<ConstantPositionMobilityModel> sender1Mobility =
245 // Configure position 10 m distance
246 sender1Mobility->SetPosition(Vector(0, 10, 0));
247 dev1->GetPhy()->SetMobility(sender1Mobility);
248
251 dev0->GetMac()->SetMcpsDataConfirmCallback(cb0);
252
255 dev1->GetMac()->SetMcpsDataConfirmCallback(cb1);
256
259 params.m_dstPanId = 0;
260
261 params.m_srcAddrMode = SHORT_ADDR;
262 params.m_dstAddrMode = SHORT_ADDR;
263 params.m_dstAddr = Mac16Address("00:02");
264 params.m_msduHandle = 0;
265
266 Time ifsSize;
267
268 // NOTE: // For all the test , PAN SRC and DST are the same (PAN compression is ON) therefore
269 // MAC header is 2 bytes smaller than the usual 11 bytes (see IEEE 802.15.4 Section 7.5.6.1)
270
271 //////////////////////// SIFS ///////////////////////////
272
274 Seconds(0.0),
276 dev0->GetMac(),
277 params,
278 p0);
279
281
282 // MPDU = MAC header (9 bytes) + MSDU (2 bytes)+ MAC trailer (2 bytes) = 13)
283 // MPDU (13 bytes) < 18 bytes therefore IFS = SIFS
284 // SIFS = 12 symbols (192 Microseconds on a 2.4Ghz O-QPSK PHY)
285 ifsSize = m_endIfs - m_lastTxTime;
286 NS_TEST_EXPECT_MSG_EQ(ifsSize,
287 Time(MicroSeconds(192)),
288 "Wrong Short InterFrame Space (SIFS) Size after dataframe Tx");
289 std::cout << "----------------------------------\n";
290
291 //////////////////////// LIFS ///////////////////////////
292
293 p0 = Create<Packet>(8);
294
296 Seconds(0.0),
298 dev0->GetMac(),
299 params,
300 p0);
301
303
304 // MPDU = MAC header (9 bytes) + MSDU (8 bytes)+ MAC trailer (2 bytes) = 19)
305 // MPDU (19 bytes) > 18 bytes therefore IFS = LIFS
306 // LIFS = 40 symbols (640 Microseconds on a 2.4Ghz O-QPSK PHY)
307 ifsSize = m_endIfs - m_lastTxTime;
308 NS_TEST_EXPECT_MSG_EQ(ifsSize,
309 Time(MicroSeconds(640)),
310 "Wrong Long InterFrame Space (LIFS) Size after dataframe Tx");
311 std::cout << "----------------------------------\n";
312
313 //////////////////////// SIFS after ACK //////////////////
314
315 params.m_txOptions = TX_OPTION_ACK;
316 p0 = Create<Packet>(2);
317
319 Seconds(0.0),
321 dev0->GetMac(),
322 params,
323 p0);
324
326
327 // MPDU = MAC header (9 bytes) + MSDU (2 bytes)+ MAC trailer (2 bytes) = 13)
328 // MPDU (13 bytes) < 18 bytes therefore IFS = SIFS
329 // SIFS = 12 symbols (192 Microseconds on a 2.4Ghz O-QPSK PHY)
330 ifsSize = m_endIfs - m_ackRxTime;
331 NS_TEST_EXPECT_MSG_EQ(ifsSize,
332 Time(MicroSeconds(192)),
333 "Wrong Short InterFrame Space (SIFS) Size after ACK Rx");
334 std::cout << "----------------------------------\n";
335
336 //////////////////////// LIFS after ACK //////////////////
337
338 params.m_txOptions = TX_OPTION_ACK;
339 p0 = Create<Packet>(8);
340
342 Seconds(0.0),
344 dev0->GetMac(),
345 params,
346 p0);
347
349
350 // MPDU = MAC header (9 bytes) + MSDU (8 bytes)+ MAC trailer (2 bytes) = 19)
351 // MPDU (19 bytes) > 18 bytes therefore IFS = LIFS
352 // LIFS = 40 symbols (640 Microseconds on a 2.4Ghz O-QPSK PHY)
353 ifsSize = m_endIfs - m_ackRxTime;
354 NS_TEST_EXPECT_MSG_EQ(ifsSize,
355 Time(MicroSeconds(640)),
356 "Wrong Long InterFrame Space (LIFS) Size after ACK Rx");
357 std::cout << "----------------------------------\n";
358
359 /////////////////////// BCST frame with immediate BCST response //////////////////
360
361 // A packet is broadcasted and the receiving device respond with another broadcast.
362 // The devices are configured to not have any backoff delays in their CSMA/CA.
363 // In most cases, a device receive a packet after its IFS, however in this test,
364 // the receiving device of the reply broadcast will still be in its IFS when the
365 // broadcast is received (i.e. a PHY StartRX () occur before the end of IFS).
366 // This demonstrates that a device can start receiving a frame even during an IFS.
367
368 // Makes the backoff delay period = 0 in the CSMA/CA
369 dev0->GetCsmaCa()->SetMacMinBE(0);
370 dev1->GetCsmaCa()->SetMacMinBE(0);
371
372 p0 = Create<Packet>(50); // 50 bytes of dummy data
373 params.m_dstPanId = 0;
374 params.m_srcAddrMode = SHORT_ADDR;
375 params.m_dstAddrMode = SHORT_ADDR;
376 params.m_dstAddr = Mac16Address("ff:ff");
377 params.m_msduHandle = 0;
378
380 Seconds(0.0),
382 dev0->GetMac(),
383 params,
384 p0);
385
387
390 "Error, IFS end time should be greater than PHY start Rx time");
391
392 //////////////////////////////////////////////////////////////////////////////////
393
395}
396
397/**
398 * \ingroup lr-wpan-test
399 * \ingroup tests
400 *
401 * \brief LrWpan IFS TestSuite
402 */
403
405{
406 public:
408};
409
411 : TestSuite("lr-wpan-ifs-test", Type::UNIT)
412{
413 AddTestCase(new LrWpanDataIfsTestCase, TestCase::Duration::QUICK);
414}
415
416static LrWpanIfsTestSuite lrWpanIfsTestSuite; //!< Static variable for test initialization
LrWpan Dataframe transmission with Interframe Space.
static void IfsEnd(LrWpanDataIfsTestCase *testcase, Ptr< LrWpanNetDevice > dev, Time IfsTime)
Function called when the IFS ends.
Time m_endIfs
The time where the Interframe Space ended.
static void DataReceivedDev1(LrWpanDataIfsTestCase *testcase, Ptr< LrWpanNetDevice > dev, Ptr< const Packet >)
Function called when DataConfirm is hit.
void DoRun() override
Implementation to actually run this TestCase.
Time m_phyStartRx
The time the phy start receiving a packet.
Time m_lastTxTime
The time of the last transmitted packet.
static void DataReceivedDev0(LrWpanDataIfsTestCase *testcase, Ptr< LrWpanNetDevice > dev, Ptr< const Packet > p)
Function called when DataReceived is hit.
Time m_ackRxTime
The time of the received acknowledgment.
static void PhyDataRxStart(LrWpanDataIfsTestCase *testcase, Ptr< LrWpanNetDevice > dev, Ptr< const Packet > p)
Function called when PhyDataRxStart is hit.
static void DataConfirm(LrWpanDataIfsTestCase *testcase, Ptr< LrWpanNetDevice > dev, McpsDataConfirmParams params)
Function called when DataConfirm is hit.
LrWpan IFS TestSuite.
This class can contain 16 bit addresses.
bool IsBroadcast() const
Checks if the address is a broadcast address according to 802.15.4 scheme (i.e., 0xFFFF).
Smart pointer class similar to boost::intrusive_ptr.
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:577
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:594
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
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition nstime.h:392
Represent the Mac Header with the Frame Control and Sequence Number fields.
Mac16Address GetShortDstAddr() const
Get the Destination Short address.
bool IsAcknowledgment() const
Returns true if the header is an ack.
void McpsDataRequest(McpsDataRequestParams params, Ptr< Packet > p) override
IEEE 802.15.4-2006, section 7.1.1.1 MCPS-DATA.request Request to transfer a MSDU.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
@ TX_OPTION_ACK
TX_OPTION_ACK.
Definition lr-wpan-mac.h:53
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
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
#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
#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:864
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1332
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1308
static LrWpanIfsTestSuite lrWpanIfsTestSuite
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:291
@ 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
void LogComponentEnableAll(LogLevel level)
Enable the logging output for all registered log components.
Definition log.cc:309
AddressMode m_dstAddrMode
Destination address mode.
Mac16Address m_dstAddr
Destination address.
uint16_t m_dstPanId
Destination PAN identifier.
AddressMode m_srcAddrMode
Source address mode.