wifi: Extend WifiPhy::Send function to support MU transmissions
This commit is contained in:
@@ -354,11 +354,13 @@ WifiPhyStateHelper::LogPreviousIdleAndCcaBusyStates (void)
|
||||
}
|
||||
|
||||
void
|
||||
WifiPhyStateHelper::SwitchToTx (Time txDuration, Ptr<const Packet> 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 ())
|
||||
{
|
||||
|
||||
@@ -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<const Packet> packet, double txPowerDbm, WifiTxVector txVector);
|
||||
void SwitchToTx (Time txDuration, WifiConstPsduMap psdus, double txPowerDbm, WifiTxVector txVector);
|
||||
/**
|
||||
* Switch state to RX for the given duration.
|
||||
*
|
||||
|
||||
@@ -2570,20 +2570,26 @@ WifiPhy::CalculateTxDuration (WifiConstPsduMap psduMap, WifiTxVector txVector, W
|
||||
}
|
||||
|
||||
void
|
||||
WifiPhy::NotifyTxBegin (Ptr<const WifiPsdu> 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<const WifiPsdu> 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<const WifiPsdu> psdu)
|
||||
void
|
||||
WifiPhy::NotifyRxBegin (Ptr<const WifiPsdu> 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<const WifiPsdu> 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<const WifiPsdu> 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<const WifiPsdu> 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<const WifiPsdu> 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<const WifiPsdu> 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<const WifiPsdu> 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<WifiPpdu> ppdu = Create<WifiPpdu> (psdu, txVector, txDuration, GetPhyBand ());
|
||||
Ptr<WifiPpdu> ppdu = Create<WifiPpdu> (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> 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<const WifiPpdu> ppdu = event->GetPpdu ();
|
||||
Ptr<const WifiPsdu> 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<const WifiPpdu> ppdu) const
|
||||
bssColor = bssColorAttribute.Get ();
|
||||
}
|
||||
}
|
||||
uint16_t staId = SU_STA_ID;
|
||||
uint16_t staId = GetStaId ();
|
||||
psdu = ppdu->GetPsdu (bssColor, staId);
|
||||
}
|
||||
return psdu;
|
||||
|
||||
@@ -244,6 +244,13 @@ public:
|
||||
* power is calculated as txPowerMin + txPowerLevel * (txPowerMax - txPowerMin) / nTxLevels
|
||||
*/
|
||||
void Send (Ptr<const WifiPsdu> 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<const WifiPsdu> 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<const WifiPsdu> psdu);
|
||||
void NotifyTxEnd (WifiConstPsduMap psdus);
|
||||
/**
|
||||
* Public method used to fire a PhyTxDrop trace.
|
||||
* Implemented for encapsulation purposes.
|
||||
|
||||
@@ -37,6 +37,7 @@ WifiPpdu::WifiPpdu (Ptr<const WifiPsdu> 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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user