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 * 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:
18 * Alberto Gallegos Ramonet <ramonet@fc.ritsumei.ac.jp>
19 */
20
21#include "ns3/rng-seed-manager.h"
22#include <ns3/constant-position-mobility-model.h>
23#include <ns3/core-module.h>
24#include <ns3/log.h>
25#include <ns3/lr-wpan-module.h>
26#include <ns3/packet.h>
27#include <ns3/propagation-delay-model.h>
28#include <ns3/propagation-loss-model.h>
29#include <ns3/simulator.h>
30#include <ns3/single-model-spectrum-channel.h>
31
32#include <iomanip>
33#include <iostream>
34
35using namespace ns3;
36
37NS_LOG_COMPONENT_DEFINE("lr-wpan-ifs-test");
38
39/**
40 * \ingroup lr-wpan-test
41 * \ingroup tests
42 *
43 * \brief LrWpan Dataframe transmission with Interframe Space
44 */
46{
47 public:
49 ~LrWpanDataIfsTestCase() override;
50
51 private:
52 /**
53 * \brief Function called when DataConfirm is hit.
54 * \param testcase pointer to the testcase
55 * \param dev originating NetDevice
56 * \param params the MCPS params
57 */
58 static void DataConfirm(LrWpanDataIfsTestCase* testcase,
61
62 /**
63 * \brief Function called when DataReceived is hit.
64 * \param testcase pointer to the testcase
65 * \param dev originating NetDevice
66 * \param p packet
67 */
68 static void DataReceivedDev0(LrWpanDataIfsTestCase* testcase,
71
72 /**
73 * \brief Function called when PhyDataRxStart is hit.
74 * \param testcase pointer to the testcase
75 * \param dev originating NetDevice
76 * \param p packet
77 */
78 static void PhyDataRxStart(LrWpanDataIfsTestCase* testcase,
81
82 /**
83 * \brief Function called when DataConfirm is hit.
84 * \param testcase pointer to the testcase
85 * \param dev originating NetDevice
86 * \param p packet
87 */
88 static void DataReceivedDev1(LrWpanDataIfsTestCase* testcase,
91
92 /**
93 * \brief Function called when the IFS ends.
94 * \param testcase pointer to the testcase
95 * \param dev originating NetDevice
96 * \param IfsTime the IFS time
97 */
98 static void IfsEnd(LrWpanDataIfsTestCase* testcase, Ptr<LrWpanNetDevice> dev, Time IfsTime);
99
100 void DoRun() override;
101 Time m_lastTxTime; //!< The time of the last transmitted packet
102 Time m_ackRxTime; //!< The time of the received acknowledgment.
103 Time m_endIfs; //!< The time where the Interframe Space ended.
104 Time m_phyStartRx; //!< The time the phy start receiving a packet.
105};
106
108 : TestCase("Lrwpan: IFS tests")
109{
110}
111
113{
114}
115
116void
120{
121 // get the end time of transmission
122 testcase->m_lastTxTime = Simulator::Now();
123}
124
125void
129{
130 // Callback for Data received in the Dev0
131 Ptr<Packet> RxPacket = p->Copy();
132 LrWpanMacHeader receivedMacHdr;
133 RxPacket->RemoveHeader(receivedMacHdr);
134
135 if (receivedMacHdr.IsAcknowledgment())
136 {
137 testcase->m_ackRxTime = Simulator::Now();
138 std::cout << Simulator::Now().GetSeconds() << " | Dev0 (Node 0) received Acknowledgment.\n";
139 }
140 else if (receivedMacHdr.GetShortDstAddr().IsBroadcast())
141 {
142 std::cout << Simulator::Now().GetSeconds() << " | Dev0 (Node 0) received Broadcast. \n";
143 }
144}
145
146void
150{
151 // get the start time the phy in dev 0 ( Node 0) start receiving a frame
152 testcase->m_phyStartRx = Simulator::Now();
153}
154
155void
159{
160 // Callback for Data received in the Dev1
161 Ptr<Packet> RxPacket = p->Copy();
162 LrWpanMacHeader receivedMacHdr;
163 RxPacket->RemoveHeader(receivedMacHdr);
164
165 if (receivedMacHdr.GetShortDstAddr().IsBroadcast())
166 {
167 std::cout << Simulator::Now().GetSeconds() << " | Dev1 (Node 1) received Broadcast. \n";
168
169 // Bcst received, respond with another bcst
170
171 Ptr<Packet> p0 = Create<Packet>(50); // 50 bytes of dummy data
172 McpsDataRequestParams params1;
173 params1.m_dstPanId = 0;
174 params1.m_srcAddrMode = SHORT_ADDR;
175 params1.m_dstAddrMode = SHORT_ADDR;
176 params1.m_dstAddr = Mac16Address("ff:ff");
177 params1.m_msduHandle = 0;
178
179 Simulator::ScheduleNow(&LrWpanMac::McpsDataRequest, dev->GetMac(), params1, p0);
180 }
181}
182
183void
186 Time IfsTime)
187{
188 // take the time of the end of the IFS
189 testcase->m_endIfs = Simulator::Now();
190}
191
192void
194{
195 // Test of Interframe Spaces (IFS)
196
197 // The MAC layer needs a finite amount of time to process the data received from the PHY.
198 // To allow this, to successive transmitted frames must be separated for at least one IFS.
199 // The IFS size depends on the transmitted frame. This test verifies that the IFS is correctly
200 // implemented and its size correspond to the situations described by the standard.
201 // For more info see IEEE 802.15.4-2011 Section 5.1.1.3
202
207 LogComponentEnable("LrWpanCsmaCa", LOG_LEVEL_DEBUG);
208
209 // Create 2 nodes, and a NetDevice for each one
210 Ptr<Node> n0 = CreateObject<Node>();
211 Ptr<Node> n1 = CreateObject<Node>();
212
213 Ptr<LrWpanNetDevice> dev0 = CreateObject<LrWpanNetDevice>();
214 Ptr<LrWpanNetDevice> dev1 = CreateObject<LrWpanNetDevice>();
215
216 dev0->SetAddress(Mac16Address("00:01"));
217 dev1->SetAddress(Mac16Address("00:02"));
218
219 // Each device must be attached to the same channel
220 Ptr<SingleModelSpectrumChannel> channel = CreateObject<SingleModelSpectrumChannel>();
222 CreateObject<LogDistancePropagationLossModel>();
224 CreateObject<ConstantSpeedPropagationDelayModel>();
225 channel->AddPropagationLossModel(propModel);
226 channel->SetPropagationDelayModel(delayModel);
227
228 dev0->SetChannel(channel);
229 dev1->SetChannel(channel);
230
231 // To complete configuration, a LrWpanNetDevice must be added to a node
232 n0->AddDevice(dev0);
233 n1->AddDevice(dev1);
234
235 // Connect to trace files in the MAC layer
236 dev0->GetMac()->TraceConnectWithoutContext(
237 "IfsEnd",
239 dev0->GetMac()->TraceConnectWithoutContext(
240 "MacRx",
242 dev0->GetPhy()->TraceConnectWithoutContext(
243 "PhyRxBegin",
245 dev1->GetMac()->TraceConnectWithoutContext(
246 "MacRx",
248
249 Ptr<ConstantPositionMobilityModel> sender0Mobility =
250 CreateObject<ConstantPositionMobilityModel>();
251 sender0Mobility->SetPosition(Vector(0, 0, 0));
252 dev0->GetPhy()->SetMobility(sender0Mobility);
253 Ptr<ConstantPositionMobilityModel> sender1Mobility =
254 CreateObject<ConstantPositionMobilityModel>();
255 // Configure position 10 m distance
256 sender1Mobility->SetPosition(Vector(0, 10, 0));
257 dev1->GetPhy()->SetMobility(sender1Mobility);
258
261 dev0->GetMac()->SetMcpsDataConfirmCallback(cb0);
262
265 dev1->GetMac()->SetMcpsDataConfirmCallback(cb1);
266
267 Ptr<Packet> p0 = Create<Packet>(2);
269 params.m_dstPanId = 0;
270
271 params.m_srcAddrMode = SHORT_ADDR;
272 params.m_dstAddrMode = SHORT_ADDR;
273 params.m_dstAddr = Mac16Address("00:02");
274 params.m_msduHandle = 0;
275
276 Time ifsSize;
277
278 // NOTE: // For all the test , PAN SRC and DST are the same (PAN compression is ON) therefore
279 // MAC header is 2 bytes smaller than the usual 11 bytes (see IEEE 802.15.4 Section 7.5.6.1)
280
281 //////////////////////// SIFS ///////////////////////////
282
284 Seconds(0.0),
286 dev0->GetMac(),
287 params,
288 p0);
289
291
292 // MPDU = MAC header (9 bytes) + MSDU (2 bytes)+ MAC trailer (2 bytes) = 13)
293 // MPDU (13 bytes) < 18 bytes therefore IFS = SIFS
294 // SIFS = 12 symbols (192 Microseconds on a 2.4Ghz O-QPSK PHY)
295 ifsSize = m_endIfs - m_lastTxTime;
296 NS_TEST_EXPECT_MSG_EQ(ifsSize,
297 Time(MicroSeconds(192)),
298 "Wrong Short InterFrame Space (SIFS) Size after dataframe Tx");
299 std::cout << "----------------------------------\n";
300
301 //////////////////////// LIFS ///////////////////////////
302
303 p0 = Create<Packet>(8);
304
306 Seconds(0.0),
308 dev0->GetMac(),
309 params,
310 p0);
311
313
314 // MPDU = MAC header (9 bytes) + MSDU (8 bytes)+ MAC trailer (2 bytes) = 19)
315 // MPDU (19 bytes) > 18 bytes therefore IFS = LIFS
316 // LIFS = 40 symbols (640 Microseconds on a 2.4Ghz O-QPSK PHY)
317 ifsSize = m_endIfs - m_lastTxTime;
318 NS_TEST_EXPECT_MSG_EQ(ifsSize,
319 Time(MicroSeconds(640)),
320 "Wrong Long InterFrame Space (LIFS) Size after dataframe Tx");
321 std::cout << "----------------------------------\n";
322
323 //////////////////////// SIFS after ACK //////////////////
324
325 params.m_txOptions = TX_OPTION_ACK;
326 p0 = Create<Packet>(2);
327
329 Seconds(0.0),
331 dev0->GetMac(),
332 params,
333 p0);
334
336
337 // MPDU = MAC header (9 bytes) + MSDU (2 bytes)+ MAC trailer (2 bytes) = 13)
338 // MPDU (13 bytes) < 18 bytes therefore IFS = SIFS
339 // SIFS = 12 symbols (192 Microseconds on a 2.4Ghz O-QPSK PHY)
340 ifsSize = m_endIfs - m_ackRxTime;
341 NS_TEST_EXPECT_MSG_EQ(ifsSize,
342 Time(MicroSeconds(192)),
343 "Wrong Short InterFrame Space (SIFS) Size after ACK Rx");
344 std::cout << "----------------------------------\n";
345
346 //////////////////////// LIFS after ACK //////////////////
347
348 params.m_txOptions = TX_OPTION_ACK;
349 p0 = Create<Packet>(8);
350
352 Seconds(0.0),
354 dev0->GetMac(),
355 params,
356 p0);
357
359
360 // MPDU = MAC header (9 bytes) + MSDU (8 bytes)+ MAC trailer (2 bytes) = 19)
361 // MPDU (19 bytes) > 18 bytes therefore IFS = LIFS
362 // LIFS = 40 symbols (640 Microseconds on a 2.4Ghz O-QPSK PHY)
363 ifsSize = m_endIfs - m_ackRxTime;
364 NS_TEST_EXPECT_MSG_EQ(ifsSize,
365 Time(MicroSeconds(640)),
366 "Wrong Long InterFrame Space (LIFS) Size after ACK Rx");
367 std::cout << "----------------------------------\n";
368
369 /////////////////////// BCST frame with immediate BCST response //////////////////
370
371 // A packet is broadcasted and the receiving device respond with another broadcast.
372 // The devices are configured to not have any backoff delays in their CSMA/CA.
373 // In most cases, a device receive a packet after its IFS, however in this test,
374 // the receiving device of the reply broadcast will still be in its IFS when the
375 // broadcast is received (i.e. a PHY StartRX () occur before the end of IFS).
376 // This demonstrates that a device can start receiving a frame even during an IFS.
377
378 // Makes the backoff delay period = 0 in the CSMA/CA
379 dev0->GetCsmaCa()->SetMacMinBE(0);
380 dev1->GetCsmaCa()->SetMacMinBE(0);
381
382 p0 = Create<Packet>(50); // 50 bytes of dummy data
383 params.m_dstPanId = 0;
384 params.m_srcAddrMode = SHORT_ADDR;
385 params.m_dstAddrMode = SHORT_ADDR;
386 params.m_dstAddr = Mac16Address("ff:ff");
387 params.m_msduHandle = 0;
388
390 Seconds(0.0),
392 dev0->GetMac(),
393 params,
394 p0);
395
397
400 "Error, IFS end time should be greater than PHY start Rx time");
401
402 //////////////////////////////////////////////////////////////////////////////////
403
405}
406
407/**
408 * \ingroup lr-wpan-test
409 * \ingroup tests
410 *
411 * \brief LrWpan IFS TestSuite
412 */
413
415{
416 public:
418};
419
421 : TestSuite("lr-wpan-ifs-test", Type::UNIT)
422{
423 AddTestCase(new LrWpanDataIfsTestCase, TestCase::Duration::QUICK);
424}
425
426static 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.
Represent the Mac Header with the Frame Control and Sequence Number fields.
bool IsAcknowledgment() const
Returns true if the header is an ack.
Mac16Address GetShortDstAddr() const
Get the Destination Short address.
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.
Definition: lr-wpan-mac.cc:384
This class can contain 16 bit addresses.
Definition: mac16-address.h:44
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.
Definition: ptr.h:77
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:142
static void ScheduleWithContext(uint32_t context, const Time &delay, FUNC f, Ts &&... args)
Schedule an event with the given context.
Definition: simulator.h:588
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
static void Run()
Run the simulation.
Definition: simulator.cc:178
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition: simulator.h:605
encapsulates test code
Definition: test.h:1061
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
A suite of tests to run.
Definition: test.h:1268
Type
Type of test.
Definition: test.h:1275
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:403
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
@ TX_OPTION_ACK
TX_OPTION_ACK.
Definition: lr-wpan-mac.h:61
@ SHORT_ADDR
auto MakeBoundCallback(R(*fnPtr)(Args...), BArgs &&... bargs)
Make Callbacks with varying number of bound arguments.
Definition: callback.h:765
#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:252
#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:875
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1350
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
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:302
@ 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:113
void LogComponentEnableAll(LogLevel level)
Enable the logging output for all registered log components.
Definition: log.cc:320
MCPS-DATA.confirm params.
MCPS-DATA.request params.
LrWpanAddressMode m_srcAddrMode
Source address mode.
LrWpanAddressMode m_dstAddrMode
Destination address mode.
uint16_t m_dstPanId
Destination PAN identifier.
Mac16Address m_dstAddr
Destination address.
uint8_t m_msduHandle
MSDU handle.