A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
inter-bss-test-suite.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2018 University of Washington
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 * Authors: Sébastien Deronne <sebastien.deronne@gmail.com>
18 * Scott Carpenter <scarpenter44@windstream.net>
19 */
20
21#include "ns3/config.h"
22#include "ns3/constant-obss-pd-algorithm.h"
23#include "ns3/double.h"
24#include "ns3/he-configuration.h"
25#include "ns3/log.h"
26#include "ns3/mobility-helper.h"
27#include "ns3/multi-model-spectrum-channel.h"
28#include "ns3/pointer.h"
29#include "ns3/rng-seed-manager.h"
30#include "ns3/spectrum-wifi-helper.h"
31#include "ns3/ssid.h"
32#include "ns3/string.h"
33#include "ns3/test.h"
34#include "ns3/uinteger.h"
35#include "ns3/wifi-net-device.h"
36#include "ns3/wifi-utils.h"
37
38using namespace ns3;
39
40NS_LOG_COMPONENT_DEFINE("InterBssTestSuite");
41
42static uint32_t
43ConvertContextToNodeId(std::string context)
44{
45 std::string sub = context.substr(10);
46 uint32_t pos = sub.find("/Device");
47 uint32_t nodeId = std::stoi(sub.substr(0, pos));
48 return nodeId;
49}
50
51/**
52 * \ingroup wifi-test
53 * \ingroup tests
54 *
55 * \brief Wifi Test
56 *
57 * This test case tests the transmission of inter-BSS cases
58 * and verify behavior of 11ax OBSS_PD spatial reuse.
59 *
60 * The topology for this test case is made of three networks, each with one AP and one STA:
61 *
62 * AP --d1-- STA1 --d2-- AP2 --d3-- STA2 --d4-- AP3 --d5-- STA3
63 * TX1 RX1 TX2 RX2 TX3 RX3
64 *
65 * Main parameters:
66 * OBSS_PD level = -72dbm
67 * Received Power by TX1 from TX2 = [-62dbm, -82dbm]
68 * Received SINR by RX1 from TX1 > 3dB (enough to pass MCS0 reception)
69 * Received SINR by RX2 from TX2 > 3dB (enough to pass MCS0 reception)
70 * Received SINR by RX3 from TX3 > 3dB (enough to pass MCS0 reception)
71 * TX1/RX1 BSS Color = 1
72 * TX2/RX2 transmission PPDU BSS Color = [2 0]
73 * TX3/RX3 BSS color = 3 (BSS 3 only used to test some corner cases)
74 * PHY = 11ax, MCS 0, 80MHz
75 */
76
78{
79 public:
80 /**
81 * Constructor
82 *
83 * \param standard The standard to use for the test
84 */
87
88 void DoRun() override;
89
90 private:
91 /**
92 * Send one packet function
93 * \param tx_dev the transmitting device
94 * \param rx_dev the receiving device
95 * \param payloadSize the payload size
96 */
97 void SendOnePacket(Ptr<WifiNetDevice> tx_dev, Ptr<WifiNetDevice> rx_dev, uint32_t payloadSize);
98
99 /**
100 * Allocate the node positions
101 * \param d1 distance d1 (in meters)
102 * \param d2 distance d2 (in meters)
103 * \param d3 distance d3 (in meters)
104 * \param d4 distance d4 (in meters)
105 * \param d5 distance d5 (in meters)
106 * \return the node positions
107 */
109 double d2,
110 double d3,
111 double d4,
112 double d5);
113
114 /**
115 * Set the expected transmit power in dBm
116 * \param txPowerDbm the transmit power in dBm
117 */
118 void SetExpectedTxPower(double txPowerDbm);
119
120 /**
121 * Setup the simulation
122 */
123 void SetupSimulation();
124
125 /**
126 * Check the results
127 */
128 void CheckResults();
129
130 /**
131 * Reset the results
132 */
133 void ResetResults();
134
135 /**
136 * Clear the drop reasons
137 */
138 void ClearDropReasons();
139
140 /**
141 * Run one function
142 */
143 void RunOne();
144
145 /**
146 * Check if the Phy State for a device is an expected value
147 * \param device the device to check
148 * \param expectedState the expected PHY state
149 */
150 void CheckPhyState(Ptr<WifiNetDevice> device, WifiPhyState expectedState);
151
152 /**
153 * Check if the Phy drop reasons for a device are as expected
154 * \param device the device to check
155 * \param expectedDropReasons the expected PHY drop reasons
156 */
158 std::vector<WifiPhyRxfailureReason> expectedDropReasons);
159
160 /**
161 * Notify Phy transmit begin
162 * \param context the context
163 * \param p the packet
164 * \param txPowerW the tx power
165 */
166 void NotifyPhyTxBegin(std::string context, Ptr<const Packet> p, double txPowerW);
167
168 /**
169 * Notify Phy receive ends
170 * \param context the context
171 * \param p the packet
172 */
173 void NotifyPhyRxEnd(std::string context, Ptr<const Packet> p);
174
175 /**
176 * Notify Phy receive drops
177 * \param context the context
178 * \param p the packet
179 * \param reason the reason why it was dropped
180 */
181 void NotifyPhyRxDrop(std::string context, Ptr<const Packet> p, WifiPhyRxfailureReason reason);
182
183 unsigned int m_numSta1PacketsSent; ///< number of sent packets from STA1
184 unsigned int m_numSta2PacketsSent; ///< number of sent packets from STA2
185 unsigned int m_numAp1PacketsSent; ///< number of sent packets from AP1
186 unsigned int m_numAp2PacketsSent; ///< number of sent packets from AP2
187
188 unsigned int m_numSta1PacketsReceived; ///< number of received packets from STA1
189 unsigned int m_numSta2PacketsReceived; ///< number of received packets from STA2
190 unsigned int m_numAp1PacketsReceived; ///< number of received packets from AP1
191 unsigned int m_numAp2PacketsReceived; ///< number of received packets from AP2
192
193 std::vector<WifiPhyRxfailureReason> m_dropReasonsSta1; ///< drop reasons for STA1
194 std::vector<WifiPhyRxfailureReason> m_dropReasonsSta2; ///< drop reasons for STA2
195 std::vector<WifiPhyRxfailureReason> m_dropReasonsAp1; ///< drop reasons for AP1
196 std::vector<WifiPhyRxfailureReason> m_dropReasonsAp2; ///< drop reasons for AP2
197
198 unsigned int m_payloadSize1; ///< size in bytes of packet payload in BSS 1
199 unsigned int m_payloadSize2; ///< size in bytes of packet payload in BSS 2
200 unsigned int m_payloadSize3; ///< size in bytes of packet payload in BSS 3
201
204
205 double m_txPowerDbm; ///< configured transmit power in dBm
206 double m_obssPdLevelDbm; ///< OBSS-PD level in dBm
207 double m_obssRxPowerDbm; ///< forced RX power in dBm for OBSS
208 double m_expectedTxPowerDbm; ///< expected transmit power in dBm
209
210 uint8_t m_bssColor1; ///< color for BSS 1
211 uint8_t m_bssColor2; ///< color for BSS 2
212 uint8_t m_bssColor3; ///< color for BSS 3
213
214 WifiStandard m_standard; ///< the standard to use for the test
215};
216
218 : TestCase("InterBssConstantObssPd"),
219 m_numSta1PacketsSent(0),
220 m_numSta2PacketsSent(0),
221 m_numAp1PacketsSent(0),
222 m_numAp2PacketsSent(0),
223 m_numSta1PacketsReceived(0),
224 m_numSta2PacketsReceived(0),
225 m_numAp1PacketsReceived(0),
226 m_numAp2PacketsReceived(0),
227 m_payloadSize1(1000),
228 m_payloadSize2(1500),
229 m_payloadSize3(2000),
230 m_txPowerDbm(15),
231 m_obssPdLevelDbm(-72),
232 m_obssRxPowerDbm(-82),
233 m_expectedTxPowerDbm(15),
234 m_bssColor1(1),
235 m_bssColor2(2),
236 m_bssColor3(3),
237 m_standard(standard)
238{
239}
240
242{
244}
245
248 double d2,
249 double d3,
250 double d4,
251 double d5)
252{
253 Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
254 positionAlloc->Add(Vector(0.0, 0.0, 0.0)); // AP1
255 positionAlloc->Add(Vector(d1 + d2, 0.0, 0.0)); // AP2
256 positionAlloc->Add(Vector(d1 + d2 + d3 + d4, 0.0, 0.0)); // AP3
257 positionAlloc->Add(Vector(d1, 0.0, 0.0)); // STA1
258 positionAlloc->Add(Vector(d1 + d2 + d3, 0.0, 0.0)); // STA2
259 positionAlloc->Add(Vector(d1 + d2 + d3 + d4 + d5, 0.0, 0.0)); // STA3
260 return positionAlloc;
261}
262
263void
265{
266 Ptr<WifiNetDevice> ap_device1 = DynamicCast<WifiNetDevice>(m_apDevices.Get(0));
267 Ptr<WifiNetDevice> ap_device2 = DynamicCast<WifiNetDevice>(m_apDevices.Get(1));
268 Ptr<WifiNetDevice> ap_device3 = DynamicCast<WifiNetDevice>(m_apDevices.Get(2));
269 Ptr<WifiNetDevice> sta_device1 = DynamicCast<WifiNetDevice>(m_staDevices.Get(0));
270 Ptr<WifiNetDevice> sta_device2 = DynamicCast<WifiNetDevice>(m_staDevices.Get(1));
271 Ptr<WifiNetDevice> sta_device3 = DynamicCast<WifiNetDevice>(m_staDevices.Get(2));
272
273 bool expectFilter = (m_bssColor1 != 0) && (m_bssColor2 != 0);
274 bool expectPhyReset = expectFilter && (m_obssPdLevelDbm >= m_obssRxPowerDbm);
275 std::vector<WifiPhyRxfailureReason> dropReasons;
276 WifiPhyState stateDuringPayloadNeighboringBss =
277 expectFilter ? WifiPhyState::CCA_BUSY : WifiPhyState::RX;
278 if (expectFilter)
279 {
280 dropReasons.push_back(FILTERED);
281 }
282 if (expectPhyReset)
283 {
284 dropReasons.push_back(OBSS_PD_CCA_RESET);
285 }
286
287 // In order to have all ADDBA handshakes established, each AP and STA sends a packet.
288
291 this,
292 ap_device1,
293 sta_device1,
297 this,
298 sta_device1,
299 ap_device1,
303 this,
304 ap_device2,
305 sta_device2,
309 this,
310 sta_device2,
311 ap_device2,
315 this,
316 ap_device3,
317 sta_device3,
321 this,
322 sta_device3,
323 ap_device3,
325
326 // We test PHY state and verify whether a CCA reset did occur.
327
328 // AP2 sends a packet 0.5s later.
332 this,
333 ap_device2,
334 sta_device2,
338 this,
339 ap_device2,
340 WifiPhyState::TX);
341 // All other PHYs should have stay idle until 4us (preamble detection time).
344 this,
345 sta_device1,
346 WifiPhyState::IDLE);
349 this,
350 sta_device2,
351 WifiPhyState::IDLE);
354 this,
355 ap_device1,
356 WifiPhyState::IDLE);
357 // All PHYs should be receiving the PHY header (i.e. PHY state is CCA_BUSY) if preamble has been
358 // detected (always the case in this test).
361 this,
362 sta_device1,
363 WifiPhyState::CCA_BUSY);
366 this,
367 sta_device2,
368 WifiPhyState::CCA_BUSY);
371 this,
372 ap_device1,
373 WifiPhyState::CCA_BUSY);
374 // PHYs of AP1 and STA1 should be idle after HE-SIG-A if they were reset by OBSS_PD SR,
375 // otherwise they should be CCA_busy until beginning of payload.
378 this,
379 sta_device1,
380 dropReasons);
383 this,
384 sta_device1,
385 expectPhyReset ? WifiPhyState::IDLE : WifiPhyState::CCA_BUSY);
388 this,
389 ap_device1,
390 dropReasons);
393 this,
394 ap_device1,
395 expectPhyReset ? WifiPhyState::IDLE : WifiPhyState::CCA_BUSY);
396 // PHYs of AP1 and STA1 should be idle if they were reset by OBSS_PD SR, otherwise they should
397 // be CCA_busy/Rx (since filtered/not filtered, resp.).
400 this,
401 sta_device1,
402 expectPhyReset ? WifiPhyState::IDLE : stateDuringPayloadNeighboringBss);
405 this,
406 ap_device1,
407 expectPhyReset ? WifiPhyState::IDLE : stateDuringPayloadNeighboringBss);
408 // STA2 should be receiving
411 this,
412 sta_device2,
413 WifiPhyState::RX);
414
415 // We test whether two networks can transmit simultaneously, and whether transmit power
416 // restrictions are applied.
417
418 // AP2 sends another packet 0.1s later.
422 this,
423 ap_device2,
424 sta_device2,
426 // STA1 sends a packet 42us later (i.e. right after HE-SIG-A of AP2). Even though AP2 is still
427 // transmitting, STA1 can transmit simultaneously if it's PHY was reset by OBSS_PD SR.
430 this,
431 sta_device1,
432 ap_device1,
434 if (expectPhyReset)
435 {
436 // In this case, we check the TX power is restricted (and set the expected value slightly
437 // before transmission should occur)
438 double expectedTxPower = std::min(m_txPowerDbm, 21 - (m_obssPdLevelDbm + 82));
441 this,
442 expectedTxPower);
443 }
444 // Check simultaneous transmissions
447 this,
448 ap_device2,
449 WifiPhyState::TX);
452 this,
453 sta_device1,
454 dropReasons);
457 this,
458 sta_device1,
459 expectPhyReset ? WifiPhyState::TX : stateDuringPayloadNeighboringBss);
462 this,
463 sta_device2,
464 WifiPhyState::RX);
467 this,
468 ap_device1,
469 dropReasons);
472 this,
473 ap_device1,
474 stateDuringPayloadNeighboringBss);
477 this,
478 ap_device1,
479 expectPhyReset ? WifiPhyState::RX : stateDuringPayloadNeighboringBss);
480
481 // AP2 sends another packet 0.1s later, and STA1 wanting to send a packet during the payload of
482 // the former.
486 this,
490 this,
491 ap_device2,
492 sta_device2,
494 // STA1 sends a packet 90us later (i.e. during payload of AP2). Even though AP2 is still
495 // transmitting, STA1 can transmit simultaneously if it's PHY was reset by OBSS_PD SR.
498 this,
499 sta_device1,
500 ap_device1,
502 if (expectPhyReset)
503 {
504 // In this case, we check the TX power is restricted (and set the expected value slightly
505 // before transmission should occur)
506 double expectedTxPower = std::min(m_txPowerDbm, 21 - (m_obssPdLevelDbm + 82));
509 this,
510 expectedTxPower);
511 }
512 // Check simultaneous transmissions
515 this,
516 ap_device2,
517 WifiPhyState::TX);
520 this,
521 sta_device1,
522 dropReasons);
525 this,
526 sta_device1,
527 expectPhyReset ? WifiPhyState::TX : stateDuringPayloadNeighboringBss);
530 this,
531 sta_device2,
532 WifiPhyState::RX);
535 this,
536 ap_device1,
537 dropReasons);
540 this,
541 ap_device1,
542 stateDuringPayloadNeighboringBss);
545 this,
546 ap_device1,
547 expectPhyReset ? WifiPhyState::RX : stateDuringPayloadNeighboringBss);
548
549 // Verify transmit power restrictions are not applied if access to the channel is requested
550 // after ignored OBSS transmissions.
551
554 this,
556 // AP2 sends another packet 0.1s later. Power restriction should not be applied.
559 this,
560 ap_device2,
561 sta_device2,
563 // STA1 sends a packet 0.1s later. Power restriction should not be applied.
566 this,
567 sta_device1,
568 ap_device1,
570
571 // Verify a scenario that involves 3 networks in order to verify corner cases for transmit power
572 // restrictions. First, there is a transmission on network 2 from STA to AP, followed by a
573 // response from AP to STA. During that time, the STA on network 1 has a packet to send and
574 // request access to the channel. If a CCA reset occurred, it starts deferring while
575 // transmissions are ongoing from network 2. Before its backoff expires, a transmission on
576 // network 3 occurs, also eventually triggering another CCA reset (depending on the scenario
577 // that is being run). This test checks whether this sequence preserves transmit power
578 // restrictions if CCA resets occurred, since STA 1 has been deferring during ignored OBSS
579 // transmissions.
580
583 this,
584 sta_device2,
585 ap_device2,
586 m_payloadSize2 / 10);
589 this,
590 ap_device2,
591 sta_device2,
592 m_payloadSize2 / 10);
595 this,
596 ap_device1,
597 sta_device1,
598 m_payloadSize1 / 10);
601 this,
602 ap_device3,
603 sta_device3,
604 m_payloadSize3 / 10);
605 if (expectPhyReset)
606 {
607 // In this case, we check the TX power is restricted (and set the expected value slightly
608 // before transmission should occur)
609 double expectedTxPower = std::min(m_txPowerDbm, 21 - (m_obssPdLevelDbm + 82));
612 this,
613 expectedTxPower);
614 }
615
617}
618
619void
621{
632}
633
634void
636{
637 m_dropReasonsSta1.clear();
638 m_dropReasonsSta2.clear();
639 m_dropReasonsAp1.clear();
640 m_dropReasonsAp2.clear();
641}
642
643void
645{
647 4,
648 "The number of packets sent by STA1 is not correct!");
650 2,
651 "The number of packets sent by STA2 is not correct!");
653 2,
654 "The number of packets sent by AP1 is not correct!");
656 6,
657 "The number of packets sent by AP2 is not correct!");
659 2,
660 "The number of packets received by STA1 is not correct!");
662 6,
663 "The number of packets received by STA2 is not correct!");
665 4,
666 "The number of packets received by AP1 is not correct!");
668 2,
669 "The number of packets received by AP2 is not correct!");
670}
671
672void
675 double txPowerW)
676{
677 uint32_t idx = ConvertContextToNodeId(context);
678 uint32_t pktSize = p->GetSize() - 38;
679 if ((idx == 0) && ((pktSize == m_payloadSize1) || (pktSize == (m_payloadSize1 / 10))))
680 {
683 true,
684 "Tx power is not correct!");
685 }
686 else if ((idx == 1) && ((pktSize == m_payloadSize2) || (pktSize == (m_payloadSize2 / 10))))
687 {
690 true,
691 "Tx power is not correct!");
692 }
693 else if ((idx == 3) && ((pktSize == m_payloadSize1) || (pktSize == (m_payloadSize1 / 10))))
694 {
697 true,
698 "Tx power is not correct!");
699 }
700 else if ((idx == 4) && ((pktSize == m_payloadSize2) || (pktSize == (m_payloadSize2 / 10))))
701 {
704 true,
705 "Tx power is not correct!");
706 }
707}
708
709void
711{
712 uint32_t idx = ConvertContextToNodeId(context);
713 uint32_t pktSize = p->GetSize() - 38;
714 if ((idx == 0) && ((pktSize == m_payloadSize1) || (pktSize == (m_payloadSize1 / 10))))
715 {
717 }
718 else if ((idx == 1) && ((pktSize == m_payloadSize2) || (pktSize == (m_payloadSize2 / 10))))
719 {
721 }
722 else if ((idx == 3) && ((pktSize == m_payloadSize1) || (pktSize == (m_payloadSize1 / 10))))
723 {
725 }
726 else if ((idx == 4) && ((pktSize == m_payloadSize2) || (pktSize == (m_payloadSize2 / 10))))
727 {
729 }
730}
731
732void
736{
737 uint32_t idx = ConvertContextToNodeId(context);
738 uint32_t pktSize = p->GetSize() - 38;
739 if ((idx == 0) && ((pktSize != m_payloadSize1) && (pktSize != (m_payloadSize1 / 10))))
740 {
741 m_dropReasonsSta1.push_back(reason);
742 }
743 else if ((idx == 1) && ((pktSize != m_payloadSize2) && (pktSize != (m_payloadSize2 / 10))))
744 {
745 m_dropReasonsSta2.push_back(reason);
746 }
747 else if ((idx == 3) && ((pktSize != m_payloadSize1) && (pktSize != (m_payloadSize1 / 10))))
748 {
749 m_dropReasonsAp1.push_back(reason);
750 }
751 else if ((idx == 4) && ((pktSize != m_payloadSize2) && (pktSize != (m_payloadSize2 / 10))))
752 {
753 m_dropReasonsAp2.push_back(reason);
754 }
755}
756
757void
759 Ptr<WifiNetDevice> rx_dev,
760 uint32_t payloadSize)
761{
762 Ptr<Packet> p = Create<Packet>(payloadSize);
763 tx_dev->Send(p, rx_dev->GetAddress(), 1);
764}
765
766void
768{
769 m_expectedTxPowerDbm = txPowerDbm;
770}
771
772void
774{
775 WifiPhyState currentState;
776 PointerValue ptr;
777 Ptr<WifiPhy> phy = DynamicCast<WifiPhy>(device->GetPhy());
778 phy->GetAttribute("State", ptr);
779 Ptr<WifiPhyStateHelper> state = DynamicCast<WifiPhyStateHelper>(ptr.Get<WifiPhyStateHelper>());
780 currentState = state->GetState();
781 NS_TEST_ASSERT_MSG_EQ(currentState,
782 expectedState,
783 "PHY State " << currentState << " does not match expected state "
784 << expectedState << " at " << Simulator::Now());
785}
786
787void
789 Ptr<WifiNetDevice> device,
790 std::vector<WifiPhyRxfailureReason> expectedDropReasons)
791{
792 std::vector<WifiPhyRxfailureReason> currentDropReasons;
793 uint32_t nodeId = device->GetNode()->GetId();
794 switch (nodeId)
795 {
796 case 0: // STA1
797 currentDropReasons = m_dropReasonsSta1;
798 break;
799 case 1: // STA2
800 currentDropReasons = m_dropReasonsSta2;
801 break;
802 case 3: // AP1
803 currentDropReasons = m_dropReasonsAp1;
804 break;
805 case 4: // AP2
806 currentDropReasons = m_dropReasonsAp2;
807 break;
808 default: // others, no attribute
809 return;
810 }
811 NS_TEST_ASSERT_MSG_EQ(currentDropReasons.size(),
812 expectedDropReasons.size(),
813 "Number of drop reasons "
814 << currentDropReasons.size() << " does not match expected one "
815 << expectedDropReasons.size() << " at " << Simulator::Now());
816 for (std::size_t i = 0; i < currentDropReasons.size(); ++i)
817 {
818 NS_TEST_ASSERT_MSG_EQ(currentDropReasons[i],
819 expectedDropReasons[i],
820 "Drop reason " << i << ": " << currentDropReasons[i]
821 << " does not match expected reason "
822 << expectedDropReasons[i] << " at "
823 << Simulator::Now());
824 }
825}
826
827void
829{
832 int64_t streamNumber = 50;
833
834 Config::Set("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/BE_MaxAmpduSize",
835 UintegerValue(0));
836
837 ResetResults();
838
839 NodeContainer wifiStaNodes;
840 wifiStaNodes.Create(3);
841
842 NodeContainer wifiApNodes;
843 wifiApNodes.Create(3);
844
845 Ptr<MatrixPropagationLossModel> lossModel = CreateObject<MatrixPropagationLossModel>();
846 lossModel->SetDefaultLoss(
847 m_txPowerDbm - m_obssRxPowerDbm); // Force received RSSI to be equal to m_obssRxPowerDbm
848
850 phy.DisablePreambleDetectionModel();
851 phy.SetFrameCaptureModel("ns3::SimpleFrameCaptureModel");
852 Ptr<MultiModelSpectrumChannel> channel = CreateObject<MultiModelSpectrumChannel>();
853 channel->SetPropagationDelayModel(CreateObject<ConstantSpeedPropagationDelayModel>());
854 channel->AddPropagationLossModel(lossModel);
855 phy.SetChannel(channel);
856 phy.Set("TxPowerStart", DoubleValue(m_txPowerDbm));
857 phy.Set("TxPowerEnd", DoubleValue(m_txPowerDbm));
858 phy.Set("ChannelSettings", StringValue("{36, 20, BAND_5GHZ, 0}"));
859
860 WifiHelper wifi;
861 wifi.SetStandard(m_standard);
862 wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager",
863 "DataMode",
864 StringValue("HeMcs5"),
865 "ControlMode",
866 StringValue("HeMcs0"));
867
868 wifi.SetObssPdAlgorithm("ns3::ConstantObssPdAlgorithm",
869 "ObssPdLevel",
871
872 WifiMacHelper mac;
873 Ssid ssid = Ssid("ns-3-ssid");
874 mac.SetType("ns3::StaWifiMac", "Ssid", SsidValue(ssid));
875 m_staDevices = wifi.Install(phy, mac, wifiStaNodes);
876
877 // Assign fixed streams to random variables in use
878 wifi.AssignStreams(m_staDevices, streamNumber);
879
880 mac.SetType("ns3::ApWifiMac", "Ssid", SsidValue(ssid));
881 m_apDevices = wifi.Install(phy, mac, wifiApNodes);
882
883 // Assign fixed streams to random variables in use
884 wifi.AssignStreams(m_apDevices, streamNumber);
885
886 for (uint32_t i = 0; i < m_apDevices.GetN(); i++)
887 {
888 Ptr<WifiNetDevice> device = DynamicCast<WifiNetDevice>(m_apDevices.Get(i));
889 Ptr<HeConfiguration> heConfiguration = device->GetHeConfiguration();
890 if (i == 0)
891 {
892 heConfiguration->SetAttribute("BssColor", UintegerValue(m_bssColor1));
893 }
894 else if (i == 1)
895 {
896 heConfiguration->SetAttribute("BssColor", UintegerValue(m_bssColor2));
897 }
898 else
899 {
900 heConfiguration->SetAttribute("BssColor", UintegerValue(m_bssColor3));
901 }
902 }
903
904 MobilityHelper mobility;
906 10,
907 50,
908 10,
909 50,
910 10); // distances do not really matter since we set RSSI per TX-RX pair to have full control
911 mobility.SetPositionAllocator(positionAlloc);
912 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
913 mobility.Install(wifiApNodes);
914 mobility.Install(wifiStaNodes);
915
916 lossModel->SetLoss(wifiStaNodes.Get(0)->GetObject<MobilityModel>(),
917 wifiApNodes.Get(0)->GetObject<MobilityModel>(),
918 m_txPowerDbm + 30); // Low attenuation for IBSS transmissions
919 lossModel->SetLoss(wifiStaNodes.Get(1)->GetObject<MobilityModel>(),
920 wifiApNodes.Get(1)->GetObject<MobilityModel>(),
921 m_txPowerDbm + 30); // Low attenuation for IBSS transmissions
922 lossModel->SetLoss(wifiStaNodes.Get(2)->GetObject<MobilityModel>(),
923 wifiApNodes.Get(2)->GetObject<MobilityModel>(),
924 m_txPowerDbm + 30); // Low attenuation for IBSS transmissions
925
926 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyTxBegin",
928 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyRxEnd",
930 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyRxDrop",
932
934
937
938 CheckResults();
939}
940
941void
943{
944 // Test case 1: CCA CS Threshold = m_obssRxPowerDbm < m_obssPdLevelDbm
945 m_obssPdLevelDbm = -72;
946 m_obssRxPowerDbm = -82;
947 m_bssColor1 = 1;
948 m_bssColor2 = 2;
949 m_bssColor3 = 3;
950 RunOne();
951
952 // Test case 2: CCA CS Threshold < m_obssPdLevelDbm < m_obssRxPowerDbm
953 m_obssPdLevelDbm = -72;
954 m_obssRxPowerDbm = -62;
955 m_bssColor1 = 1;
956 m_bssColor2 = 2;
957 m_bssColor3 = 3;
958 RunOne();
959
960 // Test case 3: CCA CS Threshold < m_obssPdLevelDbm = m_obssRxPowerDbm
961 m_obssPdLevelDbm = -72;
962 m_obssRxPowerDbm = -72;
963 m_bssColor1 = 1;
964 m_bssColor2 = 2;
965 m_bssColor3 = 3;
966 RunOne();
967
968 // Test case 4: CCA CS Threshold = m_obssRxPowerDbm < m_obssPdLevelDbm with BSS color 2 and 3
969 // set to 0
970 m_obssPdLevelDbm = -72;
971 m_obssRxPowerDbm = -82;
972 m_bssColor1 = 1;
973 m_bssColor2 = 0;
974 m_bssColor3 = 0;
975 RunOne();
976
977 // Test case 5: CCA CS Threshold = m_obssRxPowerDbm < m_obssPdLevelDbm with BSS color 1 set to 0
978 m_obssPdLevelDbm = -72;
979 m_obssRxPowerDbm = -82;
980 m_bssColor1 = 0;
981 m_bssColor2 = 2;
982 m_bssColor3 = 3;
983 RunOne();
984}
985
986/**
987 * \ingroup wifi-test
988 * \ingroup tests
989 *
990 * \brief Inter BSS Test Suite
991 */
992
994{
995 public:
997};
998
1000 : TestSuite("wifi-inter-bss", Type::UNIT)
1001{
1003 TestCase::Duration::QUICK);
1005 TestCase::Duration::QUICK);
1006}
1007
1008// Do not forget to allocate an instance of this TestSuite
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 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.
void DoRun() override
Implementation to actually run this TestCase.
TestInterBssConstantObssPdAlgo(WifiStandard standard)
Constructor.
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
WifiStandard m_standard
the standard to use for the test
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:42
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() 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.
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:522
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
static void SetRun(uint64_t run)
Set the run number of simulation.
static void SetSeed(uint32_t seed)
Set the seed.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:571
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:142
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
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
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.
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
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.
This objects implements the PHY state machine of the Wifi device.
void Connect(std::string path, const CallbackBase &cb)
Definition: config.cc:978
void Set(std::string path, const AttributeValue &value)
Definition: config.cc:880
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
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:45
#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_EXPECT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report if not.
Definition: test.h:252
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1343
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1319
WifiStandard
Identifies the IEEE 802.11 specifications that a Wifi device can be configured to use.
WifiPhyRxfailureReason
Enumeration of the possible reception failure reasons.
@ WIFI_STANDARD_80211be
@ 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.
WifiPhyState
The state of the PHY layer.
double WToDbm(double w)
Convert from Watts to dBm.
Definition: wifi-utils.cc:46
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:706
uint32_t pktSize
packet size used for the simulation (in bytes)