A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
wifi-ac-mapping-test-suite.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2016 Universita' degli Studi di Napoli Federico II
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: Stefano Avallone <stavallo@unina.it>
18 */
19
20#include "ns3/internet-stack-helper.h"
21#include "ns3/ipv4-address-helper.h"
22#include "ns3/llc-snap-header.h"
23#include "ns3/mobility-helper.h"
24#include "ns3/on-off-helper.h"
25#include "ns3/packet-sink-helper.h"
26#include "ns3/packet-sink.h"
27#include "ns3/pointer.h"
28#include "ns3/qos-txop.h"
29#include "ns3/ssid.h"
30#include "ns3/string.h"
31#include "ns3/test.h"
32#include "ns3/traffic-control-helper.h"
33#include "ns3/traffic-control-layer.h"
34#include "ns3/wifi-mac-queue.h"
35#include "ns3/wifi-mac.h"
36#include "ns3/wifi-net-device.h"
37#include "ns3/yans-wifi-helper.h"
38
39using namespace ns3;
40
41NS_LOG_COMPONENT_DEFINE("WifiAcMappingTest");
42
43/**
44 * \ingroup wifi-test
45 * \ingroup tests
46 *
47 * \brief Test for User priority to Access Category mapping
48 */
50{
51 public:
52 /**
53 * Constructor for WifiAcMappingTest
54 *
55 * \param tos the type of service
56 * \param expectedQueue the expected queue disc index
57 */
58 WifiAcMappingTest(uint8_t tos, uint8_t expectedQueue);
59 void DoRun() override;
60
61 private:
62 /**
63 * Function called whenever a packet is enqueued in
64 * a queue disc.
65 *
66 * \param tos the type of service
67 * \param count the pointer to the packet counter
68 * \param item the enqueued item
69 */
70 static void PacketEnqueuedInQueueDisc(uint8_t tos,
71 uint16_t* count,
73 /**
74 * Function called whenever a packet is enqueued in
75 * a Wi-Fi MAC queue.
76 *
77 * \param tos the type of service
78 * \param count the pointer to the packet counter
79 * \param item the enqueued item
80 */
81 static void PacketEnqueuedInWifiMacQueue(uint8_t tos,
82 uint16_t* count,
84 uint8_t m_tos; //!< type of service
85 uint16_t m_expectedQueue; //!< expected queue disc index
86 uint16_t m_QueueDiscCount[4]; //!< packet counter per queue disc
87 uint16_t m_WifiMacQueueCount[4]; //!< packet counter per Wi-Fi MAC queue
88};
89
90WifiAcMappingTest::WifiAcMappingTest(uint8_t tos, uint8_t expectedQueue)
91 : TestCase("User priority to Access Category mapping test. Checks that packets are "
92 "enqueued in the correct child queue disc of the mq root queue disc and "
93 "in the correct wifi MAC queue"),
94 m_tos(tos),
95 m_expectedQueue(expectedQueue)
96{
97 for (uint8_t i = 0; i < 4; i++)
98 {
99 m_QueueDiscCount[i] = 0;
100 m_WifiMacQueueCount[i] = 0;
101 }
102}
103
104void
106 uint16_t* count,
108{
109 uint8_t val;
110 if (item->GetUint8Value(QueueItem::IP_DSFIELD, val) && val == tos)
111 {
112 (*count)++;
113 }
114}
115
116void
118 uint16_t* count,
120{
121 LlcSnapHeader llc;
122 Ptr<Packet> packet = item->GetPacket()->Copy();
123 packet->RemoveHeader(llc);
124
126 {
127 Ipv4Header iph;
128 packet->PeekHeader(iph);
129 if (iph.GetTos() == tos)
130 {
131 (*count)++;
132 }
133 }
134}
135
136void
138{
139 WifiHelper wifi;
140 WifiMacHelper wifiMac;
141 YansWifiPhyHelper wifiPhy;
143 wifiPhy.SetChannel(wifiChannel.Create());
144
145 Ssid ssid = Ssid("wifi-ac-mapping");
146
147 // Setup the AP, which will be the source of traffic for this test
148 NodeContainer ap;
149 ap.Create(1);
150 wifiMac.SetType("ns3::ApWifiMac", "QosSupported", BooleanValue(true), "Ssid", SsidValue(ssid));
151
152 NetDeviceContainer apDev = wifi.Install(wifiPhy, wifiMac, ap);
153
154 // Setup one STA, which will be the sink for traffic in this test.
155 NodeContainer sta;
156 sta.Create(1);
157 wifiMac.SetType("ns3::StaWifiMac", "QosSupported", BooleanValue(true), "Ssid", SsidValue(ssid));
158 NetDeviceContainer staDev = wifi.Install(wifiPhy, wifiMac, sta);
159
160 // Our devices will have fixed positions
161 MobilityHelper mobility;
162 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
163 mobility.SetPositionAllocator("ns3::GridPositionAllocator",
164 "MinX",
165 DoubleValue(0.0),
166 "MinY",
167 DoubleValue(0.0),
168 "DeltaX",
169 DoubleValue(5.0),
170 "DeltaY",
171 DoubleValue(10.0),
172 "GridWidth",
173 UintegerValue(2),
174 "LayoutType",
175 StringValue("RowFirst"));
176 mobility.Install(sta);
177 mobility.Install(ap);
178
179 // Now we install internet stacks on our devices
181 stack.Install(ap);
182 stack.Install(sta);
183
185 uint16_t handle = tch.SetRootQueueDisc("ns3::MqQueueDisc");
187 tch.AddQueueDiscClasses(handle, 4, "ns3::QueueDiscClass");
188 tch.AddChildQueueDiscs(handle, cls, "ns3::FqCoDelQueueDisc");
189 tch.Install(apDev);
190 tch.Install(staDev);
191
192 Ipv4AddressHelper address;
193 address.SetBase("192.168.0.0", "255.255.255.0");
194 Ipv4InterfaceContainer staNodeInterface;
195 Ipv4InterfaceContainer apNodeInterface;
196 staNodeInterface = address.Assign(staDev);
197 apNodeInterface = address.Assign(apDev);
198
199 uint16_t udpPort = 50000;
200
201 PacketSinkHelper packetSink("ns3::UdpSocketFactory",
203 ApplicationContainer sinkApp = packetSink.Install(sta.Get(0));
204 sinkApp.Start(Seconds(0));
205 sinkApp.Stop(Seconds(4.0));
206
207 // The packet source is an on-off application on the AP device
208 InetSocketAddress dest(staNodeInterface.GetAddress(0), udpPort);
209 OnOffHelper onoff("ns3::UdpSocketFactory", dest);
210 onoff.SetConstantRate(DataRate("5kbps"), 500);
211 onoff.SetAttribute("Tos", UintegerValue(m_tos));
212 ApplicationContainer sourceApp = onoff.Install(ap.Get(0));
213 sourceApp.Start(Seconds(1.0));
214 sourceApp.Stop(Seconds(4.0));
215
216 // The first packet will be transmitted at time 1+(500*8)/5000 = 1.8s.
217 // The second packet will be transmitted at time 1.8+(500*8)/5000 = 2.6s.
218 // The third packet will be transmitted at time 2.6+(500*8)/5000 = 3.4s.
219
221
222 Ptr<QueueDisc> root =
223 ap.Get(0)->GetObject<TrafficControlLayer>()->GetRootQueueDiscOnDevice(apDev.Get(0));
224 NS_TEST_ASSERT_MSG_EQ(root->GetNQueueDiscClasses(),
225 4,
226 "The root queue disc should have 4 classes");
227 // Get the four child queue discs and connect their Enqueue trace to the
228 // PacketEnqueuedInQueueDisc method, which counts how many packets with the given ToS value have
229 // been enqueued
230 // NOTE the purpose of the unary + operation in +m_QueueDiscCount is to decay the array type
231 // to a pointer type, so that the type of that argument matches the type of the second
232 // parameter of the PacketEnqueuedInQueueDisc function
233 root->GetQueueDiscClass(0)->GetQueueDisc()->TraceConnectWithoutContext(
234 "Enqueue",
236
237 root->GetQueueDiscClass(1)->GetQueueDisc()->TraceConnectWithoutContext(
238 "Enqueue",
240 m_tos,
241 m_QueueDiscCount + 1));
242
243 root->GetQueueDiscClass(2)->GetQueueDisc()->TraceConnectWithoutContext(
244 "Enqueue",
246 m_tos,
247 m_QueueDiscCount + 2));
248
249 root->GetQueueDiscClass(3)->GetQueueDisc()->TraceConnectWithoutContext(
250 "Enqueue",
252 m_tos,
253 m_QueueDiscCount + 3));
254
255 Ptr<WifiMac> apMac = DynamicCast<WifiNetDevice>(apDev.Get(0))->GetMac();
256 PointerValue ptr;
257 // Get the four wifi mac queues and connect their Enqueue trace to the
258 // PacketEnqueuedInWifiMacQueue method, which counts how many packets with the given ToS value
259 // have been enqueued
260 // NOTE the purpose of the unary + operation in +m_WifiMacQueueCount is to decay the array type
261 // to a pointer type, so that the type of that argument matches the type of the second
262 // parameter of the PacketEnqueuedInWifiMacQueue function
263 apMac->GetAttribute("BE_Txop", ptr);
264 ptr.Get<QosTxop>()->GetWifiMacQueue()->TraceConnectWithoutContext(
265 "Enqueue",
267 m_tos,
269
270 apMac->GetAttribute("BK_Txop", ptr);
271 ptr.Get<QosTxop>()->GetWifiMacQueue()->TraceConnectWithoutContext(
272 "Enqueue",
274 m_tos,
276
277 apMac->GetAttribute("VI_Txop", ptr);
278 ptr.Get<QosTxop>()->GetWifiMacQueue()->TraceConnectWithoutContext(
279 "Enqueue",
281 m_tos,
283
284 apMac->GetAttribute("VO_Txop", ptr);
285 ptr.Get<QosTxop>()->GetWifiMacQueue()->TraceConnectWithoutContext(
286 "Enqueue",
288 m_tos,
290
292
293 for (uint32_t i = 0; i < 4; i++)
294 {
295 if (i == m_expectedQueue)
296 {
298 1,
299 "There is no packet in the expected queue disc " << i);
301 1,
302 "There is no packet in the expected Wifi MAC queue " << i);
303 }
304 else
305 {
307 0,
308 "Unexpectedly, there is a packet in queue disc " << i);
310 0,
311 "Unexpectedly, there is a packet in Wifi MAC queue " << i);
312 }
313 }
314
315 uint32_t totalOctetsThrough = DynamicCast<PacketSink>(sinkApp.Get(0))->GetTotalRx();
316
317 // Check that the three packets have been received
318 NS_TEST_ASSERT_MSG_EQ(totalOctetsThrough, 1500, "Three packets should have been received");
319
321}
322
323/**
324 * \ingroup wifi-test
325 * \ingroup tests
326 *
327 * \brief Access category mapping Test Suite
328 */
330{
331 public:
333};
334
336 : TestSuite("wifi-ac-mapping", Type::SYSTEM)
337{
338 AddTestCase(new WifiAcMappingTest(0xb8, 2), TestCase::Duration::QUICK); // EF in AC_VI
339 AddTestCase(new WifiAcMappingTest(0x28, 1), TestCase::Duration::QUICK); // AF11 in AC_BK
340 AddTestCase(new WifiAcMappingTest(0x70, 0), TestCase::Duration::QUICK); // AF32 in AC_BE
341 AddTestCase(new WifiAcMappingTest(0xc0, 3), TestCase::Duration::QUICK); // CS7 in AC_VO
342}
343
Test for User priority to Access Category mapping.
static void PacketEnqueuedInWifiMacQueue(uint8_t tos, uint16_t *count, Ptr< const WifiMpdu > item)
Function called whenever a packet is enqueued in a Wi-Fi MAC queue.
void DoRun() override
Implementation to actually run this TestCase.
uint16_t m_WifiMacQueueCount[4]
packet counter per Wi-Fi MAC queue
WifiAcMappingTest(uint8_t tos, uint8_t expectedQueue)
Constructor for WifiAcMappingTest.
uint8_t m_tos
type of service
static void PacketEnqueuedInQueueDisc(uint8_t tos, uint16_t *count, Ptr< const QueueDiscItem > item)
Function called whenever a packet is enqueued in a queue disc.
uint16_t m_expectedQueue
expected queue disc index
uint16_t m_QueueDiscCount[4]
packet counter per queue disc
Access category mapping Test Suite.
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.
ApplicationContainer Install(NodeContainer c)
Install an application on each node of the input container configured with all the attributes set wit...
AttributeValue implementation for Boolean.
Definition: boolean.h:37
Class for representing data rates.
Definition: data-rate.h:89
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
an Inet address class
aggregate IP/TCP/UDP functionality to existing Nodes.
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
static Ipv4Address GetAny()
Packet header for IPv4.
Definition: ipv4-header.h:34
uint8_t GetTos() const
Definition: ipv4-header.cc:196
holds a vector of std::pair of Ptr<Ipv4> and interface index.
Ipv4Address GetAddress(uint32_t i, uint32_t j=0) const
static const uint16_t PROT_NUMBER
Protocol number (0x0800)
Header for the LLC/SNAP encapsulation.
uint16_t GetType()
Return the Ethertype.
Helper class used to assign positions and mobility models to nodes.
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.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
bool TraceConnectWithoutContext(std::string name, const CallbackBase &cb)
Connect a TraceSource to a Callback without a context.
Definition: object-base.cc:322
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:522
A helper to make it easier to instantiate an ns3::OnOffApplication on a set of nodes.
Definition: on-off-helper.h:37
A helper to make it easier to instantiate an ns3::PacketSinkApplication on a set of nodes.
AttributeValue implementation for Pointer.
Definition: pointer.h:48
Ptr< T > Get() const
Definition: pointer.h:234
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
Handle packet fragmentation and retransmissions for QoS data frames as well as MSDU aggregation (A-MS...
Definition: qos-txop.h:74
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:142
static void Run()
Run the simulation.
Definition: simulator.cc:178
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:186
The IEEE 802.11 SSID Information Element.
Definition: ssid.h:36
AttributeValue implementation for Ssid.
Definition: ssid.h:96
Hold variables of type string.
Definition: string.h:56
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
Build a set of QueueDisc objects.
QueueDiscContainer Install(NetDeviceContainer c)
uint16_t SetRootQueueDisc(const std::string &type, Args &&... args)
Helper function used to set a root queue disc of the given type and with the given attributes.
std::vector< uint16_t > ClassIdList
Container type for Class IDs.
ClassIdList AddQueueDiscClasses(uint16_t handle, uint16_t count, const std::string &type, Args &&... args)
Helper function used to add the given number of queue disc classes (of the given type and with the gi...
HandleList AddChildQueueDiscs(uint16_t handle, const ClassIdList &classes, const std::string &type, Args &&... args)
Helper function used to attach a child queue disc (of the given type and with the given attributes) t...
The Traffic Control layer aims at introducing an equivalent of the Linux Traffic Control infrastructu...
Hold an unsigned integer type.
Definition: uinteger.h:45
helps to create WifiNetDevice objects
Definition: wifi-helper.h:324
create MAC layers for a ns3::WifiNetDevice.
void SetType(std::string type, Args &&... args)
manage and create wifi channel objects for the YANS model.
static YansWifiChannelHelper Default()
Create a channel helper in a default working state.
Ptr< YansWifiChannel > Create() const
Make it easy to create and manage PHY objects for the YANS model.
void SetChannel(Ptr< YansWifiChannel > channel)
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
auto MakeBoundCallback(R(*fnPtr)(Args...), BArgs &&... bargs)
Make Callbacks with varying number of bound arguments.
Definition: callback.h:765
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition: test.h:145
#define NS_TEST_ASSERT_MSG_GT_OR_EQ(actual, limit, msg)
Test that an actual value is greater than or equal to a limit and report and abort if not.
Definition: test.h:916
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static WifiAcMappingTestSuite wifiAcMappingTestSuite