13#include "ns3/ampdu-subframe-header.h"
14#include "ns3/ap-wifi-mac.h"
15#include "ns3/config.h"
16#include "ns3/eht-configuration.h"
17#include "ns3/eht-ppdu.h"
18#include "ns3/frame-capture-model.h"
19#include "ns3/he-configuration.h"
20#include "ns3/ht-configuration.h"
21#include "ns3/interference-helper.h"
23#include "ns3/mobility-model.h"
25#include "ns3/net-device-queue-interface.h"
26#include "ns3/obss-pd-algorithm.h"
27#include "ns3/pointer.h"
28#include "ns3/preamble-detection-model.h"
29#include "ns3/qos-txop.h"
30#include "ns3/qos-utils.h"
31#include "ns3/radiotap-header.h"
32#include "ns3/sta-wifi-mac.h"
33#include "ns3/vht-configuration.h"
34#include "ns3/wifi-mac-queue.h"
35#include "ns3/wifi-mac-trailer.h"
36#include "ns3/wifi-radio-energy-model.h"
56 const auto shift = std::countr_zero(mask);
57 return (val << shift) & mask;
91 auto pCopy = p->Copy();
93 pCopy->RemoveTrailer(fcs);
95 <<
" " << *pCopy <<
" " << fcs << std::endl;
114 auto pCopy = p->Copy();
116 pCopy->RemoveTrailer(fcs);
118 <<
" " << fcs << std::endl;
139 auto pCopy = p->Copy();
141 pCopy->RemoveTrailer(fcs);
143 <<
" " << *pCopy <<
" " << fcs << std::endl;
162 auto pCopy = p->Copy();
164 pCopy->RemoveTrailer(fcs);
166 <<
" " << fcs << std::endl;
198 m_phys.at(linkId).Set(name, v);
212 switch (info->pcapType)
221 if (
const auto linkId = info->device->GetMac()->GetLinkForPhy(phyId))
232 if (!info->files.contains(fileIdx))
235 auto tmp = info->commonFilename;
238 auto pos = info->commonFilename.find_last_of(
'.');
240 pos = (pos == std::string::npos) ? info->commonFilename.size() : pos;
246 tmp.insert(pos,
"-" + std::to_string(fileIdx));
250 auto file = pcapHelper.
CreateFile(tmp, std::ios::out, info->pcapDlt);
251 info->files.emplace(fileIdx, file);
254 return info->files.at(fileIdx);
261 uint16_t channelFreqMhz,
271 switch (info->pcapDlt)
277 NS_FATAL_ERROR(
"PcapSniffTxEvent(): DLT_PRISM_HEADER not implemented");
284 info->device->GetPhy(phyId)->GetPrimary20Index(),
288 p->AddHeader(header);
293 NS_ABORT_MSG(
"PcapSniffTxEvent(): Unexpected data link type " << info->pcapDlt);
301 uint16_t channelFreqMhz,
312 switch (info->pcapDlt)
318 NS_FATAL_ERROR(
"PcapSniffRxEvent(): DLT_PRISM_HEADER not implemented");
325 info->device->GetPhy(phyId)->GetPrimary20Index(),
330 p->AddHeader(header);
335 NS_ABORT_MSG(
"PcapSniffRxEvent(): Unexpected data link type " << info->pcapDlt);
341 uint16_t channelFreqMhz,
346 std::optional<SignalNoiseDbm> signalNoise)
372 if (gi.GetNanoSeconds() == 400)
384 header.
SetRate(
static_cast<uint8_t
>(rate));
389 nss = txVector.
GetNss(staId);
405 if (channelFreqMhz < 2500)
424 if (channelWidth ==
MHz_u{40})
429 if (gi.GetNanoSeconds() == 400)
434 const auto ness = txVector.
GetNess();
459 packet->RemoveHeader(hdr);
461 packet = packet->CreateFragment(0,
static_cast<uint32_t>(extractedLength));
480 if (gi.GetNanoSeconds() == 400)
488 if (channelWidth ==
MHz_u{40})
490 vhtFields.bandwidth = 1;
492 else if (channelWidth ==
MHz_u{80})
494 vhtFields.bandwidth = 4;
496 else if (channelWidth ==
MHz_u{160})
498 vhtFields.bandwidth = 11;
502 vhtFields.mcsNss.at(0) |= (nss & 0x0f) | ((mcs << 4) & 0xf0);
578 else if (channelWidth ==
MHz_u{40})
582 else if (channelWidth ==
MHz_u{80})
586 else if (channelWidth ==
MHz_u{160})
590 if (gi.GetNanoSeconds() == 1600)
594 else if (gi.GetNanoSeconds() == 3200)
618 switch (
static_cast<uint16_t
>(channelWidth))
638 channelization320MHzMap.at(channelFreqMhz));
655 std::optional<bool> isLow80MHz;
661 const auto puncturedChannelInfo =
666 puncturedChannelInfo);
682 switch (gi.GetNanoSeconds())
685 ehtFields.data.at(0) =
745 ehtFields.data.at(1) |=
748 if (channelWidth >=
MHz_u{40})
750 ehtFields.data.at(2) =
754 if (channelWidth >=
MHz_u{80})
756 ehtFields.data.at(2) |=
762 if (channelWidth >=
MHz_u{160})
764 ehtFields.data.at(3) =
771 ehtFields.data.at(4) =
775 const auto isLowP80 = p20Index < (channelWidth /
MHz_u{40});
776 ehtFields.data.at(1) |=
781 if (channelWidth >=
MHz_u{320})
783 ehtFields.data.at(4) |=
788 ehtFields.data.at(5) =
795 ehtFields.data.at(6) =
810 ehtFields.userInfo.push_back(userInfo);
832 NS_ABORT_MSG(
"WifiPhyHelper::SetPcapFormat(): Unexpected format");
858 bool explicitFilename)
860 NS_LOG_FUNCTION(
this << prefix << nd << promiscuous << explicitFilename);
868 NS_LOG_INFO(
"WifiHelper::EnablePcapInternal(): Device "
869 << &device <<
" not of type ns3::WifiNetDevice");
874 "WifiPhyHelper::EnablePcapInternal(): Phy layer in WifiNetDevice must be set");
877 std::string filename;
878 if (explicitFilename)
888 for (
auto& phy : device->GetPhys())
890 phy->TraceConnectWithoutContext(
893 phy->TraceConnectWithoutContext(
903 bool explicitFilename)
911 NS_LOG_INFO(
"WifiHelper::EnableAsciiInternal(): Device "
912 << device <<
" not of type ns3::WifiNetDevice");
920 uint32_t nodeid = nd->GetNode()->GetId();
921 uint32_t deviceid = nd->GetIfIndex();
922 std::ostringstream oss;
935 std::string filename;
936 if (explicitFilename)
946 auto pos = filename.find_last_of(
'.');
948 pos = (pos == std::string::npos) ? filename.size() : pos;
950 for (uint8_t linkId = 0; linkId < device->GetNPhys(); linkId++)
952 std::string tmp = filename;
953 if (device->GetNPhys() > 1)
956 tmp.insert(pos,
"-" + std::to_string(linkId));
964 oss <<
"/NodeList/" << nodeid <<
"/DeviceList/" << deviceid
965 <<
"/$ns3::WifiNetDevice/Phys/" << +linkId <<
"/State/RxOk";
971 oss <<
"/NodeList/" << nodeid <<
"/DeviceList/" << deviceid
972 <<
"/$ns3::WifiNetDevice/Phys/" << +linkId <<
"/State/Tx";
987 oss <<
"/NodeList/" << nodeid <<
"/DeviceList/" << deviceid
988 <<
"/$ns3::WifiNetDevice/Phy/State/RxOk";
992 oss <<
"/NodeList/" << nodeid <<
"/DeviceList/" << deviceid
993 <<
"/$ns3::WifiNetDevice/Phy/State/Tx";
1007 m_htConfig.SetTypeId(
"ns3::HtConfiguration");
1009 m_heConfig.SetTypeId(
"ns3::HeConfiguration");
1062 "Specified Wi-Fi standard " << standard <<
" is currently not supported");
1063 SetStandard(WIFI_STANDARDS_NAME_MAP.at(standard));
1085 for (
auto i =
first; i != last; ++i)
1089 node->AddDevice(device);
1099 device->SetHtConfiguration(htConfiguration);
1109 device->SetVhtConfiguration(vhtConfiguration);
1114 device->SetHeConfiguration(heConfiguration);
1119 device->SetEhtConfiguration(ehtConfiguration);
1121 std::vector<Ptr<WifiRemoteStationManager>> managers;
1122 std::vector<Ptr<WifiPhy>> phys = phyHelper.
Create(node, device);
1123 device->SetPhys(phys);
1126 if (stationManagers.size() == 1 && phys.size() > 1)
1128 stationManagers.resize(phys.size(), stationManagers[0]);
1131 "Number of station manager models ("
1132 << stationManagers.size() <<
") does not match the number of links ("
1133 << phys.size() <<
")");
1134 for (std::size_t i = 0; i < phys.size(); i++)
1139 device->SetRemoteStationManagers(managers);
1144 device->AggregateObject(obssPdAlgorithm);
1145 obssPdAlgorithm->ConnectWifiNetDevice(device);
1147 devices.Add(device);
1155 mac->GetAttributeFailSafe(
"QosSupported", qosSupported);
1156 if (qosSupported.
Get())
1163 wmq = qosTxop->GetWifiMacQueue();
1164 ndqi->GetTxQueue(
static_cast<std::size_t
>(ac))->ConnectQueueTraces(wmq);
1172 wmq = mac->GetTxop()->GetWifiMacQueue();
1173 ndqi->GetTxQueue(0)->ConnectQueueTraces(wmq);
1175 device->AggregateObject(ndqi);
1317 int64_t currentStream = stream;
1319 for (
auto i = c.
Begin(); i != c.
End(); ++i)
1325 for (
auto& phy : wifi->GetPhys())
1327 currentStream += phy->AssignStreams(currentStream);
1331 for (
auto& manager : wifi->GetRemoteStationManagers())
1333 currentStream += manager->AssignStreams(currentStream);
1337 auto mac = wifi->GetMac();
1339 if (!mac->GetQosSupported())
1341 mac->GetAttribute(
"Txop", ptr);
1343 currentStream += txop->AssignStreams(currentStream);
1347 mac->GetAttribute(
"VO_Txop", ptr);
1349 currentStream += vo_txop->AssignStreams(currentStream);
1351 mac->GetAttribute(
"VI_Txop", ptr);
1355 mac->GetAttribute(
"BE_Txop", ptr);
1359 mac->GetAttribute(
"BK_Txop", ptr);
1367 currentStream += apMac->AssignStreams(currentStream);
1372 currentStream += staMac->AssignStreams(currentStream);
1376 return (currentStream - stream);
Manage ASCII trace files for device models.
std::string GetFilenameFromDevice(std::string prefix, Ptr< NetDevice > device, bool useObjectNames=true)
Let the ascii trace helper figure out a reasonable filename to use for an ascii trace file associated...
Ptr< OutputStreamWrapper > CreateFileStream(std::string filename, std::ios::openmode filemode=std::ios::out)
Create and initialize an output stream object we'll use to write the traced bits.
Hold a value for an Attribute.
AttributeValue implementation for Boolean.
static uint8_t GetPuncturedInfo(const std::vector< bool > &inactiveSubchannels, uint8_t ehtPpduType, std::optional< bool > isLow80MHz)
Get the Punctured Channel Information field in the U-SIG.
Keep track of the current position and velocity of an object.
static Ptr< T > Find(std::string path)
Given a name path string, look to see if there's an object in the system with that associated to it.
holds a vector of ns3::NetDevice pointers
Iterator Begin() const
Get an iterator which refers to the first NetDevice in the container.
Iterator End() const
Get an iterator which indicates past-the-last NetDevice in the container.
keep track of a set of node pointers.
std::vector< Ptr< Node > >::const_iterator Iterator
Node container iterator.
Iterator End() const
Get an iterator which indicates past-the-last Node in the container.
Iterator Begin() const
Get an iterator which refers to the first Node in the container.
OBSS PD algorithm interface.
static void EnablePrinting()
Enable printing packets metadata.
Manage pcap files for device models.
std::string GetFilenameFromDevice(std::string prefix, Ptr< NetDevice > device, bool useObjectNames=true)
Let the pcap helper figure out a reasonable filename to use for a pcap file associated with a device.
Ptr< PcapFileWrapper > CreateFile(std::string filename, std::ios::openmode filemode, DataLinkType dataLinkType, uint32_t snapLen=std::numeric_limits< uint32_t >::max(), int32_t tzCorrection=0)
Create and initialize a pcap file.
DataLinkType
This enumeration holds the data link types that will be written to the pcap file.
AttributeValue implementation for Pointer.
Smart pointer class similar to boost::intrusive_ptr.
Handles the packet queue and stores DCF/EDCA access parameters (one Txop per AC).
static Time Now()
Return the current simulation virtual time.
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Handles the packet queue and stores DCF/EDCA access parameters (one Txop per AC).
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
Hold an unsigned integer type.
void SetRemoteStationManager(std::string type, Args &&... args)
Helper function used to set the station manager.
ObjectFactory m_htConfig
HT configuration.
ObjectFactory m_obssPdAlgorithm
OBSS_PD algorithm.
ObjectFactory m_ehtConfig
EHT configuration.
ObjectFactory m_vhtConfig
VHT configuration.
static void EnableLogComponents(LogLevel logLevel=LOG_LEVEL_ALL)
Helper to enable all WifiNetDevice log components with one statement.
void SetSelectQueueCallback(SelectQueueCallback f)
std::vector< ObjectFactory > m_stationManager
station manager
WifiStandard m_standard
wifi standard
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 ...
virtual void SetStandard(WifiStandard standard)
ObjectFactory m_heConfig
HE configuration.
virtual NetDeviceContainer Install(const WifiPhyHelper &phy, const WifiMacHelper &mac, NodeContainer::Iterator first, NodeContainer::Iterator last) const
void DisableFlowControl()
Disable flow control only if you know what you are doing.
SelectQueueCallback m_selectQueueCallback
select queue callback
bool m_enableFlowControl
whether to enable flow control
WifiHelper()
Create a Wifi helper in an empty state: all its parameters must be set before calling ns3::WifiHelper...
std::function< std::size_t(Ptr< QueueItem >)> SelectQueueCallback
Callback invoked to determine the MAC queue selected for a given packet.
create MAC layers for a ns3::WifiNetDevice.
virtual Ptr< WifiMac > Create(Ptr< WifiNetDevice > device, WifiStandard standard) const
Implements the IEEE 802.11 MAC trailer.
represent a single transmission mode
uint64_t GetDataRate(MHz_u channelWidth, Time guardInterval, uint8_t nss) const
uint8_t GetMcsValue() const
Hold together all Wifi-related objects.
void SetPcapCaptureType(PcapCaptureType type)
Set the PCAP capture type to be used.
void SetPcapDataLinkType(SupportedPcapDataLinkTypes dlt)
Set the data link type of PCAP traces to be used.
void EnableAsciiInternal(Ptr< OutputStreamWrapper > stream, std::string prefix, Ptr< NetDevice > nd, bool explicitFilename) override
Enable ASCII trace output on the indicated net device.
WifiPhyHelper(uint8_t nLinks=1)
Constructor.
static void PcapSniffTxEvent(const std::shared_ptr< PcapFilesInfo > &info, uint8_t phyId, Ptr< const Packet > packet, uint16_t channelFreqMhz, WifiTxVector txVector, MpduInfo aMpdu, uint16_t staId=SU_STA_ID)
void Set(std::string name, const AttributeValue &v)
~WifiPhyHelper() override
void DisablePreambleDetectionModel()
Disable the preamble detection model on all links.
void EnablePcapInternal(std::string prefix, Ptr< NetDevice > nd, bool promiscuous, bool explicitFilename) override
Enable pcap output the indicated net device.
PcapHelper::DataLinkType m_pcapDlt
PCAP data link type.
std::vector< ObjectFactory > m_frameCaptureModel
frame capture model
std::vector< ObjectFactory > m_preambleDetectionModel
preamble detection model
PcapHelper::DataLinkType GetPcapDataLinkType() const
Get the data link type of PCAP traces to be used.
PcapCaptureType m_pcapType
PCAP capture type.
PcapCaptureType GetPcapCaptureType() const
Get the PCAP capture type to be used.
std::vector< ObjectFactory > m_phys
PHY objects.
static void PcapSniffRxEvent(const std::shared_ptr< PcapFilesInfo > &info, uint8_t phyId, Ptr< const Packet > packet, uint16_t channelFreqMhz, WifiTxVector txVector, MpduInfo aMpdu, SignalNoiseDbm signalNoise, uint16_t staId=SU_STA_ID)
void SetPreambleDetectionModel(std::string type, Args &&... args)
Helper function used to set the preamble detection model.
static RadiotapHeader GetRadiotapHeader(Ptr< Packet > packet, uint16_t channelFreqMhz, uint8_t p20Index, const WifiTxVector &txVector, MpduInfo aMpdu, uint16_t staId, std::optional< SignalNoiseDbm > signalNoise=std::nullopt)
Get the Radiotap header for a received packet.
static Ptr< PcapFileWrapper > GetOrCreatePcapFile(const std::shared_ptr< PcapFilesInfo > &info, uint8_t phyId)
Get the PCAP file to write to from a list of PCAP files indexed by PHY ID.
SupportedPcapDataLinkTypes
An enumeration of the pcap data link types (DLTs) which this helper supports.
@ DLT_IEEE802_11
IEEE 802.11 Wireless LAN headers on packets.
@ DLT_IEEE802_11_RADIO
Include Radiotap link layer information.
@ DLT_PRISM_HEADER
Include Prism monitor mode information.
std::vector< ObjectFactory > m_errorRateModel
error rate model
virtual std::vector< Ptr< WifiPhy > > Create(Ptr< Node > node, Ptr< WifiNetDevice > device) const =0
PcapCaptureType
An enumeration of the PCAP capture types.
@ PCAP_PER_PHY
Single capture file per PHY.
@ PCAP_PER_DEVICE
Single capture file per device.
@ PCAP_PER_LINK
Single capture file per link.
static bool IsHe(RuSpec ru)
Get whether a given RU variant is a HE RU.
static RuType GetRuType(RuSpec ru)
Get the type of a given RU.
static std::size_t GetIndex(RuSpec ru)
Get the index of a given RU.
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
uint8_t GetBssColor() const
Get the BSS color.
const RuAllocation & GetRuAllocation(uint8_t p20Index) const
Get RU_ALLOCATION field.
WifiMode GetMode(uint16_t staId=SU_STA_ID) const
If this TX vector is associated with an SU PPDU, return the selected payload transmission mode.
bool IsStbc() const
Check if STBC is used or not.
WifiPreamble GetPreambleType() const
HeMuUserInfo GetHeMuUserInfo(uint16_t staId) const
Get the HE MU user-specific transmission information for the given STA-ID.
uint8_t GetEhtPpduType() const
Get the EHT_PPDU_TYPE parameter.
WifiModulationClass GetModulationClass() const
Get the modulation class specified by this TXVECTOR.
uint8_t GetNss(uint16_t staId=SU_STA_ID) const
If this TX vector is associated with an SU PPDU, return the number of spatial streams.
MHz_u GetChannelWidth() const
bool IsAggregation() const
Checks whether the PSDU contains A-MPDU.
Time GetGuardInterval() const
WifiRu::RuSpec GetRu(uint16_t staId) const
Get the RU specification for the STA-ID.
WifiMode GetSigBMode() const
Get MCS used for SIG-B.
const std::vector< bool > & GetInactiveSubchannels() const
Get the 20 MHz subchannels that are punctured.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
void Connect(std::string path, const CallbackBase &cb)
void ConnectWithoutContext(std::string path, const CallbackBase &cb)
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
#define NS_ABORT_IF(cond)
Abnormal program termination if a condition is true.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
auto MakeBoundCallback(R(*fnPtr)(Args...), BArgs &&... bargs)
Make Callbacks with varying number of bound arguments.
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Ptr< T > CreateObjectWithAttributes(Args... args)
Allocate an Object on the heap and initialize with a set of attributes.
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
WifiStandard
Identifies the IEEE 802.11 specifications that a Wifi device can be configured to use.
WifiPreamble
The type of preamble to be used by an IEEE 802.11 transmission.
uint8_t SelectQueueByDSField(Ptr< QueueItem > item)
Determine the TX queue for a given packet.
@ WIFI_STANDARD_UNSPECIFIED
@ WIFI_MOD_CLASS_HT
HT (Clause 19)
@ WIFI_MOD_CLASS_VHT
VHT (Clause 22)
@ WIFI_MOD_CLASS_HE
HE (Clause 27)
@ LAST_MPDU_IN_AGGREGATE
The MPDU is the last aggregate in an A-MPDU with multiple MPDUs.
const std::map< MHz_u, RadiotapHeader::UsigCommonBw > channelization320MHzMap
320 MHz channelization map
uint32_t GetRadiotapField(uint32_t mask, uint32_t val)
Helper function to place the value to set in the correct bit(s) of a radiotap subfield.
const std::unordered_map< std::string, WifiStandard > WIFI_STANDARDS_NAME_MAP
Map strings to WifiStandard enum values.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void LogComponentEnable(const std::string &name, LogLevel level)
Enable the logging output associated with that log component.
bool IsEht(WifiPreamble preamble)
Return true if a preamble corresponds to an EHT transmission.
double MHz_u
MHz weak type.
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
static void AsciiPhyReceiveSinkWithoutContext(Ptr< OutputStreamWrapper > stream, Ptr< const Packet > p, double snr, WifiMode mode, WifiPreamble preamble)
ASCII trace PHY receive sink without context.
LogLevel
Logging severity classes and levels.
@ LOG_PREFIX_TIME
Prefix all trace prints with simulation time.
@ LOG_PREFIX_NODE
Prefix all trace prints with simulation node.
static void AsciiPhyReceiveSinkWithContext(Ptr< OutputStreamWrapper > stream, std::string context, Ptr< const Packet > p, double snr, WifiMode mode, WifiPreamble preamble)
ASCII trace PHY receive sink with context.
void LogComponentEnableAll(LogLevel level)
Enable the logging output for all registered log components.
static void AsciiPhyTransmitSinkWithContext(Ptr< OutputStreamWrapper > stream, std::string context, Ptr< const Packet > p, WifiMode mode, WifiPreamble preamble, uint8_t txLevel)
ASCII trace PHY transmit sink with context.
static void AsciiPhyTransmitSinkWithoutContext(Ptr< OutputStreamWrapper > stream, Ptr< const Packet > p, WifiMode mode, WifiPreamble preamble, uint8_t txLevel)
ASCII trace PHY transmit sink without context.
WifiRu::RuSpec ru
RU specification.
MpduType type
type of MPDU
uint32_t mpduRefNumber
MPDU ref number.
SignalNoiseDbm structure.