A Discrete-Event Network Simulator
API
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 
30 namespace ns3
31 {
32 
33 NS_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 
52 void
53 OfdmPpdu::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);
60  m_phyHeaders->AddHeader(lSig);
61 #else
62  SetLSigHeader(m_lSig, txVector, psduSize);
63 #endif
64 }
65 
66 void
67 OfdmPpdu::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;
77  txVector.SetPreambleType(m_preamble);
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 
94 void
96 {
98  // OFDM uses 20 MHz, unless PHY channel width is 5 MHz or 10 MHz
101 }
102 
103 Time
105 {
106  const WifiTxVector& txVector = GetTxVector();
107  uint16_t length = 0;
108 #ifdef NS3_BUILD_PROFILE_DEBUG
109  LSigHeader lSig;
110  m_phyHeaders->PeekHeader(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 
130 TypeId
132 {
133  static TypeId tid = TypeId("ns3::LSigHeader")
134  .SetParent<Header>()
135  .SetGroupName("Wifi")
136  .AddConstructor<LSigHeader>();
137  return tid;
138 }
139 
140 TypeId
142 {
143  return GetTypeId();
144 }
145 
146 void
147 OfdmPpdu::LSigHeader::Print(std::ostream& os) const
148 {
149  os << "SIGNAL=" << GetRate() << " LENGTH=" << m_length;
150 }
151 
152 uint32_t
154 {
155  return 3;
156 }
157 
158 void
159 OfdmPpdu::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 
211 uint64_t
212 OfdmPpdu::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 
256 void
258 {
259  NS_ASSERT_MSG(length < 4096, "Invalid length");
260  m_length = length;
261 }
262 
263 uint16_t
265 {
266  return m_length;
267 }
268 
269 void
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 
283 uint32_t
285 {
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
virtual uint32_t Deserialize(Buffer::Iterator start)=0
Deserialize the object from a buffer iterator.
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
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
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
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
uint32_t GetSize() const
Return the size of the PSDU in bytes.
Definition: wifi-psdu.cc:273
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.