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