A Discrete-Event Network Simulator
API
wifi-tx-parameters.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2020 Universita' degli Studi di Napoli Federico II
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Stefano Avallone <stavallo@unina.it>
19  */
20 
21 #include "wifi-tx-parameters.h"
22 #include "wifi-mac-queue-item.h"
23 #include "wifi-mac-trailer.h"
24 #include "msdu-aggregator.h"
25 #include "mpdu-aggregator.h"
26 #include "wifi-protection.h"
27 #include "wifi-acknowledgment.h"
28 #include "ns3/packet.h"
29 #include "ns3/log.h"
30 
31 namespace ns3 {
32 
33 NS_LOG_COMPONENT_DEFINE ("WifiTxParameters");
34 
36 {
37 }
38 
40 {
41  m_txVector = txParams.m_txVector;
42  m_protection = (txParams.m_protection ? txParams.m_protection->Copy () : nullptr);
43  m_acknowledgment = (txParams.m_acknowledgment ? txParams.m_acknowledgment->Copy () : nullptr);
44  m_txDuration = txParams.m_txDuration;
45  m_info = txParams.m_info;
46 }
47 
50 {
51  // check for self-assignment
52  if (&txParams == this)
53  {
54  return *this;
55  }
56 
57  m_txVector = txParams.m_txVector;
58  m_protection = (txParams.m_protection ? txParams.m_protection->Copy () : nullptr);
59  m_acknowledgment = (txParams.m_acknowledgment ? txParams.m_acknowledgment->Copy () : nullptr);
60  m_txDuration = txParams.m_txDuration;
61  m_info = txParams.m_info;
62 
63  return *this;
64 }
65 
66 void
68 {
69  NS_LOG_FUNCTION (this);
70 
71  // Reset the current info
72  m_info.clear ();
74  m_protection.reset (nullptr);
75  m_acknowledgment.reset (nullptr);
77 }
78 
81 {
82  auto infoIt = m_info.find (receiver);
83 
84  if (infoIt == m_info.end ())
85  {
86  return nullptr;
87  }
88  return &infoIt->second;
89 }
90 
93 {
94  return m_info;
95 }
96 
97 void
99 {
100  NS_LOG_FUNCTION (this << *mpdu);
101 
102  const WifiMacHeader& hdr = mpdu->GetHeader ();
103 
104  auto infoIt = m_info.find (hdr.GetAddr1 ());
105 
106  if (infoIt == m_info.end ())
107  {
108  // this is an MPDU starting a new PSDU
109  std::map<uint8_t, std::set<uint16_t>> seqNumbers;
110  if (hdr.IsQosData ())
111  {
112  seqNumbers[hdr.GetQosTid ()] = {hdr.GetSequenceNumber ()};
113  }
114 
115  // Insert the info about the given frame
116  m_info.emplace (hdr.GetAddr1 (),
117  PsduInfo {hdr, mpdu->GetPacketSize (), 0, seqNumbers});
118  return;
119  }
120 
121  // a PSDU for the receiver of the given MPDU is already being built
122  NS_ASSERT_MSG ((hdr.IsQosData () && !hdr.HasData ()) || infoIt->second.amsduSize > 0,
123  "An MPDU can only be aggregated to an existing (A-)MPDU");
124 
125  // The (A-)MSDU being built is included in an A-MPDU subframe
126  infoIt->second.ampduSize = MpduAggregator::GetSizeIfAggregated (infoIt->second.header.GetSize ()
127  + infoIt->second.amsduSize
129  infoIt->second.ampduSize);
130  infoIt->second.header = hdr;
131  infoIt->second.amsduSize = mpdu->GetPacketSize ();
132 
133  if (hdr.IsQosData ())
134  {
135  auto ret = infoIt->second.seqNumbers.emplace (hdr.GetQosTid (),
136  std::set<uint16_t> {hdr.GetSequenceNumber ()});
137 
138  if (!ret.second)
139  {
140  // insertion did not happen because an entry with the same TID already exists
141  ret.first->second.insert (hdr.GetSequenceNumber ());
142  }
143  }
144 }
145 
146 uint32_t
148 {
149  NS_LOG_FUNCTION (this << *mpdu);
150 
151  auto infoIt = m_info.find (mpdu->GetHeader ().GetAddr1 ());
152 
153  if (infoIt == m_info.end ())
154  {
155  // this is an MPDU starting a new PSDU
157  {
158  // All MPDUs are sent with the A-MPDU structure
159  return MpduAggregator::GetSizeIfAggregated (mpdu->GetSize (), 0);
160  }
161  return mpdu->GetSize ();
162  }
163 
164  // aggregate the (A-)MSDU being built to the existing A-MPDU (if any)
165  uint32_t ampduSize = MpduAggregator::GetSizeIfAggregated (infoIt->second.header.GetSize ()
166  + infoIt->second.amsduSize
168  infoIt->second.ampduSize);
169  // aggregate the new MPDU to the A-MPDU
170  return MpduAggregator::GetSizeIfAggregated (mpdu->GetSize (), ampduSize);
171 }
172 
173 void
175 {
176  NS_LOG_FUNCTION (this << *msdu);
177 
178  auto infoIt = m_info.find (msdu->GetHeader ().GetAddr1 ());
179  NS_ASSERT_MSG (infoIt != m_info.end (),
180  "There must be already an MPDU addressed to the same receiver");
181 
182  infoIt->second.amsduSize = GetSizeIfAggregateMsdu (msdu).first;
183  infoIt->second.header.SetQosAmsdu ();
184 }
185 
186 std::pair<uint32_t, uint32_t>
188 {
189  NS_LOG_FUNCTION (this << *msdu);
190 
191  NS_ASSERT_MSG (msdu->GetHeader ().IsQosData (), "Can only aggregate a QoS data frame to an A-MSDU");
192 
193  auto infoIt = m_info.find (msdu->GetHeader ().GetAddr1 ());
194  NS_ASSERT_MSG (infoIt != m_info.end (),
195  "There must be already an MPDU addressed to the same receiver");
196 
197  NS_ASSERT_MSG (infoIt->second.amsduSize > 0,
198  "The amsduSize should be set to the size of the previous MSDU(s)");
199  NS_ASSERT_MSG (infoIt->second.header.IsQosData (),
200  "The MPDU being built for this receiver must be a QoS data frame");
201  NS_ASSERT_MSG (infoIt->second.header.GetQosTid () == msdu->GetHeader ().GetQosTid (),
202  "The MPDU being built must belong to the same TID as the MSDU to aggregate");
203  NS_ASSERT_MSG (infoIt->second.seqNumbers.find (msdu->GetHeader ().GetQosTid ()) != infoIt->second.seqNumbers.end (),
204  "At least one MPDU with the same TID must have been added previously");
205 
206  // all checks passed
207  uint32_t currAmsduSize = infoIt->second.amsduSize;
208 
209  if (!infoIt->second.header.IsQosAmsdu ())
210  {
211  // consider the A-MSDU subframe for the first MSDU
212  currAmsduSize = MsduAggregator::GetSizeIfAggregated (currAmsduSize, 0);
213  }
214 
215  uint32_t newAmsduSize = MsduAggregator::GetSizeIfAggregated (msdu->GetPacket ()->GetSize (), currAmsduSize);
216  uint32_t newMpduSize = infoIt->second.header.GetSize () + newAmsduSize + WIFI_MAC_FCS_LENGTH;
217 
218  if (infoIt->second.ampduSize > 0 || m_txVector.GetModulationClass () >= WIFI_MOD_CLASS_VHT)
219  {
220  return {newAmsduSize, MpduAggregator::GetSizeIfAggregated (newMpduSize, infoIt->second.ampduSize)};
221  }
222 
223  return {newAmsduSize, newMpduSize};
224 }
225 
226 uint32_t
228 {
229  NS_LOG_FUNCTION (this << receiver);
230 
231  auto infoIt = m_info.find (receiver);
232 
233  if (infoIt == m_info.end ())
234  {
235  return 0;
236  }
237 
238  uint32_t newMpduSize = infoIt->second.header.GetSize () + infoIt->second.amsduSize + WIFI_MAC_FCS_LENGTH;
239 
240  if (infoIt->second.ampduSize > 0 || m_txVector.GetModulationClass () >= WIFI_MOD_CLASS_VHT)
241  {
242  return MpduAggregator::GetSizeIfAggregated (newMpduSize, infoIt->second.ampduSize);
243  }
244 
245  return newMpduSize;
246 }
247 
248 void
249 WifiTxParameters::Print (std::ostream& os) const
250 {
251  os << "TXVECTOR=" << m_txVector;
252  if (m_protection)
253  {
254  os << ", Protection=" << m_protection.get ();
255  }
256  if (m_acknowledgment)
257  {
258  os << ", Acknowledgment=" << m_acknowledgment.get ();
259  }
260  os << ", PSDUs:";
261  for (const auto& info : m_info)
262  {
263  os << " [To=" << info.second.header.GetAddr1 () << ", A-MSDU size="
264  << info.second.amsduSize << ", A-MPDU size=" << info.second.ampduSize << "]";
265  }
266 }
267 
268 std::ostream & operator << (std::ostream &os, const WifiTxParameters* txParams)
269 {
270  txParams->Print (os);
271  return os;
272 }
273 
274 } //namespace ns3
NS_LOG_COMPONENT_DEFINE
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
ns3::WifiTxParameters::PsduInfoMap
std::map< Mac48Address, PsduInfo > PsduInfoMap
Map containing information about the PSDUs addressed to every receiver.
Definition: wifi-tx-parameters.h:135
ns3::WifiTxParameters::GetPsduInfo
const PsduInfo * GetPsduInfo(Mac48Address receiver) const
Get a pointer to the information about the PSDU addressed to the given receiver, if present,...
Definition: wifi-tx-parameters.cc:80
ns3::WifiTxParameters::Print
void Print(std::ostream &os) const
Print the object contents.
Definition: wifi-tx-parameters.cc:249
ns3::WifiTxParameters::m_txDuration
Time m_txDuration
TX duration of the frame.
Definition: wifi-tx-parameters.h:65
ns3::WifiTxParameters::GetPsduInfoMap
const PsduInfoMap & GetPsduInfoMap(void) const
Get a const reference to the map containing information about PSDUs.
Definition: wifi-tx-parameters.cc:92
wifi-tx-parameters.h
ns3
Every class exported by the ns3 library is enclosed in the ns3 namespace.
ns3::WIFI_MAC_FCS_LENGTH
static const uint16_t WIFI_MAC_FCS_LENGTH
The length in octects of the IEEE 802.11 MAC FCS field.
Definition: wifi-mac-trailer.h:31
wifi-acknowledgment.h
ns3::WifiTxParameters::GetSize
uint32_t GetSize(Mac48Address receiver) const
Get the size in bytes of the (A-)MPDU addressed to the given receiver.
Definition: wifi-tx-parameters.cc:227
ns3::Mac48Address
an EUI-48 address
Definition: mac48-address.h:44
ns3::WifiTxVector
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
Definition: wifi-tx-vector.h:71
wifi-mac-queue-item.h
ns3::WifiMacHeader::GetAddr1
Mac48Address GetAddr1(void) const
Return the address in the Address 1 field.
Definition: wifi-mac-header.cc:424
ns3::WifiTxParameters::operator=
WifiTxParameters & operator=(const WifiTxParameters &txParams)
Copy assignment operator.
Definition: wifi-tx-parameters.cc:49
ns3::WifiTxParameters
This class stores the TX parameters (TX vector, protection mechanism, acknowledgment mechanism,...
Definition: wifi-tx-parameters.h:45
mpdu-aggregator.h
ns3::WifiTxParameters::m_protection
std::unique_ptr< WifiProtection > m_protection
protection method
Definition: wifi-tx-parameters.h:63
ns3::WifiMacHeader
Implements the IEEE 802.11 MAC header.
Definition: wifi-mac-header.h:85
ns3::Ptr
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:74
ns3::WifiTxVector::GetModulationClass
WifiModulationClass GetModulationClass(void) const
Get the modulation class specified by this TXVECTOR.
Definition: wifi-tx-vector.cc:127
ns3::WifiTxParameters::GetSizeIfAddMpdu
uint32_t GetSizeIfAddMpdu(Ptr< const WifiMacQueueItem > mpdu) const
Get the size in bytes of the frame in case the given MPDU is added.
Definition: wifi-tx-parameters.cc:147
ns3::WifiTxParameters::WifiTxParameters
WifiTxParameters()
Definition: wifi-tx-parameters.cc:35
ns3::WifiTxParameters::GetSizeIfAggregateMsdu
std::pair< uint32_t, uint32_t > GetSizeIfAggregateMsdu(Ptr< const WifiMacQueueItem > msdu) const
Get the size in bytes of the frame in case the given MSDU is aggregated.
Definition: wifi-tx-parameters.cc:187
ns3::WifiMacHeader::HasData
bool HasData(void) const
Return true if the header type is DATA and is not DATA_NULL.
Definition: wifi-mac-header.cc:632
ns3::WifiTxParameters::Clear
void Clear(void)
Reset the TX parameters.
Definition: wifi-tx-parameters.cc:67
ns3::WifiMacHeader::IsQosData
bool IsQosData(void) const
Return true if the Type is DATA and Subtype is one of the possible values for QoS Data.
Definition: wifi-mac-header.cc:565
ns3::WifiMacHeader::GetSequenceNumber
uint16_t GetSequenceNumber(void) const
Return the sequence number of the header.
Definition: wifi-mac-header.cc:777
NS_ASSERT_MSG
#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:88
msdu-aggregator.h
ns3::WifiTxParameters::m_acknowledgment
std::unique_ptr< WifiAcknowledgment > m_acknowledgment
acknowledgment method
Definition: wifi-tx-parameters.h:64
ns3::WifiMacHeader::GetQosTid
uint8_t GetQosTid(void) const
Return the Traffic ID of a QoS header.
Definition: wifi-mac-header.cc:862
ns3::Time::Min
static Time Min()
Minimum representable Time Not to be confused with Min(Time,Time).
Definition: nstime.h:274
ns3::WifiTxParameters::m_txVector
WifiTxVector m_txVector
TXVECTOR of the frame being prepared.
Definition: wifi-tx-parameters.h:62
ns3::MsduAggregator::GetSizeIfAggregated
static uint16_t GetSizeIfAggregated(uint16_t msduSize, uint16_t amsduSize)
Compute the size of the A-MSDU resulting from the aggregation of an MSDU of size msduSize and an A-MS...
Definition: msdu-aggregator.cc:77
wifi-protection.h
ns3::WifiTxParameters::m_info
PsduInfoMap m_info
information about the frame being prepared.
Definition: wifi-tx-parameters.h:151
NS_LOG_FUNCTION
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Definition: log-macros-enabled.h:244
ns3::WifiTxParameters::PsduInfo
information about the frame being prepared for a specific receiver
Definition: wifi-tx-parameters.h:115
ns3::WifiTxParameters::AggregateMsdu
void AggregateMsdu(Ptr< const WifiMacQueueItem > msdu)
Record that an MSDU is being aggregated to the last MPDU added to the frame that hase the same receiv...
Definition: wifi-tx-parameters.cc:174
ns3::WifiTxParameters::AddMpdu
void AddMpdu(Ptr< const WifiMacQueueItem > mpdu)
Record that an MPDU is being added to the current frame.
Definition: wifi-tx-parameters.cc:98
ns3::WIFI_MOD_CLASS_VHT
@ WIFI_MOD_CLASS_VHT
VHT (Clause 22)
Definition: wifi-phy-common.h:126
ns3::operator<<
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:137
wifi-mac-trailer.h
ns3::MpduAggregator::GetSizeIfAggregated
static uint32_t GetSizeIfAggregated(uint32_t mpduSize, uint32_t ampduSize)
Compute the size of the A-MPDU resulting from the aggregation of an MPDU of size mpduSize and an A-MP...
Definition: mpdu-aggregator.cc:113