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/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
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 */
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 */
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 */
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 */
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 */
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();
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();
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
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
170 }
171}
172
173void
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
241 sender0Mobility->SetPosition(Vector(0, 0, 0));
242 dev0->GetPhy()->SetMobility(sender0Mobility);
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
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),
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)
287 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),
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)
309 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),
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)
332 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),
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)
355 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),
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
394 // Disconnect traces to eliminate Valgrid errors
395 dev0->GetMac()->TraceDisconnectWithoutContext(
396 "IfsEnd",
398 dev0->GetMac()->TraceDisconnectWithoutContext(
399 "MacRx",
401 dev0->GetPhy()->TraceDisconnectWithoutContext(
402 "PhyRxBegin",
404 dev1->GetMac()->TraceDisconnectWithoutContext(
405 "MacRx",
407
409}
410
411/**
412 * @ingroup lr-wpan-test
413 * @ingroup tests
414 *
415 * @brief LrWpan IFS TestSuite
416 */
417
419{
420 public:
422};
423
425 : TestSuite("lr-wpan-ifs-test", Type::UNIT)
426{
427 AddTestCase(new LrWpanDataIfsTestCase, TestCase::Duration::QUICK);
428}
429
430static 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.
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:66
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.
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 > 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:1368
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1344
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
uint16_t m_dstPanId
Destination PAN identifier.