A Discrete-Event Network Simulator
API
wifi-mac-queue-item.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2005, 2009 INRIA
4  * Copyright (c) 2009 MIRKO BANCHI
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation;
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
20  * Mirko Banchi <mk.banchi@gmail.com>
21  * Stefano Avallone <stavallo@unina.it>
22  */
23 
24 #include "ns3/simulator.h"
25 #include "ns3/packet.h"
26 #include "ns3/log.h"
27 #include "wifi-mac-queue-item.h"
28 #include "wifi-mac-trailer.h"
29 #include "wifi-utils.h"
30 #include "msdu-aggregator.h"
31 
32 namespace ns3 {
33 
34 NS_LOG_COMPONENT_DEFINE ("WifiMacQueueItem");
35 
37  : WifiMacQueueItem (p, header, Simulator::Now ())
38 {
39 }
40 
42  : m_packet (p),
43  m_header (header),
44  m_tstamp (tstamp),
45  m_queueAc (AC_UNDEF)
46 {
47  if (header.IsQosData () && header.IsQosAmsdu ())
48  {
50  }
51  m_inFlight = false;
52 }
53 
55 {
56 }
57 
60 {
61  NS_ASSERT (IsQueued ());
62  return *m_queueIt;
63 }
64 
67 {
68  return m_packet;
69 }
70 
71 const WifiMacHeader&
73 {
74  return m_header;
75 }
76 
79 {
80  return m_header;
81 }
82 
85 {
86  return m_header.GetAddr1 ();
87 }
88 
89 Time
91 {
92  return m_tstamp;
93 }
94 
95 uint32_t
97 {
98  return m_packet->GetSize ();
99 }
100 
101 uint32_t
103 {
105 }
106 
107 bool
109 {
111 }
112 
115 {
116  Ptr<Packet> mpdu = m_packet->Copy ();
117  mpdu->AddHeader (m_header);
118  AddWifiMacTrailer (mpdu);
119  return mpdu;
120 }
121 
122 void
124 {
125  NS_ASSERT (msdu != 0);
126  NS_LOG_FUNCTION (this << *msdu);
127  NS_ABORT_MSG_IF (!msdu->GetHeader ().IsQosData () || msdu->GetHeader ().IsQosAmsdu (),
128  "Only QoS data frames that do not contain an A-MSDU can be aggregated");
129 
130  if (m_msduList.empty ())
131  {
132  // An MSDU is going to be aggregated to this MPDU, hence this has to be an A-MSDU now
133  Ptr<const WifiMacQueueItem> firstMsdu = Create<const WifiMacQueueItem> (*this);
134  m_packet = Create<Packet> ();
135  DoAggregate (firstMsdu);
136 
138  // Set Address3 according to Table 9-26 of 802.11-2016
139  if (m_header.IsToDs () && !m_header.IsFromDs ())
140  {
141  // from STA to AP: BSSID is in Address1
143  }
144  else if (!m_header.IsToDs () && m_header.IsFromDs ())
145  {
146  // from AP to STA: BSSID is in Address2
148  }
149  // in the WDS case (ToDS = FromDS = 1), both Address 3 and Address 4 need
150  // to be set to the BSSID, but neither Address 1 nor Address 2 contain the
151  // BSSID. Hence, it is left up to the caller to set these Address fields.
152  }
153  DoAggregate (msdu);
154 }
155 
156 void
158 {
159  NS_LOG_FUNCTION (this << *msdu);
160 
161  // build the A-MSDU Subframe header
163  /*
164  * (See Table 9-26 of 802.11-2016)
165  *
166  * ToDS | FromDS | DA | SA
167  * 0 | 0 | Addr1 | Addr2
168  * 0 | 1 | Addr1 | Addr3
169  * 1 | 0 | Addr3 | Addr2
170  * 1 | 1 | Addr3 | Addr4
171  */
172  hdr.SetDestinationAddr (msdu->GetHeader ().IsToDs () ? msdu->GetHeader ().GetAddr3 ()
173  : msdu->GetHeader ().GetAddr1 ());
174  hdr.SetSourceAddr (!msdu->GetHeader ().IsFromDs () ? msdu->GetHeader ().GetAddr2 ()
175  : (!msdu->GetHeader ().IsToDs ()
176  ? msdu->GetHeader ().GetAddr3 ()
177  : msdu->GetHeader ().GetAddr4 ()));
178  hdr.SetLength (static_cast<uint16_t> (msdu->GetPacket ()->GetSize ()));
179 
180  m_msduList.push_back ({msdu->GetPacket (), hdr});
181 
182  // build the A-MSDU
184  Ptr<Packet> amsdu = m_packet->Copy ();
185 
186  // pad the previous A-MSDU subframe if the A-MSDU is not empty
187  if (m_packet->GetSize () > 0)
188  {
189  uint8_t padding = MsduAggregator::CalculatePadding (m_packet->GetSize ());
190 
191  if (padding)
192  {
193  amsdu->AddAtEnd (Create<Packet> (padding));
194  }
195  }
196 
197  // add A-MSDU subframe header and MSDU
198  Ptr<Packet> amsduSubframe = msdu->GetPacket ()->Copy ();
199  amsduSubframe->AddHeader (hdr);
200  amsdu->AddAtEnd (amsduSubframe);
201  m_packet = amsdu;
202 
203  /* "The expiration of the A-MSDU lifetime timer occurs only when the lifetime
204  * timer of all of the constituent MSDUs of the A-MSDU have expired" (Section
205  * 10.12 of 802.11-2016)
206  */
207  // The timestamp of the A-MSDU is the most recent among those of the MSDUs
208  m_tstamp = Max (m_tstamp, msdu->GetTimeStamp ());
209 }
210 
211 bool
213 {
214  return m_queueAc != AC_UNDEF;
215 }
216 
217 AcIndex
219 {
220  NS_ASSERT (IsQueued ());
221  return m_queueAc;
222 }
223 
224 void
226 {
227  m_inFlight = true;
228 }
229 
230 void
232 {
233  m_inFlight = false;
234 }
235 
236 bool
238 {
239  return m_inFlight;
240 }
241 
244 {
245  return m_msduList.begin ();
246 }
247 
250 {
251  return m_msduList.end ();
252 }
253 
254 void
255 WifiMacQueueItem::Print (std::ostream& os) const
256 {
257  os << m_header.GetTypeString ()
258  << ", payloadSize=" << GetPacketSize ()
259  << ", to=" << m_header.GetAddr1 ()
260  << ", seqN=" << m_header.GetSequenceNumber ()
261  << ", duration/ID=" << m_header.GetDuration ()
262  << ", lifetime=" << (Simulator::Now () - m_tstamp).As (Time::US);
263  if (m_header.IsQosData ())
264  {
265  os << ", tid=" << +m_header.GetQosTid ();
266  if (m_header.IsQosNoAck ())
267  {
268  os << ", ack=NoAck";
269  }
270  else if (m_header.IsQosAck ())
271  {
272  os << ", ack=NormalAck";
273  }
274  else if (m_header.IsQosBlockAck ())
275  {
276  os << ", ack=BlockAck";
277  }
278  }
279  os << ", packet=" << m_packet
280  << ", queued=" << IsQueued ()
281  << ", inflight=" << IsInFlight ();
282 }
283 
284 std::ostream & operator << (std::ostream &os, const WifiMacQueueItem &item)
285 {
286  item.Print (os);
287  return os;
288 }
289 
290 } //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:44
static WifiMacQueueItem::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:335
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:256
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:121
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:856
Control the scheduling of simulation events.
Definition: simulator.h:69
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
@ US
microsecond
Definition: nstime.h:116
Implements the IEEE 802.11 MAC header.
uint8_t GetQosTid(void) const
Return the Traffic ID of a QoS header.
bool IsQosAck(void) const
Return if the QoS Ack policy is Normal Ack.
Time GetDuration(void) const
Return the duration from the Duration/ID field (Time object).
void SetQosAmsdu(void)
Set that A-MSDU is present.
bool IsQosData(void) const
Return true if the Type is DATA and Subtype is one of the possible values for QoS Data.
bool IsFromDs(void) const
uint16_t GetSequenceNumber(void) const
Return the sequence number of the header.
Mac48Address GetAddr2(void) const
Return the address in the Address 2 field.
bool IsQosNoAck(void) const
Return if the QoS Ack policy is No Ack.
const char * GetTypeString(void) const
Return a string corresponds to the header type.
Mac48Address GetAddr1(void) const
Return the address in the Address 1 field.
uint32_t GetSerializedSize(void) const override
bool IsMoreFragments(void) const
Return if the More Fragment bit is set.
void SetAddr3(Mac48Address address)
Fill the Address 3 field with the given address.
uint8_t GetFragmentNumber(void) const
Return the fragment number of the header.
bool IsToDs(void) const
bool IsQosAmsdu(void) const
Check if the A-MSDU present bit is set in the QoS control field.
bool IsQosBlockAck(void) const
Return if the QoS Ack policy is Block Ack.
WifiMacQueueItem stores (const) packets along with their Wifi MAC headers and the time when they were...
Ptr< const Packet > GetPacket(void) const
Get the packet stored in this item.
uint32_t GetSize(void) const
Return the size of the packet stored by this item, including header size and trailer size.
void Aggregate(Ptr< const WifiMacQueueItem > msdu)
Aggregate the MSDU contained in the given MPDU to this MPDU (thus constituting an A-MSDU).
DeaggregatedMsdusCI end(void)
Get a constant iterator indicating past-the-last MSDU in the list of aggregated MSDUs.
AcIndex GetQueueAc(void) const
Get the AC of the queue this item is stored into.
bool IsFragment(void) const
Return true if this item contains an MSDU fragment, false otherwise.
void DoAggregate(Ptr< const WifiMacQueueItem > msdu)
Aggregate the MSDU contained in the given MPDU to this MPDU (thus constituting an A-MSDU).
bool IsQueued(void) const
Return true if this item is stored in some queue, false otherwise.
DeaggregatedMsdus m_msduList
The list of aggregated MSDUs included in this MPDU.
virtual void Print(std::ostream &os) const
Print the item contents.
WifiMacQueueItem(Ptr< const Packet > p, const WifiMacHeader &header)
Create a Wifi MAC queue item containing a packet and a Wifi MAC header.
AcIndex m_queueAc
AC associated with the queue this MPDU is stored into.
bool IsInFlight(void) const
Return true if this MPDU is in flight, false otherwise.
Ptr< WifiMacQueueItem > GetItem(void) const
Get a pointer to this WifiMacQueueItem object.
Ptr< Packet > GetProtocolDataUnit(void) const
Get the MAC protocol data unit (MPDU) corresponding to this item (i.e.
Time GetTimeStamp(void) const
Get the timestamp included in this item.
bool m_inFlight
whether the MPDU is in flight
std::list< std::pair< Ptr< const Packet >, AmsduSubframeHeader > >::const_iterator DeaggregatedMsdusCI
DeaggregatedMsdusCI typedef.
DeaggregatedMsdusCI begin(void)
Get a constant iterator pointing to the first MSDU in the list of aggregated MSDUs.
uint32_t GetPacketSize(void) const
Return the size in bytes of the packet or control header or management header stored by this item.
Time m_tstamp
timestamp when the packet arrived at the queue
void SetInFlight(void)
Mark this MPDU as being in flight (only used if Block Ack agreement established).
Ptr< const Packet > m_packet
The packet (MSDU or A-MSDU) contained in this queue item.
ConstIterator m_queueIt
Queue iterator pointing to this MPDU, if queued.
void ResetInFlight(void)
Mark this MPDU as not being in flight (only used if Block Ack agreement established).
Mac48Address GetDestinationAddress(void) const
Return the destination address present in the header.
const WifiMacHeader & GetHeader(void) const
Get the header stored in this item.
WifiMacHeader m_header
Wifi MAC header associated with the packet.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:67
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
int64x64_t Max(const int64x64_t &a, const int64x64_t &b)
Maximum.
Definition: int64x64.h:230
#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 ",...
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:287
AcIndex
This enumeration defines the Access Categories as an enumeration with values corresponding to the AC ...
Definition: qos-utils.h:71
@ AC_UNDEF
Total number of ACs.
Definition: qos-utils.h:85
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.
void AddWifiMacTrailer(Ptr< Packet > packet)
Add FCS trailer to a packet.
Definition: wifi-utils.cc:122
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:139