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 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Stefano Avallone <stavallo@unina.it>
7 */
8
9#include "ns3/internet-stack-helper.h"
10#include "ns3/ipv4-address-helper.h"
11#include "ns3/llc-snap-header.h"
12#include "ns3/mobility-helper.h"
13#include "ns3/on-off-helper.h"
14#include "ns3/packet-sink-helper.h"
15#include "ns3/packet-sink.h"
16#include "ns3/pointer.h"
17#include "ns3/qos-txop.h"
18#include "ns3/ssid.h"
19#include "ns3/string.h"
20#include "ns3/test.h"
21#include "ns3/traffic-control-helper.h"
22#include "ns3/traffic-control-layer.h"
23#include "ns3/wifi-mac-queue.h"
24#include "ns3/wifi-mac.h"
25#include "ns3/wifi-net-device.h"
26#include "ns3/yans-wifi-helper.h"
27
28using namespace ns3;
29
30NS_LOG_COMPONENT_DEFINE("WifiAcMappingTest");
31
32/**
33 * \ingroup wifi-test
34 * \ingroup tests
35 *
36 * \brief Test for User priority to Access Category mapping
37 */
39{
40 public:
41 /**
42 * Constructor for WifiAcMappingTest
43 *
44 * \param tos the type of service
45 * \param expectedQueue the expected queue disc index
46 */
47 WifiAcMappingTest(uint8_t tos, uint8_t expectedQueue);
48 void DoRun() override;
49
50 private:
51 /**
52 * Function called whenever a packet is enqueued in
53 * a queue disc.
54 *
55 * \param tos the type of service
56 * \param count the pointer to the packet counter
57 * \param item the enqueued item
58 */
59 static void PacketEnqueuedInQueueDisc(uint8_t tos,
60 uint16_t* count,
62 /**
63 * Function called whenever a packet is enqueued in
64 * a Wi-Fi MAC queue.
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 PacketEnqueuedInWifiMacQueue(uint8_t tos,
71 uint16_t* count,
73 uint8_t m_tos; //!< type of service
74 uint16_t m_expectedQueue; //!< expected queue disc index
75 uint16_t m_QueueDiscCount[4]; //!< packet counter per queue disc
76 uint16_t m_WifiMacQueueCount[4]; //!< packet counter per Wi-Fi MAC queue
77};
78
79WifiAcMappingTest::WifiAcMappingTest(uint8_t tos, uint8_t expectedQueue)
80 : TestCase("User priority to Access Category mapping test. Checks that packets are "
81 "enqueued in the correct child queue disc of the mq root queue disc and "
82 "in the correct wifi MAC queue"),
83 m_tos(tos),
84 m_expectedQueue(expectedQueue)
85{
86 for (uint8_t i = 0; i < 4; i++)
87 {
88 m_QueueDiscCount[i] = 0;
90 }
91}
92
93void
95 uint16_t* count,
97{
98 uint8_t val;
99 if (item->GetUint8Value(QueueItem::IP_DSFIELD, val) && val == tos)
100 {
101 (*count)++;
102 }
103}
104
105void
107 uint16_t* count,
109{
110 LlcSnapHeader llc;
111 Ptr<Packet> packet = item->GetPacket()->Copy();
112 packet->RemoveHeader(llc);
113
115 {
116 Ipv4Header iph;
117 packet->PeekHeader(iph);
118 if (iph.GetTos() == tos)
119 {
120 (*count)++;
121 }
122 }
123}
124
125void
127{
128 WifiHelper wifi;
129 WifiMacHelper wifiMac;
130 YansWifiPhyHelper wifiPhy;
132 wifiPhy.SetChannel(wifiChannel.Create());
133
134 Ssid ssid = Ssid("wifi-ac-mapping");
135
136 // Setup the AP, which will be the source of traffic for this test
137 NodeContainer ap;
138 ap.Create(1);
139 wifiMac.SetType("ns3::ApWifiMac", "QosSupported", BooleanValue(true), "Ssid", SsidValue(ssid));
140
141 NetDeviceContainer apDev = wifi.Install(wifiPhy, wifiMac, ap);
142
143 // Setup one STA, which will be the sink for traffic in this test.
144 NodeContainer sta;
145 sta.Create(1);
146 wifiMac.SetType("ns3::StaWifiMac", "QosSupported", BooleanValue(true), "Ssid", SsidValue(ssid));
147 NetDeviceContainer staDev = wifi.Install(wifiPhy, wifiMac, sta);
148
149 // Our devices will have fixed positions
150 MobilityHelper mobility;
151 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
152 mobility.SetPositionAllocator("ns3::GridPositionAllocator",
153 "MinX",
154 DoubleValue(0.0),
155 "MinY",
156 DoubleValue(0.0),
157 "DeltaX",
158 DoubleValue(5.0),
159 "DeltaY",
160 DoubleValue(10.0),
161 "GridWidth",
162 UintegerValue(2),
163 "LayoutType",
164 StringValue("RowFirst"));
165 mobility.Install(sta);
166 mobility.Install(ap);
167
168 // Now we install internet stacks on our devices
170 stack.Install(ap);
171 stack.Install(sta);
172
174 uint16_t handle = tch.SetRootQueueDisc("ns3::MqQueueDisc");
176 tch.AddQueueDiscClasses(handle, 4, "ns3::QueueDiscClass");
177 tch.AddChildQueueDiscs(handle, cls, "ns3::FqCoDelQueueDisc");
178 tch.Install(apDev);
179 tch.Install(staDev);
180
181 Ipv4AddressHelper address;
182 address.SetBase("192.168.0.0", "255.255.255.0");
183 Ipv4InterfaceContainer staNodeInterface;
184 Ipv4InterfaceContainer apNodeInterface;
185 staNodeInterface = address.Assign(staDev);
186 apNodeInterface = address.Assign(apDev);
187
188 uint16_t udpPort = 50000;
189
190 PacketSinkHelper packetSink("ns3::UdpSocketFactory",
192 ApplicationContainer sinkApp = packetSink.Install(sta.Get(0));
193 sinkApp.Start(Seconds(0));
194 sinkApp.Stop(Seconds(4.0));
195
196 // The packet source is an on-off application on the AP device
197 InetSocketAddress dest(staNodeInterface.GetAddress(0), udpPort);
198 OnOffHelper onoff("ns3::UdpSocketFactory", dest);
199 onoff.SetConstantRate(DataRate("5kbps"), 500);
200 onoff.SetAttribute("Tos", UintegerValue(m_tos));
201 ApplicationContainer sourceApp = onoff.Install(ap.Get(0));
202 sourceApp.Start(Seconds(1.0));
203 sourceApp.Stop(Seconds(4.0));
204
205 // The first packet will be transmitted at time 1+(500*8)/5000 = 1.8s.
206 // The second packet will be transmitted at time 1.8+(500*8)/5000 = 2.6s.
207 // The third packet will be transmitted at time 2.6+(500*8)/5000 = 3.4s.
208
210
211 Ptr<QueueDisc> root =
212 ap.Get(0)->GetObject<TrafficControlLayer>()->GetRootQueueDiscOnDevice(apDev.Get(0));
213 NS_TEST_ASSERT_MSG_EQ(root->GetNQueueDiscClasses(),
214 4,
215 "The root queue disc should have 4 classes");
216 // Get the four child queue discs and connect their Enqueue trace to the
217 // PacketEnqueuedInQueueDisc method, which counts how many packets with the given ToS value have
218 // been enqueued
219 // NOTE the purpose of the unary + operation in +m_QueueDiscCount is to decay the array type
220 // to a pointer type, so that the type of that argument matches the type of the second
221 // parameter of the PacketEnqueuedInQueueDisc function
222 root->GetQueueDiscClass(0)->GetQueueDisc()->TraceConnectWithoutContext(
223 "Enqueue",
225
226 root->GetQueueDiscClass(1)->GetQueueDisc()->TraceConnectWithoutContext(
227 "Enqueue",
229 m_tos,
230 m_QueueDiscCount + 1));
231
232 root->GetQueueDiscClass(2)->GetQueueDisc()->TraceConnectWithoutContext(
233 "Enqueue",
235 m_tos,
236 m_QueueDiscCount + 2));
237
238 root->GetQueueDiscClass(3)->GetQueueDisc()->TraceConnectWithoutContext(
239 "Enqueue",
241 m_tos,
242 m_QueueDiscCount + 3));
243
244 Ptr<WifiMac> apMac = DynamicCast<WifiNetDevice>(apDev.Get(0))->GetMac();
245 PointerValue ptr;
246 // Get the four wifi mac queues and connect their Enqueue trace to the
247 // PacketEnqueuedInWifiMacQueue method, which counts how many packets with the given ToS value
248 // have been enqueued
249 // NOTE the purpose of the unary + operation in +m_WifiMacQueueCount is to decay the array type
250 // to a pointer type, so that the type of that argument matches the type of the second
251 // parameter of the PacketEnqueuedInWifiMacQueue function
252 apMac->GetAttribute("BE_Txop", ptr);
253 ptr.Get<QosTxop>()->GetWifiMacQueue()->TraceConnectWithoutContext(
254 "Enqueue",
256 m_tos,
258
259 apMac->GetAttribute("BK_Txop", ptr);
260 ptr.Get<QosTxop>()->GetWifiMacQueue()->TraceConnectWithoutContext(
261 "Enqueue",
263 m_tos,
265
266 apMac->GetAttribute("VI_Txop", ptr);
267 ptr.Get<QosTxop>()->GetWifiMacQueue()->TraceConnectWithoutContext(
268 "Enqueue",
270 m_tos,
272
273 apMac->GetAttribute("VO_Txop", ptr);
274 ptr.Get<QosTxop>()->GetWifiMacQueue()->TraceConnectWithoutContext(
275 "Enqueue",
277 m_tos,
279
281
282 for (uint32_t i = 0; i < 4; i++)
283 {
284 if (i == m_expectedQueue)
285 {
287 1,
288 "There is no packet in the expected queue disc " << i);
290 1,
291 "There is no packet in the expected Wifi MAC queue " << i);
292 }
293 else
294 {
296 0,
297 "Unexpectedly, there is a packet in queue disc " << i);
299 0,
300 "Unexpectedly, there is a packet in Wifi MAC queue " << i);
301 }
302 }
303
304 uint32_t totalOctetsThrough = DynamicCast<PacketSink>(sinkApp.Get(0))->GetTotalRx();
305
306 // Check that the three packets have been received
307 NS_TEST_ASSERT_MSG_EQ(totalOctetsThrough, 1500, "Three packets should have been received");
308
310}
311
312/**
313 * \ingroup wifi-test
314 * \ingroup tests
315 *
316 * \brief Access category mapping Test Suite
317 */
319{
320 public:
322};
323
325 : TestSuite("wifi-ac-mapping", Type::SYSTEM)
326{
327 AddTestCase(new WifiAcMappingTest(0xb8, 2), TestCase::Duration::QUICK); // EF in AC_VI
328 AddTestCase(new WifiAcMappingTest(0x28, 1), TestCase::Duration::QUICK); // AF11 in AC_BK
329 AddTestCase(new WifiAcMappingTest(0x70, 0), TestCase::Duration::QUICK); // AF32 in AC_BE
330 AddTestCase(new WifiAcMappingTest(0xc0, 3), TestCase::Duration::QUICK); // CS7 in AC_VO
331}
332
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...
Class for representing data rates.
Definition data-rate.h:78
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition double.h:31
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:23
uint8_t GetTos() const
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.
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition object.h:511
A helper to make it easier to instantiate an ns3::OnOffApplication on a set of nodes.
A helper to make it easier to instantiate an ns3::PacketSinkApplication on a set of nodes.
AttributeValue implementation for Pointer.
Ptr< T > Get() const
Definition pointer.h:223
Smart pointer class similar to boost::intrusive_ptr.
Handles the packet queue and stores DCF/EDCA access parameters (one Txop per AC).
Definition qos-txop.h:52
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:131
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
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
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:34
helps to create WifiNetDevice objects
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:191
auto MakeBoundCallback(R(*fnPtr)(Args...), BArgs &&... bargs)
Make Callbacks with varying number of bound arguments.
Definition callback.h:745
#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:134
#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:905
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1308
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 WifiAcMappingTestSuite wifiAcMappingTestSuite