A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
wifi-ppdu.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2019 Orange Labs
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Rediet <getachew.redieteab@orange.com>
7 */
8
9#include "wifi-ppdu.h"
10
12#include "wifi-psdu.h"
13
14#include "ns3/log.h"
15
16namespace
17{
18/**
19 * Get the center frequency of each segment covered by the provided channel width. If the specified
20 * channel width is contained in a single frequency segment, a single center frequency is returned.
21 * If the specified channel width is spread over multiple frequency segments (e.g. 160 MHz if
22 * operating channel is 80+80MHz), multiple center frequencies are returned.
23 *
24 * @param channel the operating channel of the PHY
25 * @param channelWidth the channel width
26 * @return the center frequency of each segment covered by the given width
27 */
28std::vector<ns3::MHz_u>
30 ns3::MHz_u channelWidth)
31{
32 if (!channel.IsSet())
33 {
34 return {};
35 }
36 std::vector<ns3::MHz_u> freqs{};
37 const auto width = std::min(channelWidth, channel.GetWidth(0));
38 const auto primarySegmentIndex = channel.GetPrimarySegmentIndex(width);
39 const auto secondarySegmentIndex = channel.GetSecondarySegmentIndex(width);
40 const auto primaryIndex = channel.GetPrimaryChannelIndex(channelWidth);
41 const auto segmentIndices =
42 ((channel.GetNSegments() < 2) || (channelWidth <= channel.GetWidth(primarySegmentIndex)))
43 ? std::vector<uint8_t>{primarySegmentIndex}
44 : std::vector<uint8_t>{primarySegmentIndex, secondarySegmentIndex};
45 for (auto segmentIndex : segmentIndices)
46 {
47 const auto segmentFrequency = channel.GetFrequency(segmentIndex);
48 const auto segmentWidth = channel.GetWidth(segmentIndex);
49 // segmentOffset has to be an (unsigned) integer to ensure correct calculation
50 const uint8_t segmentOffset = (primarySegmentIndex * (segmentWidth / channelWidth));
51 const auto freq =
52 segmentFrequency - (segmentWidth / 2.) + (primaryIndex - segmentOffset + 0.5) * width;
53 freqs.push_back(freq);
54 }
55 return freqs;
56}
57} // namespace
58
59namespace ns3
60{
61
62NS_LOG_COMPONENT_DEFINE("WifiPpdu");
63
65 const WifiTxVector& txVector,
66 const WifiPhyOperatingChannel& channel,
67 uint64_t uid /* = UINT64_MAX */)
68 : m_preamble(txVector.GetPreambleType()),
69 m_modulation(txVector.IsValid() ? txVector.GetModulationClass() : WIFI_MOD_CLASS_UNKNOWN),
70 m_txCenterFreqs(GetChannelCenterFrequenciesPerSegment(channel, txVector.GetChannelWidth())),
71 m_uid(uid),
72 m_txVector(txVector),
73 m_operatingChannel(channel),
74 m_truncatedTx(false),
75 m_txPowerLevel(txVector.GetTxPowerLevel()),
76 m_txAntennas(txVector.GetNTx()),
77 m_txChannelWidth(txVector.GetChannelWidth())
78{
79 NS_LOG_FUNCTION(this << *psdu << txVector << channel << uid);
80 m_psdus.insert(std::make_pair(SU_STA_ID, psdu));
81}
82
84 const WifiTxVector& txVector,
85 const WifiPhyOperatingChannel& channel,
86 uint64_t uid)
87 : m_preamble(txVector.GetPreambleType()),
88 m_modulation(txVector.IsValid() ? txVector.GetMode(psdus.begin()->first).GetModulationClass()
90 m_txCenterFreqs(GetChannelCenterFrequenciesPerSegment(channel, txVector.GetChannelWidth())),
91 m_uid(uid),
92 m_txVector(txVector),
93 m_operatingChannel(channel),
94 m_truncatedTx(false),
95 m_txPowerLevel(txVector.GetTxPowerLevel()),
96 m_txAntennas(txVector.GetNTx()),
97 m_txChannelWidth(txVector.GetChannelWidth())
98{
99 NS_LOG_FUNCTION(this << psdus << txVector << channel << uid);
100 m_psdus = psdus;
101}
102
103WifiPpdu::~WifiPpdu() = default;
104
105const WifiTxVector&
107{
108 if (!m_txVector.has_value())
109 {
111 m_txVector->SetTxPowerLevel(m_txPowerLevel);
112 m_txVector->SetNTx(m_txAntennas);
113 m_txVector->SetChannelWidth(m_txChannelWidth);
114 }
115 return m_txVector.value();
116}
117
120{
121 NS_FATAL_ERROR("This method should not be called for the base WifiPpdu class. Use the "
122 "overloaded version in the amendment-specific PPDU subclasses instead!");
123 return WifiTxVector(); // should be overloaded
124}
125
126void
128{
129 NS_LOG_FUNCTION(this);
130 m_txVector.reset();
131}
132
133void
134WifiPpdu::UpdateTxVector(const WifiTxVector& updatedTxVector) const
135{
136 NS_LOG_FUNCTION(this << updatedTxVector);
138 m_txVector = updatedTxVector;
139}
140
143{
144 return m_psdus.begin()->second;
145}
146
147bool
149{
150 return m_truncatedTx;
151}
152
153void
155{
156 NS_LOG_FUNCTION(this);
157 m_truncatedTx = true;
158}
159
162{
163 return m_modulation;
164}
165
166MHz_u
168{
169 return m_txChannelWidth;
170}
171
172std::vector<MHz_u>
174{
175 return m_txCenterFreqs;
176}
177
178bool
180{
181 NS_LOG_FUNCTION(this << minFreq << maxFreq);
182 // all segments have the same width
183 const MHz_u txChannelWidth = (m_txChannelWidth / m_txCenterFreqs.size());
184 for (auto txCenterFreq : m_txCenterFreqs)
185 {
186 const auto minTxFreq = txCenterFreq - txChannelWidth / 2;
187 const auto maxTxFreq = txCenterFreq + txChannelWidth / 2;
188 /**
189 * The PPDU does not overlap the channel in two cases.
190 *
191 * First non-overlapping case:
192 *
193 * ┌─────────┐
194 * PPDU │ Nominal │
195 * │ Band │
196 * └─────────┘
197 * minTxFreq maxTxFreq
198 *
199 * minFreq maxFreq
200 * ┌──────────────────────────────┐
201 * │ Channel │
202 * └──────────────────────────────┘
203 *
204 * Second non-overlapping case:
205 *
206 * ┌─────────┐
207 * PPDU │ Nominal │
208 * │ Band │
209 * └─────────┘
210 * minTxFreq maxTxFreq
211 *
212 * minFreq maxFreq
213 * ┌──────────────────────────────┐
214 * │ Channel │
215 * └──────────────────────────────┘
216 */
217 if ((minTxFreq < maxFreq) && (maxTxFreq > minFreq))
218 {
219 return true;
220 }
221 }
222 return false;
223}
224
225uint64_t
227{
228 return m_uid;
229}
230
233{
234 return m_preamble;
235}
236
239{
240 return WIFI_PPDU_TYPE_SU;
241}
242
243uint16_t
245{
246 return SU_STA_ID;
247}
248
249Time
251{
252 NS_FATAL_ERROR("This method should not be called for the base WifiPpdu class. Use the "
253 "overloaded version in the amendment-specific PPDU subclasses instead!");
254 return MicroSeconds(0); // should be overloaded
255}
256
257void
258WifiPpdu::Print(std::ostream& os) const
259{
260 os << "[ preamble=" << m_preamble << ", modulation=" << m_modulation
261 << ", truncatedTx=" << (m_truncatedTx ? "Y" : "N") << ", UID=" << m_uid << ", "
262 << PrintPayload() << "]";
263}
264
265std::string
267{
268 std::ostringstream ss;
269 ss << "PSDU=" << *GetPsdu() << " ";
270 return ss.str();
271}
272
275{
276 NS_FATAL_ERROR("This method should not be called for the base WifiPpdu class. Use the "
277 "overloaded version in the amendment-specific PPDU subclasses instead!");
278 return Ptr<WifiPpdu>(new WifiPpdu(*this), false);
279}
280
281std::ostream&
282operator<<(std::ostream& os, const Ptr<const WifiPpdu>& ppdu)
283{
284 ppdu->Print(os);
285 return os;
286}
287
288} // namespace ns3
Smart pointer class similar to boost::intrusive_ptr.
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
Class that keeps track of all information about the current PHY operating channel.
void Print(std::ostream &os) const
Print the PPDU contents.
Definition wifi-ppdu.cc:258
virtual Time GetTxDuration() const
Get the total transmission duration of the PPDU.
Definition wifi-ppdu.cc:250
bool IsTruncatedTx() const
Definition wifi-ppdu.cc:148
WifiPreamble GetPreamble() const
Get the preamble of the PPDU.
Definition wifi-ppdu.cc:232
virtual MHz_u GetTxChannelWidth() const
Get the channel width over which the PPDU will effectively be transmitted.
Definition wifi-ppdu.cc:167
void ResetTxVector() const
Reset the TXVECTOR.
Definition wifi-ppdu.cc:127
virtual uint16_t GetStaId() const
Get the ID of the STA that transmitted the PPDU for UL MU, SU_STA_ID otherwise.
Definition wifi-ppdu.cc:244
WifiPpdu(Ptr< const WifiPsdu > psdu, const WifiTxVector &txVector, const WifiPhyOperatingChannel &channel, uint64_t uid=UINT64_MAX)
Create a PPDU storing a PSDU.
Definition wifi-ppdu.cc:64
void UpdateTxVector(const WifiTxVector &updatedTxVector) const
Update the TXVECTOR based on some information known at the receiver.
Definition wifi-ppdu.cc:134
virtual WifiPpduType GetType() const
Return the PPDU type (.
Definition wifi-ppdu.cc:238
std::optional< WifiTxVector > m_txVector
the TXVECTOR at TX PHY or the reconstructed TXVECTOR at RX PHY (or std::nullopt if TXVECTOR has not b...
Definition wifi-ppdu.h:199
WifiModulationClass m_modulation
the modulation used for the transmission of this PPDU
Definition wifi-ppdu.h:193
WifiPreamble m_preamble
the PHY preamble
Definition wifi-ppdu.h:192
MHz_u m_txChannelWidth
The channel width used for the transmission of this PPDU.
Definition wifi-ppdu.h:217
virtual ~WifiPpdu()
Destructor for WifiPpdu.
Ptr< const WifiPsdu > GetPsdu() const
Get the payload of the PPDU.
Definition wifi-ppdu.cc:142
virtual WifiTxVector DoGetTxVector() const
Get the TXVECTOR used to send the PPDU.
Definition wifi-ppdu.cc:119
uint64_t m_uid
the unique ID of this PPDU
Definition wifi-ppdu.h:197
std::vector< MHz_u > m_txCenterFreqs
the center frequency per segment used for the transmission of this PPDU
Definition wifi-ppdu.h:195
void SetTruncatedTx()
Indicate that the PPDU's transmission was aborted due to transmitter switch off.
Definition wifi-ppdu.cc:154
bool DoesOverlapChannel(MHz_u minFreq, MHz_u maxFreq) const
Check whether the given PPDU overlaps a given channel.
Definition wifi-ppdu.cc:179
const WifiTxVector & GetTxVector() const
Get the TXVECTOR used to send the PPDU.
Definition wifi-ppdu.cc:106
uint64_t GetUid() const
Get the UID of the PPDU.
Definition wifi-ppdu.cc:226
WifiModulationClass GetModulation() const
Get the modulation used for the PPDU.
Definition wifi-ppdu.cc:161
WifiConstPsduMap m_psdus
the PSDUs contained in this PPDU
Definition wifi-ppdu.h:194
virtual std::string PrintPayload() const
Print the payload of the PPDU.
Definition wifi-ppdu.cc:266
uint8_t m_txAntennas
the number of antennas used to transmit this PPDU
Definition wifi-ppdu.h:215
uint8_t m_txPowerLevel
the transmission power level (used only for TX and initializing the returned WifiTxVector)
Definition wifi-ppdu.h:213
virtual Ptr< WifiPpdu > Copy() const
Copy this instance.
Definition wifi-ppdu.cc:274
bool m_truncatedTx
flag indicating whether the frame's transmission was aborted due to transmitter switch off
Definition wifi-ppdu.h:211
std::vector< MHz_u > GetTxCenterFreqs() const
Definition wifi-ppdu.cc:173
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1369
WifiPreamble
The type of preamble to be used by an IEEE 802.11 transmission.
WifiPpduType
The type of PPDU (SU, DL MU, or UL MU)
WifiModulationClass
This enumeration defines the modulation classes per (Table 10-6 "Modulation classes"; IEEE 802....
@ WIFI_PPDU_TYPE_SU
@ WIFI_MOD_CLASS_UNKNOWN
Modulation class unknown or unspecified.
std::vector< ns3::MHz_u > GetChannelCenterFrequenciesPerSegment(const ns3::WifiPhyOperatingChannel &channel, ns3::MHz_u channelWidth)
Get the center frequency of each segment covered by the provided channel width.
Definition wifi-ppdu.cc:29
Definition first.py:1
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition angles.cc:148
double MHz_u
MHz weak type.
Definition wifi-units.h:31
std::unordered_map< uint16_t, Ptr< const WifiPsdu > > WifiConstPsduMap
Map of const PSDUs indexed by STA-ID.
Definition wifi-ppdu.h:38
static constexpr uint16_t SU_STA_ID
STA_ID to identify a single user (SU)
Definition wifi-mode.h:24
Declaration of ns3::WifiPpdu class and ns3::WifiConstPsduMap.