9#include "ns3/ap-wifi-mac.h"
10#include "ns3/attribute-container.h"
11#include "ns3/boolean.h"
12#include "ns3/config.h"
13#include "ns3/ctrl-headers.h"
15#include "ns3/he-configuration.h"
16#include "ns3/he-phy.h"
17#include "ns3/mobility-helper.h"
18#include "ns3/multi-model-spectrum-channel.h"
19#include "ns3/rng-seed-manager.h"
20#include "ns3/spectrum-wifi-helper.h"
21#include "ns3/sta-wifi-mac.h"
24#include "ns3/wifi-net-device.h"
25#include "ns3/wifi-psdu.h"
191 void DoRun()
override;
210 :
TestCase(
"Check correct transmissions for various primary channel settings"),
211 m_channelWidth(channelWidth),
226 for (
const auto&
psduPair : psduMap)
228 std::stringstream
ss;
234 ss <<
" " <<
psduPair.second->GetHeader(0).GetTypeString() <<
" seq "
235 <<
psduPair.second->GetHeader(0).GetSequenceNumber() <<
" from "
250 if (psdu->GetNMpdus() == 1)
254 if (
hdr.IsQosData() ||
hdr.IsTrigger())
260 "Station [" << +bss <<
"][" << +
station
261 <<
"] received a frame twice");
265 if ((
hdr.IsQosData() &&
hdr.GetAddr1() == dev->GetMac()->GetAddress()) ||
270 "Station [" << +bss <<
"][" << +
station
271 <<
"] processed a frame twice");
287 if (psdu->GetNMpdus() == 1 && psdu->GetHeader(0).IsQosData() && txVector.
IsUlMu())
293 NS_LOG_INFO(
"RECEIVED FROM BSSID=" << psdu->GetHeader(0).GetAddr3() <<
" STA=" << +
station
298 "AP of BSS " << +bss <<
" received a frame from station " << +
station
302 if (psdu->GetHeader(0).GetAddr1() == dev->GetMac()->GetAddress())
306 "AP of BSS " << +bss <<
" received a frame from station "
351 std::vector<NodeContainer> wifiStaNodes(
m_nBss);
352 for (
auto& container : wifiStaNodes)
369 wifi.SetRemoteStationManager(
"ns3::ConstantRateWifiManager");
372 mac.SetType(
"ns3::StaWifiMac",
386 for (uint8_t bss = 0; bss <
m_nBss; bss++)
392 m_staDevices.push_back(wifi.Install(phy, mac, wifiStaNodes[bss]));
395 for (uint8_t bss = 0; bss <
m_nBss; bss++)
401 mac.SetType(
"ns3::ApWifiMac",
406 "EnableBeaconJitter",
414 for (uint8_t bss = 0; bss <
m_nBss; bss++)
422 for (uint8_t bss = 0; bss <
m_nBss; bss++)
425 dev->GetHeConfiguration()->m_bssColor = bss + 1;
435 mobility.SetMobilityModel(
"ns3::ConstantPositionMobilityModel");
437 for (uint8_t bss = 0; bss <
m_nBss; bss++)
439 mobility.Install(wifiStaNodes[bss]);
452 hdr.SetSequenceNumber(1);
456 trigger.
SetType(TriggerFrameType::BASIC_TRIGGER);
457 pkt->AddHeader(trigger);
474 apDev->GetMac()->GetWifiPhy()->GetPhyBand());
486 for (uint8_t bss = 0; bss <
m_nBss; bss++)
489 dev->GetMac()->SetSsid(
Ssid(
"wifi-ssid-" + std::to_string(bss)));
497 Ssid(
"wifi-ssid-" + std::to_string(bss)));
503 for (uint8_t bss = 0; bss <
m_nBss; bss++)
520 for (uint8_t bss = 0; bss <
m_nBss; bss++)
621 std::set<uint8_t>
txBss;
658 for (
unsigned int type = 0; type < 7; type++)
662 std::set<uint8_t>
txBss;
707 for (
unsigned int type = 0; type < 7; type++)
711 std::set<uint8_t>
txBss;
748 Config::Connect(
"/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyTxPsduBegin",
765 uint8_t bssColor =
apDev->GetHeConfiguration()->m_bssColor;
781 hdr.SetAddr1(
staDev->GetMac()->GetAddress());
782 hdr.SetAddr2(
apDev->GetMac()->GetAddress());
783 hdr.SetAddr3(
apDev->GetMac()->GetBssid(0));
784 hdr.SetSequenceNumber(1);
796 <<
" MHz channel a DL MU PPDU "
797 <<
"addressed to " <<
nRus <<
" stations (RU type: " <<
ruType <<
")");
800 uint8_t bssColor =
apDev->GetHeConfiguration()->m_bssColor;
817 hdr.SetAddr2(
apDev->GetMac()->GetAddress());
818 hdr.SetAddr3(
apDev->GetMac()->GetBssid(0));
819 hdr.SetSequenceNumber(1);
823 for (std::size_t
i = 1;
i <=
nRus;
i++)
831 hdr.SetAddr1(
staDev->GetMac()->GetAddress());
843 apDev->GetPhy()->Send(psduMap, txVector);
852 NS_LOG_INFO(
"*** BSS " << +bss <<
" transmits a Basic Trigger Frame");
877 uint8_t bssColor =
apDev->GetHeConfiguration()->m_bssColor;
882 hdr.SetAddr1(
apDev->GetMac()->GetAddress());
883 hdr.SetAddr3(
apDev->GetMac()->GetBssid(0));
884 hdr.SetSequenceNumber(1);
901 for (std::size_t
i = 1;
i <=
nRus;
i++)
903 NS_LOG_INFO(
"*** BSS " << +bss <<
" STA " <<
i - 1 <<
" transmits on primary "
905 <<
" MHz channel an HE TB PPDU (RU type: " <<
ruType <<
")");
928 hdr.SetAddr2(
staDev->GetMac()->GetAddress());
936 staDev->GetMac()->GetWifiPhy()->GetPhyBand(),
941 staDev->GetMac()->GetWifiPhy()->GetPhyBand());
957 for (uint8_t bss = 0; bss <
m_nBss; bss++)
963 "Not all the stations completed association");
970 for (uint8_t bss = 0; bss <
m_nBss; bss++)
980 "Station [" << +bss <<
"][" << +
sta
981 <<
"] did not receive the SU frame on primary"
987 "Station [" << +bss <<
"][0]"
988 <<
" did not process the SU frame on primary"
994 "Station [" << +bss <<
"][" << +
sta
995 <<
"] processed the SU frame on primary"
1005 std::none_of(
txBss.begin(),
txBss.end(), [&](
const uint8_t&
txAp) {
1006 auto txApPhy = DynamicCast<WifiNetDevice>(m_apDevices.Get(txAp))->GetPhy();
1007 auto thisApPhy = DynamicCast<WifiNetDevice>(m_apDevices.Get(bss))->GetPhy();
1008 return txApPhy->GetOperatingChannel().GetPrimaryChannelIndex(txChannelWidth) ==
1009 thisApPhy->GetOperatingChannel().GetPrimaryChannelIndex(txChannelWidth);
1016 "Station [" << +bss <<
"][" << +
sta
1017 <<
"] received the SU frame on primary"
1028 "Station [" << +bss <<
"][" << +
sta
1029 <<
"] did not receive the SU frame on primary"
1033 "Station [" << +bss <<
"][" << +
sta
1034 <<
"] processed the SU frame on primary"
1052 for (uint8_t bss = 0; bss <
m_nBss; bss++)
1064 (
isDlMu ?
"A DL MU PPDU transmitted to" :
"An HE TB PPDU transmitted by")
1066 <<
" channel, RU type " <<
ruType <<
" was not received");
1072 (
isDlMu ?
"A DL MU PPDU" :
"An HE TB PPDU")
1074 <<
" channel, RU type " <<
ruType <<
" was received "
1075 << (
isDlMu ?
"by" :
"from") <<
" station [" << +bss
1076 <<
"][" << +
sta <<
"]");
1085 (
isDlMu ?
"A DL MU PPDU transmitted to" :
"An HE TB PPDU transmitted by")
1087 <<
" channel, RU type " <<
ruType <<
" was not processed");
1093 (
isDlMu ?
"A DL MU PPDU" :
"An HE TB PPDU")
1095 <<
" channel, RU type " <<
ruType <<
" was received "
1096 << (
isDlMu ?
"by" :
"from") <<
" station [" << +bss
1097 <<
"][" << +
sta <<
"] and processed");
1107 std::none_of(
txBss.begin(),
txBss.end(), [&](
const uint8_t&
txAp) {
1108 auto txApPhy = DynamicCast<WifiNetDevice>(m_apDevices.Get(txAp))->GetPhy();
1109 auto thisApPhy = DynamicCast<WifiNetDevice>(m_apDevices.Get(bss))->GetPhy();
1110 return txApPhy->GetOperatingChannel().GetPrimaryChannelIndex(txChannelWidth) ==
1111 thisApPhy->GetOperatingChannel().GetPrimaryChannelIndex(txChannelWidth);
1118 (
isDlMu ?
"A DL MU PPDU" :
"An HE TB PPDU")
1120 <<
" channel, RU type " <<
ruType <<
" was received "
1121 << (
isDlMu ?
"by" :
"from") <<
" station [" << +bss
1122 <<
"][" << +
sta <<
"]");
1134 (
isDlMu ?
"A DL MU PPDU transmitted to" :
"An HE TB PPDU transmitted by")
1135 <<
" station [" << +bss <<
"][" << +
sta <<
"] on primary"
1137 <<
" was not received");
1143 (
isDlMu ?
"A DL MU PPDU" :
"An HE TB PPDU")
1145 <<
" channel, RU type " <<
ruType <<
" was received "
1146 << (
isDlMu ?
"by" :
"from") <<
" station [" << +bss
1147 <<
"][" << +
sta <<
"]");
1154 (
isDlMu ?
"A DL MU PPDU" :
"An HE TB PPDU")
1156 <<
" channel, RU type " <<
ruType <<
" was received "
1157 << (
isDlMu ?
"by" :
"from") <<
" station [" << +bss
1158 <<
"][" << +
sta <<
"] and processed");
1171 for (uint8_t bss = 0; bss <
m_nBss; bss++)
1181 "Station [" << +bss <<
"][" << +
sta
1182 <<
"] did not receive the Trigger Frame "
1183 "soliciting a transmission on primary"
1187 "Station [" << +bss <<
"][" << +
sta
1188 <<
"] did not process the Trigger Frame "
1189 "soliciting a transmission on primary"
1203 << +bss <<
"][" << +
sta
1204 <<
"] received the Trigger Frame soliciting a transmission on primary"
1249 void DoRun()
override;
1255 :
TestCase(
"Check computation of primary and secondary channel indices")
1267 auto printToStr = [](
const std::set<uint8_t>& s) {
1268 std::stringstream
ss;
1270 for (
const auto& index : s)
1272 ss << +index <<
" ";
1283 "Expected Primary20 {" << +
primary20 <<
"}"
1284 <<
" differs from actual "
1291 <<
" differs from actual "
1304 <<
" differs from actual "
1317 <<
" differs from actual "
1326 RunOne(0, {}, {}, {}, {}, {});
1330 RunOne(0, {1}, {0, 1}, {}, {}, {});
1331 RunOne(1, {0}, {0, 1}, {}, {}, {});
1335 RunOne(0, {1}, {0, 1}, {2, 3}, {0, 1, 2, 3}, {});
1336 RunOne(1, {0}, {0, 1}, {2, 3}, {0, 1, 2, 3}, {});
1337 RunOne(2, {3}, {2, 3}, {0, 1}, {0, 1, 2, 3}, {});
1338 RunOne(3, {2}, {2, 3}, {0, 1}, {0, 1, 2, 3}, {});
1342 RunOne(0, {1}, {0, 1}, {2, 3}, {0, 1, 2, 3}, {4, 5, 6, 7});
1343 RunOne(1, {0}, {0, 1}, {2, 3}, {0, 1, 2, 3}, {4, 5, 6, 7});
1344 RunOne(2, {3}, {2, 3}, {0, 1}, {0, 1, 2, 3}, {4, 5, 6, 7});
1345 RunOne(3, {2}, {2, 3}, {0, 1}, {0, 1, 2, 3}, {4, 5, 6, 7});
1346 RunOne(4, {5}, {4, 5}, {6, 7}, {4, 5, 6, 7}, {0, 1, 2, 3});
1347 RunOne(5, {4}, {4, 5}, {6, 7}, {4, 5, 6, 7}, {0, 1, 2, 3});
1348 RunOne(6, {7}, {6, 7}, {4, 5}, {4, 5, 6, 7}, {0, 1, 2, 3});
1349 RunOne(7, {6}, {6, 7}, {4, 5}, {4, 5, 6, 7}, {0, 1, 2, 3});
Test functions returning the indices of primary and secondary channels of different width.
Wifi20MHzChannelIndicesTest()
Constructor.
void DoRun() override
Implementation to actually run this TestCase.
~Wifi20MHzChannelIndicesTest() override=default
void RunOne(uint8_t primary20, const std::set< uint8_t > &secondary20, const std::set< uint8_t > &primary40, const std::set< uint8_t > &secondary40, const std::set< uint8_t > &primary80, const std::set< uint8_t > &secondary80)
Check that the indices of the 20 MHz channels included in all the primary and secondary channels are ...
WifiPhyOperatingChannel m_channel
operating channel
Test transmissions under different primary channel settings.
void DoSendHeTbPpdu(uint8_t bss, MHz_u txChannelWidth, HeRu::RuType ruType, std::size_t nRus)
Have the STAs of the given BSS transmit an HE TB PPDU using the given transmission channel width and ...
std::vector< std::bitset< 74 > > m_processed
whether the last packet transmitted to/from each of the (up to 74 per BSS) stations was processed
WifiPrimaryChannelsTest(MHz_u channelWidth, bool useDistinctBssColors)
Constructor.
void CheckAssociation()
Check that all stations associated with an AP.
void CheckReceivedSuPpdus(std::set< uint8_t > txBss, MHz_u txChannelWidth)
Check that (i) all stations belonging to the given BSSes received the SU PPDUs transmitted over the g...
std::vector< std::bitset< 74 > > m_received
whether the last packet transmitted to/from each of the (up to 74 per BSS) stations was received
uint8_t m_nBss
number of BSSes
void CheckReceivedTriggerFrames(std::set< uint8_t > txBss, MHz_u txChannelWidth)
Check that (i) all stations belonging to the given BSSes received the transmitted Trigger Frame; and ...
void Transmit(std::string context, WifiConstPsduMap psduMap, WifiTxVector txVector, double txPowerW)
Callback invoked when PHY receives a PSDU to transmit.
void SendDlMuPpdu(uint8_t bss, MHz_u txChannelWidth, HeRu::RuType ruType, std::size_t nRus)
Have the AP of the given BSS transmit a MU PPDU using the given transmission channel width and RU typ...
MHz_u m_channelWidth
operating channel width
void ReceiveUl(uint8_t bss, Ptr< const WifiPsdu > psdu, RxSignalInfo rxSignalInfo, const WifiTxVector &txVector, const std::vector< bool > &perMpduStatus)
Callback invoked when an AP receives an UL PPDU.
Ptr< WifiPsdu > m_trigger
Basic Trigger Frame.
void DoRun() override
Implementation to actually run this TestCase.
void DoSetup() override
Implementation to do any local setup required for this TestCase.
Time m_time
the time when the current action is executed
Time m_triggerTxDuration
TX duration for Basic Trigger Frame.
uint8_t m_nStationsPerBss
number of stations per AP
void ReceiveDl(uint8_t bss, uint8_t station, Ptr< const WifiPsdu > psdu, RxSignalInfo rxSignalInfo, const WifiTxVector &txVector, const std::vector< bool > &perMpduStatus)
Callback invoked when a station receives a DL PPDU.
void CheckReceivedMuPpdus(std::set< uint8_t > txBss, MHz_u txChannelWidth, HeRu::RuType ruType, std::size_t nRus, bool isDlMu)
Check that (i) all stations/APs belonging to the given BSSes received the DL/UL MU PPDUs transmitted ...
std::vector< NetDeviceContainer > m_staDevices
containers for stations' NetDevices
NetDeviceContainer m_apDevices
container for AP's NetDevice
~WifiPrimaryChannelsTest() override
void SendHeTbPpdu(uint8_t bss, MHz_u txChannelWidth, HeRu::RuType ruType, std::size_t nRus)
Have the AP of the given BSS transmit a Basic Trigger Frame.
bool m_useDistinctBssColors
true to set distinct BSS colors to BSSes
WifiTxVector m_triggerTxVector
TX vector for Basic Trigger Frame.
void SendDlSuPpdu(uint8_t bss, MHz_u txChannelWidth)
Have the AP of the given BSS transmit a SU PPDU using the given transmission channel width.
wifi primary channels test suite
WifiPrimaryChannelsTestSuite()
void SetBeaconInterval(Time interval)
A container for one type of attribute.
AttributeValue implementation for Boolean.
static WifiMode GetHeMcs8()
Return MCS 8 from HE MCS values.
static std::pair< uint16_t, Time > ConvertHeTbPpduDurationToLSigLength(Time ppduDuration, const WifiTxVector &txVector, WifiPhyBand band)
Compute the L-SIG length value corresponding to the given HE TB PPDU duration.
static uint8_t GetEqualizedRuAllocation(RuType ruType, bool isOdd)
Get the RU_ALLOCATION value for equal size RUs.
static std::size_t GetNRus(MHz_u bw, RuType ruType)
Get the number of distinct RUs of the given type (number of tones) available in a HE PPDU of the give...
RuType
The different HE Resource Unit (RU) types.
static Mac48Address GetBroadcast()
Helper class used to assign positions and mobility models to nodes.
holds a vector of ns3::NetDevice pointers
void Add(NetDeviceContainer other)
Append the contents of another NetDeviceContainer to the end of 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.
static WifiMode GetOfdmRate6Mbps()
Return a WifiMode for OFDM at 6 Mbps.
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.
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
static void Run()
Run the simulation.
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Make it easy to create and manage PHY objects for the spectrum model.
The IEEE 802.11 SSID Information Element.
AttributeValue implementation for Ssid.
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Simulation virtual time values and global simulation resolution.
bool IsZero() const
Exactly equivalent to t == 0.
AttributeValue implementation for Time.
AttributeValue implementation for Tuple.
Hold an unsigned integer type.
void Set(const uint64_t &value)
Set the value.
static WifiMode GetVhtMcs5()
Return MCS 5 from VHT MCS values.
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.
static Time CalculateTxDuration(uint32_t size, const WifiTxVector &txVector, WifiPhyBand band, uint16_t staId=SU_STA_ID)
std::vector< ChannelTuple > ChannelSegments
segments identifying an operating channel
void SetReceiveOkCallback(RxOkCallback callback)
Class that keeps track of all information about the current PHY operating channel.
std::set< uint8_t > GetAll20MHzChannelIndicesInSecondary(MHz_u width) const
Get the channel indices of all the 20 MHz channels included in the secondary channel of the given wid...
void SetPrimary20Index(uint8_t index)
Set the index of the primary 20 MHz channel (0 indicates the 20 MHz subchannel with the lowest center...
std::set< uint8_t > GetAll20MHzChannelIndicesInPrimary(MHz_u width) const
Get the channel indices of all the 20 MHz channels included in the primary channel of the given width...
void SetDefault(MHz_u width, WifiStandard standard, WifiPhyBand band)
Set the default channel of the given width and for the given standard and band.
const WifiMacHeader & GetHeader(std::size_t i) const
Get the header of the i-th MPDU.
uint32_t GetSize() const
Return the size of the PSDU in bytes.
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
void SetRuAllocation(const RuAllocation &ruAlloc, uint8_t p20Index)
Set RU_ALLOCATION field.
void SetHeMuUserInfo(uint16_t staId, HeMuUserInfo userInfo)
Set the HE MU user-specific transmission information for the given STA-ID.
const HeMuUserInfoMap & GetHeMuUserInfoMap() const
Get a const reference to the map HE MU user-specific transmission information indexed by STA-ID.
void SetLength(uint16_t length)
Set the LENGTH field of the L-SIG.
void SetSigBMode(const WifiMode &mode)
Set the MCS used for SIG-B.
void Connect(std::string path, const CallbackBase &cb)
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
#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.
#define NS_TEST_EXPECT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report if not.
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
@ WIFI_PHY_BAND_5GHZ
The 5 GHz band.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::unordered_map< uint16_t, Ptr< const WifiPsdu > > WifiConstPsduMap
Map of const PSDUs indexed by STA-ID.
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...
std::size_t Count20MHzSubchannels(MHz_u channelWidth)
Return the number of 20 MHz subchannels covering the channel width.
static constexpr uint8_t SINGLE_LINK_OP_ID
Link ID for single link operations (helps tracking places where correct link ID is to be used to supp...
std::vector< uint16_t > RuAllocation
9 bits RU_ALLOCATION per 20 MHz
static constexpr uint16_t SU_STA_ID
STA_ID to identify a single user (SU)
-ns3 Test suite for the ns3 wrapper script
RxSignalInfo structure containing info on the received signal.
static WifiPrimaryChannelsTestSuite g_wifiPrimaryChannelsTestSuite
the test suite