wifi: Extend WifiPhy::Send function to support MU transmissions

This commit is contained in:
Sébastien Deronne
2019-05-31 10:44:29 +02:00
parent e068d50032
commit b70c85a25d
6 changed files with 106 additions and 40 deletions

View File

@@ -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 ())
{

View File

@@ -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.
*

View File

@@ -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;

View File

@@ -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.

View File

@@ -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

View File

@@ -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 */