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 {
46  if (header.IsQosData () && header.IsQosAmsdu ())
47  {
49  }
50 }
51 
53 {
54 }
55 
58 {
59  return m_packet;
60 }
61 
62 const WifiMacHeader&
64 {
65  return m_header;
66 }
67 
70 {
71  return m_header;
72 }
73 
76 {
77  return m_header.GetAddr1 ();
78 }
79 
80 Time
82 {
83  return m_tstamp;
84 }
85 
86 uint32_t
88 {
89  return m_packet->GetSize ();
90 }
91 
92 uint32_t
94 {
96 }
97 
98 bool
100 {
102 }
103 
106 {
107  Ptr<Packet> mpdu = m_packet->Copy ();
108  mpdu->AddHeader (m_header);
109  AddWifiMacTrailer (mpdu);
110  return mpdu;
111 }
112 
113 void
115 {
116  NS_ASSERT (msdu != 0);
117  NS_LOG_FUNCTION (this << *msdu);
118  NS_ABORT_MSG_IF (!msdu->GetHeader ().IsQosData () || msdu->GetHeader ().IsQosAmsdu (),
119  "Only QoS data frames that do not contain an A-MSDU can be aggregated");
120 
121  if (m_msduList.empty ())
122  {
123  // An MSDU is going to be aggregated to this MPDU, hence this has to be an A-MSDU now
124  Ptr<const WifiMacQueueItem> firstMsdu = Create<const WifiMacQueueItem> (*this);
125  m_packet = Create<Packet> ();
126  m_queueIts.clear ();
127  DoAggregate (firstMsdu);
128 
130  // Set Address3 according to Table 9-26 of 802.11-2016
131  if (m_header.IsToDs () && !m_header.IsFromDs ())
132  {
133  // from STA to AP: BSSID is in Address1
135  }
136  else if (!m_header.IsToDs () && m_header.IsFromDs ())
137  {
138  // from AP to STA: BSSID is in Address2
140  }
141  // in the WDS case (ToDS = FromDS = 1), both Address 3 and Address 4 need
142  // to be set to the BSSID, but neither Address 1 nor Address 2 contain the
143  // BSSID. Hence, it is left up to the caller to set these Address fields.
144  }
145  DoAggregate (msdu);
146 }
147 
148 void
150 {
151  NS_LOG_FUNCTION (this << *msdu);
152 
153  // build the A-MSDU Subframe header
155  /*
156  * (See Table 9-26 of 802.11-2016)
157  *
158  * ToDS | FromDS | DA | SA
159  * 0 | 0 | Addr1 | Addr2
160  * 0 | 1 | Addr1 | Addr3
161  * 1 | 0 | Addr3 | Addr2
162  * 1 | 1 | Addr3 | Addr4
163  */
164  hdr.SetDestinationAddr (msdu->GetHeader ().IsToDs () ? msdu->GetHeader ().GetAddr3 ()
165  : msdu->GetHeader ().GetAddr1 ());
166  hdr.SetSourceAddr (!msdu->GetHeader ().IsFromDs () ? msdu->GetHeader ().GetAddr2 ()
167  : (!msdu->GetHeader ().IsToDs ()
168  ? msdu->GetHeader ().GetAddr3 ()
169  : msdu->GetHeader ().GetAddr4 ()));
170  hdr.SetLength (static_cast<uint16_t> (msdu->GetPacket ()->GetSize ()));
171 
172  m_msduList.push_back ({msdu->GetPacket (), hdr});
173  m_queueIts.insert (m_queueIts.end (), msdu->m_queueIts.begin (), msdu->m_queueIts.end ());
174 
175  // build the A-MSDU
177  Ptr<Packet> amsdu = m_packet->Copy ();
178 
179  // pad the previous A-MSDU subframe if the A-MSDU is not empty
180  if (m_packet->GetSize () > 0)
181  {
182  uint8_t padding = MsduAggregator::CalculatePadding (m_packet->GetSize ());
183 
184  if (padding)
185  {
186  amsdu->AddAtEnd (Create<Packet> (padding));
187  }
188  }
189 
190  // add A-MSDU subframe header and MSDU
191  Ptr<Packet> amsduSubframe = msdu->GetPacket ()->Copy ();
192  amsduSubframe->AddHeader (hdr);
193  amsdu->AddAtEnd (amsduSubframe);
194  m_packet = amsdu;
195 
196  /* "The expiration of the A-MSDU lifetime timer occurs only when the lifetime
197  * timer of all of the constituent MSDUs of the A-MSDU have expired" (Section
198  * 10.12 of 802.11-2016)
199  */
200  // The timestamp of the A-MSDU is the most recent among those of the MSDUs
201  m_tstamp = Max (m_tstamp, msdu->GetTimeStamp ());
202 }
203 
204 bool
206 {
207  return !m_queueIts.empty ();
208 }
209 
210 const std::list<WifiMacQueueItem::QueueIteratorPair>&
212 {
213  return m_queueIts;
214 }
215 
218 {
219  return m_msduList.begin ();
220 }
221 
224 {
225  return m_msduList.end ();
226 }
227 
228 void
229 WifiMacQueueItem::Print (std::ostream& os) const
230 {
231  os << m_header.GetTypeString ()
232  << ", payloadSize=" << GetPacketSize ()
233  << ", to=" << m_header.GetAddr1 ()
234  << ", seqN=" << m_header.GetSequenceNumber ()
235  << ", duration/ID=" << m_header.GetDuration ()
236  << ", lifetime=" << (Simulator::Now () - m_tstamp).As (Time::US);
237  if (m_header.IsQosData ())
238  {
239  os << ", tid=" << +m_header.GetQosTid ();
240  if (m_header.IsQosNoAck ())
241  {
242  os << ", ack=NoAck";
243  }
244  else if (m_header.IsQosAck ())
245  {
246  os << ", ack=NormalAck";
247  }
248  else if (m_header.IsQosBlockAck ())
249  {
250  os << ", ack=BlockAck";
251  }
252  }
253  os << ", packet=" << m_packet;
254 }
255 
256 std::ostream & operator << (std::ostream &os, const WifiMacQueueItem &item)
257 {
258  item.Print (os);
259  return os;
260 }
261 
262 } //namespace ns3
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
microsecond
Definition: nstime.h:117
Control the scheduling of simulation events.
Definition: simulator.h:68
DeaggregatedMsdusCI end(void)
Get a constant iterator indicating past-the-last MSDU in the list of aggregated MSDUs.
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:852
void AddWifiMacTrailer(Ptr< Packet > packet)
Add FCS trailer to a packet.
Definition: wifi-utils.cc:231
virtual void Print(std::ostream &os) const
Print the item contents.
std::list< QueueIteratorPair > m_queueIts
Queue iterators pointing to this MSDU(s), if queued.
DeaggregatedMsdusCI begin(void)
Get a constant iterator pointing to the first MSDU in the list of aggregated MSDUs.
uint32_t GetSize(void) const
Return the size of the packet stored by this item, including header size and trailer size...
Mac48Address GetAddr1(void) const
Return the address in the Address 1 field.
#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
Time GetTimeStamp(void) const
Get the timestamp included in this item.
static const uint16_t WIFI_MAC_FCS_LENGTH
The length in octects of the IEEE 802.11 MAC FCS field.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
const char * GetTypeString(void) const
Return a string corresponds to the header type.
Mac48Address GetDestinationAddress(void) const
Return the destination address present in the header.
void SetSourceAddr(Mac48Address to)
Set source address function.
Ptr< const Packet > m_packet
The packet (MSDU or A-MSDU) contained in this queue item.
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:137
void AddAtEnd(Ptr< const Packet > packet)
Concatenate the input packet at the end of the current packet.
Definition: packet.cc:335
std::list< std::pair< Ptr< const Packet >, AmsduSubframeHeader > >::const_iterator DeaggregatedMsdusCI
DeaggregatedMsdusCI typedef.
WifiMacQueueItem stores (const) packets along with their Wifi MAC headers and the time when they were...
const WifiMacHeader & GetHeader(void) const
Get the header stored in this item.
Time m_tstamp
timestamp when the packet arrived at the queue
bool IsQosNoAck(void) const
Return if the QoS Ack policy is No Ack.
bool IsQosAmsdu(void) const
Check if the A-MSDU present bit is set in the QoS control field.
void SetAddr3(Mac48Address address)
Fill the Address 3 field with the given address.
static WifiMacQueueItem::DeaggregatedMsdus Deaggregate(Ptr< Packet > aggregatedPacket)
bool IsFromDs(void) const
int64x64_t Max(const int64x64_t &a, const int64x64_t &b)
Maximum.
Definition: int64x64.h:230
uint8_t GetQosTid(void) const
Return the Traffic ID of a QoS header.
WifiMacHeader m_header
Wifi MAC header associated with the packet.
void Aggregate(Ptr< const WifiMacQueueItem > msdu)
Aggregate the MSDU contained in the given MPDU to this MPDU (thus constituting an A-MSDU)...
void SetLength(uint16_t length)
Set length function.
bool IsQosAck(void) const
Return if the QoS Ack policy is Normal Ack.
Mac48Address GetAddr2(void) const
Return the address in the Address 2 field.
Ptr< const Packet > GetPacket(void) const
Get the packet stored in this item.
Ptr< Packet > GetProtocolDataUnit(void) const
Get the MAC protocol data unit (MPDU) corresponding to this item (i.e.
bool IsFragment(void) const
Return true if this item contains an MSDU fragment, false otherwise.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
uint16_t GetSequenceNumber(void) const
Return the sequence number of the header.
WifiMacQueueItem(Ptr< const Packet > p, const WifiMacHeader &header)
Create a Wifi MAC queue item containing a packet and a Wifi MAC header.
Time GetDuration(void) const
Return the duration from the Duration/ID field (Time object).
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:121
an EUI-48 address
Definition: mac48-address.h:43
DeaggregatedMsdus m_msduList
The list of aggregated MSDUs included in this MPDU.
Headers for A-MSDU subframes.
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
bool IsMoreFragments(void) const
Return if the More Fragment bit is set.
void SetDestinationAddr(Mac48Address to)
Set destination address function.
bool IsQosBlockAck(void) const
Return if the QoS Ack policy is Block Ack.
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
bool IsQueued(void) const
Return true if this item is stored in some queue, false otherwise.
uint32_t GetSerializedSize(void) const
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 DoAggregate(Ptr< const WifiMacQueueItem > msdu)
Aggregate the MSDU contained in the given MPDU to this MPDU (thus constituting an A-MSDU)...
bool IsQosData(void) const
Return true if the Type is DATA and Subtype is one of the possible values for QoS Data...
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:287
uint32_t GetPacketSize(void) const
Return the size in bytes of the packet or control header or management header stored by this item...
uint8_t GetFragmentNumber(void) const
Return the fragment number of the header.
const std::list< QueueIteratorPair > & GetQueueIteratorPairs(void) const
Get a const reference to the list of iterators pointing to the positions of the items in the queue...
void SetQosAmsdu(void)
Set that A-MSDU is present.
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:256
Implements the IEEE 802.11 MAC header.
bool IsToDs(void) const