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
31namespace ns3 {
32
33NS_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
66void
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
97void
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
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
173void
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
186std::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
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
248void
249WifiTxParameters::Print (std::ostream& os) const
250{
251 os << "TXVECTOR=" << m_txVector;
252 if (m_protection)
253 {
254 os << ", Protection=" << m_protection.get ();
255 }
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
268std::ostream & operator << (std::ostream &os, const WifiTxParameters* txParams)
269{
270 txParams->Print (os);
271 return os;
272}
273
274} //namespace ns3
an EUI-48 address
Definition: mac48-address.h:44
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...
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...
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:74
static Time Min()
Minimum representable Time Not to be confused with Min(Time,Time).
Definition: nstime.h:273
Implements the IEEE 802.11 MAC header.
uint8_t GetQosTid(void) const
Return the Traffic ID of a QoS header.
bool HasData(void) const
Return true if the header type is DATA and is not DATA_NULL.
bool IsQosData(void) const
Return true if the Type is DATA and Subtype is one of the possible values for QoS Data.
uint16_t GetSequenceNumber(void) const
Return the sequence number of the header.
Mac48Address GetAddr1(void) const
Return the address in the Address 1 field.
This class stores the TX parameters (TX vector, protection mechanism, acknowledgment mechanism,...
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...
void Clear(void)
Reset the TX parameters.
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.
const PsduInfoMap & GetPsduInfoMap(void) const
Get a const reference to the map containing information about PSDUs.
std::unique_ptr< WifiProtection > m_protection
protection method
WifiTxParameters & operator=(const WifiTxParameters &txParams)
Copy assignment operator.
uint32_t GetSize(Mac48Address receiver) const
Get the size in bytes of the (A-)MPDU addressed to the given receiver.
uint32_t GetSizeIfAddMpdu(Ptr< const WifiMacQueueItem > mpdu) const
Get the size in bytes of the frame in case the given MPDU is added.
std::unique_ptr< WifiAcknowledgment > m_acknowledgment
acknowledgment method
const PsduInfo * GetPsduInfo(Mac48Address receiver) const
Get a pointer to the information about the PSDU addressed to the given receiver, if present,...
Time m_txDuration
TX duration of the frame.
WifiTxVector m_txVector
TXVECTOR of the frame being prepared.
PsduInfoMap m_info
information about the frame being prepared.
void Print(std::ostream &os) const
Print the object contents.
void AddMpdu(Ptr< const WifiMacQueueItem > mpdu)
Record that an MPDU is being added to the current frame.
std::map< Mac48Address, PsduInfo > PsduInfoMap
Map containing information about the PSDUs addressed to every receiver.
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
WifiModulationClass GetModulationClass(void) const
Get the modulation class specified by this TXVECTOR.
#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
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
@ WIFI_MOD_CLASS_VHT
VHT (Clause 22)
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static const uint16_t WIFI_MAC_FCS_LENGTH
The length in octects of the IEEE 802.11 MAC FCS field.
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:139
information about the frame being prepared for a specific receiver