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
104{
105 for (auto& psdu : m_psdus)
106 {
107 psdu.second = nullptr;
108 }
109 m_psdus.clear();
110}
111
112const WifiTxVector&
114{
115 if (!m_txVector.has_value())
116 {
118 m_txVector->SetTxPowerLevel(m_txPowerLevel);
119 m_txVector->SetNTx(m_txAntennas);
120 m_txVector->SetChannelWidth(m_txChannelWidth);
121 }
122 return m_txVector.value();
123}
124
127{
128 NS_FATAL_ERROR("This method should not be called for the base WifiPpdu class. Use the "
129 "overloaded version in the amendment-specific PPDU subclasses instead!");
130 return WifiTxVector(); // should be overloaded
131}
132
133void
135{
136 NS_LOG_FUNCTION(this);
137 m_txVector.reset();
138}
139
140void
141WifiPpdu::UpdateTxVector(const WifiTxVector& updatedTxVector) const
142{
143 NS_LOG_FUNCTION(this << updatedTxVector);
145 m_txVector = updatedTxVector;
146}
147
150{
151 return m_psdus.begin()->second;
152}
153
154bool
156{
157 return m_truncatedTx;
158}
159
160void
162{
163 NS_LOG_FUNCTION(this);
164 m_truncatedTx = true;
165}
166
169{
170 return m_modulation;
171}
172
173MHz_u
175{
176 return m_txChannelWidth;
177}
178
179std::vector<MHz_u>
181{
182 return m_txCenterFreqs;
183}
184
185bool
187{
188 NS_LOG_FUNCTION(this << minFreq << maxFreq);
189 // all segments have the same width
190 const MHz_u txChannelWidth = (m_txChannelWidth / m_txCenterFreqs.size());
191 for (auto txCenterFreq : m_txCenterFreqs)
192 {
193 const auto minTxFreq = txCenterFreq - txChannelWidth / 2;
194 const auto maxTxFreq = txCenterFreq + txChannelWidth / 2;
195 /**
196 * The PPDU does not overlap the channel in two cases.
197 *
198 * First non-overlapping case:
199 *
200 * ┌─────────┐
201 * PPDU │ Nominal │
202 * │ Band │
203 * └─────────┘
204 * minTxFreq maxTxFreq
205 *
206 * minFreq maxFreq
207 * ┌──────────────────────────────┐
208 * │ Channel │
209 * └──────────────────────────────┘
210 *
211 * Second non-overlapping case:
212 *
213 * ┌─────────┐
214 * PPDU │ Nominal │
215 * │ Band │
216 * └─────────┘
217 * minTxFreq maxTxFreq
218 *
219 * minFreq maxFreq
220 * ┌──────────────────────────────┐
221 * │ Channel │
222 * └──────────────────────────────┘
223 */
224 if ((minTxFreq < maxFreq) && (maxTxFreq > minFreq))
225 {
226 return true;
227 }
228 }
229 return false;
230}
231
232uint64_t
234{
235 return m_uid;
236}
237
240{
241 return m_preamble;
242}
243
246{
247 return WIFI_PPDU_TYPE_SU;
248}
249
250uint16_t
252{
253 return SU_STA_ID;
254}
255
256Time
258{
259 NS_FATAL_ERROR("This method should not be called for the base WifiPpdu class. Use the "
260 "overloaded version in the amendment-specific PPDU subclasses instead!");
261 return MicroSeconds(0); // should be overloaded
262}
263
264void
265WifiPpdu::Print(std::ostream& os) const
266{
267 os << "[ preamble=" << m_preamble << ", modulation=" << m_modulation
268 << ", truncatedTx=" << (m_truncatedTx ? "Y" : "N") << ", UID=" << m_uid << ", "
269 << PrintPayload() << "]";
270}
271
272std::string
274{
275 std::ostringstream ss;
276 ss << "PSDU=" << GetPsdu() << " ";
277 return ss.str();
278}
279
282{
283 NS_FATAL_ERROR("This method should not be called for the base WifiPpdu class. Use the "
284 "overloaded version in the amendment-specific PPDU subclasses instead!");
285 return Ptr<WifiPpdu>(new WifiPpdu(*this), false);
286}
287
288std::ostream&
289operator<<(std::ostream& os, const Ptr<const WifiPpdu>& ppdu)
290{
291 ppdu->Print(os);
292 return os;
293}
294
295std::ostream&
296operator<<(std::ostream& os, const WifiConstPsduMap& psdus)
297{
298 for (const auto& psdu : psdus)
299 {
300 os << "PSDU for STA_ID=" << psdu.first << " (" << *psdu.second << ") ";
301 }
302 return os;
303}
304
305} // 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:265
virtual Time GetTxDuration() const
Get the total transmission duration of the PPDU.
Definition wifi-ppdu.cc:257
bool IsTruncatedTx() const
Definition wifi-ppdu.cc:155
WifiPreamble GetPreamble() const
Get the preamble of the PPDU.
Definition wifi-ppdu.cc:239
virtual MHz_u GetTxChannelWidth() const
Get the channel width over which the PPDU will effectively be transmitted.
Definition wifi-ppdu.cc:174
void ResetTxVector() const
Reset the TXVECTOR.
Definition wifi-ppdu.cc:134
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:251
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:141
virtual WifiPpduType GetType() const
Return the PPDU type (.
Definition wifi-ppdu.cc:245
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.
Definition wifi-ppdu.cc:103
Ptr< const WifiPsdu > GetPsdu() const
Get the payload of the PPDU.
Definition wifi-ppdu.cc:149
virtual WifiTxVector DoGetTxVector() const
Get the TXVECTOR used to send the PPDU.
Definition wifi-ppdu.cc:126
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:161
bool DoesOverlapChannel(MHz_u minFreq, MHz_u maxFreq) const
Check whether the given PPDU overlaps a given channel.
Definition wifi-ppdu.cc:186
const WifiTxVector & GetTxVector() const
Get the TXVECTOR used to send the PPDU.
Definition wifi-ppdu.cc:113
uint64_t GetUid() const
Get the UID of the PPDU.
Definition wifi-ppdu.cc:233
WifiModulationClass GetModulation() const
Get the modulation used for the PPDU.
Definition wifi-ppdu.cc:168
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:273
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:281
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:180
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:1332
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::unordered_map< uint16_t, Ptr< const WifiPsdu > > WifiConstPsduMap
Map of const PSDUs indexed by STA-ID.
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition angles.cc:148
double MHz_u
MHz weak type.
Definition wifi-units.h:31
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.