1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ 2 /* 3 * Copyright (c) 2020 Universita' degli Studi di Napoli Federico II 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: Stefano Avallone <stavallo@unina.it> 19 */ 20 21 #ifndef FRAME_EXCHANGE_MANAGER_H 22 #define FRAME_EXCHANGE_MANAGER_H 23 24 #include "ns3/object.h" 25 #include "qos-txop.h" 26 #include "wifi-tx-vector.h" 27 #include "wifi-psdu.h" 28 #include "regular-wifi-mac.h" 29 #include "mac-rx-middle.h" 30 #include "mac-tx-middle.h" 31 #include "wifi-phy.h" 32 #include "wifi-tx-timer.h" 33 #include "wifi-tx-parameters.h" 34 // Needed to compile wave bindings 35 #include "ns3/wifi-protection-manager.h" 36 #include "ns3/wifi-ack-manager.h" 37 #include "channel-access-manager.h" 38 39 namespace ns3 { 40 41 struct RxSignalInfo; 42 struct WifiProtection; 43 struct WifiAcknowledgment; 44 45 /** 46 * \ingroup wifi 47 * 48 * FrameExchangeManager is a base class handling the basic frame exchange 49 * sequences for non-QoS stations. 50 */ 51 class FrameExchangeManager : public Object 52 { 53 public: 54 /** 55 * \brief Get the type ID. 56 * \return the object TypeId 57 */ 58 static TypeId GetTypeId (void); 59 FrameExchangeManager (); 60 virtual ~FrameExchangeManager (); 61 62 /** 63 * typedef for a callback to invoke when an MPDU is dropped. 64 */ 65 typedef Callback <void, WifiMacDropReason, Ptr<const WifiMacQueueItem>> DroppedMpdu; 66 /** 67 * typedef for a callback to invoke when an MPDU is successfully acknowledged. 68 */ 69 typedef Callback <void, Ptr<const WifiMacQueueItem>> AckedMpdu; 70 71 /** 72 * Request the FrameExchangeManager to start a frame exchange sequence. 73 * 74 * \param dcf the channel access function that gained channel access. It is 75 * the DCF on non-QoS stations and an EDCA on QoS stations. 76 * \return true if a frame exchange sequence was started, false otherwise 77 */ 78 virtual bool StartTransmission (Ptr<Txop> dcf); 79 80 /** 81 * This method is intended to be called by the PHY layer every time an MPDU 82 * is received and also when the reception of an A-MPDU is completed. In case 83 * the PSDU contains multiple MPDUs, the <i>perMpduStatus</i> vector is empty 84 * when receiving the individual MPDUs. 85 * 86 * \param psdu the received PSDU 87 * \param rxSignalInfo the info on the received signal (\see RxSignalInfo) 88 * \param txVector TxVector of the received PSDU 89 * \param perMpduStatus per MPDU reception status 90 */ 91 void Receive (Ptr<WifiPsdu> psdu, RxSignalInfo rxSignalInfo, 92 WifiTxVector txVector, std::vector<bool> perMpduStatus); 93 94 /** 95 * Set the MAC layer to use. 96 * 97 * \param mac the MAC layer to use 98 */ 99 virtual void SetWifiMac (const Ptr<RegularWifiMac> mac); 100 /** 101 * Set the MAC TX Middle to use. 102 * 103 * \param txMiddle the MAC TX Middle to use 104 */ 105 virtual void SetMacTxMiddle (const Ptr<MacTxMiddle> txMiddle); 106 /** 107 * Set the MAC RX Middle to use. 108 * 109 * \param rxMiddle the MAC RX Middle to use 110 */ 111 virtual void SetMacRxMiddle (const Ptr<MacRxMiddle> rxMiddle); 112 /** 113 * Set the channel access manager to use 114 * 115 * \param channelAccessManager the channel access manager to use 116 */ 117 virtual void SetChannelAccessManager (const Ptr<ChannelAccessManager> channelAccessManager); 118 /** 119 * Set the PHY layer to use. 120 * 121 * \param phy the PHY layer to use 122 */ 123 virtual void SetWifiPhy (const Ptr<WifiPhy> phy); 124 /** 125 * Remove WifiPhy associated with this FrameExchangeManager. 126 */ 127 virtual void ResetPhy (void); 128 /** 129 * Set the Protection Manager to use 130 * 131 * \param protectionManager the Protection Manager to use 132 */ 133 virtual void SetProtectionManager (Ptr<WifiProtectionManager> protectionManager); 134 /** 135 * Set the Acknowledgment Manager to use 136 * 137 * \param ackManager the Acknowledgment Manager to use 138 */ 139 virtual void SetAckManager (Ptr<WifiAckManager> ackManager); 140 /** 141 * Set the MAC address. 142 * 143 * \param address the MAC address 144 */ 145 virtual void SetAddress (Mac48Address address); 146 /** 147 * Set the Basic Service Set Identification. 148 * 149 * \param bssid the BSSID 150 */ 151 virtual void SetBssid (Mac48Address bssid); 152 /** 153 * Set the callback to invoke when an MPDU is dropped. 154 * 155 * \param callback the callback to invoke when an MPDU is dropped 156 */ 157 virtual void SetDroppedMpduCallback (DroppedMpdu callback); 158 /** 159 * Set the callback to invoke when an MPDU is successfully acked. 160 * 161 * \param callback the callback to invoke when an MPDU is successfully acked 162 */ 163 void SetAckedMpduCallback (AckedMpdu callback); 164 /** 165 * Enable promiscuous mode. 166 */ 167 void SetPromisc (void); 168 /** 169 * Check if the device is operating in promiscuous mode. 170 * 171 * \return true if the device is operating in promiscuous mode, 172 * false otherwise 173 */ 174 bool IsPromisc (void) const; 175 176 /** 177 * Get a const reference to the WifiTxTimer object. 178 * 179 * \return a const reference to the WifiTxTimer object 180 */ 181 const WifiTxTimer& GetWifiTxTimer (void) const; 182 183 /** 184 * Get the Protection Manager used by this node. 185 * 186 * \return the Protection Manager used by this node 187 */ 188 Ptr<WifiProtectionManager> GetProtectionManager (void) const; 189 190 /** 191 * Calculate the time required to protect a frame according to the given 192 * protection method. The protection time is stored in the protection 193 * object itself. 194 * 195 * \param protection the protection method 196 */ 197 virtual void CalculateProtectionTime (WifiProtection* protection) const; 198 199 /** 200 * Get the Acknowledgment Manager used by this node. 201 * 202 * \return the Acknowledgment Manager used by this node 203 */ 204 Ptr<WifiAckManager> GetAckManager (void) const; 205 206 /** 207 * Calculate the time required to acknowledge a frame according to the given 208 * acknowledgment method. The acknowledgment time is stored in the acknowledgment 209 * object itself. 210 * 211 * \param acknowledgment the acknowledgment method 212 */ 213 virtual void CalculateAcknowledgmentTime (WifiAcknowledgment* acknowledgment) const; 214 215 /** 216 * Notify that an internal collision has occurred for the given Txop 217 * 218 * \param txop the Txop for which an internal collision has occurred 219 */ 220 virtual void NotifyInternalCollision (Ptr<Txop> txop); 221 222 /** 223 * \param duration switching delay duration. 224 * 225 * This method is typically invoked by the PhyListener to notify 226 * the MAC layer that a channel switching occurred. When a channel switching 227 * occurs, pending MAC transmissions (RTS, CTS, Data and Ack) are cancelled. 228 */ 229 void NotifySwitchingStartNow (Time duration); 230 231 /** 232 * This method is typically invoked by the PhyListener to notify 233 * the MAC layer that the device has been put into sleep mode. When the device is put 234 * into sleep mode, pending MAC transmissions (RTS, CTS, Data and Ack) are cancelled. 235 */ 236 void NotifySleepNow (void); 237 238 /** 239 * This method is typically invoked by the PhyListener to notify 240 * the MAC layer that the device has been put into off mode. When the device is put 241 * into off mode, pending MAC transmissions (RTS, CTS, Data and Ack) are cancelled. 242 */ 243 void NotifyOffNow (void); 244 245 protected: 246 void DoDispose () override; 247 248 /** 249 * Fragment the given MPDU if needed. If fragmentation is needed, return the 250 * first fragment; otherwise, return the given MPDU. Note that, if fragmentation 251 * is applied, the given MPDU is dequeued from the MAC queue and the first 252 * fragment is enqueued in its place. 253 * 254 * \param mpdu the given MPDU 255 * \return the first fragment if fragmentation is needed, the given MPDU otherwise 256 */ 257 Ptr<WifiMacQueueItem> GetFirstFragmentIfNeeded (Ptr<WifiMacQueueItem> mpdu); 258 259 /** 260 * Send an MPDU with the given TX parameters (with the specified protection). 261 * Note that <i>txParams</i> is moved to m_txParams and hence is left in an 262 * undefined state. 263 * 264 * \param mpdu the MPDU to send 265 * \param txParams the TX parameters to use to transmit the MPDU 266 */ 267 void SendMpduWithProtection (Ptr<WifiMacQueueItem> mpdu, WifiTxParameters& txParams); 268 269 /** 270 * Update the NAV, if needed, based on the Duration/ID of the given <i>psdu</i>. 271 * 272 * \param psdu the received PSDU 273 * \param txVector TxVector of the received PSDU 274 */ 275 virtual void UpdateNav (Ptr<const WifiPsdu> psdu, const WifiTxVector& txVector); 276 277 /** 278 * Reset the NAV upon expiration of the NAV reset timer. 279 */ 280 virtual void NavResetTimeout (void); 281 282 /** 283 * This method handles the reception of an MPDU (possibly included in an A-MPDU) 284 * 285 * \param mpdu the received MPDU 286 * \param rxSignalInfo the info on the received signal (\see RxSignalInfo) 287 * \param txVector TxVector of the received PSDU 288 * \param inAmpdu true if the MPDU is part of an A-MPDU 289 */ 290 virtual void ReceiveMpdu (Ptr<WifiMacQueueItem> mpdu, RxSignalInfo rxSignalInfo, 291 const WifiTxVector& txVector, bool inAmpdu); 292 293 /** 294 * This method is called when the reception of an A-MPDU including multiple 295 * MPDUs is completed. 296 * 297 * \param psdu the received PSDU 298 * \param rxSignalInfo the info on the received signal (\see RxSignalInfo) 299 * \param txVector TxVector of the received PSDU 300 * \param perMpduStatus per MPDU reception status 301 */ 302 virtual void EndReceiveAmpdu (Ptr<const WifiPsdu> psdu, const RxSignalInfo& rxSignalInfo, 303 const WifiTxVector& txVector, const std::vector<bool>& perMpduStatus); 304 305 /** 306 * Perform the actions needed when a Normal Ack is received. 307 * 308 * \param mpdu the MPDU that was acknowledged 309 * \param txVector the TXVECTOR used to transmit the MPDU that was acknowledged 310 * \param ackTxVector the TXVECTOR used to transmit the Normal Ack frame 311 * \param rxInfo the info on the received signal (\see RxSignalInfo) 312 * \param snr the SNR at the receiver for the MPDU that was acknowledged 313 */ 314 virtual void ReceivedNormalAck (Ptr<WifiMacQueueItem> mpdu, const WifiTxVector& txVector, 315 const WifiTxVector& ackTxVector, const RxSignalInfo& rxInfo, double snr); 316 317 /** 318 * Notify other components that an MPDU was acknowledged. 319 * 320 * \param mpdu the MPDU that was acknowledged 321 */ 322 virtual void NotifyReceivedNormalAck (Ptr<WifiMacQueueItem> mpdu); 323 324 /** 325 * Retransmit an MPDU that was not acknowledged. 326 * 327 * \param mpdu the MPDU to retransmit 328 */ 329 virtual void RetransmitMpduAfterMissedAck (Ptr<WifiMacQueueItem> mpdu) const; 330 331 /** 332 * Retransmit an MPDU that was not sent because a CTS was not received. 333 * 334 * \param mpdu the MPDU to retransmit 335 */ 336 virtual void RetransmitMpduAfterMissedCts (Ptr<WifiMacQueueItem> mpdu) const; 337 338 /** 339 * Pass the given MPDU, discarded because of the max retry limit was reached, 340 * to the MPDU dropped callback. 341 * 342 * \param mpdu the discarded MPDU 343 */ 344 virtual void NotifyPacketDiscarded (Ptr<const WifiMacQueueItem> mpdu); 345 346 /** 347 * Perform actions that are possibly needed when receiving any frame, 348 * independently of whether the frame is addressed to this station 349 * (e.g., setting the NAV or the TXOP holder). 350 * 351 * \param psdu the received PSDU 352 * \param txVector TX vector of the received PSDU 353 */ 354 virtual void PreProcessFrame (Ptr<const WifiPsdu> psdu, const WifiTxVector& txVector); 355 356 /** 357 * Get the updated TX duration of the frame associated with the given TX 358 * parameters if the size of the PSDU addressed to the given receiver 359 * becomes <i>ppduPayloadSize</i>. 360 * 361 * \param ppduPayloadSize the new PSDU size 362 * \param receiver the MAC address of the receiver of the PSDU 363 * \param txParams the TX parameters 364 * \return the updated TX duration 365 */ 366 virtual Time GetTxDuration (uint32_t ppduPayloadSize, Mac48Address receiver, 367 const WifiTxParameters& txParams) const; 368 369 /** 370 * Update the TX duration field of the given TX parameters after that the PSDU 371 * addressed to the given receiver has changed. 372 * 373 * \param receiver the MAC address of the receiver of the PSDU 374 * \param txParams the TX parameters 375 */ 376 void UpdateTxDuration (Mac48Address receiver, WifiTxParameters& txParams) const; 377 378 Ptr<Txop> m_dcf; //!< the DCF/EDCAF that gained channel access 379 WifiTxTimer m_txTimer; //!< the timer set upon frame transmission 380 EventId m_navResetEvent; //!< the event to reset the NAV after an RTS 381 Ptr<RegularWifiMac> m_mac; //!< the MAC layer on this station 382 Ptr<MacTxMiddle> m_txMiddle; //!< the MAC TX Middle on this station 383 Ptr<MacRxMiddle> m_rxMiddle; //!< the MAC RX Middle on this station 384 Ptr<ChannelAccessManager> m_channelAccessManager; //!< the channel access manager 385 Ptr<WifiPhy> m_phy; //!< the PHY layer on this station 386 Mac48Address m_self; //!< the MAC address of this device 387 Mac48Address m_bssid; //!< BSSID address (Mac48Address) 388 Time m_navEnd; //!< NAV expiration time 389 bool m_promisc; //!< Flag if the device is operating in promiscuous mode 390 DroppedMpdu m_droppedMpduCallback; //!< the dropped MPDU callback 391 AckedMpdu m_ackedMpduCallback; //!< the acknowledged MPDU callback 392 393 /** 394 * Forward an MPDU down to the PHY layer. 395 * 396 * \param mpdu the MPDU to forward down 397 * \param txVector the TXVECTOR used to transmit the MPDU 398 */ 399 virtual void ForwardMpduDown (Ptr<WifiMacQueueItem> mpdu, WifiTxVector& txVector); 400 401 /** 402 * Dequeue the given MPDU from the queue in which it is stored. 403 * 404 * \param mpdu the given MPDU 405 */ 406 virtual void DequeueMpdu (Ptr<const WifiMacQueueItem> mpdu); 407 408 /** 409 * Compute how to set the Duration/ID field of a frame being transmitted with 410 * the given TX parameters 411 * 412 * \param header the MAC header of the frame 413 * \param size the size of the frame in bytes 414 * \param txParams the TX parameters used to send the frame 415 * \param fragmentedPacket the packet that originated the frame to transmit, in case 416 * the latter is a fragment 417 * \return the computed Duration/ID value 418 */ 419 virtual Time GetFrameDurationId (const WifiMacHeader& header, uint32_t size, 420 const WifiTxParameters& txParams, 421 Ptr<Packet> fragmentedPacket) const; 422 423 /** 424 * Compute how to set the Duration/ID field of an RTS frame to send to protect 425 * a frame transmitted with the given TX vector. 426 * 427 * \param rtsTxVector the TX vector used to send the RTS frame 428 * \param txDuration the TX duration of the data frame 429 * \param response the time taken by the response (acknowledgment) to the data frame 430 * \return the computed Duration/ID value for the RTS frame 431 */ 432 virtual Time GetRtsDurationId (const WifiTxVector& rtsTxVector, Time txDuration, Time response) const; 433 434 /** 435 * Send RTS to begin RTS-CTS-Data-Ack transaction. 436 * 437 * \param txParams the TX parameters for the data frame 438 */ 439 void SendRts (const WifiTxParameters& txParams); 440 441 /** 442 * Send CTS after receiving RTS. 443 * 444 * \param rtsHdr the header of the received RTS 445 * \param rtsTxMode the TX mode used to transmit the RTS 446 * \param rtsSnr the SNR of the RTS in linear scale 447 */ 448 void SendCtsAfterRts (const WifiMacHeader& rtsHdr, WifiMode rtsTxMode, double rtsSnr); 449 450 /** 451 * Send CTS after receiving RTS. 452 * 453 * \param rtsHdr the header of the received RTS 454 * \param ctsTxVector the TXVECTOR to use to transmit the CTS 455 * \param rtsSnr the SNR of the RTS in linear scale 456 */ 457 void DoSendCtsAfterRts (const WifiMacHeader& rtsHdr, WifiTxVector& ctsTxVector, double rtsSnr); 458 459 /** 460 * Compute how to set the Duration/ID field of a CTS-to-self frame to send to 461 * protect a frame transmitted with the given TX vector. 462 * 463 * \param ctsTxVector the TX vector used to send the CTS-to-self frame 464 * \param txDuration the TX duration of the data frame 465 * \param response the time taken by the response (acknowledgment) to the data frame 466 * \return the computed Duration/ID value for the CTS-to-self frame 467 */ 468 virtual Time GetCtsToSelfDurationId (const WifiTxVector& ctsTxVector, Time txDuration, 469 Time response) const; 470 471 /** 472 * Send CTS for a CTS-to-self mechanism. 473 * 474 * \param txParams the TX parameters for the data frame 475 */ 476 void SendCtsToSelf (const WifiTxParameters& txParams); 477 478 /** 479 * Send Normal Ack. 480 * 481 * \param hdr the header of the frame soliciting the Normal Ack 482 * \param dataTxVector the TXVECTOR used to transmit the frame soliciting the Normal Ack 483 * \param dataSnr the SNR of the frame soliciting the Normal Ack in linear scale 484 */ 485 void SendNormalAck (const WifiMacHeader& hdr, const WifiTxVector& dataTxVector, double dataSnr); 486 487 /** 488 * Get the next fragment of the current MSDU. 489 * Only called for fragmented MSDUs. 490 * 491 * \return the next fragment of the current MSDU. 492 */ 493 Ptr<WifiMacQueueItem> GetNextFragment (void); 494 495 /** 496 * Take necessary actions upon a transmission success. A non-QoS station 497 * transmits the next fragment, if any, or releases the channel, otherwise. 498 */ 499 virtual void TransmissionSucceeded (void); 500 501 /** 502 * Take necessary actions upon a transmission failure. A non-QoS station 503 * releases the channel when this method is called. 504 */ 505 virtual void TransmissionFailed (void); 506 507 /** 508 * Called when the Ack timeout expires. 509 * 510 * \param mpdu the MPDU that solicited a Normal Ack response 511 * \param txVector the TXVECTOR used to transmit the frame soliciting the Normal Ack 512 */ 513 void NormalAckTimeout (Ptr<WifiMacQueueItem> mpdu, const WifiTxVector& txVector); 514 515 /** 516 * Called when the CTS timeout expires. 517 * 518 * \param rts the RTS that solicited a CTS response 519 * \param txVector the TXVECTOR used to transmit the RTS frame 520 */ 521 virtual void CtsTimeout (Ptr<WifiMacQueueItem> rts, const WifiTxVector& txVector); 522 523 private: 524 /** 525 * \param txVector the TXVECTOR decoded from PHY header. 526 * \param psduDuration the duration of the PSDU that is about to be received. 527 * 528 * This method is typically invoked by the lower PHY layer to notify 529 * the MAC layer that the reception of a PSDU is starting. 530 * This is equivalent to the PHY-RXSTART primitive. 531 * If the reception is correct for at least one MPDU of the PSDU 532 * the Receive method will be called after \p psduDuration. 533 */ 534 void RxStartIndication (WifiTxVector txVector, Time psduDuration); 535 536 /** 537 * Send the current MPDU, which can be acknowledged by a Normal Ack. 538 */ 539 void SendMpdu (void); 540 541 /** 542 * Reset this frame exchange manager. 543 */ 544 virtual void Reset (void); 545 546 Ptr<WifiMacQueueItem> m_mpdu; //!< the MPDU being transmitted 547 WifiTxParameters m_txParams; //!< the TX parameters for the current frame 548 Ptr<Packet> m_fragmentedPacket; //!< the MSDU being fragmented 549 bool m_moreFragments; //!< true if a fragment has to be sent after a SIFS 550 Ptr<WifiProtectionManager> m_protectionManager; //!< Protection manager 551 Ptr<WifiAckManager> m_ackManager; //!< Acknowledgment manager 552 }; 553 554 } //namespace ns3 555 556 #endif /* FRAME_EXCHANGE_MANAGER_H */ 557