A Discrete-Event Network Simulator
API
wifi-mpdu.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2005, 2009 INRIA
3 * Copyright (c) 2009 MIRKO BANCHI
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 * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19 * Mirko Banchi <mk.banchi@gmail.com>
20 * Stefano Avallone <stavallo@unina.it>
21 */
22
23#include "wifi-mpdu.h"
24
25#include "msdu-aggregator.h"
26#include "wifi-mac-trailer.h"
27#include "wifi-utils.h"
28
29#include "ns3/log.h"
30#include "ns3/packet.h"
31#include "ns3/simulator.h"
32
33namespace ns3
34{
35
36NS_LOG_COMPONENT_DEFINE("WifiMpdu");
37
39 : m_packet(p),
40 m_header(header)
41{
42 if (header.IsQosData() && header.IsQosAmsdu())
43 {
45 }
46 m_inFlight = false;
47}
48
50{
51}
52
55{
56 return m_packet;
57}
58
59const WifiMacHeader&
61{
62 return m_header;
63}
64
67{
68 return m_header;
69}
70
73{
74 return m_header.GetAddr1();
75}
76
79{
80 return m_packet->GetSize();
81}
82
85{
87}
88
89bool
91{
93}
94
97{
98 Ptr<Packet> mpdu = m_packet->Copy();
99 mpdu->AddHeader(m_header);
100 AddWifiMacTrailer(mpdu);
101 return mpdu;
102}
103
104void
106{
107 NS_ASSERT(msdu);
108 NS_LOG_FUNCTION(this << *msdu);
109 NS_ABORT_MSG_IF(!msdu->GetHeader().IsQosData() || msdu->GetHeader().IsQosAmsdu(),
110 "Only QoS data frames that do not contain an A-MSDU can be aggregated");
111
112 if (m_msduList.empty())
113 {
114 // An MSDU is going to be aggregated to this MPDU, hence this has to be an A-MSDU now
115 Ptr<const WifiMpdu> firstMsdu = Create<const WifiMpdu>(*this);
116 m_packet = Create<Packet>();
117 DoAggregate(firstMsdu);
118
120 // Set Address3 according to Table 9-26 of 802.11-2016
121 if (m_header.IsToDs() && !m_header.IsFromDs())
122 {
123 // from STA to AP: BSSID is in Address1
125 }
126 else if (!m_header.IsToDs() && m_header.IsFromDs())
127 {
128 // from AP to STA: BSSID is in Address2
130 }
131 // in the WDS case (ToDS = FromDS = 1), both Address 3 and Address 4 need
132 // to be set to the BSSID, but neither Address 1 nor Address 2 contain the
133 // BSSID. Hence, it is left up to the caller to set these Address fields.
134 }
135 DoAggregate(msdu);
136}
137
138void
140{
141 NS_LOG_FUNCTION(this << *msdu);
142
143 // build the A-MSDU Subframe header
145 /*
146 * (See Table 9-26 of 802.11-2016)
147 *
148 * ToDS | FromDS | DA | SA
149 * 0 | 0 | Addr1 | Addr2
150 * 0 | 1 | Addr1 | Addr3
151 * 1 | 0 | Addr3 | Addr2
152 * 1 | 1 | Addr3 | Addr4
153 */
154 hdr.SetDestinationAddr(msdu->GetHeader().IsToDs() ? msdu->GetHeader().GetAddr3()
155 : msdu->GetHeader().GetAddr1());
156 hdr.SetSourceAddr(!msdu->GetHeader().IsFromDs()
157 ? msdu->GetHeader().GetAddr2()
158 : (!msdu->GetHeader().IsToDs() ? msdu->GetHeader().GetAddr3()
159 : msdu->GetHeader().GetAddr4()));
160 hdr.SetLength(static_cast<uint16_t>(msdu->GetPacket()->GetSize()));
161
162 m_msduList.emplace_back(msdu->GetPacket(), hdr);
163
164 // build the A-MSDU
166 Ptr<Packet> amsdu = m_packet->Copy();
167
168 // pad the previous A-MSDU subframe if the A-MSDU is not empty
169 if (m_packet->GetSize() > 0)
170 {
172
173 if (padding)
174 {
175 amsdu->AddAtEnd(Create<Packet>(padding));
176 }
177 }
178
179 // add A-MSDU subframe header and MSDU
180 Ptr<Packet> amsduSubframe = msdu->GetPacket()->Copy();
181 amsduSubframe->AddHeader(hdr);
182 amsdu->AddAtEnd(amsduSubframe);
183 m_packet = amsdu;
184}
185
186bool
188{
189 return m_queueIt.has_value();
190}
191
192void
193WifiMpdu::SetQueueIt(std::optional<Iterator> queueIt, WmqIteratorTag tag)
194{
195 m_queueIt = queueIt;
196}
197
200{
202 return m_queueIt.value();
203}
204
207{
209 return (*m_queueIt)->ac;
210}
211
212Time
214{
216 return (*m_queueIt)->expiryTime;
217}
218
219void
221{
222 m_inFlight = true;
223}
224
225void
227{
228 m_inFlight = false;
229}
230
231bool
233{
234 return m_inFlight;
235}
236
239{
240 return m_msduList.cbegin();
241}
242
245{
246 return m_msduList.cend();
247}
248
249void
250WifiMpdu::Print(std::ostream& os) const
251{
252 os << m_header.GetTypeString() << ", payloadSize=" << GetPacketSize()
253 << ", to=" << m_header.GetAddr1() << ", seqN=" << m_header.GetSequenceNumber()
254 << ", duration/ID=" << m_header.GetDuration();
255 if (m_header.IsQosData())
256 {
257 os << ", tid=" << +m_header.GetQosTid();
258 if (m_header.IsQosNoAck())
259 {
260 os << ", ack=NoAck";
261 }
262 else if (m_header.IsQosAck())
263 {
264 os << ", ack=NormalAck";
265 }
266 else if (m_header.IsQosBlockAck())
267 {
268 os << ", ack=BlockAck";
269 }
270 }
271 os << ", queued=" << IsQueued();
272 if (IsQueued())
273 {
274 os << ", residualLifetime=" << (GetExpiryTime() - Simulator::Now()).As(Time::US)
275 << ", inflight=" << IsInFlight();
276 }
277 os << ", packet=" << m_packet;
278}
279
280std::ostream&
281operator<<(std::ostream& os, const WifiMpdu& item)
282{
283 item.Print(os);
284 return os;
285}
286
287} // namespace ns3
Headers for A-MSDU subframes.
void SetSourceAddr(Mac48Address to)
Set source address function.
void SetDestinationAddr(Mac48Address to)
Set destination address function.
void SetLength(uint16_t length)
Set length function.
an EUI-48 address
Definition: mac48-address.h:46
static WifiMpdu::DeaggregatedMsdus Deaggregate(Ptr< Packet > aggregatedPacket)
static uint8_t CalculatePadding(uint16_t amsduSize)
Calculate how much padding must be added to the end of an A-MSDU of the given size if a new MSDU is a...
void AddAtEnd(Ptr< const Packet > packet)
Concatenate the input packet at the end of the current packet.
Definition: packet.cc:354
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:268
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:863
Ptr< Packet > Copy() const
performs a COW copy of the packet.
Definition: packet.cc:131
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:199
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
@ US
microsecond
Definition: nstime.h:118
Implements the IEEE 802.11 MAC header.
uint8_t GetQosTid() const
Return the Traffic ID of a QoS header.
bool IsQosAmsdu() const
Check if the A-MSDU present bit is set in the QoS control field.
void SetQosAmsdu()
Set that A-MSDU is present.
uint32_t GetSerializedSize() const override
Mac48Address GetAddr1() const
Return the address in the Address 1 field.
uint16_t GetSequenceNumber() const
Return the sequence number of the header.
bool IsMoreFragments() const
Return if the More Fragment bit is set.
Time GetDuration() const
Return the duration from the Duration/ID field (Time object).
Mac48Address GetAddr2() const
Return the address in the Address 2 field.
const char * GetTypeString() const
Return a string corresponds to the header type.
bool IsQosAck() const
Return if the QoS Ack policy is Normal Ack.
bool IsQosNoAck() const
Return if the QoS Ack policy is No Ack.
bool IsQosBlockAck() const
Return if the QoS Ack policy is Block Ack.
uint8_t GetFragmentNumber() const
Return the fragment number of the header.
bool IsQosData() const
Return true if the Type is DATA and Subtype is one of the possible values for QoS Data.
void SetAddr3(Mac48Address address)
Fill the Address 3 field with the given address.
WifiMpdu stores (const) packets along with their Wifi MAC headers and the time when they were enqueue...
Definition: wifi-mpdu.h:57
Time GetExpiryTime() const
Definition: wifi-mpdu.cc:213
bool IsInFlight() const
Return true if this MPDU is in flight, false otherwise.
Definition: wifi-mpdu.cc:232
DeaggregatedMsdus m_msduList
The list of aggregated MSDUs included in this MPDU.
Definition: wifi-mpdu.h:216
Ptr< const Packet > m_packet
The packet (MSDU or A-MSDU) contained in this queue item.
Definition: wifi-mpdu.h:214
WifiMacHeader m_header
Wifi MAC header associated with the packet.
Definition: wifi-mpdu.h:215
std::list< std::pair< Ptr< constPacket >, AmsduSubframeHeader > >::const_iterator DeaggregatedMsdusCI
DeaggregatedMsdusCI typedef.
Definition: wifi-mpdu.h:127
const WifiMacHeader & GetHeader() const
Get the header stored in this item.
Definition: wifi-mpdu.cc:60
void Aggregate(Ptr< const WifiMpdu > msdu)
Aggregate the MSDU contained in the given MPDU to this MPDU (thus constituting an A-MSDU).
Definition: wifi-mpdu.cc:105
void ResetInFlight()
Mark this MPDU as not being in flight (only used if Block Ack agreement established).
Definition: wifi-mpdu.cc:226
virtual ~WifiMpdu()
Definition: wifi-mpdu.cc:49
uint32_t GetSize() const
Return the size of the packet stored by this item, including header size and trailer size.
Definition: wifi-mpdu.cc:84
Ptr< Packet > GetProtocolDataUnit() const
Get the MAC protocol data unit (MPDU) corresponding to this item (i.e.
Definition: wifi-mpdu.cc:96
void DoAggregate(Ptr< const WifiMpdu > msdu)
Aggregate the MSDU contained in the given MPDU to this MPDU (thus constituting an A-MSDU).
Definition: wifi-mpdu.cc:139
bool m_inFlight
whether the MPDU is in flight
Definition: wifi-mpdu.h:218
virtual void Print(std::ostream &os) const
Print the item contents.
Definition: wifi-mpdu.cc:250
Iterator GetQueueIt(WmqIteratorTag tag) const
Definition: wifi-mpdu.cc:199
void SetInFlight()
Mark this MPDU as being in flight (only used if Block Ack agreement established).
Definition: wifi-mpdu.cc:220
Ptr< const Packet > GetPacket() const
Get the packet stored in this item.
Definition: wifi-mpdu.cc:54
DeaggregatedMsdusCI end() const
Get a constant iterator indicating past-the-last MSDU in the list of aggregated MSDUs.
Definition: wifi-mpdu.cc:244
DeaggregatedMsdusCI begin() const
Get a constant iterator pointing to the first MSDU in the list of aggregated MSDUs.
Definition: wifi-mpdu.cc:238
uint32_t GetPacketSize() const
Return the size in bytes of the packet or control header or management header stored by this item.
Definition: wifi-mpdu.cc:78
AcIndex GetQueueAc() const
Get the AC of the queue this item is stored into.
Definition: wifi-mpdu.cc:206
std::list< WifiMacQueueElem >::iterator Iterator
Const iterator typedef.
Definition: wifi-mpdu.h:143
Mac48Address GetDestinationAddress() const
Return the destination address present in the header.
Definition: wifi-mpdu.cc:72
bool IsQueued() const
Return true if this item is stored in some queue, false otherwise.
Definition: wifi-mpdu.cc:187
void SetQueueIt(std::optional< Iterator > queueIt, WmqIteratorTag tag)
Set the queue iterator stored by this object.
Definition: wifi-mpdu.cc:193
bool IsFragment() const
Return true if this item contains an MSDU fragment, false otherwise.
Definition: wifi-mpdu.cc:90
WifiMpdu(Ptr< const Packet > p, const WifiMacHeader &header)
Create a Wifi MAC queue item containing a packet and a Wifi MAC header.
Definition: wifi-mpdu.cc:38
std::optional< Iterator > m_queueIt
Queue iterator pointing to this MPDU, if queued.
Definition: wifi-mpdu.h:217
Tag used to allow (only) WifiMacQueue to access the queue iterator stored by a WifiMpdu.
Definition: wifi-mpdu.h:45
#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_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
#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 ",...
AcIndex
This enumeration defines the Access Categories as an enumeration with values corresponding to the AC ...
Definition: qos-utils.h:74
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:129
void AddWifiMacTrailer(Ptr< Packet > packet)
Add FCS trailer to a packet.
Definition: wifi-utils.cc:125