1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2008 INRIA
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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19  */
20 
21 #ifndef REGULAR_WIFI_MAC_H
22 #define REGULAR_WIFI_MAC_H
23 
24 #include "wifi-mac.h"
25 #include "qos-txop.h"
26 #include "ssid.h"
27 #include <set>
28 #include <unordered_map>
29 
30 namespace ns3 {
31 
32 class MacRxMiddle;
33 class MacTxMiddle;
34 class ChannelAccessManager;
35 class ExtendedCapabilities;
36 class FrameExchangeManager;
37 class WifiPsdu;
38 class WifiMacQueue;
39 enum WifiTxTimerReason : uint8_t;
40 
41 typedef std::unordered_map <uint16_t /* staId */, Ptr<WifiPsdu> /* PSDU */> WifiPsduMap;
42 
43 /**
44  * \brief base class for all MAC-level wifi objects.
45  * \ingroup wifi
46  *
47  * This class encapsulates all the low-level MAC functionality and all the
48  * high-level MAC functionality (association/disassociation state machines).
49  *
50  */
51 class RegularWifiMac : public WifiMac
52 {
53 public:
54   /**
55    * \brief Get the type ID.
56    * \return the object TypeId
57    */
58   static TypeId GetTypeId (void);
59 
60   RegularWifiMac ();
61   virtual ~RegularWifiMac ();
62 
63   // Implementations of pure virtual methods.
64   void SetShortSlotTimeSupported (bool enable) override;
65   void SetSsid (Ssid ssid) override;
66   void SetAddress (Mac48Address address) override;
67   void SetPromisc (void) override;
68   bool GetShortSlotTimeSupported (void) const override;
69   Ssid GetSsid (void) const override;
70   Mac48Address GetAddress (void) const override;
71   Mac48Address GetBssid (void) const override;
72   void Enqueue (Ptr<Packet> packet, Mac48Address to, Mac48Address from) override;
73   bool SupportsSendFrom (void) const override;
74   void SetWifiPhy (const Ptr<WifiPhy> phy) override;
75   Ptr<WifiPhy> GetWifiPhy (void) const override;
76   void ResetWifiPhy (void) override;
77   void SetWifiRemoteStationManager (const Ptr<WifiRemoteStationManager> stationManager) override;
78   void ConfigureStandard (WifiStandard standard) override;
79   TypeOfStation GetTypeOfStation (void) const override;
80   void SetForwardUpCallback (ForwardUpCallback upCallback) override;
81   void SetLinkUpCallback (Callback<void> linkUp) override;
82   void SetLinkDownCallback (Callback<void> linkDown) override;
83   Ptr<WifiRemoteStationManager> GetWifiRemoteStationManager (void) const override;
84 
85   // Should be implemented by child classes
86   void Enqueue (Ptr<Packet> packet, Mac48Address to) override = 0;
87 
88   /**
89    * Get the Frame Exchange Manager
90    *
91    * \return the Frame Exchange Manager
92    */
93   Ptr<FrameExchangeManager> GetFrameExchangeManager (void) const;
94 
95   /**
96    * Enable or disable CTS-to-self feature.
97    *
98    * \param enable true if CTS-to-self is to be supported,
99    *               false otherwise
100    */
101   void SetCtsToSelfSupported (bool enable);
102   /**
103    * \param bssid the BSSID of the network that this device belongs to.
104    */
105   void SetBssid (Mac48Address bssid);
106 
107   /**
108    * Accessor for the DCF object
109    *
110    * \return a smart pointer to Txop
111    */
112   Ptr<Txop> GetTxop (void) const;
113   /**
114    * Accessor for a specified EDCA object
115    *
116    * \param ac the Access Category
117    * \return a smart pointer to a QosTxop
118    */
119   Ptr<QosTxop> GetQosTxop (AcIndex ac) const;
120   /**
121    * Accessor for a specified EDCA object
122    *
123    * \param tid the Traffic ID
124    * \return a smart pointer to a QosTxop
125    */
126   Ptr<QosTxop> GetQosTxop (uint8_t tid) const;
127   /**
128    * Get the wifi MAC queue of the (Qos)Txop associated with the given AC.
129    *
130    * \param ac the given Access Category
131    * \return the wifi MAC queue of the (Qos)Txop associated with the given AC
132    */
133   virtual Ptr<WifiMacQueue> GetTxopQueue (AcIndex ac) const;
134 
135   /**
136    * Return whether the device supports QoS.
137    *
138    * \return true if QoS is supported, false otherwise
139    */
140   bool GetQosSupported () const;
141   /**
142    * Return whether the device supports ERP.
143    *
144    * \return true if ERP is supported, false otherwise
145    */
146   bool GetErpSupported () const;
147   /**
148    * Return whether the device supports DSSS.
149    *
150    * \return true if DSSS is supported, false otherwise
151    */
152   bool GetDsssSupported () const;
153   /**
154    * Return whether the device supports HT.
155    *
156    * \return true if HT is supported, false otherwise
157    */
158   bool GetHtSupported () const;
159   /**
160    * Return whether the device supports VHT.
161    *
162    * \return true if VHT is supported, false otherwise
163    */
164   bool GetVhtSupported () const;
165   /**
166    * Return whether the device supports HE.
167    *
168    * \return true if HE is supported, false otherwise
169    */
170   bool GetHeSupported () const;
171 
172   /**
173    * Return the extended capabilities of the device.
174    *
175    * \return the extended capabilities that we support
176    */
177   ExtendedCapabilities GetExtendedCapabilities (void) const;
178   /**
179    * Return the HT capabilities of the device.
180    *
181    * \return the HT capabilities that we support
182    */
183   HtCapabilities GetHtCapabilities (void) const;
184   /**
185    * Return the VHT capabilities of the device.
186    *
187    * \return the VHT capabilities that we support
188    */
189   VhtCapabilities GetVhtCapabilities (void) const;
190   /**
191    * Return the HE capabilities of the device.
192    *
193    * \return the HE capabilities that we support
194    */
195   HeCapabilities GetHeCapabilities (void) const;
196 
197   /**
198    * Return the maximum A-MPDU size of the given Access Category.
199    *
200    * \param ac Access Category index
201    * \return the maximum A-MPDU size
202    */
203   uint32_t GetMaxAmpduSize (AcIndex ac) const;
204   /**
205    * Return the maximum A-MSDU size of the given Access Category.
206    *
207    * \param ac Access Category index
208    * \return the maximum A-MSDU size
209    */
210   uint16_t GetMaxAmsduSize (AcIndex ac) const;
211 
212 protected:
213   void DoInitialize () override;
214   void DoDispose () override;
215   void SetTypeOfStation (TypeOfStation type) override;
216 
217   Ptr<MacRxMiddle> m_rxMiddle;                      //!< RX middle (defragmentation etc.)
218   Ptr<MacTxMiddle> m_txMiddle;                      //!< TX middle (aggregation etc.)
219   Ptr<ChannelAccessManager> m_channelAccessManager; //!< channel access manager
220   Ptr<WifiPhy> m_phy;                               //!< Wifi PHY
221   Ptr<FrameExchangeManager> m_feManager;            //!< Frame Exchange Manager
222 
223   Ptr<WifiRemoteStationManager> m_stationManager; //!< Remote station manager (rate control, RTS/CTS/fragmentation thresholds etc.)
224 
225   ForwardUpCallback m_forwardUp; //!< Callback to forward packet up the stack
226   Callback<void> m_linkUp;       //!< Callback when a link is up
227   Callback<void> m_linkDown;     //!< Callback when a link is down
228 
229   Ssid m_ssid; //!< Service Set ID (SSID)
230 
231   /** This holds a pointer to the TXOP instance for this WifiMac - used
232   for transmission of frames to non-QoS peers. */
233   Ptr<Txop> m_txop;
234 
235   /** This type defines a mapping between an Access Category index,
236   and a pointer to the corresponding channel access function */
237   typedef std::map<AcIndex, Ptr<QosTxop> > EdcaQueues;
238 
239   /** This is a map from Access Category index to the corresponding
240   channel access function */
241   EdcaQueues m_edca;
242 
243   /**
244    * Accessor for the AC_VO channel access function
245    *
246    * \return a smart pointer to QosTxop
247    */
248   Ptr<QosTxop> GetVOQueue (void) const;
249   /**
250    * Accessor for the AC_VI channel access function
251    *
252    * \return a smart pointer to QosTxop
253    */
254   Ptr<QosTxop> GetVIQueue (void) const;
255   /**
256    * Accessor for the AC_BE channel access function
257    *
258    * \return a smart pointer to QosTxop
259    */
260   Ptr<QosTxop> GetBEQueue (void) const;
261   /**
262    * Accessor for the AC_BK channel access function
263    *
264    * \return a smart pointer to QosTxop
265    */
266   Ptr<QosTxop> GetBKQueue (void) const;
267 
268   /**
269    * \param cwMin the minimum contention window size
270    * \param cwMax the maximum contention window size
271    *
272    * This method is called to set the minimum and the maximum
273    * contention window size.
274    */
275   void ConfigureContentionWindow (uint32_t cwMin, uint32_t cwMax);
276 
277   /**
278    * This method acts as the MacRxMiddle receive callback and is
279    * invoked to notify us that a frame has been received. The
280    * implementation is intended to capture logic that is going to be
281    * common to all (or most) derived classes. Specifically, handling
282    * of Block Ack management frames is dealt with here.
283    *
284    * This method will need, however, to be overridden by derived
285    * classes so that they can perform their data handling before
286    * invoking the base version.
287    *
288    * \param mpdu the MPDU that has been received.
289    */
290   virtual void Receive (Ptr<WifiMacQueueItem> mpdu);
291 
292   /**
293    * Forward the packet up to the device.
294    *
295    * \param packet the packet that we are forwarding up to the device
296    * \param from the address of the source
297    * \param to the address of the destination
298    */
299   void ForwardUp (Ptr<const Packet> packet, Mac48Address from, Mac48Address to);
300 
301   /**
302    * This method can be called to de-aggregate an A-MSDU and forward
303    * the constituent packets up the stack.
304    *
305    * \param mpdu the MPDU containing the A-MSDU.
306    */
307   virtual void DeaggregateAmsduAndForward (Ptr<WifiMacQueueItem> mpdu);
308 
309   /**
310    * Enable or disable QoS support for the device.
311    *
312    * \param enable whether QoS is supported
313    */
314   virtual void SetQosSupported (bool enable);
315 
316   /**
317    * Create a Frame Exchange Manager depending on the supported version
318    * of the standard.
319    */
320   void SetupFrameExchangeManager (void);
321 
322   /**
323    * Enable or disable ERP support for the device.
324    *
325    * \param enable whether ERP is supported
326    */
327   void SetErpSupported (bool enable);
328 
329   /**
330    * Enable or disable DSSS support for the device.
331    *
332    * \param enable whether DSSS is supported
333    */
334   void SetDsssSupported (bool enable);
335 
336 private:
337   /// type conversion operator
338   RegularWifiMac (const RegularWifiMac &);
339   /**
340    * assignment operator
341    *
342    * \param mac the RegularWifiMac to assign
343    * \returns the assigned value
344    */
345   RegularWifiMac & operator= (const RegularWifiMac & mac);
346 
347   /**
348    * This method is a private utility invoked to configure the channel
349    * access function for the specified Access Category.
350    *
351    * \param ac the Access Category of the queue to initialise.
352    */
353   void SetupEdcaQueue (AcIndex ac);
354 
355   /**
356    * Set the block ack threshold for AC_VO.
357    *
358    * \param threshold the block ack threshold for AC_VO.
359    */
360   void SetVoBlockAckThreshold (uint8_t threshold);
361   /**
362    * Set the block ack threshold for AC_VI.
363    *
364    * \param threshold the block ack threshold for AC_VI.
365    */
366   void SetViBlockAckThreshold (uint8_t threshold);
367   /**
368    * Set the block ack threshold for AC_BE.
369    *
370    * \param threshold the block ack threshold for AC_BE.
371    */
372   void SetBeBlockAckThreshold (uint8_t threshold);
373   /**
374    * Set the block ack threshold for AC_BK.
375    *
376    * \param threshold the block ack threshold for AC_BK.
377    */
378   void SetBkBlockAckThreshold (uint8_t threshold);
379 
380   /**
381    * Set VO block ack inactivity timeout.
382    *
383    * \param timeout the VO block ack inactivity timeout.
384    */
385   void SetVoBlockAckInactivityTimeout (uint16_t timeout);
386   /**
387    * Set VI block ack inactivity timeout.
388    *
389    * \param timeout the VI block ack inactivity timeout.
390    */
391   void SetViBlockAckInactivityTimeout (uint16_t timeout);
392   /**
393    * Set BE block ack inactivity timeout.
394    *
395    * \param timeout the BE block ack inactivity timeout.
396    */
397   void SetBeBlockAckInactivityTimeout (uint16_t timeout);
398   /**
399    * Set BK block ack inactivity timeout.
400    *
401    * \param timeout the BK block ack inactivity timeout.
402    */
403   void SetBkBlockAckInactivityTimeout (uint16_t timeout);
404 
405   TypeOfStation m_typeOfStation;                        //!< the type of station
406 
407   /**
408    * This Boolean is set \c true iff this WifiMac is to model
409    * 802.11e/WMM style Quality of Service. It is exposed through the
410    * attribute system.
411    *
412    * At the moment, this flag is the sole selection between QoS and
413    * non-QoS operation for the STA (whether IBSS, AP, or
414    * non-AP). Ultimately, we will want a QoS-enabled STA to be able to
415    * fall back to non-QoS operation with a non-QoS peer. This'll
416    * require further intelligence - i.e., per-association QoS
417    * state. Having a big switch seems like a good intermediate stage,
418    * however.
419    */
420   bool m_qosSupported;
421   /**
422    * This Boolean is set \c true iff this WifiMac is to model
423    * 802.11g. It is exposed through the attribute system.
424    */
425   bool m_erpSupported;
426   /**
427    * This Boolean is set \c true iff this WifiMac is to model
428    * 802.11b. It is exposed through the attribute system.
429    */
430   bool m_dsssSupported;
431 
432   Mac48Address m_address;   ///< MAC address of this station
433   Mac48Address m_bssid;     ///< the BSSID
434 
435   uint16_t m_voMaxAmsduSize; ///< maximum A-MSDU size for AC_VO (in bytes)
436   uint16_t m_viMaxAmsduSize; ///< maximum A-MSDU size for AC_VI (in bytes)
437   uint16_t m_beMaxAmsduSize; ///< maximum A-MSDU size for AC_BE (in bytes)
438   uint16_t m_bkMaxAmsduSize; ///< maximum A-MSDU size for AC_BK (in bytes)
439 
440   uint32_t m_voMaxAmpduSize; ///< maximum A-MPDU size for AC_VO (in bytes)
441   uint32_t m_viMaxAmpduSize; ///< maximum A-MPDU size for AC_VI (in bytes)
442   uint32_t m_beMaxAmpduSize; ///< maximum A-MPDU size for AC_BE (in bytes)
443   uint32_t m_bkMaxAmpduSize; ///< maximum A-MPDU size for AC_BK (in bytes)
444 
445   TracedCallback<const WifiMacHeader &> m_txOkCallback; ///< transmit OK callback
446   TracedCallback<const WifiMacHeader &> m_txErrCallback; ///< transmit error callback
447 
448   /// TracedCallback for acked/nacked MPDUs typedef
449   typedef TracedCallback<Ptr<const WifiMacQueueItem>> MpduTracedCallback;
450 
451   MpduTracedCallback m_ackedMpduCallback;  ///< ack'ed MPDU callback
452   MpduTracedCallback m_nackedMpduCallback; ///< nack'ed MPDU callback
453 
454   /**
455    * TracedCallback signature for MPDU drop events.
456    *
457    * \param reason the reason why the MPDU was dropped (\see WifiMacDropReason)
458    * \param mpdu the dropped MPDU
459    */
460   typedef void (* DroppedMpduCallback)(WifiMacDropReason reason, Ptr<const WifiMacQueueItem> mpdu);
461 
462   /// TracedCallback for MPDU drop events typedef
463   typedef TracedCallback<WifiMacDropReason, Ptr<const WifiMacQueueItem>> DroppedMpduTracedCallback;
464 
465   /**
466    * This trace indicates that an MPDU was dropped for the given reason.
467    */
468   DroppedMpduTracedCallback m_droppedMpduCallback;
469 
470   /**
471    * TracedCallback signature for MPDU response timeout events.
472    *
473    * \param reason the reason why the timer was started
474    * \param mpdu the MPDU whose response was not received before the timeout
475    * \param txVector the TXVECTOR used to transmit the MPDU
476    */
477   typedef void (* MpduResponseTimeoutCallback)(uint8_t reason, Ptr<const WifiMacQueueItem> mpdu,
478                                                const WifiTxVector& txVector);
479 
480   /// TracedCallback for MPDU response timeout events typedef
481   typedef TracedCallback<uint8_t, Ptr<const WifiMacQueueItem>, const WifiTxVector&> MpduResponseTimeoutTracedCallback;
482 
483   /**
484    * MPDU response timeout traced callback.
485    * This trace source is fed by a WifiTxTimer object.
486    */
487   MpduResponseTimeoutTracedCallback m_mpduResponseTimeoutCallback;
488 
489   /**
490    * TracedCallback signature for PSDU response timeout events.
491    *
492    * \param reason the reason why the timer was started
493    * \param psdu the PSDU whose response was not received before the timeout
494    * \param txVector the TXVECTOR used to transmit the PSDU
495    */
496   typedef void (* PsduResponseTimeoutCallback)(uint8_t reason, Ptr<const WifiPsdu> psdu,
497                                                const WifiTxVector& txVector);
498 
499   /// TracedCallback for PSDU response timeout events typedef
500   typedef TracedCallback<uint8_t, Ptr<const WifiPsdu>, const WifiTxVector&> PsduResponseTimeoutTracedCallback;
501 
502   /**
503    * PSDU response timeout traced callback.
504    * This trace source is fed by a WifiTxTimer object.
505    */
506   PsduResponseTimeoutTracedCallback m_psduResponseTimeoutCallback;
507 
508   /**
509    * TracedCallback signature for PSDU map response timeout events.
510    *
511    * \param reason the reason why the timer was started
512    * \param psduMap the PSDU map for which not all responses were received before the timeout
513    * \param missingStations the MAC addresses of the stations that did not respond
514    * \param nTotalStations the total number of stations that had to respond
515    */
516   typedef void (* PsduMapResponseTimeoutCallback)(uint8_t reason, WifiPsduMap* psduMap,
517                                                   const std::set<Mac48Address>* missingStations,
518                                                   std::size_t nTotalStations);
519 
520   /// TracedCallback for PSDU map response timeout events typedef
521   typedef TracedCallback<uint8_t, WifiPsduMap*, const std::set<Mac48Address>*, std::size_t> PsduMapResponseTimeoutTracedCallback;
522 
523   /**
524    * PSDU map response timeout traced callback.
525    * This trace source is fed by a WifiTxTimer object.
526    */
527   PsduMapResponseTimeoutTracedCallback m_psduMapResponseTimeoutCallback;
528 
529   bool m_shortSlotTimeSupported; ///< flag whether short slot time is supported
530   bool m_ctsToSelfSupported;     ///< flag indicating whether CTS-To-Self is supported
531 };
532 
533 } //namespace ns3
534 
535 #endif /* REGULAR_WIFI_MAC_H */
536