1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
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  * Author: Mirko Banchi <mk.banchi@gmail.com>
19  */
20 
21 #ifndef MSDU_AGGREGATOR_H
22 #define MSDU_AGGREGATOR_H
23 
24 #include "ns3/object.h"
25 #include "ns3/nstime.h"
26 #include "wifi-mode.h"
27 #include "qos-utils.h"
28 #include "wifi-mac-queue-item.h"
29 #include <map>
30 
31 namespace ns3 {
32 
33 class Packet;
34 class QosTxop;
35 class WifiTxVector;
36 class RegularWifiMac;
37 class HtFrameExchangeManager;
38 class WifiTxParameters;
39 
40 /**
41  * \brief Aggregator used to construct A-MSDUs
42  * \ingroup wifi
43  */
44 class MsduAggregator : public Object
45 {
46 public:
47   /// EDCA queues typedef
48   typedef std::map<AcIndex, Ptr<QosTxop> > EdcaQueues;
49 
50   /**
51    * \brief Get the type ID.
52    * \return the object TypeId
53    */
54   static TypeId GetTypeId (void);
55 
56   MsduAggregator ();
57   virtual ~MsduAggregator ();
58 
59   /**
60    * Compute the size of the A-MSDU resulting from the aggregation of an MSDU of
61    * size <i>msduSize</i> and an A-MSDU of size <i>amsduSize</i>.
62    * Note that only the basic A-MSDU subframe format (section 9.3.2.2.2 of IEEE
63    * 802.11-2016) is supported.
64    *
65    * \param msduSize the MSDU size in bytes.
66    * \param amsduSize the A-MSDU size in bytes.
67    * \return the size of the resulting A-MSDU in bytes.
68    */
69   static uint16_t GetSizeIfAggregated (uint16_t msduSize, uint16_t amsduSize);
70 
71   /**
72    * Attempt to aggregate other MSDUs to the given A-MSDU while meeting the
73    * following constraints:
74    *
75    * - the A-MSDU size does not exceed the maximum A-MSDU size as determined for
76    * the modulation class indicated by the given TxVector
77    *
78    * - the size of the A-MPDU resulting from the aggregation of the MPDU in which
79    * the A-MSDU will be embedded and the current A-MPDU (as specified by the given
80    * TX parameters) does not exceed the maximum A-MPDU size as determined for
81    * the modulation class indicated by the given TxVector
82    *
83    * - the time to transmit the resulting PPDU, according to the given TxVector,
84    * does not exceed the maximum PPDU duration allowed by the corresponding
85    * modulation class (if any)
86    *
87    * - the time to transmit the resulting PPDU and to carry out protection and
88    * acknowledgment, as specified by the given TX parameters, does not exceed the
89    * given available time (if distinct from Time::Min ())
90    *
91    * If aggregation succeeds (it was possible to aggregate at least an MSDU to the
92    * given MSDU), all the aggregated MSDUs are dequeued and an MPDU containing the
93    * A-MSDU is enqueued in the queue (replacing the given MPDU) and returned.
94    * Otherwise, no MSDU is dequeued from the EDCA queue and a null pointer is returned.
95    *
96    * \param peekedItem the MSDU which we attempt to aggregate other MSDUs to
97    * \param txParams the TX parameters for the current frame
98    * \param availableTime the time available for the frame exchange
99    * \param[out] queueIt a queue iterator pointing to the queue item following the
100    *                     last item used to prepare the returned A-MSDU, if any; otherwise,
101    *                     its value is unchanged
102    * \return the resulting A-MSDU, if aggregation is possible, a null pointer otherwise.
103    */
104   Ptr<WifiMacQueueItem> GetNextAmsdu (Ptr<const WifiMacQueueItem> peekedItem, WifiTxParameters& txParams,
105                                       Time availableTime, WifiMacQueueItem::ConstIterator& queueIt) const;
106 
107   /**
108    * Determine the maximum size for an A-MSDU of the given TID that can be sent
109    * to the given receiver when using the given modulation class.
110    *
111    * \param recipient the receiver station address.
112    * \param tid the TID.
113    * \param modulation the modulation class.
114    * \return the maximum A-MSDU size in bytes.
115    */
116   uint16_t GetMaxAmsduSize (Mac48Address recipient, uint8_t tid,
117                             WifiModulationClass modulation) const;
118 
119   /**
120    *
121    * \param aggregatedPacket the aggregated packet.
122    * \returns DeaggregatedMsdus.
123    */
124   static WifiMacQueueItem::DeaggregatedMsdus Deaggregate (Ptr<Packet> aggregatedPacket);
125 
126   /**
127    * Set the MAC layer to use.
128    *
129    * \param mac the MAC layer to use
130    */
131   void SetWifiMac (const Ptr<RegularWifiMac> mac);
132 
133   /**
134    * Calculate how much padding must be added to the end of an A-MSDU of the
135    * given size if a new MSDU is added.
136    * Each A-MSDU subframe is padded so that its length is multiple of 4 octets.
137    *
138    * \param amsduSize the size of the A-MSDU
139    *
140    * \return the number of octets required for padding
141    */
142   static uint8_t CalculatePadding (uint16_t amsduSize);
143 
144 protected:
145   void DoDispose () override;
146 
147 private:
148   Ptr<RegularWifiMac> m_mac;            //!< the MAC of this station
149   Ptr<HtFrameExchangeManager> m_htFem;  //!< the HT Frame Exchange Manager of this station
150 };
151 
152 } //namespace ns3
153 
154 #endif /* MSDU_AGGREGATOR_H */
155