diff --git a/src/wifi/model/wifi-phy-state-helper.cc b/src/wifi/model/wifi-phy-state-helper.cc index c08903fbd..3bab853af 100644 --- a/src/wifi/model/wifi-phy-state-helper.cc +++ b/src/wifi/model/wifi-phy-state-helper.cc @@ -354,11 +354,13 @@ WifiPhyStateHelper::LogPreviousIdleAndCcaBusyStates (void) } void -WifiPhyStateHelper::SwitchToTx (Time txDuration, Ptr packet, double txPowerDbm, - WifiTxVector txVector) +WifiPhyStateHelper::SwitchToTx (Time txDuration, WifiConstPsduMap psdus, double txPowerDbm, WifiTxVector txVector) { - NS_LOG_FUNCTION (this << txDuration << packet << txPowerDbm << txVector); - m_txTrace (packet, txVector.GetMode (), txVector.GetPreambleType (), txVector.GetTxPowerLevel ()); + NS_LOG_FUNCTION (this << txDuration << psdus << txPowerDbm << txVector); + for (auto const& psdu : psdus) + { + m_txTrace (psdu.second->GetPacket (), txVector.GetMode (), txVector.GetPreambleType (), txVector.GetTxPowerLevel ()); + } Time now = Simulator::Now (); switch (GetState ()) { diff --git a/src/wifi/model/wifi-phy-state-helper.h b/src/wifi/model/wifi-phy-state-helper.h index 9474caff6..142d0cf95 100644 --- a/src/wifi/model/wifi-phy-state-helper.h +++ b/src/wifi/model/wifi-phy-state-helper.h @@ -27,6 +27,7 @@ #include "ns3/nstime.h" #include "wifi-phy-state.h" #include "wifi-preamble.h" +#include "wifi-ppdu.h" namespace ns3 { @@ -164,12 +165,12 @@ public: /** * Switch state to TX for the given duration. * - * \param txDuration the duration of the TX - * \param packet the packet + * \param txDuration the duration of the PPDU to transmit + * \param psdus the PSDUs in the transmitted PPDU (only one unless it is a MU PPDU) * \param txPowerDbm the nominal TX power in dBm - * \param txVector the TX vector of the packet + * \param txVector the TX vector for the transmission */ - void SwitchToTx (Time txDuration, Ptr packet, double txPowerDbm, WifiTxVector txVector); + void SwitchToTx (Time txDuration, WifiConstPsduMap psdus, double txPowerDbm, WifiTxVector txVector); /** * Switch state to RX for the given duration. * diff --git a/src/wifi/model/wifi-phy.cc b/src/wifi/model/wifi-phy.cc index e5d7f2e5a..516d406c3 100644 --- a/src/wifi/model/wifi-phy.cc +++ b/src/wifi/model/wifi-phy.cc @@ -2570,20 +2570,26 @@ WifiPhy::CalculateTxDuration (WifiConstPsduMap psduMap, WifiTxVector txVector, W } void -WifiPhy::NotifyTxBegin (Ptr psdu, double txPowerW) +WifiPhy::NotifyTxBegin (WifiConstPsduMap psdus, double txPowerW) { - for (auto& mpdu : *PeekPointer (psdu)) + for (auto const& psdu : psdus) { - m_phyTxBeginTrace (mpdu->GetProtocolDataUnit (), txPowerW); + for (auto& mpdu : *PeekPointer (psdu.second)) + { + m_phyTxBeginTrace (mpdu->GetProtocolDataUnit (), txPowerW); + } } } void -WifiPhy::NotifyTxEnd (Ptr psdu) +WifiPhy::NotifyTxEnd (WifiConstPsduMap psdus) { - for (auto& mpdu : *PeekPointer (psdu)) + for (auto const& psdu : psdus) { - m_phyTxEndTrace (mpdu->GetProtocolDataUnit ()); + for (auto& mpdu : *PeekPointer (psdu.second)) + { + m_phyTxEndTrace (mpdu->GetProtocolDataUnit ()); + } } } @@ -2599,27 +2605,36 @@ WifiPhy::NotifyTxDrop (Ptr psdu) void WifiPhy::NotifyRxBegin (Ptr psdu) { - for (auto& mpdu : *PeekPointer (psdu)) + if (psdu) { - m_phyRxBeginTrace (mpdu->GetProtocolDataUnit ()); + for (auto& mpdu : *PeekPointer (psdu)) + { + m_phyRxBeginTrace (mpdu->GetProtocolDataUnit ()); + } } } void WifiPhy::NotifyRxEnd (Ptr psdu) { - for (auto& mpdu : *PeekPointer (psdu)) + if (psdu) { - m_phyRxEndTrace (mpdu->GetProtocolDataUnit ()); + for (auto& mpdu : *PeekPointer (psdu)) + { + m_phyRxEndTrace (mpdu->GetProtocolDataUnit ()); + } } } void WifiPhy::NotifyRxDrop (Ptr psdu, WifiPhyRxfailureReason reason) { - for (auto& mpdu : *PeekPointer (psdu)) + if (psdu) { - m_phyRxDropTrace (mpdu->GetProtocolDataUnit (), reason); + for (auto& mpdu : *PeekPointer (psdu)) + { + m_phyRxDropTrace (mpdu->GetProtocolDataUnit (), reason); + } } } @@ -2635,7 +2650,7 @@ WifiPhy::NotifyMonitorSniffRx (Ptr psdu, uint16_t channelFreqMhz aMpdu.mpduRefNumber = ++m_rxMpduReferenceNumber; size_t nMpdus = psdu->GetNMpdus (); NS_ASSERT_MSG (statusPerMpdu.size () == nMpdus, "Should have one reception status per MPDU"); - aMpdu.type = (psdu->IsSingle ()) ? SINGLE_MPDU: FIRST_MPDU_IN_AGGREGATE; + aMpdu.type = (psdu->IsSingle ()) ? SINGLE_MPDU : FIRST_MPDU_IN_AGGREGATE; for (size_t i = 0; i < nMpdus;) { if (statusPerMpdu.at (i)) //packet received without error, hand over to sniffer @@ -2689,6 +2704,15 @@ void WifiPhy::Send (Ptr psdu, WifiTxVector txVector) { NS_LOG_FUNCTION (this << *psdu << txVector); + WifiConstPsduMap psdus; + psdus.insert (std::make_pair (SU_STA_ID, psdu)); + Send (psdus, txVector); +} + +void +WifiPhy::Send (WifiConstPsduMap psdus, WifiTxVector txVector) +{ + NS_LOG_FUNCTION (this << psdus << txVector); /* Transmission can happen if: * - we are syncing on a packet. It is the responsibility of the * MAC layer to avoid doing this but the PHY does nothing to @@ -2706,11 +2730,14 @@ WifiPhy::Send (Ptr psdu, WifiTxVector txVector) if (m_state->IsStateSleep ()) { NS_LOG_DEBUG ("Dropping packet because in sleep mode"); - NotifyTxDrop (psdu); + for (auto const& psdu : psdus) + { + NotifyTxDrop (psdu.second); + } return; } - Time txDuration = CalculateTxDuration (psdu->GetSize (), txVector, GetPhyBand ()); + Time txDuration = CalculateTxDuration (psdus.at (SU_STA_ID)->GetSize (), txVector, GetPhyBand ()); //TODO: extend CalculateTxDuration for MU NS_ASSERT (txDuration.IsStrictlyPositive ()); if ((m_currentEvent != 0) && (m_currentEvent->GetEndTime () > (Simulator::Now () + m_state->GetDelayUntilIdle ()))) @@ -2740,19 +2767,19 @@ WifiPhy::Send (Ptr psdu, WifiTxVector txVector) } double txPowerW = DbmToW (GetTxPowerForTransmission (txVector) + GetTxGain ()); - NotifyTxBegin (psdu, txPowerW); - m_phyTxPsduBeginTrace (psdu, txVector, txPowerW); - NotifyMonitorSniffTx (psdu, GetFrequency (), txVector); - m_state->SwitchToTx (txDuration, psdu->GetPacket (), GetPowerDbm (txVector.GetTxPowerLevel ()), txVector); + NotifyTxBegin (psdus, txPowerW); + m_phyTxPsduBeginTrace (psdus.at (SU_STA_ID), txVector, txPowerW); // TODO: fix for MU + NotifyMonitorSniffTx (psdus.at (SU_STA_ID), GetFrequency (), txVector); //TODO: fix for MU + m_state->SwitchToTx (txDuration, psdus, GetPowerDbm (txVector.GetTxPowerLevel ()), txVector); - Ptr ppdu = Create (psdu, txVector, txDuration, GetPhyBand ()); + Ptr ppdu = Create (psdus, txVector, txDuration, GetPhyBand ()); if (m_wifiRadioEnergyModel != 0 && m_wifiRadioEnergyModel->GetMaximumTimeInState (WifiPhyState::TX) < txDuration) { ppdu->SetTruncatedTx (); } - m_endTxEvent = Simulator::Schedule (txDuration, &WifiPhy::NotifyTxEnd, this, psdu); + m_endTxEvent = Simulator::Schedule (txDuration, &WifiPhy::NotifyTxEnd, this, psdus); //TODO: fix for MU StartTx (ppdu); @@ -3054,9 +3081,20 @@ WifiPhy::StartReceivePayload (Ptr event) ScheduleEndOfMpdus (event); } m_state->SwitchToRx (payloadDuration); - m_endRxEvent = Simulator::Schedule (payloadDuration, &WifiPhy::EndReceive, this, event); - NS_LOG_DEBUG ("Receiving PSDU"); m_phyRxPayloadBeginTrace (txVector, payloadDuration); //this callback (equivalent to PHY-RXSTART primitive) is triggered only if headers have been correctly decoded and that the mode within is supported + Ptr ppdu = event->GetPpdu (); + Ptr psdu = GetAddressedPsduInPpdu (ppdu); + if (psdu) + { + m_endRxEvent = Simulator::Schedule (payloadDuration, &WifiPhy::EndReceive, this, event); + NS_LOG_DEBUG ("Receiving PSDU"); + } + else + { + NS_ASSERT (ppdu->IsMu ()); + m_endRxEvent = Simulator::Schedule (payloadDuration, &WifiPhy::ResetReceive, this, event); + NS_LOG_DEBUG ("Receiving MU PPDU without any PSDU for this STA"); + } if (txMode.GetModulationClass () == WIFI_MOD_CLASS_HE) { HePreambleParameters params; @@ -4589,7 +4627,7 @@ WifiPhy::GetAddressedPsduInPpdu (Ptr ppdu) const bssColor = bssColorAttribute.Get (); } } - uint16_t staId = SU_STA_ID; + uint16_t staId = GetStaId (); psdu = ppdu->GetPsdu (bssColor, staId); } return psdu; diff --git a/src/wifi/model/wifi-phy.h b/src/wifi/model/wifi-phy.h index ecd7580cd..ee71c6b7d 100644 --- a/src/wifi/model/wifi-phy.h +++ b/src/wifi/model/wifi-phy.h @@ -244,6 +244,13 @@ public: * power is calculated as txPowerMin + txPowerLevel * (txPowerMax - txPowerMin) / nTxLevels */ void Send (Ptr psdu, WifiTxVector txVector); + /** + * \param psdus the PSDUs to send + * \param txVector the TXVECTOR that has tx parameters such as mode, the transmission mode to use to send + * this PSDU, and txPowerLevel, a power level to use to send the whole PPDU. The real transmission + * power is calculated as txPowerMin + txPowerLevel * (txPowerMax - txPowerMin) / nTxLevels + */ + void Send (WifiConstPsduMap psdus, WifiTxVector txVector); /** * \param ppdu the PPDU to send @@ -1288,17 +1295,17 @@ public: * Public method used to fire a PhyTxBegin trace. * Implemented for encapsulation purposes. * - * \param psdu the PSDU being transmitted + * \param psdus the PSDUs being transmitted (only one unless DL MU transmission) * \param txPowerW the transmit power in Watts */ - void NotifyTxBegin (Ptr psdu, double txPowerW); + void NotifyTxBegin (WifiConstPsduMap psdus, double txPowerW); /** * Public method used to fire a PhyTxEnd trace. * Implemented for encapsulation purposes. * - * \param psdu the PSDU being transmitted + * \param psdus the PSDUs being transmitted (only one unless DL MU transmission) */ - void NotifyTxEnd (Ptr psdu); + void NotifyTxEnd (WifiConstPsduMap psdus); /** * Public method used to fire a PhyTxDrop trace. * Implemented for encapsulation purposes. diff --git a/src/wifi/model/wifi-ppdu.cc b/src/wifi/model/wifi-ppdu.cc index 89c34b751..aaa56c39f 100644 --- a/src/wifi/model/wifi-ppdu.cc +++ b/src/wifi/model/wifi-ppdu.cc @@ -37,6 +37,7 @@ WifiPpdu::WifiPpdu (Ptr psdu, WifiTxVector txVector, Time ppduDu m_channelWidth (txVector.GetChannelWidth ()), m_txPowerLevel (txVector.GetTxPowerLevel ()) { + NS_LOG_FUNCTION (this << *psdu << txVector << ppduDuration << band); m_psdus.insert (std::make_pair (SU_STA_ID, psdu)); SetPhyHeaders (txVector, ppduDuration, band); } @@ -49,6 +50,7 @@ WifiPpdu::WifiPpdu (const WifiConstPsduMap & psdus, WifiTxVector txVector, Time m_band (band), m_channelWidth (txVector.GetChannelWidth ()) { + NS_LOG_FUNCTION (this << psdus << txVector << ppduDuration << band); SetPhyHeaders (txVector, ppduDuration, band); } @@ -473,10 +475,7 @@ WifiPpdu::Print (std::ostream& os) const os << "preamble=" << m_preamble << ", modulation=" << m_modulation << ", truncatedTx=" << (m_truncatedTx ? "Y" : "N"); - for (auto const& psdu : m_psdus) - { - os << ", PSDU=" << psdu.second; - } + IsMu () ? (os << ", " << m_psdus) : (os << ", PSDU=" << m_psdus.at (SU_STA_ID)); } std::ostream & operator << (std::ostream &os, const WifiPpdu &ppdu) @@ -485,4 +484,14 @@ std::ostream & operator << (std::ostream &os, const WifiPpdu &ppdu) return os; } +std::ostream & operator << (std::ostream &os, const WifiConstPsduMap &psdus) +{ + for (auto const& psdu : psdus) + { + os << "PSDU for STA_ID=" << psdu.first + << " (" << *psdu.second << ") "; + } + return os; +} + } //namespace ns3 diff --git a/src/wifi/model/wifi-ppdu.h b/src/wifi/model/wifi-ppdu.h index 22beedd97..a922e7989 100644 --- a/src/wifi/model/wifi-ppdu.h +++ b/src/wifi/model/wifi-ppdu.h @@ -148,6 +148,15 @@ private: */ std::ostream& operator<< (std::ostream& os, const WifiPpdu &ppdu); +/** + * \brief Stream insertion operator. + * + * \param os the stream + * \param psdus the PSDUs + * \returns a reference to the stream + */ +std::ostream & operator << (std::ostream &os, const WifiConstPsduMap &psdus); + } //namespace ns3 #endif /* WIFI_PPDU_H */