A Discrete-Event Network Simulator
API
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
50{
51 public:
58 WifiAcMappingTest(uint8_t tos, uint8_t expectedQueue);
59 void DoRun() override;
60
61 private:
70 static void PacketEnqueuedInQueueDisc(uint8_t tos,
71 uint16_t* count,
81 static void PacketEnqueuedInWifiMacQueue(uint8_t tos,
82 uint16_t* count,
84 uint8_t m_tos;
85 uint16_t m_expectedQueue;
86 uint16_t m_QueueDiscCount[4];
87 uint16_t m_WifiMacQueueCount[4];
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
125 if (llc.GetType() == Ipv4L3Protocol::PROT_NUMBER)
126 {
127 Ipv4Header iph;
128 packet->PeekHeader(iph);
129 if (iph.GetTos() == tos)
130 {
131 (*count)++;
132 }
133 }
134}
135
136void
138{
140 WifiMacHelper wifiMac;
141 YansWifiPhyHelper wifiPhy;
142 YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default();
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
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
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",
202 InetSocketAddress(Ipv4Address::GetAny(), udpPort));
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 dest.SetTos(m_tos);
210 OnOffHelper onoff("ns3::UdpSocketFactory", dest);
211 onoff.SetConstantRate(DataRate("5kbps"), 500);
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
220 Simulator::Stop(Seconds(5.0));
221
222 Ptr<QueueDisc> root =
223 ap.Get(0)->GetObject<TrafficControlLayer>()->GetRootQueueDiscOnDevice(apDev.Get(0));
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 root->GetQueueDiscClass(0)->GetQueueDisc()->TraceConnectWithoutContext(
231 "Enqueue",
233
234 root->GetQueueDiscClass(1)->GetQueueDisc()->TraceConnectWithoutContext(
235 "Enqueue",
237 m_tos,
238 m_QueueDiscCount + 1));
239
240 root->GetQueueDiscClass(2)->GetQueueDisc()->TraceConnectWithoutContext(
241 "Enqueue",
243 m_tos,
244 m_QueueDiscCount + 2));
245
246 root->GetQueueDiscClass(3)->GetQueueDisc()->TraceConnectWithoutContext(
247 "Enqueue",
249 m_tos,
250 m_QueueDiscCount + 3));
251
252 Ptr<WifiMac> apMac = DynamicCast<WifiNetDevice>(apDev.Get(0))->GetMac();
253 PointerValue ptr;
254 // Get the four wifi mac queues and connect their Enqueue trace to the
255 // PacketEnqueuedInWifiMacQueue method, which counts how many packets with the given ToS value
256 // have been enqueued
257 apMac->GetAttribute("BE_Txop", ptr);
258 ptr.Get<QosTxop>()->GetWifiMacQueue()->TraceConnectWithoutContext(
259 "Enqueue",
261 m_tos,
263
264 apMac->GetAttribute("BK_Txop", ptr);
265 ptr.Get<QosTxop>()->GetWifiMacQueue()->TraceConnectWithoutContext(
266 "Enqueue",
268 m_tos,
270
271 apMac->GetAttribute("VI_Txop", ptr);
272 ptr.Get<QosTxop>()->GetWifiMacQueue()->TraceConnectWithoutContext(
273 "Enqueue",
275 m_tos,
277
278 apMac->GetAttribute("VO_Txop", ptr);
279 ptr.Get<QosTxop>()->GetWifiMacQueue()->TraceConnectWithoutContext(
280 "Enqueue",
282 m_tos,
284
285 Simulator::Run();
286
287 for (uint32_t i = 0; i < 4; i++)
288 {
289 if (i == m_expectedQueue)
290 {
292 1,
293 "There is no packet in the expected queue disc " << i);
295 1,
296 "There is no packet in the expected Wifi MAC queue " << i);
297 }
298 else
299 {
301 0,
302 "Unexpectedly, there is a packet in queue disc " << i);
304 0,
305 "Unexpectedly, there is a packet in Wifi MAC queue " << i);
306 }
307 }
308
309 uint32_t totalOctetsThrough = DynamicCast<PacketSink>(sinkApp.Get(0))->GetTotalRx();
310
311 // Check that the three packets have been received
312 NS_TEST_ASSERT_MSG_EQ(totalOctetsThrough, 1500, "Three packets should have been received");
313
314 Simulator::Destroy();
315}
316
324{
325 public:
327};
328
330 : TestSuite("wifi-ac-mapping", SYSTEM)
331{
332 AddTestCase(new WifiAcMappingTest(0xb8, 2), TestCase::QUICK); // EF in AC_VI
333 AddTestCase(new WifiAcMappingTest(0x28, 1), TestCase::QUICK); // AF11 in AC_BK
334 AddTestCase(new WifiAcMappingTest(0x70, 0), TestCase::QUICK); // AF32 in AC_BE
335 AddTestCase(new WifiAcMappingTest(0xc0, 3), TestCase::QUICK); // CS7 in AC_VO
336}
337
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.
Ptr< Application > Get(uint32_t i) const
Get the Ptr<Application> stored in this container at a given index.
void Start(Time start)
Arrange for all of the Applications in this container to Start() at the Time given as a parameter.
void Stop(Time stop)
Arrange for all of the Applications in this container to Stop() at the Time given as a parameter.
AttributeValue implementation for Boolean.
Definition: boolean.h:37
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.
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
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:369
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:471
A helper to make it easier to instantiate an ns3::OnOffApplication on a set of nodes.
Definition: on-off-helper.h:44
void SetConstantRate(DataRate dataRate, uint32_t packetSize=512)
Helper function to set a constant rate source.
ApplicationContainer Install(NodeContainer c) const
Install an ns3::OnOffApplication on each node of the input container configured with all the attribut...
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:294
uint32_t PeekHeader(Header &header) const
Deserialize but does not remove the header from the internal buffer.
Definition: packet.cc:305
A helper to make it easier to instantiate an ns3::PacketSinkApplication on a set of nodes.
ApplicationContainer Install(NodeContainer c) const
Install an ns3::PacketSinkApplication on each node of the input container configured with all the att...
Hold objects of type Ptr<T>.
Definition: pointer.h:37
Ptr< T > Get() const
Definition: pointer.h:205
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
Handle packet fragmentation and retransmissions for QoS data frames as well as MSDU aggregation (A-MS...
Definition: qos-txop.h:73
std::size_t GetNQueueDiscClasses() const
Get the number of queue disc classes.
Definition: queue-disc.cc:665
Ptr< QueueDiscClass > GetQueueDiscClass(std::size_t i) const
Get the i-th queue disc class.
Definition: queue-disc.cc:658
The IEEE 802.11 SSID Information Element.
Definition: ssid.h:36
AttributeValue implementation for Ssid.
Hold variables of type string.
Definition: string.h:42
encapsulates test code
Definition: test.h:1060
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:305
A suite of tests to run.
Definition: test.h:1256
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...
Introspection did not find any typical Config paths.
Hold an unsigned integer type.
Definition: uinteger.h:45
helps to create WifiNetDevice objects
Definition: wifi-helper.h:325
create MAC layers for a ns3::WifiNetDevice.
void SetType(std::string type, Args &&... args)
manage and create wifi channel objects for the YANS model.
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:752
void(* DataRate)(DataRate oldValue, DataRate newValue)
TracedValue callback signature for DataRate.
Definition: data-rate.h:328
#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:144
#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:915
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1338
address
Definition: first.py:40
stack
Definition: first.py:37
Every class exported by the ns3 library is enclosed in the ns3 namespace.
ssid
Definition: third.py:86
wifi
Definition: third.py:88
mobility
Definition: third.py:96
static WifiAcMappingTestSuite wifiAcMappingTestSuite