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 original.m_retryCount = 0;
33
34 if (header.IsQosData() && header.IsQosAmsdu())
35 {
36 original.m_msduList = MsduAggregator::Deaggregate(p->Copy());
37 }
38}
39
41{
42 // Aliases can be queued (i.e., the original copy is queued) when destroyed
43 NS_ASSERT(std::holds_alternative<Ptr<WifiMpdu>>(m_instanceInfo) || !IsQueued());
44}
45
46bool
48{
49 return std::holds_alternative<OriginalInfo>(m_instanceInfo);
50}
51
54{
55 if (std::holds_alternative<OriginalInfo>(m_instanceInfo))
56 {
57 return this;
58 }
59 return std::get<ALIAS>(m_instanceInfo);
60}
61
63WifiMpdu::CreateAlias(uint8_t linkId) const
64{
65 NS_LOG_FUNCTION(this << +linkId);
66 NS_ABORT_MSG_IF(!std::holds_alternative<OriginalInfo>(m_instanceInfo),
67 "This method can only be called on the original version of the MPDU");
68
69 auto alias = Ptr<WifiMpdu>(new WifiMpdu, false);
70
71 alias->m_header = m_header; // copy the MAC header
72 alias->m_instanceInfo = Ptr(const_cast<WifiMpdu*>(this));
73 NS_ASSERT(alias->m_instanceInfo.index() == ALIAS);
74
75 return alias;
76}
77
80{
81 if (auto original = std::get_if<ORIGINAL>(&m_instanceInfo))
82 {
83 return *original;
84 }
85 auto& origInstanceInfo = std::get<Ptr<WifiMpdu>>(m_instanceInfo)->m_instanceInfo;
86 return std::get<OriginalInfo>(origInstanceInfo);
87}
88
91{
92 if (auto original = std::get_if<ORIGINAL>(&m_instanceInfo))
93 {
94 return *original;
95 }
96 const auto& origInstanceInfo = std::get<Ptr<WifiMpdu>>(m_instanceInfo)->m_instanceInfo;
97 return std::get<OriginalInfo>(origInstanceInfo);
98}
99
102{
103 return GetOriginalInfo().m_packet;
104}
105
106Time
108{
109 if (auto original = std::get_if<ORIGINAL>(&m_instanceInfo))
110 {
111 return original->m_timestamp;
112 }
113 const auto& origInstanceInfo = std::get<Ptr<WifiMpdu>>(m_instanceInfo)->m_instanceInfo;
114 return std::get<OriginalInfo>(origInstanceInfo).m_timestamp;
115}
116
119{
120 if (auto original = std::get_if<ORIGINAL>(&m_instanceInfo))
121 {
122 return original->m_retryCount;
123 }
124 const auto& origInstanceInfo = std::get<Ptr<WifiMpdu>>(m_instanceInfo)->m_instanceInfo;
125 return std::get<OriginalInfo>(origInstanceInfo).m_retryCount;
126}
127
128void
130{
131 NS_LOG_FUNCTION(this);
132
134 {
135 // this function may be called for these frames, but a retry count must not be maintained
136 // for them
137 return;
138 }
139
141 "Frame retry count is not maintained for frames of type "
143 if (auto original = std::get_if<ORIGINAL>(&m_instanceInfo))
144 {
145 ++original->m_retryCount;
146 return;
147 }
148 auto& origInstanceInfo = std::get<Ptr<WifiMpdu>>(m_instanceInfo)->m_instanceInfo;
149 ++std::get<OriginalInfo>(origInstanceInfo).m_retryCount;
150}
151
152const WifiMacHeader&
154{
155 return m_header;
156}
157
160{
161 return m_header;
162}
163
166{
167 return m_header.GetAddr1();
168}
169
172{
173 return GetPacket()->GetSize();
174}
175
181
182bool
187
190{
191 Ptr<Packet> mpdu = GetPacket()->Copy();
192 mpdu->AddHeader(m_header);
193 AddWifiMacTrailer(mpdu);
194 return mpdu;
195}
196
197void
199{
200 if (msdu)
201 {
202 NS_LOG_FUNCTION(this << *msdu);
203 }
204 else
205 {
206 NS_LOG_FUNCTION(this);
207 }
208 NS_ABORT_MSG_IF(msdu && (!msdu->GetHeader().IsQosData() || msdu->GetHeader().IsQosAmsdu()),
209 "Only QoS data frames that do not contain an A-MSDU can be aggregated");
210 NS_ABORT_MSG_IF(!std::holds_alternative<OriginalInfo>(m_instanceInfo),
211 "This method can only be called on the original version of the MPDU");
212
213 auto& original = std::get<OriginalInfo>(m_instanceInfo);
214
215 if (original.m_msduList.empty())
216 {
217 // An MSDU is going to be aggregated to this MPDU, hence this has to be an A-MSDU now
219 original.m_packet = Create<Packet>();
220 original.m_retryCount = 0;
221 DoAggregate(firstMsdu);
222
224 // Set Address3 according to Table 9-26 of 802.11-2016
225 if (m_header.IsToDs() && !m_header.IsFromDs())
226 {
227 // from STA to AP: BSSID is in Address1
229 }
230 else if (!m_header.IsToDs() && m_header.IsFromDs())
231 {
232 // from AP to STA: BSSID is in Address2
234 }
235 // in the WDS case (ToDS = FromDS = 1), both Address 3 and Address 4 need
236 // to be set to the BSSID, but neither Address 1 nor Address 2 contain the
237 // BSSID. Hence, it is left up to the caller to set these Address fields.
238 }
239 if (msdu)
240 {
241 DoAggregate(msdu);
242 }
243}
244
245void
247{
248 NS_LOG_FUNCTION(this << *msdu);
249
250 // build the A-MSDU Subframe header
252 /*
253 * (See Table 9-26 of 802.11-2016)
254 *
255 * ToDS | FromDS | DA | SA
256 * 0 | 0 | Addr1 | Addr2
257 * 0 | 1 | Addr1 | Addr3
258 * 1 | 0 | Addr3 | Addr2
259 * 1 | 1 | Addr3 | Addr4
260 */
261 hdr.SetDestinationAddr(msdu->GetHeader().IsToDs() ? msdu->GetHeader().GetAddr3()
262 : msdu->GetHeader().GetAddr1());
263 hdr.SetSourceAddr(!msdu->GetHeader().IsFromDs()
264 ? msdu->GetHeader().GetAddr2()
265 : (!msdu->GetHeader().IsToDs() ? msdu->GetHeader().GetAddr3()
266 : msdu->GetHeader().GetAddr4()));
267 hdr.SetLength(static_cast<uint16_t>(msdu->GetPacket()->GetSize()));
268
269 auto& original = std::get<OriginalInfo>(m_instanceInfo);
270
271 original.m_msduList.emplace_back(msdu->GetPacket(), hdr);
272
273 // build the A-MSDU
274 NS_ASSERT(original.m_packet);
275 Ptr<Packet> amsdu = original.m_packet->Copy();
276
277 // pad the previous A-MSDU subframe if the A-MSDU is not empty
278 if (original.m_packet->GetSize() > 0)
279 {
280 uint8_t padding = MsduAggregator::CalculatePadding(original.m_packet->GetSize());
281
282 if (padding)
283 {
284 amsdu->AddAtEnd(Create<Packet>(padding));
285 }
286 }
287
288 // add A-MSDU subframe header and MSDU
289 Ptr<Packet> amsduSubframe = msdu->GetPacket()->Copy();
290 amsduSubframe->AddHeader(hdr);
291 amsdu->AddAtEnd(amsduSubframe);
292 original.m_packet = amsdu;
293}
294
295bool
297{
298 return GetOriginalInfo().m_queueIt.has_value();
299}
300
301void
302WifiMpdu::SetQueueIt(std::optional<Iterator> queueIt, WmqIteratorTag tag)
303{
304 NS_ABORT_MSG_IF(!std::holds_alternative<OriginalInfo>(m_instanceInfo),
305 "This method can only be called on the original version of the MPDU");
306
307 auto& original = std::get<OriginalInfo>(m_instanceInfo);
308 original.m_queueIt = queueIt;
309}
310
313{
314 return GetQueueIt();
315}
316
319{
321 return GetOriginalInfo().m_queueIt.value();
322}
323
326{
327 return GetQueueIt()->ac;
328}
329
330Time
332{
333 return GetQueueIt()->expiryTime;
334}
335
336void
337WifiMpdu::SetInFlight(uint8_t linkId) const
338{
339 GetQueueIt()->inflights[linkId] = Ptr(const_cast<WifiMpdu*>(this));
340}
341
342void
343WifiMpdu::ResetInFlight(uint8_t linkId) const
344{
345 GetQueueIt()->inflights.erase(linkId);
346}
347
348std::set<uint8_t>
350{
351 if (!IsQueued())
352 {
353 return {};
354 }
355 std::set<uint8_t> linkIds;
356 for (const auto& [linkId, mpdu] : GetQueueIt()->inflights)
357 {
358 linkIds.insert(linkId);
359 }
360 return linkIds;
361}
362
363bool
365{
366 return IsQueued() && !GetQueueIt()->inflights.empty();
367}
368
369void
371{
372 NS_LOG_FUNCTION(this << seqNo);
373
375 // if this is an alias, set the sequence number on the original copy, too
376 if (auto originalPtr = std::get_if<ALIAS>(&m_instanceInfo))
377 {
378 (*originalPtr)->m_header.SetSequenceNumber(seqNo);
379 }
381}
382
383bool
388
389void
394
397{
398 return GetOriginalInfo().m_msduList.cbegin();
399}
400
403{
404 return GetOriginalInfo().m_msduList.cend();
405}
406
407void
408WifiMpdu::Print(std::ostream& os) const
409{
410 os << m_header << ", payloadSize=" << GetPacketSize() << ", retryCount=" << GetRetryCount()
411 << ", queued=" << IsQueued();
412 if (IsQueued())
413 {
414 os << ", residualLifetime=" << (GetExpiryTime() - Simulator::Now()).As(Time::US)
415 << ", inflight=" << IsInFlight();
416 }
417 os << ", packet=" << GetPacket();
418}
419
420std::ostream&
421operator<<(std::ostream& os, const WifiMpdu& item)
422{
423 item.Print(os);
424 return os;
425}
426
427} // 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 IsBlockAckReq() const
Return true if the header is a BlockAckRequest 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.
bool IsTrigger() const
Return true if the header is a Trigger header.
bool IsMgt() const
Return true if the Type is Management.
void SetSequenceNumber(uint16_t seq)
Set the sequence number of the header.
Mac48Address GetAddr2() const
Return the address in the Address 2 field.
virtual const char * GetTypeString() const
Return a string corresponds to the header type.
bool IsData() const
Return true if the Type is DATA.
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:47
InstanceInfo m_instanceInfo
information associated with the instance type
Definition wifi-mpdu.h:307
Time GetTimestamp() const
Definition wifi-mpdu.cc:107
bool HasSeqNoAssigned() const
Definition wifi-mpdu.cc:384
Time GetExpiryTime() const
Definition wifi-mpdu.cc:331
bool IsInFlight() const
Definition wifi-mpdu.cc:364
static constexpr std::size_t ALIAS
index of an alias in the InstanceInfo variant
Definition wifi-mpdu.h:310
uint32_t GetRetryCount() const
Definition wifi-mpdu.cc:118
void ResetInFlight(uint8_t linkId) const
Mark this MPDU as not being in flight on the given link.
Definition wifi-mpdu.cc:343
void IncrementRetryCount()
Increment the frame retry count.
Definition wifi-mpdu.cc:129
WifiMacHeader m_header
Information stored by both the original copy and the aliases.
Definition wifi-mpdu.h:280
void SetInFlight(uint8_t linkId) const
Mark this MPDU as being in flight on the given link.
Definition wifi-mpdu.cc:337
Iterator GetQueueIt() const
Definition wifi-mpdu.cc:318
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:153
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:198
OriginalInfo & GetOriginalInfo()
Definition wifi-mpdu.cc:79
virtual ~WifiMpdu()
Definition wifi-mpdu.cc:40
uint32_t GetSize() const
Return the size of the packet stored by this item, including header size and trailer size.
Definition wifi-mpdu.cc:177
Ptr< Packet > GetProtocolDataUnit() const
Get the MAC protocol data unit (MPDU) corresponding to this item (i.e.
Definition wifi-mpdu.cc:189
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:246
void UnassignSeqNo()
Record that a sequence number is no (longer) assigned to this MPDU.
Definition wifi-mpdu.cc:390
virtual void Print(std::ostream &os) const
Print the item contents.
Definition wifi-mpdu.cc:408
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:101
DeaggregatedMsdusCI end() const
Get a constant iterator indicating past-the-last MSDU in the list of aggregated MSDUs.
Definition wifi-mpdu.cc:402
DeaggregatedMsdusCI begin() const
Get a constant iterator pointing to the first MSDU in the list of aggregated MSDUs.
Definition wifi-mpdu.cc:396
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:171
AcIndex GetQueueAc() const
Get the AC of the queue this item is stored into.
Definition wifi-mpdu.cc:325
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:165
bool IsQueued() const
Return true if this item is stored in some queue, false otherwise.
Definition wifi-mpdu.cc:296
void SetQueueIt(std::optional< Iterator > queueIt, WmqIteratorTag tag)
Set the queue iterator stored by this object.
Definition wifi-mpdu.cc:302
bool IsFragment() const
Return true if this item contains an MSDU fragment, false otherwise.
Definition wifi-mpdu.cc:183
std::set< uint8_t > GetInFlightLinkIds() const
Definition wifi-mpdu.cc:349
Ptr< const WifiMpdu > GetOriginal() const
Definition wifi-mpdu.cc:53
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:370
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:63
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_UNLESS(cond, msg)
Abnormal program termination if a condition is false, with a message.
Definition abort.h:133
#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:286
bool m_seqNoAssigned
whether a sequence number has been assigned
Definition wifi-mpdu.h:291
DeaggregatedMsdus m_msduList
list of aggregated MSDUs included in this MPDU
Definition wifi-mpdu.h:289
Ptr< const Packet > m_packet
MSDU or A-MSDU contained in this queue item.
Definition wifi-mpdu.h:287
std::optional< Iterator > m_queueIt
Queue iterator pointing to this MPDU, if queued.
Definition wifi-mpdu.h:290