A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
ofdm-ppdu.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2020 Orange Labs
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Author: Rediet <getachew.redieteab@orange.com>
18 * Muhammad Iqbal Rochman <muhiqbalcr@uchicago.edu>
19 * Sébastien Deronne <sebastien.deronne@gmail.com> (LSigHeader)
20 */
21
22#include "ofdm-ppdu.h"
23
24#include "ofdm-phy.h"
25
26#include "ns3/log.h"
27#include "ns3/wifi-phy.h"
28#include "ns3/wifi-psdu.h"
29
30namespace ns3
31{
32
33NS_LOG_COMPONENT_DEFINE("OfdmPpdu");
34
36 const WifiTxVector& txVector,
37 uint16_t txCenterFreq,
38 WifiPhyBand band,
39 uint64_t uid,
40 bool instantiateLSig /* = true */)
41 : WifiPpdu(psdu, txVector, txCenterFreq, uid),
42 m_band(band),
43 m_channelWidth(txVector.IsNonHtDuplicate() ? 20 : txVector.GetChannelWidth())
44{
45 NS_LOG_FUNCTION(this << psdu << txVector << txCenterFreq << band << uid);
46 if (instantiateLSig)
47 {
48 SetPhyHeaders(txVector, psdu->GetSize());
49 }
50}
51
52void
53OfdmPpdu::SetPhyHeaders(const WifiTxVector& txVector, std::size_t psduSize)
54{
55 NS_LOG_FUNCTION(this << txVector << psduSize);
56
57#ifdef NS3_BUILD_PROFILE_DEBUG
58 LSigHeader lSig;
59 SetLSigHeader(lSig, txVector, psduSize);
61#else
62 SetLSigHeader(m_lSig, txVector, psduSize);
63#endif
64}
65
66void
67OfdmPpdu::SetLSigHeader(LSigHeader& lSig, const WifiTxVector& txVector, std::size_t psduSize) const
68{
69 lSig.SetRate(txVector.GetMode().GetDataRate(txVector), m_channelWidth);
70 lSig.SetLength(psduSize);
71}
72
75{
76 WifiTxVector txVector;
78
79#ifdef NS3_BUILD_PROFILE_DEBUG
80 LSigHeader lSig;
81 if (m_phyHeaders->PeekHeader(lSig) == 0)
82 {
83 NS_FATAL_ERROR("Missing L-SIG in PPDU");
84 }
85
86 SetTxVectorFromLSigHeader(txVector, lSig);
87#else
88 SetTxVectorFromLSigHeader(txVector, m_lSig);
89#endif
90
91 return txVector;
92}
93
94void
96{
98 // OFDM uses 20 MHz, unless PHY channel width is 5 MHz or 10 MHz
101}
102
103Time
105{
106 const WifiTxVector& txVector = GetTxVector();
107 uint16_t length = 0;
108#ifdef NS3_BUILD_PROFILE_DEBUG
109 LSigHeader lSig;
111 length = lSig.GetLength();
112#else
113 length = m_lSig.GetLength();
114#endif
115 return WifiPhy::CalculateTxDuration(length, txVector, m_band);
116}
117
120{
121 return Ptr<WifiPpdu>(new OfdmPpdu(*this), false);
122}
123
125 : m_rate(0b1101),
126 m_length(0)
127{
128}
129
130TypeId
132{
133 static TypeId tid = TypeId("ns3::LSigHeader")
134 .SetParent<Header>()
135 .SetGroupName("Wifi")
136 .AddConstructor<LSigHeader>();
137 return tid;
138}
139
140TypeId
142{
143 return GetTypeId();
144}
145
146void
147OfdmPpdu::LSigHeader::Print(std::ostream& os) const
148{
149 os << "SIGNAL=" << GetRate() << " LENGTH=" << m_length;
150}
151
154{
155 return 3;
156}
157
158void
159OfdmPpdu::LSigHeader::SetRate(uint64_t rate, uint16_t channelWidth)
160{
161 if (channelWidth == 5)
162 {
163 rate *= 4; // corresponding 20 MHz rate if 5 MHz is used
164 }
165 else if (channelWidth == 10)
166 {
167 rate *= 2; // corresponding 20 MHz rate if 10 MHz is used
168 }
169 /* Here is the binary representation for a given rate:
170 * 6 Mbit/s: 1101
171 * 9 Mbit/s: 1111
172 * 12 Mbit/s: 0101
173 * 18 Mbit/s: 0111
174 * 24 Mbit/s: 1001
175 * 36 Mbit/s: 1011
176 * 48 Mbit/s: 0001
177 * 54 Mbit/s: 0011
178 */
179 switch (rate)
180 {
181 case 6000000:
182 m_rate = 0b1101;
183 break;
184 case 9000000:
185 m_rate = 0b1111;
186 break;
187 case 12000000:
188 m_rate = 0b0101;
189 break;
190 case 18000000:
191 m_rate = 0b0111;
192 break;
193 case 24000000:
194 m_rate = 0b1001;
195 break;
196 case 36000000:
197 m_rate = 0b1011;
198 break;
199 case 48000000:
200 m_rate = 0b0001;
201 break;
202 case 54000000:
203 m_rate = 0b0011;
204 break;
205 default:
206 NS_ASSERT_MSG(false, "Invalid rate");
207 break;
208 }
209}
210
211uint64_t
212OfdmPpdu::LSigHeader::GetRate(uint16_t channelWidth) const
213{
214 uint64_t rate = 0;
215 switch (m_rate)
216 {
217 case 0b1101:
218 rate = 6000000;
219 break;
220 case 0b1111:
221 rate = 9000000;
222 break;
223 case 0b0101:
224 rate = 12000000;
225 break;
226 case 0b0111:
227 rate = 18000000;
228 break;
229 case 0b1001:
230 rate = 24000000;
231 break;
232 case 0b1011:
233 rate = 36000000;
234 break;
235 case 0b0001:
236 rate = 48000000;
237 break;
238 case 0b0011:
239 rate = 54000000;
240 break;
241 default:
242 NS_ASSERT_MSG(false, "Invalid rate");
243 break;
244 }
245 if (channelWidth == 5)
246 {
247 rate /= 4; // compute corresponding 5 MHz rate
248 }
249 else if (channelWidth == 10)
250 {
251 rate /= 2; // compute corresponding 10 MHz rate
252 }
253 return rate;
254}
255
256void
258{
259 NS_ASSERT_MSG(length < 4096, "Invalid length");
260 m_length = length;
261}
262
263uint16_t
265{
266 return m_length;
267}
268
269void
271{
272 uint8_t byte = 0;
273 uint16_t bytes = 0;
274
275 byte |= m_rate;
276 byte |= (m_length & 0x07) << 5;
277 start.WriteU8(byte);
278
279 bytes |= (m_length & 0x0ff8) >> 3;
280 start.WriteU16(bytes);
281}
282
285{
286 Buffer::Iterator i = start;
287
288 uint8_t byte = i.ReadU8();
289 m_rate = byte & 0x0f;
290 m_length = (byte >> 5) & 0x07;
291
292 uint16_t bytes = i.ReadU16();
293 m_length |= (bytes << 3) & 0x0ff8;
294
295 return i.GetDistanceFrom(start);
296}
297
298} // namespace ns3
iterator in a Buffer instance
Definition: buffer.h:100
uint8_t ReadU8()
Definition: buffer.h:1027
uint32_t GetDistanceFrom(const Iterator &o) const
Definition: buffer.cc:783
uint16_t ReadU16()
Definition: buffer.h:1035
Protocol header serialization and deserialization.
Definition: header.h:44
static WifiMode GetOfdmRate(uint64_t rate, uint16_t bw=20)
Return a WifiMode for OFDM corresponding to the provided rate and the channel bandwidth (20,...
Definition: ofdm-phy.cc:413
OFDM and ERP OFDM L-SIG PHY header.
Definition: ofdm-ppdu.h:55
void SetRate(uint64_t rate, uint16_t channelWidth=20)
Fill the RATE field of L-SIG (in bit/s).
Definition: ofdm-ppdu.cc:159
uint64_t GetRate(uint16_t channelWidth=20) const
Return the RATE field of L-SIG (in bit/s).
Definition: ofdm-ppdu.cc:212
uint16_t GetLength() const
Return the LENGTH field of L-SIG (in bytes).
Definition: ofdm-ppdu.cc:264
void Print(std::ostream &os) const override
Definition: ofdm-ppdu.cc:147
uint32_t Deserialize(Buffer::Iterator start) override
Definition: ofdm-ppdu.cc:284
TypeId GetInstanceTypeId() const override
Get the most derived TypeId for this Object.
Definition: ofdm-ppdu.cc:141
uint32_t GetSerializedSize() const override
Definition: ofdm-ppdu.cc:153
void SetLength(uint16_t length)
Fill the LENGTH field of L-SIG (in bytes).
Definition: ofdm-ppdu.cc:257
static TypeId GetTypeId()
Get the type ID.
Definition: ofdm-ppdu.cc:131
void Serialize(Buffer::Iterator start) const override
Definition: ofdm-ppdu.cc:270
OFDM PPDU (11a)
Definition: ofdm-ppdu.h:48
WifiPhyBand m_band
the WifiPhyBand used to transmit that PPDU
Definition: ofdm-ppdu.h:125
void SetLSigHeader(LSigHeader &lSig, const WifiTxVector &txVector, std::size_t psduSize) const
Fill in the L-SIG header.
Definition: ofdm-ppdu.cc:67
OfdmPpdu(Ptr< const WifiPsdu > psdu, const WifiTxVector &txVector, uint16_t txCenterFreq, WifiPhyBand band, uint64_t uid, bool instantiateLSig=true)
Create an OFDM PPDU.
Definition: ofdm-ppdu.cc:35
void SetPhyHeaders(const WifiTxVector &txVector, std::size_t psduSize)
Fill in the PHY headers.
Definition: ofdm-ppdu.cc:53
Time GetTxDuration() const override
Get the total transmission duration of the PPDU.
Definition: ofdm-ppdu.cc:104
uint16_t m_channelWidth
the channel width used to transmit that PPDU in MHz (needed to distinguish 5 MHz, 10 MHz or 20 MHz PP...
Definition: ofdm-ppdu.h:158
Ptr< WifiPpdu > Copy() const override
Copy this instance.
Definition: ofdm-ppdu.cc:119
virtual void SetTxVectorFromLSigHeader(WifiTxVector &txVector, const LSigHeader &lSig) const
Fill in the TXVECTOR from L-SIG header.
Definition: ofdm-ppdu.cc:95
WifiTxVector DoGetTxVector() const override
Get the TXVECTOR used to send the PPDU.
Definition: ofdm-ppdu.cc:74
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:268
uint32_t PeekHeader(Header &header) const
Deserialize but does not remove the header from the internal buffer.
Definition: packet.cc:305
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
a unique identifier for an interface.
Definition: type-id.h:60
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
uint64_t GetDataRate(uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
Definition: wifi-mode.cc:122
static Time CalculateTxDuration(uint32_t size, const WifiTxVector &txVector, WifiPhyBand band, uint16_t staId=SU_STA_ID)
Definition: wifi-phy.cc:1480
WifiPpdu stores a preamble, a modulation class, PHY headers and a PSDU.
Definition: wifi-ppdu.h:56
WifiPreamble m_preamble
the PHY preamble
Definition: wifi-ppdu.h:201
const WifiTxVector & GetTxVector() const
Get the TXVECTOR used to send the PPDU.
Definition: wifi-ppdu.cc:82
Ptr< Packet > m_phyHeaders
the PHY headers contained in this PPDU
Definition: wifi-ppdu.h:211
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
void SetChannelWidth(uint16_t channelWidth)
Sets the selected channelWidth (in MHz)
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.
void SetMode(WifiMode mode)
Sets the selected payload transmission mode.
void SetPreambleType(WifiPreamble preamble)
Sets the preamble type.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:86
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
WifiPhyBand
Identifies the PHY band.
Definition: wifi-phy-band.h:33
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Declaration of ns3::OfdmPhy class and ns3::OfdmPhyVariant enum.
Declaration of ns3::OfdmPpdu class.