A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
power-save-test.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2022 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: Davide Magrin <davide@magr.in>
18 */
19
20#include "ns3/assert.h"
21#include "ns3/header-serialization-test.h"
22#include "ns3/log.h"
23#include "ns3/test.h"
24#include "ns3/tim.h"
25
26#include <algorithm>
27#include <iterator>
28#include <list>
29#include <sstream>
30#include <vector>
31
32using namespace ns3;
33
34NS_LOG_COMPONENT_DEFINE("PowerSaveTest");
35
36/**
37 * \ingroup wifi-test
38 * \ingroup tests
39 *
40 * \brief Test TIM Information element serialization and deserialization
41 */
43{
44 public:
45 /**
46 * \brief Constructor
47 */
49
50 void DoRun() override;
51 /**
52 * Reset the passed TIM to have the provided parameters.
53 *
54 * \param tim the TIM element to set
55 * \param dtimCount the DTIM count value
56 * \param dtimPeriod the DTIM period value
57 * \param multicastPending whether group addressed frames are queued
58 * \param aidValues the AID values to set
59 */
60 void SetTim(Tim& tim,
61 uint8_t dtimCount,
62 uint8_t dtimPeriod,
63 bool multicastPending,
64 const std::list<uint16_t>& aidValues);
65
66 /**
67 * Test that the Bitmap Control and the Partial Virtual Bitmap
68 * fields of the provided TIM match the passed bufferContents.
69 *
70 * \param tim the provided TIM
71 * \param bufferContents the expected content of the buffer
72 */
73 void CheckSerializationAgainstBuffer(Tim& tim, const std::vector<uint8_t>& bufferContents);
74
75 /**
76 * Test that the GetAidSet() method return the expected set of AID values.
77 *
78 * \param tim the TIM element
79 * \param aid the AID value passed to GetAidSet()
80 * \param expectedSet the expected set of AID values returned by GetAidSet()
81 */
82 void CheckAidSet(const Tim& tim, uint16_t aid, const std::set<uint16_t>& expectedSet);
83};
84
86 : HeaderSerializationTestCase("Test for the TIM Information Element implementation")
87{
88}
89
90void
92 uint8_t dtimCount,
93 uint8_t dtimPeriod,
94 bool multicastPending,
95 const std::list<uint16_t>& aidValues)
96{
97 tim = Tim();
98 tim.m_dtimCount = dtimCount;
99 tim.m_dtimPeriod = dtimPeriod;
100 tim.m_hasMulticastPending = multicastPending;
101 tim.AddAid(aidValues.begin(), aidValues.end());
102}
103
104void
106 Tim& tim,
107 const std::vector<uint8_t>& bufferContents)
108{
109 // Serialize the TIM
110 Buffer buffer;
111 buffer.AddAtStart(tim.GetSerializedSize());
112 tim.Serialize(buffer.Begin());
113
114 // Check the two Buffer instances
115 Buffer::Iterator bufferIterator = buffer.Begin();
116 for (uint32_t j = 0; j < buffer.GetSize(); j++)
117 {
118 // We skip the first four bytes, since they contain known information
119 if (j > 3)
120 {
121 NS_TEST_EXPECT_MSG_EQ(bufferIterator.ReadU8(),
122 bufferContents.at(j - 4),
123 "Serialization is different than provided known serialization");
124 }
125 else
126 {
127 // Advance the serialized buffer, which also contains
128 // the Element ID, Length, DTIM Count, DTIM Period fields
129 bufferIterator.ReadU8();
130 }
131 }
132}
133
134void
136 uint16_t aid,
137 const std::set<uint16_t>& expectedSet)
138{
139 auto ret = tim.GetAidSet(aid);
140
141 {
142 std::vector<uint16_t> diff;
143
144 // Expected set minus returned set provides expected elements that are not returned
145 std::set_difference(expectedSet.cbegin(),
146 expectedSet.cend(),
147 ret.cbegin(),
148 ret.cend(),
149 std::back_inserter(diff));
150
151 std::stringstream ss;
152 std::copy(diff.cbegin(), diff.cend(), std::ostream_iterator<uint16_t>(ss, " "));
153
154 NS_TEST_EXPECT_MSG_EQ(diff.size(),
155 0,
156 "Expected elements not returned by GetAidSet(): " << ss.str());
157 }
158 {
159 std::vector<uint16_t> diff;
160
161 // Returned set minus expected set provides returned elements that are not expected
162 std::set_difference(ret.cbegin(),
163 ret.cend(),
164 expectedSet.cbegin(),
165 expectedSet.cend(),
166 std::back_inserter(diff));
167
168 std::stringstream ss;
169 std::copy(diff.cbegin(), diff.cend(), std::ostream_iterator<uint16_t>(ss, " "));
170
171 NS_TEST_EXPECT_MSG_EQ(diff.size(),
172 0,
173 "Returned elements not expected by GetAidSet(): " << ss.str());
174 }
175}
176
177void
179{
180 Tim tim;
181
182 // The first three examples from 802.11-2020, Annex L
183 //
184 // 1. No group addressed MSDUs, but there is traffic for STAs with AID 2 and AID 7
185 SetTim(tim, 0, 3, false, {2, 7});
187 CheckSerializationAgainstBuffer(tim, {0b00000000, 0b10000100});
188 CheckAidSet(tim, 0, {2, 7});
189 CheckAidSet(tim, 1, {2, 7});
190 CheckAidSet(tim, 2, {7});
191 CheckAidSet(tim, 7, {});
192 //
193 // 2. There are group addressed MSDUs, DTIM count = 0, the nodes
194 // with AID 2, 7, 22, and 24 have data buffered in the AP
195 SetTim(tim, 0, 3, true, {2, 7, 22, 24});
198 {
199 0b00000001,
200 // NOTE The following byte is different from the example
201 // in the standard. This is because the example sets the
202 // AID 0 bit in the partial virtual bitmap to 1. Our code
203 // and the example code provided in the Annex, instead, do
204 // not set this bit. Relevant Note from 802.11-2020,
205 // Section 9.4.2.5.1: "The bit numbered 0 in the traffic
206 // indication virtual bitmap need not be included in the
207 // Partial Virtual Bitmap field even if that bit is set."
208 0b10000100,
209 0b00000000,
210 0b01000000,
211 0b00000001,
212 });
213 CheckAidSet(tim, 0, {2, 7, 22, 24});
214 CheckAidSet(tim, 2, {7, 22, 24});
215 CheckAidSet(tim, 7, {22, 24});
216 CheckAidSet(tim, 22, {24});
217 CheckAidSet(tim, 24, {});
218 //
219 // 3. There are group addressed MSDUs, DTIM count = 0, only the node
220 // with AID 24 has data buffered in the AP
221 SetTim(tim, 0, 3, true, {24});
223 CheckSerializationAgainstBuffer(tim, {0b00000011, 0b00000000, 0b00000001});
224
225 // Other arbitrary examples just to make sure
226 // Serialization -> Deserialization -> Serialization works
227 SetTim(tim, 0, 3, false, {2000});
229 SetTim(tim, 1, 3, true, {1, 134});
231 SetTim(tim, 1, 3, false, {1, 2});
233
234 // Edge cases
235 //
236 // What if there is group addressed data only?
237 //
238 // In this case, we should still have an empty byte in the Partial Virtual Bitmap.
239 // From 802.11-2020: in the event that all bits other than bit 0 in the traffic indication
240 // virtual bitmap are 0, the Partial Virtual Bitmap field is encoded as a single octet
241 // equal to 0, the Bitmap Offset subfield is 0, and the Length field is 4.
242 SetTim(tim, 0, 3, true, {});
244 CheckSerializationAgainstBuffer(tim, {0b00000001, 0b00000000});
245 NS_TEST_EXPECT_MSG_EQ(tim.GetSerializedSize() - 2, 4, "Unexpected TIM Length");
246 //
247 // What if there is no group addressed data and no unicast data?
248 //
249 // From 802.11-2020: When the TIM is carried in a non-S1G PPDU, in the event that all bits
250 // other than bit 0 in the traffic indication virtual bitmap are 0, the Partial Virtual Bitmap
251 // field is encoded as a single octet equal to 0, the Bitmap Offset subfield is 0, and the
252 // Length field is 4.
253 SetTim(tim, 0, 3, false, {});
255 CheckSerializationAgainstBuffer(tim, {0b00000000, 0b00000000});
256 NS_TEST_EXPECT_MSG_EQ(tim.GetSerializedSize() - 2, 4, "Unexpected TIM Length");
257}
258
259/**
260 * \ingroup wifi-test
261 * \ingroup tests
262 *
263 * \brief Power Save Test Suite
264 */
266{
267 public:
269};
270
272 : TestSuite("wifi-power-save", Type::UNIT)
273{
274 AddTestCase(new TimInformationElementTest, TestCase::Duration::QUICK);
275}
276
277static PowerSaveTestSuite g_powerSaveTestSuite; ///< the test suite
Power Save Test Suite.
Test TIM Information element serialization and deserialization.
TimInformationElementTest()
Constructor.
void SetTim(Tim &tim, uint8_t dtimCount, uint8_t dtimPeriod, bool multicastPending, const std::list< uint16_t > &aidValues)
Reset the passed TIM to have the provided parameters.
void DoRun() override
Implementation to actually run this TestCase.
void CheckSerializationAgainstBuffer(Tim &tim, const std::vector< uint8_t > &bufferContents)
Test that the Bitmap Control and the Partial Virtual Bitmap fields of the provided TIM match the pass...
void CheckAidSet(const Tim &tim, uint16_t aid, const std::set< uint16_t > &expectedSet)
Test that the GetAidSet() method return the expected set of AID values.
iterator in a Buffer instance
Definition: buffer.h:100
uint8_t ReadU8()
Definition: buffer.h:1027
automatically resized byte buffer
Definition: buffer.h:94
uint32_t GetSize() const
Definition: buffer.h:1068
void AddAtStart(uint32_t start)
Definition: buffer.cc:314
Buffer::Iterator Begin() const
Definition: buffer.h:1074
Subclass of TestCase class adding the ability to test the serialization and deserialization of a Head...
void TestHeaderSerialization(const T &hdr, Args &&... args)
Serialize the given header in a buffer, then create a new header by deserializing from the buffer and...
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:302
A suite of tests to run.
Definition: test.h:1273
Type
Type of test.
Definition: test.h:1280
The Traffic Indication Map Information Element.
Definition: tim.h:40
uint8_t m_dtimPeriod
The DTIM Period field.
Definition: tim.h:97
uint8_t m_dtimCount
The DTIM Count field.
Definition: tim.h:96
void AddAid(uint16_t aid)
Add the provided AID value to the list contained in the Virtual Bitmap.
Definition: tim.cc:49
std::set< uint16_t > GetAidSet(uint16_t aid=0) const
Return the AID values, greater than the given AID value, whose corresponding bits are set in the virt...
Definition: tim.cc:63
bool m_hasMulticastPending
Whether there is Multicast / Broadcast data.
Definition: tim.h:98
uint16_t GetSerializedSize() const
Get the size of the serialized IE including Element ID and length fields (for every element this IE i...
Buffer::Iterator Serialize(Buffer::Iterator i) const
Serialize entire IE including Element ID and length fields.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#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
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static PowerSaveTestSuite g_powerSaveTestSuite
the test suite