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 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Authors: Sébastien Deronne <sebastien.deronne@gmail.com>
7 * Scott Carpenter <scarpenter44@windstream.net>
8 */
9
10#include "ns3/config.h"
11#include "ns3/constant-obss-pd-algorithm.h"
12#include "ns3/double.h"
13#include "ns3/he-configuration.h"
14#include "ns3/log.h"
15#include "ns3/mobility-helper.h"
16#include "ns3/multi-model-spectrum-channel.h"
17#include "ns3/pointer.h"
18#include "ns3/rng-seed-manager.h"
19#include "ns3/spectrum-wifi-helper.h"
20#include "ns3/ssid.h"
21#include "ns3/string.h"
22#include "ns3/test.h"
23#include "ns3/uinteger.h"
24#include "ns3/wifi-net-device.h"
25#include "ns3/wifi-utils.h"
26
27using namespace ns3;
28
29NS_LOG_COMPONENT_DEFINE("InterBssTestSuite");
30
31static uint32_t
32ConvertContextToNodeId(std::string context)
33{
34 std::string sub = context.substr(10);
35 uint32_t pos = sub.find("/Device");
36 uint32_t nodeId = std::stoi(sub.substr(0, pos));
37 return nodeId;
38}
39
40/**
41 * @ingroup wifi-test
42 * @ingroup tests
43 *
44 * @brief Wifi Test
45 *
46 * This test case tests the transmission of inter-BSS cases
47 * and verify behavior of 11ax OBSS_PD spatial reuse.
48 *
49 * The topology for this test case is made of three networks, each with one AP and one STA:
50 *
51 * AP --d1-- STA1 --d2-- AP2 --d3-- STA2 --d4-- AP3 --d5-- STA3
52 * TX1 RX1 TX2 RX2 TX3 RX3
53 *
54 * Main parameters:
55 * OBSS_PD level = -72dbm
56 * Received Power by TX1 from TX2 = [-62dbm, -82dbm]
57 * Received SINR by RX1 from TX1 > 3dB (enough to pass MCS0 reception)
58 * Received SINR by RX2 from TX2 > 3dB (enough to pass MCS0 reception)
59 * Received SINR by RX3 from TX3 > 3dB (enough to pass MCS0 reception)
60 * TX1/RX1 BSS Color = 1
61 * TX2/RX2 transmission PPDU BSS Color = [2 0]
62 * TX3/RX3 BSS color = 3 (BSS 3 only used to test some corner cases)
63 * PHY = 11ax, MCS 0, 80MHz
64 */
65
67{
68 public:
69 /**
70 * Constructor
71 *
72 * @param standard The standard to use for the test
73 */
76
77 void DoRun() override;
78
79 private:
80 /**
81 * Send one packet function
82 * @param tx_dev the transmitting device
83 * @param rx_dev the receiving device
84 * @param payloadSize the payload size
85 */
86 void SendOnePacket(Ptr<WifiNetDevice> tx_dev, Ptr<WifiNetDevice> rx_dev, uint32_t payloadSize);
87
88 /**
89 * Allocate the node positions
90 * @param d1 distance d1
91 * @param d2 distance d2
92 * @param d3 distance d3
93 * @param d4 distance d4
94 * @param d5 distance d5
95 * @return the node positions
96 */
98 meter_u d2,
99 meter_u d3,
100 meter_u d4,
101 meter_u d5);
102
103 /**
104 * Set the expected transmit power
105 * @param txPower the transmit power
106 */
107 void SetExpectedTxPower(dBm_u txPower);
108
109 /**
110 * Setup the simulation
111 */
112 void SetupSimulation();
113
114 /**
115 * Check the results
116 */
117 void CheckResults();
118
119 /**
120 * Reset the results
121 */
122 void ResetResults();
123
124 /**
125 * Clear the drop reasons
126 */
127 void ClearDropReasons();
128
129 /**
130 * Run one function
131 */
132 void RunOne();
133
134 /**
135 * Check if the Phy State for a device is an expected value
136 * @param device the device to check
137 * @param expectedState the expected PHY state
138 */
139 void CheckPhyState(Ptr<WifiNetDevice> device, WifiPhyState expectedState);
140
141 /**
142 * Check if the Phy drop reasons for a device are as expected
143 * @param device the device to check
144 * @param expectedDropReasons the expected PHY drop reasons
145 */
147 std::vector<WifiPhyRxfailureReason> expectedDropReasons);
148
149 /**
150 * Notify Phy transmit begin
151 * @param context the context
152 * @param p the packet
153 * @param txPowerW the tx power
154 */
155 void NotifyPhyTxBegin(std::string context, Ptr<const Packet> p, double txPowerW);
156
157 /**
158 * Notify Phy receive ends
159 * @param context the context
160 * @param p the packet
161 */
162 void NotifyPhyRxEnd(std::string context, Ptr<const Packet> p);
163
164 /**
165 * Notify Phy receive drops
166 * @param context the context
167 * @param p the packet
168 * @param reason the reason why it was dropped
169 */
170 void NotifyPhyRxDrop(std::string context, Ptr<const Packet> p, WifiPhyRxfailureReason reason);
171
172 unsigned int m_numSta1PacketsSent; ///< number of sent packets from STA1
173 unsigned int m_numSta2PacketsSent; ///< number of sent packets from STA2
174 unsigned int m_numAp1PacketsSent; ///< number of sent packets from AP1
175 unsigned int m_numAp2PacketsSent; ///< number of sent packets from AP2
176
177 unsigned int m_numSta1PacketsReceived; ///< number of received packets from STA1
178 unsigned int m_numSta2PacketsReceived; ///< number of received packets from STA2
179 unsigned int m_numAp1PacketsReceived; ///< number of received packets from AP1
180 unsigned int m_numAp2PacketsReceived; ///< number of received packets from AP2
181
182 std::vector<WifiPhyRxfailureReason> m_dropReasonsSta1; ///< drop reasons for STA1
183 std::vector<WifiPhyRxfailureReason> m_dropReasonsSta2; ///< drop reasons for STA2
184 std::vector<WifiPhyRxfailureReason> m_dropReasonsAp1; ///< drop reasons for AP1
185 std::vector<WifiPhyRxfailureReason> m_dropReasonsAp2; ///< drop reasons for AP2
186
187 unsigned int m_payloadSize1; ///< size in bytes of packet payload in BSS 1
188 unsigned int m_payloadSize2; ///< size in bytes of packet payload in BSS 2
189 unsigned int m_payloadSize3; ///< size in bytes of packet payload in BSS 3
190
193
194 dBm_u m_txPower; ///< configured transmit power
195 dBm_u m_obssPdLevel; ///< OBSS-PD level
196 dBm_u m_obssRxPower; ///< forced RX power for OBSS
197 dBm_u m_expectedTxPower; ///< expected transmit power
198
199 uint8_t m_bssColor1; ///< color for BSS 1
200 uint8_t m_bssColor2; ///< color for BSS 2
201 uint8_t m_bssColor3; ///< color for BSS 3
202
203 WifiStandard m_standard; ///< the standard to use for the test
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_txPower(dBm_u{15}),
220 m_obssPdLevel(dBm_u{-72}),
221 m_obssRxPower(dBm_u{-82}),
222 m_expectedTxPower(dBm_u{15}),
223 m_bssColor1(1),
224 m_bssColor2(2),
225 m_bssColor3(3),
226 m_standard(standard)
227{
228}
229
234
237 meter_u d2,
238 meter_u d3,
239 meter_u d4,
240 meter_u d5)
241{
243 positionAlloc->Add(Vector(0.0, 0.0, 0.0)); // AP1
244 positionAlloc->Add(Vector(d1 + d2, 0.0, 0.0)); // AP2
245 positionAlloc->Add(Vector(d1 + d2 + d3 + d4, 0.0, 0.0)); // AP3
246 positionAlloc->Add(Vector(d1, 0.0, 0.0)); // STA1
247 positionAlloc->Add(Vector(d1 + d2 + d3, 0.0, 0.0)); // STA2
248 positionAlloc->Add(Vector(d1 + d2 + d3 + d4 + d5, 0.0, 0.0)); // STA3
249 return positionAlloc;
250}
251
252void
254{
261
262 bool expectFilter = (m_bssColor1 != 0) && (m_bssColor2 != 0);
263 bool expectPhyReset = expectFilter && (m_obssPdLevel >= m_obssRxPower);
264 std::vector<WifiPhyRxfailureReason> dropReasons;
265 WifiPhyState stateDuringPayloadNeighboringBss =
266 expectFilter ? WifiPhyState::CCA_BUSY : WifiPhyState::RX;
267 if (expectFilter)
268 {
269 dropReasons.push_back(FILTERED);
270 }
271 if (expectPhyReset)
272 {
273 dropReasons.push_back(OBSS_PD_CCA_RESET);
274 }
275
276 // In order to have all ADDBA handshakes established, each AP and STA sends a packet.
277
280 this,
281 ap_device1,
282 sta_device1,
286 this,
287 sta_device1,
288 ap_device1,
292 this,
293 ap_device2,
294 sta_device2,
298 this,
299 sta_device2,
300 ap_device2,
304 this,
305 ap_device3,
306 sta_device3,
310 this,
311 sta_device3,
312 ap_device3,
314
315 // We test PHY state and verify whether a CCA reset did occur.
316
317 // AP2 sends a packet 0.5s later.
321 this,
322 ap_device2,
323 sta_device2,
327 this,
328 ap_device2,
329 WifiPhyState::TX);
330 // All other PHYs should have stay idle until 4us (preamble detection time).
333 this,
334 sta_device1,
335 WifiPhyState::IDLE);
338 this,
339 sta_device2,
340 WifiPhyState::IDLE);
343 this,
344 ap_device1,
345 WifiPhyState::IDLE);
346 // All PHYs should be receiving the PHY header (i.e. PHY state is CCA_BUSY) if preamble has been
347 // detected (always the case in this test).
350 this,
351 sta_device1,
352 WifiPhyState::CCA_BUSY);
355 this,
356 sta_device2,
357 WifiPhyState::CCA_BUSY);
360 this,
361 ap_device1,
362 WifiPhyState::CCA_BUSY);
363 // PHYs of AP1 and STA1 should be idle after HE-SIG-A if they were reset by OBSS_PD SR,
364 // otherwise they should be CCA_busy until beginning of payload.
367 this,
368 sta_device1,
369 dropReasons);
372 this,
373 sta_device1,
374 expectPhyReset ? WifiPhyState::IDLE : WifiPhyState::CCA_BUSY);
377 this,
378 ap_device1,
379 dropReasons);
382 this,
383 ap_device1,
384 expectPhyReset ? WifiPhyState::IDLE : WifiPhyState::CCA_BUSY);
385 // PHYs of AP1 and STA1 should be idle if they were reset by OBSS_PD SR, otherwise they should
386 // be CCA_busy/Rx (since filtered/not filtered, resp.).
389 this,
390 sta_device1,
391 expectPhyReset ? WifiPhyState::IDLE : stateDuringPayloadNeighboringBss);
394 this,
395 ap_device1,
396 expectPhyReset ? WifiPhyState::IDLE : stateDuringPayloadNeighboringBss);
397 // STA2 should be receiving
400 this,
401 sta_device2,
402 WifiPhyState::RX);
403
404 // We test whether two networks can transmit simultaneously, and whether transmit power
405 // restrictions are applied.
406
407 // AP2 sends another packet 0.1s later.
411 this,
412 ap_device2,
413 sta_device2,
415 // STA1 sends a packet 42us later (i.e. right after HE-SIG-A of AP2). Even though AP2 is still
416 // transmitting, STA1 can transmit simultaneously if it's PHY was reset by OBSS_PD SR.
419 this,
420 sta_device1,
421 ap_device1,
423 if (expectPhyReset)
424 {
425 // In this case, we check the TX power is restricted (and set the expected value slightly
426 // before transmission should occur)
427 const auto expectedTxPower = std::min(m_txPower, 21 - (m_obssPdLevel + 82));
430 this,
431 expectedTxPower);
432 }
433 // Check simultaneous transmissions
436 this,
437 ap_device2,
438 WifiPhyState::TX);
441 this,
442 sta_device1,
443 dropReasons);
446 this,
447 sta_device1,
448 expectPhyReset ? WifiPhyState::TX : stateDuringPayloadNeighboringBss);
451 this,
452 sta_device2,
453 WifiPhyState::RX);
456 this,
457 ap_device1,
458 dropReasons);
461 this,
462 ap_device1,
463 stateDuringPayloadNeighboringBss);
466 this,
467 ap_device1,
468 expectPhyReset ? WifiPhyState::RX : stateDuringPayloadNeighboringBss);
469
470 // AP2 sends another packet 0.1s later, and STA1 wanting to send a packet during the payload of
471 // the former.
475 this,
476 m_txPower);
479 this,
480 ap_device2,
481 sta_device2,
483 // STA1 sends a packet 90us later (i.e. during payload of AP2). Even though AP2 is still
484 // transmitting, STA1 can transmit simultaneously if it's PHY was reset by OBSS_PD SR.
487 this,
488 sta_device1,
489 ap_device1,
491 if (expectPhyReset)
492 {
493 // In this case, we check the TX power is restricted (and set the expected value slightly
494 // before transmission should occur)
495 const auto expectedTxPower = std::min(m_txPower, 21 - (m_obssPdLevel + 82));
498 this,
499 expectedTxPower);
500 }
501 // Check simultaneous transmissions
504 this,
505 ap_device2,
506 WifiPhyState::TX);
509 this,
510 sta_device1,
511 dropReasons);
514 this,
515 sta_device1,
516 expectPhyReset ? WifiPhyState::TX : stateDuringPayloadNeighboringBss);
519 this,
520 sta_device2,
521 WifiPhyState::RX);
524 this,
525 ap_device1,
526 dropReasons);
529 this,
530 ap_device1,
531 stateDuringPayloadNeighboringBss);
534 this,
535 ap_device1,
536 expectPhyReset ? WifiPhyState::RX : stateDuringPayloadNeighboringBss);
537
538 // Verify transmit power restrictions are not applied if access to the channel is requested
539 // after ignored OBSS transmissions.
540
543 this,
544 m_txPower);
545 // AP2 sends another packet 0.1s later. Power restriction should not be applied.
548 this,
549 ap_device2,
550 sta_device2,
552 // STA1 sends a packet 0.1s later. Power restriction should not be applied.
555 this,
556 sta_device1,
557 ap_device1,
559
560 // Verify a scenario that involves 3 networks in order to verify corner cases for transmit power
561 // restrictions. First, there is a transmission on network 2 from STA to AP, followed by a
562 // response from AP to STA. During that time, the STA on network 1 has a packet to send and
563 // request access to the channel. If a CCA reset occurred, it starts deferring while
564 // transmissions are ongoing from network 2. Before its backoff expires, a transmission on
565 // network 3 occurs, also eventually triggering another CCA reset (depending on the scenario
566 // that is being run). This test checks whether this sequence preserves transmit power
567 // restrictions if CCA resets occurred, since STA 1 has been deferring during ignored OBSS
568 // transmissions.
569
572 this,
573 sta_device2,
574 ap_device2,
575 m_payloadSize2 / 10);
578 this,
579 ap_device2,
580 sta_device2,
581 m_payloadSize2 / 10);
584 this,
585 ap_device1,
586 sta_device1,
587 m_payloadSize1 / 10);
590 this,
591 ap_device3,
592 sta_device3,
593 m_payloadSize3 / 10);
594 if (expectPhyReset)
595 {
596 // In this case, we check the TX power is restricted (and set the expected value slightly
597 // before transmission should occur)
598 const auto expectedTxPower = std::min(m_txPower, 21 - (m_obssPdLevel + 82));
601 this,
602 expectedTxPower);
603 }
604
606}
607
608void
622
623void
631
632void
634{
636 4,
637 "The number of packets sent by STA1 is not correct!");
639 2,
640 "The number of packets sent by STA2 is not correct!");
642 2,
643 "The number of packets sent by AP1 is not correct!");
645 6,
646 "The number of packets sent by AP2 is not correct!");
648 2,
649 "The number of packets received by STA1 is not correct!");
651 6,
652 "The number of packets received by STA2 is not correct!");
654 4,
655 "The number of packets received by AP1 is not correct!");
657 2,
658 "The number of packets received by AP2 is not correct!");
659}
660
661void
664 double txPowerW)
665{
666 uint32_t idx = ConvertContextToNodeId(context);
667 uint32_t pktSize = p->GetSize() - 38;
668 Watt_u txPower{txPowerW};
669 if ((idx == 0) && ((pktSize == m_payloadSize1) || (pktSize == (m_payloadSize1 / 10))))
670 {
673 true,
674 "Tx power is not correct!");
675 }
676 else if ((idx == 1) && ((pktSize == m_payloadSize2) || (pktSize == (m_payloadSize2 / 10))))
677 {
680 true,
681 "Tx power is not correct!");
682 }
683 else if ((idx == 3) && ((pktSize == m_payloadSize1) || (pktSize == (m_payloadSize1 / 10))))
684 {
687 true,
688 "Tx power is not correct!");
689 }
690 else if ((idx == 4) && ((pktSize == m_payloadSize2) || (pktSize == (m_payloadSize2 / 10))))
691 {
694 true,
695 "Tx power is not correct!");
696 }
697}
698
699void
701{
702 uint32_t idx = ConvertContextToNodeId(context);
703 uint32_t pktSize = p->GetSize() - 38;
704 if ((idx == 0) && ((pktSize == m_payloadSize1) || (pktSize == (m_payloadSize1 / 10))))
705 {
707 }
708 else if ((idx == 1) && ((pktSize == m_payloadSize2) || (pktSize == (m_payloadSize2 / 10))))
709 {
711 }
712 else if ((idx == 3) && ((pktSize == m_payloadSize1) || (pktSize == (m_payloadSize1 / 10))))
713 {
715 }
716 else if ((idx == 4) && ((pktSize == m_payloadSize2) || (pktSize == (m_payloadSize2 / 10))))
717 {
719 }
720}
721
722void
726{
727 uint32_t idx = ConvertContextToNodeId(context);
728 uint32_t pktSize = p->GetSize() - 38;
729 if ((idx == 0) && ((pktSize != m_payloadSize1) && (pktSize != (m_payloadSize1 / 10))))
730 {
731 m_dropReasonsSta1.push_back(reason);
732 }
733 else if ((idx == 1) && ((pktSize != m_payloadSize2) && (pktSize != (m_payloadSize2 / 10))))
734 {
735 m_dropReasonsSta2.push_back(reason);
736 }
737 else if ((idx == 3) && ((pktSize != m_payloadSize1) && (pktSize != (m_payloadSize1 / 10))))
738 {
739 m_dropReasonsAp1.push_back(reason);
740 }
741 else if ((idx == 4) && ((pktSize != m_payloadSize2) && (pktSize != (m_payloadSize2 / 10))))
742 {
743 m_dropReasonsAp2.push_back(reason);
744 }
745}
746
747void
749 Ptr<WifiNetDevice> rx_dev,
750 uint32_t payloadSize)
751{
752 Ptr<Packet> p = Create<Packet>(payloadSize);
753 tx_dev->Send(p, rx_dev->GetAddress(), 1);
754}
755
756void
761
762void
764{
765 WifiPhyState currentState;
766 PointerValue ptr;
767 Ptr<WifiPhy> phy = DynamicCast<WifiPhy>(device->GetPhy());
768 phy->GetAttribute("State", ptr);
770 currentState = state->GetState();
771 NS_TEST_ASSERT_MSG_EQ(currentState,
772 expectedState,
773 "PHY State " << currentState << " does not match expected state "
774 << expectedState << " at " << Simulator::Now());
775}
776
777void
779 Ptr<WifiNetDevice> device,
780 std::vector<WifiPhyRxfailureReason> expectedDropReasons)
781{
782 std::vector<WifiPhyRxfailureReason> currentDropReasons;
783 uint32_t nodeId = device->GetNode()->GetId();
784 switch (nodeId)
785 {
786 case 0: // STA1
787 currentDropReasons = m_dropReasonsSta1;
788 break;
789 case 1: // STA2
790 currentDropReasons = m_dropReasonsSta2;
791 break;
792 case 3: // AP1
793 currentDropReasons = m_dropReasonsAp1;
794 break;
795 case 4: // AP2
796 currentDropReasons = m_dropReasonsAp2;
797 break;
798 default: // others, no attribute
799 return;
800 }
801 NS_TEST_ASSERT_MSG_EQ(currentDropReasons.size(),
802 expectedDropReasons.size(),
803 "Number of drop reasons "
804 << currentDropReasons.size() << " does not match expected one "
805 << expectedDropReasons.size() << " at " << Simulator::Now());
806 for (std::size_t i = 0; i < currentDropReasons.size(); ++i)
807 {
808 NS_TEST_ASSERT_MSG_EQ(currentDropReasons[i],
809 expectedDropReasons[i],
810 "Drop reason " << i << ": " << currentDropReasons[i]
811 << " does not match expected reason "
812 << expectedDropReasons[i] << " at "
813 << Simulator::Now());
814 }
815}
816
817void
819{
822 int64_t streamNumber = 50;
823
824 Config::Set("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/BE_MaxAmpduSize",
825 UintegerValue(0));
826
827 ResetResults();
828
829 NodeContainer wifiStaNodes;
830 wifiStaNodes.Create(3);
831
832 NodeContainer wifiApNodes;
833 wifiApNodes.Create(3);
834
836 lossModel->SetDefaultLoss(m_txPower -
837 m_obssRxPower); // Force received RSSI to be equal to m_obssRxPower
838
840 phy.DisablePreambleDetectionModel();
841 phy.SetFrameCaptureModel("ns3::SimpleFrameCaptureModel");
843 channel->SetPropagationDelayModel(CreateObject<ConstantSpeedPropagationDelayModel>());
844 channel->AddPropagationLossModel(lossModel);
845 phy.SetChannel(channel);
846 phy.Set("TxPowerStart", DoubleValue(m_txPower));
847 phy.Set("TxPowerEnd", DoubleValue(m_txPower));
848 phy.Set("ChannelSettings", StringValue("{36, 20, BAND_5GHZ, 0}"));
849
850 WifiHelper wifi;
851 wifi.SetStandard(m_standard);
852 wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager",
853 "DataMode",
854 StringValue("HeMcs5"),
855 "ControlMode",
856 StringValue("HeMcs0"));
857
858 wifi.SetObssPdAlgorithm("ns3::ConstantObssPdAlgorithm",
859 "ObssPdLevel",
861
862 WifiMacHelper mac;
863 Ssid ssid = Ssid("ns-3-ssid");
864 mac.SetType("ns3::StaWifiMac", "Ssid", SsidValue(ssid));
865 m_staDevices = wifi.Install(phy, mac, wifiStaNodes);
866
867 // Assign fixed streams to random variables in use
869
870 mac.SetType("ns3::ApWifiMac", "Ssid", SsidValue(ssid));
871 m_apDevices = wifi.Install(phy, mac, wifiApNodes);
872
873 // Assign fixed streams to random variables in use
875
876 for (uint32_t i = 0; i < m_apDevices.GetN(); i++)
877 {
879 Ptr<HeConfiguration> heConfiguration = device->GetHeConfiguration();
880 if (i == 0)
881 {
882 heConfiguration->SetAttribute("BssColor", UintegerValue(m_bssColor1));
883 }
884 else if (i == 1)
885 {
886 heConfiguration->SetAttribute("BssColor", UintegerValue(m_bssColor2));
887 }
888 else
889 {
890 heConfiguration->SetAttribute("BssColor", UintegerValue(m_bssColor3));
891 }
892 }
893
894 MobilityHelper mobility;
896 10,
897 50,
898 10,
899 50,
900 10); // distances do not really matter since we set RSSI per TX-RX pair to have full control
901 mobility.SetPositionAllocator(positionAlloc);
902 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
903 mobility.Install(wifiApNodes);
904 mobility.Install(wifiStaNodes);
905
906 lossModel->SetLoss(wifiStaNodes.Get(0)->GetObject<MobilityModel>(),
907 wifiApNodes.Get(0)->GetObject<MobilityModel>(),
908 m_txPower + dB_u{30.0}); // Low attenuation for IBSS transmissions
909 lossModel->SetLoss(wifiStaNodes.Get(1)->GetObject<MobilityModel>(),
910 wifiApNodes.Get(1)->GetObject<MobilityModel>(),
911 m_txPower + dB_u{30.0}); // Low attenuation for IBSS transmissions
912 lossModel->SetLoss(wifiStaNodes.Get(2)->GetObject<MobilityModel>(),
913 wifiApNodes.Get(2)->GetObject<MobilityModel>(),
914 m_txPower + dB_u{30.0}); // Low attenuation for IBSS transmissions
915
916 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyTxBegin",
918 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyRxEnd",
920 Config::Connect("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyRxDrop",
922
924
927
928 CheckResults();
929}
930
931void
933{
934 // Test case 1: CCA CS Threshold = m_obssRxPower < m_obssPdLevel
935 m_obssPdLevel = dBm_u{-72};
936 m_obssRxPower = dBm_u{-82};
937 m_bssColor1 = 1;
938 m_bssColor2 = 2;
939 m_bssColor3 = 3;
940 RunOne();
941
942 // Test case 2: CCA CS Threshold < m_obssPdLevel < m_obssRxPower
943 m_obssPdLevel = dBm_u{-72};
944 m_obssRxPower = dBm_u{-62};
945 m_bssColor1 = 1;
946 m_bssColor2 = 2;
947 m_bssColor3 = 3;
948 RunOne();
949
950 // Test case 3: CCA CS Threshold < m_obssPdLevel = m_obssRxPower
951 m_obssPdLevel = dBm_u{-72};
952 m_obssRxPower = dBm_u{-72};
953 m_bssColor1 = 1;
954 m_bssColor2 = 2;
955 m_bssColor3 = 3;
956 RunOne();
957
958 // Test case 4: CCA CS Threshold = m_obssRxPower < m_obssPdLevel with BSS color 2 and 3
959 // set to 0
960 m_obssPdLevel = dBm_u{-72};
961 m_obssRxPower = dBm_u{-82};
962 m_bssColor1 = 1;
963 m_bssColor2 = 0;
964 m_bssColor3 = 0;
965 RunOne();
966
967 // Test case 5: CCA CS Threshold = m_obssRxPower < m_obssPdLevel with BSS color 1 set to 0
968 m_obssPdLevel = dBm_u{-72};
969 m_obssRxPower = dBm_u{-82};
970 m_bssColor1 = 0;
971 m_bssColor2 = 2;
972 m_bssColor3 = 3;
973 RunOne();
974}
975
976/**
977 * @ingroup wifi-test
978 * @ingroup tests
979 *
980 * @brief Inter BSS Test Suite
981 */
982
984{
985 public:
987};
988
990 : TestSuite("wifi-inter-bss", Type::UNIT)
991{
993 TestCase::Duration::QUICK);
995 TestCase::Duration::QUICK);
996}
997
998// 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
unsigned int m_payloadSize2
size in bytes of packet payload in BSS 2
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.
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.
dBm_u m_txPower
configured transmit power
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.
dBm_u m_obssRxPower
forced RX power for OBSS
void SetExpectedTxPower(dBm_u txPower)
Set the expected transmit power.
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
std::vector< WifiPhyRxfailureReason > m_dropReasonsAp1
drop reasons for AP1
Ptr< ListPositionAllocator > AllocatePositions(meter_u d1, meter_u d2, meter_u d3, meter_u d4, meter_u d5)
Allocate the node positions.
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
dBm_u m_expectedTxPower
expected transmit power
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition double.h:31
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:511
AttributeValue implementation for Pointer.
Ptr< T > Get() const
Definition pointer.h:223
Smart pointer class similar to boost::intrusive_ptr.
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:560
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:131
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:197
static void Run()
Run the simulation.
Definition simulator.cc:167
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition simulator.cc:175
Make it easy to create and manage PHY objects for the spectrum model.
The IEEE 802.11 SSID Information Element.
Definition ssid.h:25
AttributeValue implementation for Ssid.
Definition ssid.h:85
Hold variables of type string.
Definition string.h:45
encapsulates test code
Definition test.h:1050
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition test.cc:292
A suite of tests to run.
Definition test.h:1267
Type
Type of test.
Definition test.h:1274
Hold an unsigned integer type.
Definition uinteger.h:34
helps to create WifiNetDevice objects
static int64_t AssignStreams(NetDeviceContainer c, int64_t stream)
Assign a fixed random variable stream number to the random variables used by the PHY and MAC aspects ...
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:967
void Set(std::string path, const AttributeValue &value)
Definition config.cc:869
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
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:36
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition test.h:134
#define NS_TEST_EXPECT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report if not.
Definition test.h:241
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1368
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1344
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.
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:684
dBm_u WToDbm(Watt_u val)
Convert from Watts to dBm.
Definition wifi-utils.cc:37
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:580
uint32_t pktSize
packet size used for the simulation (in bytes)