A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
wifi-issue-211-test-suite.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2020
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Authors: Stefano Avallone <stavallo@unina.it>
7 * Rémy Grünblatt <remy@grunblatt.org>
8 */
9
10#include "ns3/ap-wifi-mac.h"
11#include "ns3/boolean.h"
12#include "ns3/config.h"
13#include "ns3/internet-stack-helper.h"
14#include "ns3/ipv4-address-helper.h"
15#include "ns3/mobility-helper.h"
16#include "ns3/multi-model-spectrum-channel.h"
17#include "ns3/packet.h"
18#include "ns3/qos-utils.h"
19#include "ns3/queue-size.h"
20#include "ns3/rng-seed-manager.h"
21#include "ns3/spectrum-wifi-helper.h"
22#include "ns3/string.h"
23#include "ns3/test.h"
24#include "ns3/udp-client-server-helper.h"
25#include "ns3/udp-server.h"
26#include "ns3/wifi-net-device.h"
27
28using namespace ns3;
29
30/**
31 * \ingroup wifi-test
32 * \ingroup tests
33 *
34 * \brief Test for issue 211 (https://gitlab.com/nsnam/ns-3-dev/-/issues/211)
35 *
36 * This test aims to check that the transmission of data frames (under a
37 * Block Ack agreement) resumes after a period in which the connectivity
38 * between originator and recipient is interrupted (e.g., the station
39 * moves away and comes back). Issue 211 revealed that MSDUs with expired
40 * lifetime were not removed from the wifi MAC queue if the station had
41 * to transmit a Block Ack Request. If the connectivity was lost for enough
42 * time, the wifi MAC queue could become full of MSDUs with expired lifetime,
43 * thus preventing the traffic control layer to forward down new packets.
44 * At this point, the station gave up transmitting the Block Ack Request
45 * and did not request channel access anymore.
46 */
47class Issue211Test : public TestCase
48{
49 public:
50 /**
51 * \brief Constructor
52 */
54 ~Issue211Test() override;
55
56 void DoRun() override;
57
58 private:
59 /**
60 * Compute the average throughput since the last check-point
61 * \param server the UDP server
62 */
63 void CalcThroughput(Ptr<UdpServer> server);
64
65 std::vector<double> m_tputValues; ///< throughput in sub-intervals
66 uint64_t m_lastRxBytes; ///< RX bytes at last check-point
67 Time m_lastCheckPointTime; ///< time of last check-point
68 uint32_t m_payloadSize; ///< payload size in bytes
69};
70
72 : TestCase("Test case for resuming data transmission when the recipient moves back"),
73 m_lastRxBytes(0),
74 m_lastCheckPointTime(Seconds(0)),
75 m_payloadSize(2000)
76{
77}
78
82
83void
85{
86 uint64_t rxBytes = m_payloadSize * server->GetReceived();
87 double tput = (rxBytes - m_lastRxBytes) * 8. /
88 (Simulator::Now() - m_lastCheckPointTime).ToDouble(Time::US); // Mb/s
89 m_tputValues.push_back(tput);
90 m_lastRxBytes = rxBytes;
92}
93
94void
96{
97 Time simulationTime(Seconds(6.0));
98 Time moveAwayTime(Seconds(2.0));
99 Time moveBackTime(Seconds(4.0));
100
103 int64_t streamNumber = 100;
104
105 NodeContainer wifiApNode;
106 wifiApNode.Create(1);
107
108 NodeContainer wifiStaNode;
109 wifiStaNode.Create(1);
110
113 spectrumChannel->AddPropagationLossModel(lossModel);
116 spectrumChannel->SetPropagationDelayModel(delayModel);
117
119 phy.SetChannel(spectrumChannel);
120
121 WifiHelper wifi;
122 wifi.SetStandard(WIFI_STANDARD_80211n);
123 wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager",
124 "DataMode",
125 StringValue("HtMcs0"),
126 "ControlMode",
127 StringValue("HtMcs0"));
128
129 Config::SetDefault("ns3::WifiMacQueue::MaxSize", QueueSizeValue(QueueSize("50p")));
130
131 WifiMacHelper mac;
132 mac.SetType("ns3::StaWifiMac", "Ssid", SsidValue(Ssid("issue211-test")));
133
134 NetDeviceContainer staDevices = wifi.Install(phy, mac, wifiStaNode);
135
136 mac.SetType("ns3::ApWifiMac",
137 "Ssid",
138 SsidValue(Ssid("issue211-test")),
139 "EnableBeaconJitter",
140 BooleanValue(false));
141
142 NetDeviceContainer apDevices = wifi.Install(phy, mac, wifiApNode);
143
144 // Assign fixed streams to random variables in use
145 WifiHelper::AssignStreams(apDevices, streamNumber);
146
147 MobilityHelper mobility;
149
150 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
151 positionAlloc->Add(Vector(5.0, 0.0, 0.0));
152 mobility.SetPositionAllocator(positionAlloc);
153
154 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
155 mobility.Install(wifiApNode);
156 mobility.Install(wifiStaNode);
157
158 /* Internet stack*/
160 stack.Install(wifiApNode);
161 stack.Install(wifiStaNode);
162
163 Ipv4AddressHelper address;
164 address.SetBase("192.168.1.0", "255.255.255.0");
165 Ipv4InterfaceContainer staNodeInterface;
166 Ipv4InterfaceContainer apNodeInterface;
167
168 staNodeInterface = address.Assign(staDevices.Get(0));
169 apNodeInterface = address.Assign(apDevices.Get(0));
170
171 ApplicationContainer serverApp;
172 Time warmup(Seconds(1.0)); // to account for association
173
174 uint16_t port = 9;
175 UdpServerHelper server(port);
176 serverApp = server.Install(wifiStaNode.Get(0));
177 serverApp.Start(Seconds(0.0));
178 serverApp.Stop(warmup + simulationTime);
179
180 UdpClientHelper client(staNodeInterface.GetAddress(0), port);
181 client.SetAttribute("MaxPackets", UintegerValue(4294967295U));
182 client.SetAttribute("Interval", TimeValue(MilliSeconds(1)));
183 client.SetAttribute("PacketSize", UintegerValue(m_payloadSize)); // 16 Mb/s
184 ApplicationContainer clientApp = client.Install(wifiApNode.Get(0));
185 clientApp.Start(warmup);
186 clientApp.Stop(warmup + simulationTime);
187
188 Ptr<MobilityModel> staMobility = wifiStaNode.Get(0)->GetObject<MobilityModel>();
189
190 // First check-point: station moves away
191 Simulator::Schedule(warmup + moveAwayTime,
193 staMobility,
194 Vector(10000.0, 0.0, 0.0));
195 Simulator::Schedule(warmup + moveAwayTime + MilliSeconds(10),
197 this,
198 DynamicCast<UdpServer>(serverApp.Get(0)));
199
200 // Second check-point: station moves back
201 Simulator::Schedule(warmup + moveBackTime,
203 staMobility,
204 Vector(5.0, 0.0, 0.0));
205 Simulator::Schedule(warmup + moveBackTime,
207 this,
208 DynamicCast<UdpServer>(serverApp.Get(0)));
209
210 // Last check-point: simulation finish time
211 Simulator::Schedule(warmup + simulationTime,
213 this,
214 DynamicCast<UdpServer>(serverApp.Get(0)));
215
216 Simulator::Stop(warmup + simulationTime);
218
219 NS_TEST_EXPECT_MSG_EQ(m_tputValues.size(), 3, "Unexpected number of throughput values");
221 0,
222 "Throughput must be non null before station moves away");
223 NS_TEST_EXPECT_MSG_EQ(m_tputValues[1], 0, "Throughput must be null while the station is away");
225 0,
226 "Throughput must be non null when the station is back");
227
228 // Print throughput values when the test is run through test-runner
229 for (const auto& t : m_tputValues)
230 {
231 std::cout << "Throughput = " << t << " Mb/s" << std::endl;
232 }
233
235}
236
237/**
238 * \ingroup wifi-test
239 * \ingroup tests
240 *
241 * \brief Block Ack Test Suite
242 */
244{
245 public:
247};
248
250 : TestSuite("wifi-issue-211", Type::UNIT)
251{
252 AddTestCase(new Issue211Test, TestCase::Duration::QUICK);
253}
254
255static Issue211TestSuite g_issue211TestSuite; ///< the test suite
Test for issue 211 (https://gitlab.com/nsnam/ns-3-dev/-/issues/211)
std::vector< double > m_tputValues
throughput in sub-intervals
Time m_lastCheckPointTime
time of last check-point
uint32_t m_payloadSize
payload size in bytes
void DoRun() override
Implementation to actually run this TestCase.
uint64_t m_lastRxBytes
RX bytes at last check-point.
void CalcThroughput(Ptr< UdpServer > server)
Compute the average throughput since the last check-point.
holds a vector of ns3::Application pointers.
void Start(Time start) const
Start all of the Applications in this container at the start time given as a parameter.
Ptr< Application > Get(uint32_t i) const
Get the Ptr<Application> stored in this container at a given index.
void Stop(Time stop) const
Arrange for all of the Applications in this container to Stop() at the Time given as a parameter.
aggregate IP/TCP/UDP functionality to existing Nodes.
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
holds a vector of std::pair of Ptr<Ipv4> and interface index.
Ipv4Address GetAddress(uint32_t i, uint32_t j=0) const
Helper class used to assign positions and mobility models to nodes.
Keep track of the current position and velocity of an object.
void SetPosition(const Vector &position)
holds a vector of ns3::NetDevice pointers
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.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition object.h:511
Smart pointer class similar to boost::intrusive_ptr.
Class for representing queue sizes.
Definition queue-size.h:85
static void SetRun(uint64_t run)
Set the run number of simulation.
static void SetSeed(uint32_t seed)
Set the seed.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:560
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:131
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:197
static void Run()
Run the simulation.
Definition simulator.cc:167
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition simulator.cc:175
Make it easy to create and manage PHY objects for the spectrum model.
The IEEE 802.11 SSID Information Element.
Definition ssid.h:25
Hold variables of type string.
Definition string.h:45
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
@ US
microsecond
Definition nstime.h:107
Create a client application which sends UDP packets carrying a 32bit sequence number and a 64 bit tim...
Create a server application which waits for input UDP packets and uses the information carried into t...
Hold an unsigned integer type.
Definition uinteger.h:34
helps to create WifiNetDevice objects
static int64_t AssignStreams(NetDeviceContainer c, int64_t stream)
Assign a fixed random variable stream number to the random variables used by the PHY and MAC aspects ...
create MAC layers for a ns3::WifiNetDevice.
uint16_t port
Definition dsdv-manet.cc:33
void SetDefault(std::string name, const AttributeValue &value)
Definition config.cc:883
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_GT(actual, limit, msg)
Test that an actual value is greater than a limit and report if not.
Definition test.h:946
#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:1308
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1320
@ WIFI_STANDARD_80211n
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:580
static Issue211TestSuite g_issue211TestSuite
the test suite