A Discrete-Event Network Simulator
API
inter-bss-test-suite.cc
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2018 University of Washington
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Authors: Sébastien Deronne <sebastien.deronne@gmail.com>
19 * Scott Carpenter <scarpenter44@windstream.net>
20 */
21
22#include "ns3/log.h"
23#include "ns3/test.h"
24#include "ns3/uinteger.h"
25#include "ns3/double.h"
26#include "ns3/string.h"
27#include "ns3/pointer.h"
28#include "ns3/config.h"
29#include "ns3/ssid.h"
30#include "ns3/rng-seed-manager.h"
31#include "ns3/mobility-helper.h"
32#include "ns3/wifi-net-device.h"
33#include "ns3/spectrum-wifi-helper.h"
34#include "ns3/multi-model-spectrum-channel.h"
35#include "ns3/constant-obss-pd-algorithm.h"
36#include "ns3/he-configuration.h"
37#include "ns3/wifi-utils.h"
38
39using namespace ns3;
40
41NS_LOG_COMPONENT_DEFINE ("InterBssTestSuite");
42
43static uint32_t
44ConvertContextToNodeId (std::string context)
45{
46 std::string sub = context.substr (10);
47 uint32_t pos = sub.find ("/Device");
48 uint32_t nodeId = atoi (sub.substr (0, pos).c_str ());
49 return nodeId;
50}
51
79{
80public:
83
84 void DoRun (void) override;
85
86private:
93 void SendOnePacket (Ptr<WifiNetDevice> tx_dev, Ptr<WifiNetDevice> rx_dev, uint32_t payloadSize);
94
104 Ptr<ListPositionAllocator> AllocatePositions (double d1, double d2, double d3, double d4, double d5);
105
110 void SetExpectedTxPower (double txPowerDbm);
111
115 void SetupSimulation ();
116
120 void CheckResults ();
121
125 void ResetResults ();
126
130 void ClearDropReasons ();
131
135 void RunOne ();
136
142 void CheckPhyState (Ptr<WifiNetDevice> device, WifiPhyState expectedState);
143
149 void CheckPhyDropReasons (Ptr<WifiNetDevice> device, std::vector<WifiPhyRxfailureReason> expectedDropReasons);
150
157 void NotifyPhyTxBegin (std::string context, Ptr<const Packet> p, double txPowerW);
158
164 void NotifyPhyRxEnd (std::string context, Ptr<const Packet> p);
165
172 void NotifyPhyRxDrop (std::string context, Ptr<const Packet> p, WifiPhyRxfailureReason reason);
173
174 unsigned int m_numSta1PacketsSent;
175 unsigned int m_numSta2PacketsSent;
176 unsigned int m_numAp1PacketsSent;
177 unsigned int m_numAp2PacketsSent;
178
183
184 std::vector<WifiPhyRxfailureReason> m_dropReasonsSta1;
185 std::vector<WifiPhyRxfailureReason> m_dropReasonsSta2;
186 std::vector<WifiPhyRxfailureReason> m_dropReasonsAp1;
187 std::vector<WifiPhyRxfailureReason> m_dropReasonsAp2;
188
189 unsigned int m_payloadSize1;
190 unsigned int m_payloadSize2;
191 unsigned int m_payloadSize3;
192
195
200
201 uint8_t m_bssColor1;
202 uint8_t m_bssColor2;
203 uint8_t m_bssColor3;
204};
205
207 : TestCase ("InterBssConstantObssPd"),
208 m_numSta1PacketsSent (0),
209 m_numSta2PacketsSent (0),
210 m_numAp1PacketsSent (0),
211 m_numAp2PacketsSent (0),
212 m_numSta1PacketsReceived (0),
213 m_numSta2PacketsReceived (0),
214 m_numAp1PacketsReceived (0),
215 m_numAp2PacketsReceived (0),
216 m_payloadSize1 (1000),
217 m_payloadSize2 (1500),
218 m_payloadSize3 (2000),
219 m_txPowerDbm (15),
220 m_obssPdLevelDbm (-72),
221 m_obssRxPowerDbm (-82),
222 m_expectedTxPowerDbm (15),
223 m_bssColor1 (1),
224 m_bssColor2 (2),
225 m_bssColor3 (3)
226{
227}
228
230{
232}
233
235TestInterBssConstantObssPdAlgo::AllocatePositions (double d1, double d2, double d3, double d4, double d5)
236{
237 Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
238 positionAlloc->Add (Vector (0.0, 0.0, 0.0)); // AP1
239 positionAlloc->Add (Vector (d1 + d2, 0.0, 0.0)); // AP2
240 positionAlloc->Add (Vector (d1 + d2 + d3 + d4, 0.0, 0.0)); // AP3
241 positionAlloc->Add (Vector (d1, 0.0, 0.0)); // STA1
242 positionAlloc->Add (Vector (d1 + d2 + d3, 0.0, 0.0)); // STA2
243 positionAlloc->Add (Vector (d1 + d2 + d3 + d4 + d5, 0.0, 0.0)); // STA3
244 return positionAlloc;
245}
246
247void
249{
250 Ptr<WifiNetDevice> ap_device1 = DynamicCast<WifiNetDevice> (m_apDevices.Get (0));
251 Ptr<WifiNetDevice> ap_device2 = DynamicCast<WifiNetDevice> (m_apDevices.Get (1));
252 Ptr<WifiNetDevice> ap_device3 = DynamicCast<WifiNetDevice> (m_apDevices.Get (2));
253 Ptr<WifiNetDevice> sta_device1 = DynamicCast<WifiNetDevice> (m_staDevices.Get (0));
254 Ptr<WifiNetDevice> sta_device2 = DynamicCast<WifiNetDevice> (m_staDevices.Get (1));
255 Ptr<WifiNetDevice> sta_device3 = DynamicCast<WifiNetDevice> (m_staDevices.Get (2));
256
257 bool expectFilter = (m_bssColor1 != 0) && (m_bssColor2 != 0);
258 bool expectPhyReset = expectFilter && (m_obssPdLevelDbm >= m_obssRxPowerDbm);
259 std::vector<WifiPhyRxfailureReason> dropReasons;
260 WifiPhyState stateDuringPayloadNeighboringBss = expectFilter ? WifiPhyState::CCA_BUSY : WifiPhyState::RX;
261 if (expectFilter)
262 {
263 dropReasons.push_back (FILTERED);
264 }
265 if (expectPhyReset)
266 {
267 dropReasons.push_back (OBSS_PD_CCA_RESET);
268 }
269
270 // In order to have all ADDBA handshakes established, each AP and STA sends a packet.
271
272 Simulator::Schedule (Seconds (0.25), &TestInterBssConstantObssPdAlgo::SendOnePacket, this, ap_device1, sta_device1, m_payloadSize1);
273 Simulator::Schedule (Seconds (0.5), &TestInterBssConstantObssPdAlgo::SendOnePacket, this, sta_device1, ap_device1, m_payloadSize1);
274 Simulator::Schedule (Seconds (0.75), &TestInterBssConstantObssPdAlgo::SendOnePacket, this, ap_device2, sta_device2, m_payloadSize2);
275 Simulator::Schedule (Seconds (1), &TestInterBssConstantObssPdAlgo::SendOnePacket, this, sta_device2, ap_device2, m_payloadSize2);
276 Simulator::Schedule (Seconds (1.25), &TestInterBssConstantObssPdAlgo::SendOnePacket, this, ap_device3, sta_device3, m_payloadSize3);
277 Simulator::Schedule (Seconds (1.5), &TestInterBssConstantObssPdAlgo::SendOnePacket, this, sta_device3, ap_device3, m_payloadSize3);
278
279 // We test PHY state and verify whether a CCA reset did occur.
280
281 // AP2 sends a packet 0.5s later.
282 Simulator::Schedule (Seconds (2.0), &TestInterBssConstantObssPdAlgo::ClearDropReasons, this);
283 Simulator::Schedule (Seconds (2.0), &TestInterBssConstantObssPdAlgo::SendOnePacket, this, ap_device2, sta_device2, m_payloadSize2);
284 Simulator::Schedule (Seconds (2.0) + MicroSeconds (10), &TestInterBssConstantObssPdAlgo::CheckPhyState, this, ap_device2, WifiPhyState::TX);
285 // All other PHYs should have stay idle until 4us (preamble detection time).
286 Simulator::Schedule (Seconds (2.0) + MicroSeconds (13), &TestInterBssConstantObssPdAlgo::CheckPhyState, this, sta_device1, WifiPhyState::IDLE);
287 Simulator::Schedule (Seconds (2.0) + MicroSeconds (13), &TestInterBssConstantObssPdAlgo::CheckPhyState, this, sta_device2, WifiPhyState::IDLE);
288 Simulator::Schedule (Seconds (2.0) + MicroSeconds (13), &TestInterBssConstantObssPdAlgo::CheckPhyState, this, ap_device1, WifiPhyState::IDLE);
289 // All PHYs should be receiving the PHY header (i.e. PHY state is CCA_BUSY) if preamble has been detected (always the case in this test).
290 Simulator::Schedule (Seconds (2.0) + MicroSeconds (14), &TestInterBssConstantObssPdAlgo::CheckPhyState, this, sta_device1, WifiPhyState::CCA_BUSY);
291 Simulator::Schedule (Seconds (2.0) + MicroSeconds (14), &TestInterBssConstantObssPdAlgo::CheckPhyState, this, sta_device2, WifiPhyState::CCA_BUSY);
292 Simulator::Schedule (Seconds (2.0) + MicroSeconds (14), &TestInterBssConstantObssPdAlgo::CheckPhyState, this, ap_device1, WifiPhyState::CCA_BUSY);
293 // PHYs of AP1 and STA1 should be idle after HE-SIG-A if they were reset by OBSS_PD SR, otherwise they should be CCA_busy until beginning of payload.
294 Simulator::Schedule (Seconds (2.0) + MicroSeconds (43), &TestInterBssConstantObssPdAlgo::CheckPhyDropReasons, this, sta_device1, dropReasons);
295 Simulator::Schedule (Seconds (2.0) + MicroSeconds (43), &TestInterBssConstantObssPdAlgo::CheckPhyState, this, sta_device1, expectPhyReset ? WifiPhyState::IDLE : WifiPhyState::CCA_BUSY);
296 Simulator::Schedule (Seconds (2.0) + MicroSeconds (43), &TestInterBssConstantObssPdAlgo::CheckPhyDropReasons, this, ap_device1, dropReasons);
297 Simulator::Schedule (Seconds (2.0) + MicroSeconds (43), &TestInterBssConstantObssPdAlgo::CheckPhyState, this, ap_device1, expectPhyReset ? WifiPhyState::IDLE : WifiPhyState::CCA_BUSY);
298 // PHYs of AP1 and STA1 should be idle if they were reset by OBSS_PD SR, otherwise they should be CCA_busy/Rx (since filtered/not filtered, resp.).
299 Simulator::Schedule (Seconds (2.0) + MicroSeconds (54), &TestInterBssConstantObssPdAlgo::CheckPhyState, this, sta_device1, expectPhyReset ? WifiPhyState::IDLE : stateDuringPayloadNeighboringBss);
300 Simulator::Schedule (Seconds (2.0) + MicroSeconds (54), &TestInterBssConstantObssPdAlgo::CheckPhyState, this, ap_device1, expectPhyReset ? WifiPhyState::IDLE : stateDuringPayloadNeighboringBss);
301 // STA2 should be receiving
302 Simulator::Schedule (Seconds (2.0) + MicroSeconds (54), &TestInterBssConstantObssPdAlgo::CheckPhyState, this, sta_device2, WifiPhyState::RX);
303
304 // We test whether two networks can transmit simultaneously, and whether transmit power restrictions are applied.
305
306 // AP2 sends another packet 0.1s later.
307 Simulator::Schedule (Seconds (2.1), &TestInterBssConstantObssPdAlgo::ClearDropReasons, this);
308 Simulator::Schedule (Seconds (2.1), &TestInterBssConstantObssPdAlgo::SendOnePacket, this, ap_device2, sta_device2, m_payloadSize2);
309 // STA1 sends a packet 42us later (i.e. right after HE-SIG-A of AP2). Even though AP2 is still transmitting, STA1 can transmit simultaneously if it's PHY was reset by OBSS_PD SR.
310 Simulator::Schedule (Seconds (2.1) + MicroSeconds (42), &TestInterBssConstantObssPdAlgo::SendOnePacket, this, sta_device1, ap_device1, m_payloadSize1);
311 if (expectPhyReset)
312 {
313 // In this case, we check the TX power is restricted (and set the expected value slightly before transmission should occur)
314 double expectedTxPower = std::min (m_txPowerDbm, 21 - (m_obssPdLevelDbm + 82));
315 Simulator::Schedule (Seconds (2.1) + MicroSeconds (41), &TestInterBssConstantObssPdAlgo::SetExpectedTxPower, this, expectedTxPower);
316 }
317 // Check simultaneous transmissions
318 Simulator::Schedule (Seconds (2.1) + MicroSeconds (100), &TestInterBssConstantObssPdAlgo::CheckPhyState, this, ap_device2, WifiPhyState::TX);
319 Simulator::Schedule (Seconds (2.1) + MicroSeconds (100), &TestInterBssConstantObssPdAlgo::CheckPhyDropReasons, this, sta_device1, dropReasons);
320 Simulator::Schedule (Seconds (2.1) + MicroSeconds (100), &TestInterBssConstantObssPdAlgo::CheckPhyState, this, sta_device1, expectPhyReset ? WifiPhyState::TX : stateDuringPayloadNeighboringBss);
321 Simulator::Schedule (Seconds (2.1) + MicroSeconds (100), &TestInterBssConstantObssPdAlgo::CheckPhyState, this, sta_device2, WifiPhyState::RX);
322 Simulator::Schedule (Seconds (2.1) + MicroSeconds (100), &TestInterBssConstantObssPdAlgo::CheckPhyDropReasons, this, ap_device1, dropReasons);
323 Simulator::Schedule (Seconds (2.1) + MicroSeconds (100), &TestInterBssConstantObssPdAlgo::CheckPhyState, this, ap_device1, stateDuringPayloadNeighboringBss);
324 Simulator::Schedule (Seconds (2.1) + MicroSeconds (142), &TestInterBssConstantObssPdAlgo::CheckPhyState, this, ap_device1, expectPhyReset ? WifiPhyState::RX : stateDuringPayloadNeighboringBss);
325
326 // AP2 sends another packet 0.1s later, and STA1 wanting to send a packet during the payload of the former.
327 Simulator::Schedule (Seconds (2.2), &TestInterBssConstantObssPdAlgo::ClearDropReasons, this);
329 Simulator::Schedule (Seconds (2.2), &TestInterBssConstantObssPdAlgo::SendOnePacket, this, ap_device2, sta_device2, m_payloadSize2);
330 // STA1 sends a packet 90us later (i.e. during payload of AP2). Even though AP2 is still transmitting, STA1 can transmit simultaneously if it's PHY was reset by OBSS_PD SR.
331 Simulator::Schedule (Seconds (2.2) + MicroSeconds (90), &TestInterBssConstantObssPdAlgo::SendOnePacket, this, sta_device1, ap_device1, m_payloadSize1);
332 if (expectPhyReset)
333 {
334 // In this case, we check the TX power is restricted (and set the expected value slightly before transmission should occur)
335 double expectedTxPower = std::min (m_txPowerDbm, 21 - (m_obssPdLevelDbm + 82));
336 Simulator::Schedule (Seconds (2.2) + MicroSeconds (89), &TestInterBssConstantObssPdAlgo::SetExpectedTxPower, this, expectedTxPower);
337 }
338 // Check simultaneous transmissions
339 Simulator::Schedule (Seconds (2.2) + MicroSeconds (105), &TestInterBssConstantObssPdAlgo::CheckPhyState, this, ap_device2, WifiPhyState::TX);
340 Simulator::Schedule (Seconds (2.2) + MicroSeconds (105), &TestInterBssConstantObssPdAlgo::CheckPhyDropReasons, this, sta_device1, dropReasons);
341 Simulator::Schedule (Seconds (2.2) + MicroSeconds (105), &TestInterBssConstantObssPdAlgo::CheckPhyState, this, sta_device1, expectPhyReset ? WifiPhyState::TX : stateDuringPayloadNeighboringBss);
342 Simulator::Schedule (Seconds (2.2) + MicroSeconds (105), &TestInterBssConstantObssPdAlgo::CheckPhyState, this, sta_device2, WifiPhyState::RX);
343 Simulator::Schedule (Seconds (2.2) + MicroSeconds (105), &TestInterBssConstantObssPdAlgo::CheckPhyDropReasons, this, ap_device1, dropReasons);
344 Simulator::Schedule (Seconds (2.2) + MicroSeconds (105), &TestInterBssConstantObssPdAlgo::CheckPhyState, this, ap_device1, stateDuringPayloadNeighboringBss);
345 Simulator::Schedule (Seconds (2.2) + MicroSeconds (195), &TestInterBssConstantObssPdAlgo::CheckPhyState, this, ap_device1, expectPhyReset ? WifiPhyState::RX : stateDuringPayloadNeighboringBss);
346
347
348 // Verify transmit power restrictions are not applied if access to the channel is requested after ignored OBSS transmissions.
349
351 // AP2 sends another packet 0.1s later. Power restriction should not be applied.
352 Simulator::Schedule (Seconds (2.3), &TestInterBssConstantObssPdAlgo::SendOnePacket, this, ap_device2, sta_device2, m_payloadSize2);
353 // STA1 sends a packet 0.1s later. Power restriction should not be applied.
354 Simulator::Schedule (Seconds (2.4), &TestInterBssConstantObssPdAlgo::SendOnePacket, this, sta_device1, ap_device1, m_payloadSize1);
355
356 // Verify a scenario that involves 3 networks in order to verify corner cases for transmit power restrictions.
357 // First, there is a transmission on network 2 from STA to AP, followed by a response from AP to STA.
358 // During that time, the STA on network 1 has a packet to send and request access to the channel.
359 // If a CCA reset occurred, it starts deferring while transmissions are ongoing from network 2.
360 // Before its backoff expires, a transmission on network 3 occurs, also eventually triggering another CCA reset (depending on the scenario that is being run).
361 // This test checks whether this sequence preserves transmit power restrictions if CCA resets occurred, since STA 1 has been deferring during ignored OBSS transmissions.
362
363 Simulator::Schedule (Seconds (2.5), &TestInterBssConstantObssPdAlgo::SendOnePacket, this, sta_device2, ap_device2, m_payloadSize2 / 10);
364 Simulator::Schedule (Seconds (2.5) + MicroSeconds (15), &TestInterBssConstantObssPdAlgo::SendOnePacket, this, ap_device2, sta_device2, m_payloadSize2 / 10);
365 Simulator::Schedule (Seconds (2.5) + MicroSeconds (270), &TestInterBssConstantObssPdAlgo::SendOnePacket, this, ap_device1, sta_device1, m_payloadSize1 / 10);
366 Simulator::Schedule (Seconds (2.5) + MicroSeconds (300), &TestInterBssConstantObssPdAlgo::SendOnePacket, this, ap_device3, sta_device3, m_payloadSize3 / 10);
367 if (expectPhyReset)
368 {
369 // In this case, we check the TX power is restricted (and set the expected value slightly before transmission should occur)
370 double expectedTxPower = std::min (m_txPowerDbm, 21 - (m_obssPdLevelDbm + 82));
371 Simulator::Schedule (Seconds (2.5) + MicroSeconds (338), &TestInterBssConstantObssPdAlgo::SetExpectedTxPower, this, expectedTxPower);
372 }
373
374 Simulator::Stop (Seconds (2.6));
375}
376
377void
379{
390}
391
392void
394{
395 m_dropReasonsSta1.clear ();
396 m_dropReasonsSta2.clear ();
397 m_dropReasonsAp1.clear ();
398 m_dropReasonsAp2.clear ();
399}
400
401void
403{
404 NS_TEST_ASSERT_MSG_EQ (m_numSta1PacketsSent, 4, "The number of packets sent by STA1 is not correct!");
405 NS_TEST_ASSERT_MSG_EQ (m_numSta2PacketsSent, 2, "The number of packets sent by STA2 is not correct!");
406 NS_TEST_ASSERT_MSG_EQ (m_numAp1PacketsSent, 2, "The number of packets sent by AP1 is not correct!");
407 NS_TEST_ASSERT_MSG_EQ (m_numAp2PacketsSent, 6, "The number of packets sent by AP2 is not correct!");
408 NS_TEST_ASSERT_MSG_EQ (m_numSta1PacketsReceived, 2, "The number of packets received by STA1 is not correct!");
409 NS_TEST_ASSERT_MSG_EQ (m_numSta2PacketsReceived, 6, "The number of packets received by STA2 is not correct!");
410 NS_TEST_ASSERT_MSG_EQ (m_numAp1PacketsReceived, 4, "The number of packets received by AP1 is not correct!");
411 NS_TEST_ASSERT_MSG_EQ (m_numAp2PacketsReceived, 2, "The number of packets received by AP2 is not correct!");
412}
413
414void
416{
417 uint32_t idx = ConvertContextToNodeId (context);
418 uint32_t pktSize = p->GetSize () - 38;
419 if ((idx == 0) && ((pktSize == m_payloadSize1) || (pktSize == (m_payloadSize1 / 10))))
420 {
422 NS_TEST_EXPECT_MSG_EQ (TestDoubleIsEqual (WToDbm (txPowerW), m_expectedTxPowerDbm, 1e-12), true, "Tx power is not correct!");
423 }
424 else if ((idx == 1) && ((pktSize == m_payloadSize2) || (pktSize == (m_payloadSize2 / 10))))
425 {
427 NS_TEST_EXPECT_MSG_EQ (TestDoubleIsEqual (WToDbm (txPowerW), m_expectedTxPowerDbm, 1e-12), true, "Tx power is not correct!");
428 }
429 else if ((idx == 3) && ((pktSize == m_payloadSize1) || (pktSize == (m_payloadSize1 / 10))))
430 {
432 NS_TEST_EXPECT_MSG_EQ (TestDoubleIsEqual (WToDbm (txPowerW), m_expectedTxPowerDbm, 1e-12), true, "Tx power is not correct!");
433 }
434 else if ((idx == 4) && ((pktSize == m_payloadSize2) || (pktSize == (m_payloadSize2 / 10))))
435 {
437 NS_TEST_EXPECT_MSG_EQ (TestDoubleIsEqual (WToDbm (txPowerW), m_expectedTxPowerDbm, 1e-12), true, "Tx power is not correct!");
438 }
439}
440
441void
443{
444 uint32_t idx = ConvertContextToNodeId (context);
445 uint32_t pktSize = p->GetSize () - 38;
446 if ((idx == 0) && ((pktSize == m_payloadSize1) || (pktSize == (m_payloadSize1 / 10))))
447 {
449 }
450 else if ((idx == 1) && ((pktSize == m_payloadSize2) || (pktSize == (m_payloadSize2 / 10))))
451 {
453 }
454 else if ((idx == 3) && ((pktSize == m_payloadSize1) || (pktSize == (m_payloadSize1 / 10))))
455 {
457 }
458 else if ((idx == 4) && ((pktSize == m_payloadSize2) || (pktSize == (m_payloadSize2 / 10))))
459 {
461 }
462}
463
464void
467{
468 uint32_t idx = ConvertContextToNodeId (context);
469 uint32_t pktSize = p->GetSize () - 38;
470 if ((idx == 0) && ((pktSize != m_payloadSize1) && (pktSize != (m_payloadSize1 / 10))))
471 {
472 m_dropReasonsSta1.push_back (reason);
473 }
474 else if ((idx == 1) && ((pktSize != m_payloadSize2) && (pktSize != (m_payloadSize2 / 10))))
475 {
476 m_dropReasonsSta2.push_back (reason);
477 }
478 else if ((idx == 3) && ((pktSize != m_payloadSize1) && (pktSize != (m_payloadSize1 / 10))))
479 {
480 m_dropReasonsAp1.push_back (reason);
481 }
482 else if ((idx == 4) && ((pktSize != m_payloadSize2) && (pktSize != (m_payloadSize2 / 10))))
483 {
484 m_dropReasonsAp2.push_back (reason);
485 }
486}
487
488void
490{
491 Ptr<Packet> p = Create<Packet> (payloadSize);
492 tx_dev->Send (p, rx_dev->GetAddress (), 1);
493}
494
495void
497{
498 m_expectedTxPowerDbm = txPowerDbm;
499}
500
501void
503{
504 WifiPhyState currentState;
505 PointerValue ptr;
506 Ptr<WifiPhy> phy = DynamicCast<WifiPhy> (device->GetPhy ());
507 phy->GetAttribute ("State", ptr);
508 Ptr <WifiPhyStateHelper> state = DynamicCast <WifiPhyStateHelper> (ptr.Get<WifiPhyStateHelper> ());
509 currentState = state->GetState ();
510 NS_TEST_ASSERT_MSG_EQ (currentState, expectedState, "PHY State " << currentState << " does not match expected state " << expectedState << " at " << Simulator::Now ());
511}
512
513void
515 std::vector<WifiPhyRxfailureReason> expectedDropReasons)
516{
517 std::vector<WifiPhyRxfailureReason> currentDropReasons;
518 uint32_t nodeId = device->GetNode ()->GetId ();
519 switch (nodeId)
520 {
521 case 0: //STA1
522 currentDropReasons = m_dropReasonsSta1;
523 break;
524 case 1: //STA2
525 currentDropReasons = m_dropReasonsSta2;
526 break;
527 case 3: //AP1
528 currentDropReasons = m_dropReasonsAp1;
529 break;
530 case 4: //AP2
531 currentDropReasons = m_dropReasonsAp2;
532 break;
533 default: //others, no attribute
534 return;
535 }
536 NS_TEST_ASSERT_MSG_EQ (currentDropReasons.size (), expectedDropReasons.size (), "Number of drop reasons " << currentDropReasons.size () << " does not match expected one " << expectedDropReasons.size () << " at " << Simulator::Now ());
537 for (std::size_t i = 0; i < currentDropReasons.size (); ++i)
538 {
539 NS_TEST_ASSERT_MSG_EQ (currentDropReasons[i], expectedDropReasons[i], "Drop reason " << i << ": " << currentDropReasons[i] << " does not match expected reason " << expectedDropReasons[i] << " at " << Simulator::Now ());
540 }
541}
542
543void
545{
546 RngSeedManager::SetSeed (1);
547 RngSeedManager::SetRun (3);
548 int64_t streamNumber = 50;
549
550 Config::Set ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/BE_MaxAmpduSize", UintegerValue (0));
551
552 ResetResults ();
553
555 wifiStaNodes.Create (3);
556
557 NodeContainer wifiApNodes;
558 wifiApNodes.Create (3);
559
560 Ptr<MatrixPropagationLossModel> lossModel = CreateObject<MatrixPropagationLossModel> ();
561 lossModel->SetDefaultLoss (m_txPowerDbm - m_obssRxPowerDbm); //Force received RSSI to be equal to m_obssRxPowerDbm
562
564 phy.DisablePreambleDetectionModel ();
565 phy.SetFrameCaptureModel ("ns3::SimpleFrameCaptureModel");
566 Ptr<MultiModelSpectrumChannel> channel = CreateObject<MultiModelSpectrumChannel> ();
567 channel->SetPropagationDelayModel (CreateObject<ConstantSpeedPropagationDelayModel> ());
568 channel->AddPropagationLossModel (lossModel);
569 phy.SetChannel (channel);
570 phy.Set ("TxPowerStart", DoubleValue (m_txPowerDbm));
571 phy.Set ("TxPowerEnd", DoubleValue (m_txPowerDbm));
572 phy.Set ("ChannelSettings", StringValue ("{36, 20, BAND_5GHZ, 0}"));
573
575 wifi.SetStandard (WIFI_STANDARD_80211ax);
576 wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
577 "DataMode", StringValue ("HeMcs5"),
578 "ControlMode", StringValue ("HeMcs0"));
579
580 wifi.SetObssPdAlgorithm ("ns3::ConstantObssPdAlgorithm",
581 "ObssPdLevel", DoubleValue (m_obssPdLevelDbm));
582
584 Ssid ssid = Ssid ("ns-3-ssid");
585 mac.SetType ("ns3::StaWifiMac",
586 "Ssid", SsidValue (ssid));
587 m_staDevices = wifi.Install (phy, mac, wifiStaNodes);
588
589 // Assign fixed streams to random variables in use
590 wifi.AssignStreams (m_staDevices, streamNumber);
591
592 mac.SetType ("ns3::ApWifiMac",
593 "Ssid", SsidValue (ssid));
594 m_apDevices = wifi.Install (phy, mac, wifiApNodes);
595
596 // Assign fixed streams to random variables in use
597 wifi.AssignStreams (m_apDevices, streamNumber);
598
599 for (uint32_t i = 0; i < m_apDevices.GetN (); i++)
600 {
601 Ptr<WifiNetDevice> device = DynamicCast<WifiNetDevice> (m_apDevices.Get (i));
602 Ptr<HeConfiguration> heConfiguration = device->GetHeConfiguration ();
603 if (i == 0)
604 {
605 heConfiguration->SetAttribute ("BssColor", UintegerValue (m_bssColor1));
606 }
607 else if (i == 1)
608 {
609 heConfiguration->SetAttribute ("BssColor", UintegerValue (m_bssColor2));
610 }
611 else
612 {
613 heConfiguration->SetAttribute ("BssColor", UintegerValue (m_bssColor3));
614 }
615 }
616
618 Ptr<ListPositionAllocator> positionAlloc = AllocatePositions (10, 50, 10, 50, 10); //distances do not really matter since we set RSSI per TX-RX pair to have full control
619 mobility.SetPositionAllocator (positionAlloc);
620 mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
621 mobility.Install (wifiApNodes);
622 mobility.Install (wifiStaNodes);
623
624 lossModel->SetLoss (wifiStaNodes.Get (0)->GetObject<MobilityModel> (), wifiApNodes.Get (0)->GetObject<MobilityModel> (), m_txPowerDbm + 30); //Low attenuation for IBSS transmissions
625 lossModel->SetLoss (wifiStaNodes.Get (1)->GetObject<MobilityModel> (), wifiApNodes.Get (1)->GetObject<MobilityModel> (), m_txPowerDbm + 30); //Low attenuation for IBSS transmissions
626 lossModel->SetLoss (wifiStaNodes.Get (2)->GetObject<MobilityModel> (), wifiApNodes.Get (2)->GetObject<MobilityModel> (), m_txPowerDbm + 30); //Low attenuation for IBSS transmissions
627
628 Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyTxBegin", MakeCallback (&TestInterBssConstantObssPdAlgo::NotifyPhyTxBegin, this));
629 Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyRxEnd", MakeCallback (&TestInterBssConstantObssPdAlgo::NotifyPhyRxEnd, this));
630 Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyRxDrop", MakeCallback (&TestInterBssConstantObssPdAlgo::NotifyPhyRxDrop, this));
631
633
634 Simulator::Run ();
635 Simulator::Destroy ();
636
637 CheckResults ();
638}
639
640void
642{
643 //Test case 1: CCA CS Threshold = m_obssRxPowerDbm < m_obssPdLevelDbm
644 m_obssPdLevelDbm = -72;
645 m_obssRxPowerDbm = -82;
646 m_bssColor1 = 1;
647 m_bssColor2 = 2;
648 m_bssColor3 = 3;
649 RunOne ();
650
651 //Test case 2: CCA CS Threshold < m_obssPdLevelDbm < m_obssRxPowerDbm
652 m_obssPdLevelDbm = -72;
653 m_obssRxPowerDbm = -62;
654 m_bssColor1 = 1;
655 m_bssColor2 = 2;
656 m_bssColor3 = 3;
657 RunOne ();
658
659 //Test case 3: CCA CS Threshold < m_obssPdLevelDbm = m_obssRxPowerDbm
660 m_obssPdLevelDbm = -72;
661 m_obssRxPowerDbm = -72;
662 m_bssColor1 = 1;
663 m_bssColor2 = 2;
664 m_bssColor3 = 3;
665 RunOne ();
666
667 //Test case 4: CCA CS Threshold = m_obssRxPowerDbm < m_obssPdLevelDbm with BSS color 2 and 3 set to 0
668 m_obssPdLevelDbm = -72;
669 m_obssRxPowerDbm = -82;
670 m_bssColor1 = 1;
671 m_bssColor2 = 0;
672 m_bssColor3 = 0;
673 RunOne ();
674
675 //Test case 5: CCA CS Threshold = m_obssRxPowerDbm < m_obssPdLevelDbm with BSS color 1 set to 0
676 m_obssPdLevelDbm = -72;
677 m_obssRxPowerDbm = -82;
678 m_bssColor1 = 0;
679 m_bssColor2 = 2;
680 m_bssColor3 = 3;
681 RunOne ();
682}
683
692{
693public:
695};
696
698 : TestSuite ("wifi-inter-bss", UNIT)
699{
700 AddTestCase (new TestInterBssConstantObssPdAlgo, TestCase::QUICK);
701}
702
703// Do not forget to allocate an instance of this TestSuite
#define min(a, b)
Definition: 80211b.c:42
Inter BSS Test Suite.
unsigned int m_numSta2PacketsSent
number of sent packets from STA2
unsigned int m_numAp2PacketsReceived
number of received packets from AP2
unsigned int m_numSta1PacketsSent
number of sent packets from STA1
double m_obssRxPowerDbm
forced RX power in dBm for OBSS
unsigned int m_payloadSize2
size in bytes of packet payload in BSS 2
Ptr< ListPositionAllocator > AllocatePositions(double d1, double d2, double d3, double d4, double d5)
Allocate the node positions.
void ClearDropReasons()
Clear the drop reasons.
std::vector< WifiPhyRxfailureReason > m_dropReasonsAp2
drop reasons for AP2
void SetupSimulation()
Setup the simulation.
void CheckPhyDropReasons(Ptr< WifiNetDevice > device, std::vector< WifiPhyRxfailureReason > expectedDropReasons)
Check if the Phy drop reasons for a device are as expected.
void SetExpectedTxPower(double txPowerDbm)
Set the expected transmit power in dBm.
unsigned int m_payloadSize3
size in bytes of packet payload in BSS 3
void NotifyPhyTxBegin(std::string context, Ptr< const Packet > p, double txPowerW)
Notify Phy transmit begin.
unsigned int m_payloadSize1
size in bytes of packet payload in BSS 1
void ResetResults()
Reset the results.
unsigned int m_numSta2PacketsReceived
number of received packets from STA2
unsigned int m_numAp2PacketsSent
number of sent packets from AP2
void DoRun(void) override
Implementation to actually run this TestCase.
void CheckPhyState(Ptr< WifiNetDevice > device, WifiPhyState expectedState)
Check if the Phy State for a device is an expected value.
void CheckResults()
Check the results.
void NotifyPhyRxDrop(std::string context, Ptr< const Packet > p, WifiPhyRxfailureReason reason)
Notify Phy receive drops.
NetDeviceContainer m_staDevices
STA devices.
std::vector< WifiPhyRxfailureReason > m_dropReasonsSta1
drop reasons for STA1
void NotifyPhyRxEnd(std::string context, Ptr< const Packet > p)
Notify Phy receive ends.
void SendOnePacket(Ptr< WifiNetDevice > tx_dev, Ptr< WifiNetDevice > rx_dev, uint32_t payloadSize)
Send one packet function.
std::vector< WifiPhyRxfailureReason > m_dropReasonsSta2
drop reasons for STA2
NetDeviceContainer m_apDevices
AP devices.
unsigned int m_numAp1PacketsSent
number of sent packets from AP1
double m_txPowerDbm
configured transmit power in dBm
std::vector< WifiPhyRxfailureReason > m_dropReasonsAp1
drop reasons for AP1
unsigned int m_numSta1PacketsReceived
number of received packets from STA1
unsigned int m_numAp1PacketsReceived
number of received packets from AP1
double m_obssPdLevelDbm
OBSS-PD level in dBm.
double m_expectedTxPowerDbm
expected transmit power in dBm
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:41
Helper class used to assign positions and mobility models to nodes.
Keep track of the current position and velocity of an object.
holds a vector of ns3::NetDevice pointers
uint32_t GetN(void) const
Get the number of Ptr<NetDevice> stored in this container.
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.
uint32_t GetId(void) const
Definition: node.cc:109
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:470
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:856
Hold objects of type Ptr<T>.
Definition: pointer.h:37
Ptr< T > Get(void) const
Definition: pointer.h:201
Make it easy to create and manage PHY objects for the spectrum model.
The IEEE 802.11 SSID Information Element.
Definition: ssid.h:36
AttributeValue implementation for Ssid.
Hold variables of type string.
Definition: string.h:41
encapsulates test code
Definition: test.h:994
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
A suite of tests to run.
Definition: test.h:1188
Hold an unsigned integer type.
Definition: uinteger.h:44
helps to create WifiNetDevice objects
Definition: wifi-helper.h:323
create MAC layers for a ns3::WifiNetDevice.
bool Send(Ptr< Packet > packet, const Address &dest, uint16_t protocolNumber) override
Address GetAddress(void) const override
Ptr< WifiPhy > GetPhy(void) const
Ptr< HeConfiguration > GetHeConfiguration(void) const
Ptr< Node > GetNode(void) const override
This objects implements the PHY state machine of the Wifi device.
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:920
void Set(std::string path, const AttributeValue &value)
Definition: config.cc:839
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:287
bool TestDoubleIsEqual(const double x1, const double x2, const double epsilon)
Compare two double precision floating point numbers and declare them equal if they are within some ep...
Definition: test.cc:44
#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:141
#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:240
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1260
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1244
WifiPhyRxfailureReason
Enumeration of the possible reception failure reasons.
@ WIFI_STANDARD_80211ax
@ OBSS_PD_CCA_RESET
static uint32_t ConvertContextToNodeId(std::string context)
static InterBssTestSuite interBssTestSuite
Every class exported by the ns3 library is enclosed in the ns3 namespace.
double WToDbm(double w)
Convert from Watts to dBm.
Definition: wifi-utils.cc:43
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1648
ssid
Definition: third.py:97
channel
Definition: third.py:92
mac
Definition: third.py:96
wifi
Definition: third.py:99
mobility
Definition: third.py:107
wifiStaNodes
Definition: third.py:88
phy
Definition: third.py:93
uint32_t pktSize
packet size used for the simulation (in bytes)
Definition: wifi-bianchi.cc:89
WifiPhyState
The state of the PHY layer.
@ CCA_BUSY
The PHY layer has sense the medium busy through the CCA mechanism.
@ RX
The PHY layer is receiving a packet.
@ TX
The PHY layer is sending a packet.
@ IDLE
The PHY layer is IDLE.