A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
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 * SPDX-License-Identifier: GPL-2.0-only
6 *
7 * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
8 * Mirko Banchi <mk.banchi@gmail.com>
9 * Stefano Avallone <stavallo@unina.it>
10 */
11
12#include "wifi-mpdu.h"
13
14#include "msdu-aggregator.h"
15#include "wifi-mac-trailer.h"
16#include "wifi-utils.h"
17
18#include "ns3/log.h"
19#include "ns3/packet.h"
20
21namespace ns3
22{
23
24NS_LOG_COMPONENT_DEFINE("WifiMpdu");
25
27 : m_header(header)
28{
29 auto& original = std::get<OriginalInfo>(m_instanceInfo);
30 original.m_packet = p;
31 original.m_timestamp = stamp;
32
33 if (header.IsQosData() && header.IsQosAmsdu())
34 {
35 original.m_msduList = MsduAggregator::Deaggregate(p->Copy());
36 }
37}
38
40{
41 // Aliases can be queued (i.e., the original copy is queued) when destroyed
42 NS_ASSERT(std::holds_alternative<Ptr<WifiMpdu>>(m_instanceInfo) || !IsQueued());
43}
44
45bool
47{
48 return std::holds_alternative<OriginalInfo>(m_instanceInfo);
49}
50
53{
54 if (std::holds_alternative<OriginalInfo>(m_instanceInfo))
55 {
56 return this;
57 }
58 return std::get<ALIAS>(m_instanceInfo);
59}
60
62WifiMpdu::CreateAlias(uint8_t linkId) const
63{
64 NS_LOG_FUNCTION(this << +linkId);
65 NS_ABORT_MSG_IF(!std::holds_alternative<OriginalInfo>(m_instanceInfo),
66 "This method can only be called on the original version of the MPDU");
67
68 auto alias = Ptr<WifiMpdu>(new WifiMpdu, false);
69
70 alias->m_header = m_header; // copy the MAC header
71 alias->m_instanceInfo = Ptr(const_cast<WifiMpdu*>(this));
72 NS_ASSERT(alias->m_instanceInfo.index() == ALIAS);
73
74 return alias;
75}
76
79{
80 if (auto original = std::get_if<ORIGINAL>(&m_instanceInfo))
81 {
82 return *original;
83 }
84 auto& origInstanceInfo = std::get<Ptr<WifiMpdu>>(m_instanceInfo)->m_instanceInfo;
85 return std::get<OriginalInfo>(origInstanceInfo);
86}
87
90{
91 if (auto original = std::get_if<ORIGINAL>(&m_instanceInfo))
92 {
93 return *original;
94 }
95 const auto& origInstanceInfo = std::get<Ptr<WifiMpdu>>(m_instanceInfo)->m_instanceInfo;
96 return std::get<OriginalInfo>(origInstanceInfo);
97}
98
101{
102 return GetOriginalInfo().m_packet;
103}
104
105Time
107{
108 if (auto original = std::get_if<ORIGINAL>(&m_instanceInfo))
109 {
110 return original->m_timestamp;
111 }
112 const auto& origInstanceInfo = std::get<Ptr<WifiMpdu>>(m_instanceInfo)->m_instanceInfo;
113 return std::get<OriginalInfo>(origInstanceInfo).m_timestamp;
114}
115
116const WifiMacHeader&
118{
119 return m_header;
120}
121
124{
125 return m_header;
126}
127
130{
131 return m_header.GetAddr1();
132}
133
136{
137 return GetPacket()->GetSize();
138}
139
145
146bool
151
154{
155 Ptr<Packet> mpdu = GetPacket()->Copy();
156 mpdu->AddHeader(m_header);
157 AddWifiMacTrailer(mpdu);
158 return mpdu;
159}
160
161void
163{
164 if (msdu)
165 {
166 NS_LOG_FUNCTION(this << *msdu);
167 }
168 else
169 {
170 NS_LOG_FUNCTION(this);
171 }
172 NS_ABORT_MSG_IF(msdu && (!msdu->GetHeader().IsQosData() || msdu->GetHeader().IsQosAmsdu()),
173 "Only QoS data frames that do not contain an A-MSDU can be aggregated");
174 NS_ABORT_MSG_IF(!std::holds_alternative<OriginalInfo>(m_instanceInfo),
175 "This method can only be called on the original version of the MPDU");
176
177 auto& original = std::get<OriginalInfo>(m_instanceInfo);
178
179 if (original.m_msduList.empty())
180 {
181 // An MSDU is going to be aggregated to this MPDU, hence this has to be an A-MSDU now
183 original.m_packet = Create<Packet>();
184 DoAggregate(firstMsdu);
185
187 // Set Address3 according to Table 9-26 of 802.11-2016
188 if (m_header.IsToDs() && !m_header.IsFromDs())
189 {
190 // from STA to AP: BSSID is in Address1
192 }
193 else if (!m_header.IsToDs() && m_header.IsFromDs())
194 {
195 // from AP to STA: BSSID is in Address2
197 }
198 // in the WDS case (ToDS = FromDS = 1), both Address 3 and Address 4 need
199 // to be set to the BSSID, but neither Address 1 nor Address 2 contain the
200 // BSSID. Hence, it is left up to the caller to set these Address fields.
201 }
202 if (msdu)
203 {
204 DoAggregate(msdu);
205 }
206}
207
208void
210{
211 NS_LOG_FUNCTION(this << *msdu);
212
213 // build the A-MSDU Subframe header
215 /*
216 * (See Table 9-26 of 802.11-2016)
217 *
218 * ToDS | FromDS | DA | SA
219 * 0 | 0 | Addr1 | Addr2
220 * 0 | 1 | Addr1 | Addr3
221 * 1 | 0 | Addr3 | Addr2
222 * 1 | 1 | Addr3 | Addr4
223 */
224 hdr.SetDestinationAddr(msdu->GetHeader().IsToDs() ? msdu->GetHeader().GetAddr3()
225 : msdu->GetHeader().GetAddr1());
226 hdr.SetSourceAddr(!msdu->GetHeader().IsFromDs()
227 ? msdu->GetHeader().GetAddr2()
228 : (!msdu->GetHeader().IsToDs() ? msdu->GetHeader().GetAddr3()
229 : msdu->GetHeader().GetAddr4()));
230 hdr.SetLength(static_cast<uint16_t>(msdu->GetPacket()->GetSize()));
231
232 auto& original = std::get<OriginalInfo>(m_instanceInfo);
233
234 original.m_msduList.emplace_back(msdu->GetPacket(), hdr);
235
236 // build the A-MSDU
237 NS_ASSERT(original.m_packet);
238 Ptr<Packet> amsdu = original.m_packet->Copy();
239
240 // pad the previous A-MSDU subframe if the A-MSDU is not empty
241 if (original.m_packet->GetSize() > 0)
242 {
243 uint8_t padding = MsduAggregator::CalculatePadding(original.m_packet->GetSize());
244
245 if (padding)
246 {
247 amsdu->AddAtEnd(Create<Packet>(padding));
248 }
249 }
250
251 // add A-MSDU subframe header and MSDU
252 Ptr<Packet> amsduSubframe = msdu->GetPacket()->Copy();
253 amsduSubframe->AddHeader(hdr);
254 amsdu->AddAtEnd(amsduSubframe);
255 original.m_packet = amsdu;
256}
257
258bool
260{
261 return GetOriginalInfo().m_queueIt.has_value();
262}
263
264void
265WifiMpdu::SetQueueIt(std::optional<Iterator> queueIt, WmqIteratorTag tag)
266{
267 NS_ABORT_MSG_IF(!std::holds_alternative<OriginalInfo>(m_instanceInfo),
268 "This method can only be called on the original version of the MPDU");
269
270 auto& original = std::get<OriginalInfo>(m_instanceInfo);
271 original.m_queueIt = queueIt;
272}
273
276{
277 return GetQueueIt();
278}
279
282{
284 return GetOriginalInfo().m_queueIt.value();
285}
286
289{
290 return GetQueueIt()->ac;
291}
292
293Time
295{
296 return GetQueueIt()->expiryTime;
297}
298
299void
300WifiMpdu::SetInFlight(uint8_t linkId) const
301{
302 GetQueueIt()->inflights[linkId] = Ptr(const_cast<WifiMpdu*>(this));
303}
304
305void
306WifiMpdu::ResetInFlight(uint8_t linkId) const
307{
308 GetQueueIt()->inflights.erase(linkId);
309}
310
311std::set<uint8_t>
313{
314 if (!IsQueued())
315 {
316 return {};
317 }
318 std::set<uint8_t> linkIds;
319 for (const auto& [linkId, mpdu] : GetQueueIt()->inflights)
320 {
321 linkIds.insert(linkId);
322 }
323 return linkIds;
324}
325
326bool
328{
329 return IsQueued() && !GetQueueIt()->inflights.empty();
330}
331
332void
334{
335 NS_LOG_FUNCTION(this << seqNo);
336
338 // if this is an alias, set the sequence number on the original copy, too
339 if (auto originalPtr = std::get_if<ALIAS>(&m_instanceInfo))
340 {
341 (*originalPtr)->m_header.SetSequenceNumber(seqNo);
342 }
344}
345
346bool
351
352void
357
360{
361 return GetOriginalInfo().m_msduList.cbegin();
362}
363
366{
367 return GetOriginalInfo().m_msduList.cend();
368}
369
370void
371WifiMpdu::Print(std::ostream& os) const
372{
373 os << m_header << ", payloadSize=" << GetPacketSize() << ", queued=" << IsQueued();
374 if (IsQueued())
375 {
376 os << ", residualLifetime=" << (GetExpiryTime() - Simulator::Now()).As(Time::US)
377 << ", inflight=" << IsInFlight();
378 }
379 os << ", packet=" << GetPacket();
380}
381
382std::ostream&
383operator<<(std::ostream& os, const WifiMpdu& item)
384{
385 item.Print(os);
386 return os;
387}
388
389} // 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
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...
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition packet.h:850
Ptr< Packet > Copy() const
performs a COW copy of the packet.
Definition packet.cc:120
Smart pointer class similar to boost::intrusive_ptr.
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:197
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
@ US
microsecond
Definition nstime.h:107
Implements the IEEE 802.11 MAC 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.
bool IsMoreFragments() const
Return if the More Fragment bit is set.
void SetSequenceNumber(uint16_t seq)
Set the sequence number of the header.
Mac48Address GetAddr2() const
Return the address in the Address 2 field.
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 a (const) packet along with a MAC header.
Definition wifi-mpdu.h:51
bool IsOriginal() const
Definition wifi-mpdu.cc:46
InstanceInfo m_instanceInfo
information associated with the instance type
Definition wifi-mpdu.h:296
Time GetTimestamp() const
Definition wifi-mpdu.cc:106
bool HasSeqNoAssigned() const
Definition wifi-mpdu.cc:347
Time GetExpiryTime() const
Definition wifi-mpdu.cc:294
bool IsInFlight() const
Definition wifi-mpdu.cc:327
static constexpr std::size_t ALIAS
index of an alias in the InstanceInfo variant
Definition wifi-mpdu.h:299
void ResetInFlight(uint8_t linkId) const
Mark this MPDU as not being in flight on the given link.
Definition wifi-mpdu.cc:306
WifiMacHeader m_header
Information stored by both the original copy and the aliases.
Definition wifi-mpdu.h:270
void SetInFlight(uint8_t linkId) const
Mark this MPDU as being in flight on the given link.
Definition wifi-mpdu.cc:300
Iterator GetQueueIt() const
Definition wifi-mpdu.cc:281
std::list< std::pair< Ptr< constPacket >, AmsduSubframeHeader > >::const_iterator DeaggregatedMsdusCI
DeaggregatedMsdusCI typedef.
Definition wifi-mpdu.h:134
const WifiMacHeader & GetHeader() const
Get the header stored in this item.
Definition wifi-mpdu.cc:117
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:162
OriginalInfo & GetOriginalInfo()
Definition wifi-mpdu.cc:78
virtual ~WifiMpdu()
Definition wifi-mpdu.cc:39
uint32_t GetSize() const
Return the size of the packet stored by this item, including header size and trailer size.
Definition wifi-mpdu.cc:141
Ptr< Packet > GetProtocolDataUnit() const
Get the MAC protocol data unit (MPDU) corresponding to this item (i.e.
Definition wifi-mpdu.cc:153
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:209
void UnassignSeqNo()
Record that a sequence number is no (longer) assigned to this MPDU.
Definition wifi-mpdu.cc:353
virtual void Print(std::ostream &os) const
Print the item contents.
Definition wifi-mpdu.cc:371
WifiMpdu()=default
Private default constructor (used to construct aliases).
Ptr< const Packet > GetPacket() const
Get the packet stored in this item.
Definition wifi-mpdu.cc:100
DeaggregatedMsdusCI end() const
Get a constant iterator indicating past-the-last MSDU in the list of aggregated MSDUs.
Definition wifi-mpdu.cc:365
DeaggregatedMsdusCI begin() const
Get a constant iterator pointing to the first MSDU in the list of aggregated MSDUs.
Definition wifi-mpdu.cc:359
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:135
AcIndex GetQueueAc() const
Get the AC of the queue this item is stored into.
Definition wifi-mpdu.cc:288
std::list< WifiMacQueueElem >::iterator Iterator
Const iterator typedef.
Definition wifi-mpdu.h:150
Mac48Address GetDestinationAddress() const
Return the destination address present in the header.
Definition wifi-mpdu.cc:129
bool IsQueued() const
Return true if this item is stored in some queue, false otherwise.
Definition wifi-mpdu.cc:259
void SetQueueIt(std::optional< Iterator > queueIt, WmqIteratorTag tag)
Set the queue iterator stored by this object.
Definition wifi-mpdu.cc:265
bool IsFragment() const
Return true if this item contains an MSDU fragment, false otherwise.
Definition wifi-mpdu.cc:147
std::set< uint8_t > GetInFlightLinkIds() const
Definition wifi-mpdu.cc:312
Ptr< const WifiMpdu > GetOriginal() const
Definition wifi-mpdu.cc:52
void AssignSeqNo(uint16_t seqNo)
Set the sequence number of this MPDU (and of the original copy, if this is an alias) to the given val...
Definition wifi-mpdu.cc:333
Ptr< WifiMpdu > CreateAlias(uint8_t linkId) const
Create an alias for this MPDU (which must be an original copy) for transmission on the link with the ...
Definition wifi-mpdu.cc:62
Tag used to allow (only) WifiMacQueue to access the queue iterator stored by a WifiMpdu.
Definition wifi-mpdu.h:37
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition abort.h:97
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
AcIndex
This enumeration defines the Access Categories as an enumeration with values corresponding to the AC ...
Definition qos-utils.h:62
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static const uint16_t WIFI_MAC_FCS_LENGTH
The length in octets of the IEEE 802.11 MAC FCS field.
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition angles.cc:148
void AddWifiMacTrailer(Ptr< Packet > packet)
Add FCS trailer to a packet.
Information stored by the original copy only.
Definition wifi-mpdu.h:276
bool m_seqNoAssigned
whether a sequence number has been assigned
Definition wifi-mpdu.h:281
DeaggregatedMsdus m_msduList
list of aggregated MSDUs included in this MPDU
Definition wifi-mpdu.h:279
Ptr< const Packet > m_packet
MSDU or A-MSDU contained in this queue item.
Definition wifi-mpdu.h:277
std::optional< Iterator > m_queueIt
Queue iterator pointing to this MPDU, if queued.
Definition wifi-mpdu.h:280