wifi: Correctly compute the time to RX end to be passed to WifiPhyStateHelper::SwitchToRx()
This commit is contained in:
@@ -677,48 +677,64 @@ HePhy::IsConfigSupported (Ptr<const WifiPpdu> ppdu) const
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
Time
|
||||
HePhy::DoStartReceivePayload (Ptr<Event> event)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << *event);
|
||||
const WifiTxVector& txVector = event->GetTxVector ();
|
||||
Ptr<const WifiPpdu> ppdu = event->GetPpdu ();
|
||||
if (txVector.IsUlMu ())
|
||||
if (!txVector.IsUlMu ())
|
||||
{
|
||||
NS_ASSERT (txVector.GetModulationClass () == WIFI_MOD_CLASS_HE);
|
||||
bool isAp = (DynamicCast<ApWifiMac> (m_wifiPhy->GetDevice ()->GetMac ()) != 0);
|
||||
if (!isAp)
|
||||
return PhyEntity::DoStartReceivePayload (event);
|
||||
}
|
||||
|
||||
NS_ASSERT (txVector.GetModulationClass () == WIFI_MOD_CLASS_HE);
|
||||
// TX duration is determined by the Length field of TXVECTOR
|
||||
Time payloadDuration = ConvertLSigLengthToHeTbPpduDuration (txVector.GetLength (),
|
||||
txVector,
|
||||
m_wifiPhy->GetPhyBand ())
|
||||
- CalculatePhyPreambleAndHeaderDuration (txVector);
|
||||
// This method is called when we start receiving the first OFDMA payload. To
|
||||
// compute the time to the reception end of the last TB PPDU, we need to add the
|
||||
// offset of the last TB PPDU to the payload duration (same for all TB PPDUs)
|
||||
Time maxOffset {0};
|
||||
for (const auto& beginOfdmaPayloadRxEvent : m_beginOfdmaPayloadRxEvents)
|
||||
{
|
||||
maxOffset = Max (maxOffset, Simulator::GetDelayLeft (beginOfdmaPayloadRxEvent.second));
|
||||
}
|
||||
Time timeToEndRx = payloadDuration + maxOffset;
|
||||
|
||||
bool isAp = (DynamicCast<ApWifiMac> (m_wifiPhy->GetDevice ()->GetMac ()) != 0);
|
||||
if (!isAp)
|
||||
{
|
||||
NS_LOG_DEBUG ("Ignore HE TB PPDU payload received by STA but keep state in Rx");
|
||||
NotifyPayloadBegin (txVector, timeToEndRx);
|
||||
m_endRxPayloadEvents.push_back (Simulator::Schedule (timeToEndRx,
|
||||
&PhyEntity::ResetReceive, this, event));
|
||||
//Cancel all scheduled events for OFDMA payload reception
|
||||
NS_ASSERT (!m_beginOfdmaPayloadRxEvents.empty () && m_beginOfdmaPayloadRxEvents.begin ()->second.IsRunning ());
|
||||
for (auto & beginOfdmaPayloadRxEvent : m_beginOfdmaPayloadRxEvents)
|
||||
{
|
||||
NS_LOG_DEBUG ("Ignore HE TB PPDU payload received by STA but keep state in Rx");
|
||||
m_endRxPayloadEvents.push_back (Simulator::Schedule (ppdu->GetTxDuration () - CalculatePhyPreambleAndHeaderDuration (txVector),
|
||||
&PhyEntity::ResetReceive, this, event));
|
||||
//Cancel all scheduled events for OFDMA payload reception
|
||||
NS_ASSERT (!m_beginOfdmaPayloadRxEvents.empty () && m_beginOfdmaPayloadRxEvents.begin ()->second.IsRunning ());
|
||||
for (auto & beginOfdmaPayloadRxEvent : m_beginOfdmaPayloadRxEvents)
|
||||
{
|
||||
beginOfdmaPayloadRxEvent.second.Cancel ();
|
||||
}
|
||||
m_beginOfdmaPayloadRxEvents.clear ();
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_LOG_DEBUG ("Receiving PSDU in HE TB PPDU");
|
||||
uint16_t staId = GetStaId (ppdu);
|
||||
m_signalNoiseMap.insert ({std::make_pair (ppdu->GetUid (), staId), SignalNoiseDbm ()});
|
||||
m_statusPerMpduMap.insert ({std::make_pair (ppdu->GetUid (), staId), std::vector<bool> ()});
|
||||
//for HE TB PPDUs, ScheduleEndOfMpdus and EndReceive are scheduled by StartReceiveOfdmaPayload
|
||||
NS_ASSERT (isAp);
|
||||
NS_ASSERT (!m_beginOfdmaPayloadRxEvents.empty ());
|
||||
for (auto & beginOfdmaPayloadRxEvent : m_beginOfdmaPayloadRxEvents)
|
||||
{
|
||||
NS_ASSERT (beginOfdmaPayloadRxEvent.second.IsRunning ());
|
||||
}
|
||||
beginOfdmaPayloadRxEvent.second.Cancel ();
|
||||
}
|
||||
m_beginOfdmaPayloadRxEvents.clear ();
|
||||
}
|
||||
else
|
||||
{
|
||||
PhyEntity::DoStartReceivePayload (event);
|
||||
NS_LOG_DEBUG ("Receiving PSDU in HE TB PPDU");
|
||||
uint16_t staId = GetStaId (ppdu);
|
||||
m_signalNoiseMap.insert ({std::make_pair (ppdu->GetUid (), staId), SignalNoiseDbm ()});
|
||||
m_statusPerMpduMap.insert ({std::make_pair (ppdu->GetUid (), staId), std::vector<bool> ()});
|
||||
//for HE TB PPDUs, ScheduleEndOfMpdus and EndReceive are scheduled by StartReceiveOfdmaPayload
|
||||
NS_ASSERT (isAp);
|
||||
NS_ASSERT (!m_beginOfdmaPayloadRxEvents.empty ());
|
||||
for (auto & beginOfdmaPayloadRxEvent : m_beginOfdmaPayloadRxEvents)
|
||||
{
|
||||
NS_ASSERT (beginOfdmaPayloadRxEvent.second.IsRunning ());
|
||||
}
|
||||
}
|
||||
|
||||
return timeToEndRx;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -386,7 +386,7 @@ protected:
|
||||
PhyFieldRxStatus ProcessSigB (Ptr<Event> event, PhyFieldRxStatus status) override;
|
||||
Ptr<Event> DoGetEvent (Ptr<const WifiPpdu> ppdu, RxPowerWattPerChannelBand& rxPowersW) override;
|
||||
bool IsConfigSupported (Ptr<const WifiPpdu> ppdu) const override;
|
||||
void DoStartReceivePayload (Ptr<Event> event) override;
|
||||
Time DoStartReceivePayload (Ptr<Event> event) override;
|
||||
std::pair<uint16_t, WifiSpectrumBand> GetChannelWidthAndBand (const WifiTxVector& txVector, uint16_t staId) const override;
|
||||
void RxPayloadSucceeded (Ptr<const WifiPsdu> psdu, RxSignalInfo rxSignalInfo,
|
||||
const WifiTxVector& txVector, uint16_t staId,
|
||||
|
||||
@@ -529,17 +529,12 @@ PhyEntity::StartReceivePayload (Ptr<Event> event)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << *event);
|
||||
NS_ASSERT (m_wifiPhy->m_endPhyRxEvent.IsExpired ());
|
||||
const WifiTxVector& txVector = event->GetTxVector ();
|
||||
Time payloadDuration = event->GetPpdu ()->GetTxDuration () - CalculatePhyPreambleAndHeaderDuration (txVector);
|
||||
|
||||
//TODO: Add method in WifiPhy to clear all other PHYs (since this one is starting Rx)
|
||||
Time payloadDuration = DoStartReceivePayload (event);
|
||||
m_state->SwitchToRx (payloadDuration);
|
||||
m_wifiPhy->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
|
||||
|
||||
DoStartReceivePayload (event);
|
||||
}
|
||||
|
||||
void
|
||||
Time
|
||||
PhyEntity::DoStartReceivePayload (Ptr<Event> event)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << *event);
|
||||
@@ -549,8 +544,12 @@ PhyEntity::DoStartReceivePayload (Ptr<Event> event)
|
||||
m_signalNoiseMap.insert ({std::make_pair (ppdu->GetUid (), staId), SignalNoiseDbm ()});
|
||||
m_statusPerMpduMap.insert ({std::make_pair (ppdu->GetUid (), staId), std::vector<bool> ()});
|
||||
ScheduleEndOfMpdus (event);
|
||||
m_endRxPayloadEvents.push_back (Simulator::Schedule (ppdu->GetTxDuration () - CalculatePhyPreambleAndHeaderDuration (event->GetTxVector ()),
|
||||
const WifiTxVector& txVector = event->GetTxVector ();
|
||||
Time payloadDuration = ppdu->GetTxDuration () - CalculatePhyPreambleAndHeaderDuration (txVector);
|
||||
m_wifiPhy->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
|
||||
m_endRxPayloadEvents.push_back (Simulator::Schedule (payloadDuration,
|
||||
&PhyEntity::EndReceivePayload, this, event));
|
||||
return payloadDuration;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -560,8 +560,9 @@ protected:
|
||||
* and perform amendment-specific actions.
|
||||
*
|
||||
* \param event the event holding incoming PPDU's information
|
||||
* \return the payload duration
|
||||
*/
|
||||
virtual void DoStartReceivePayload (Ptr<Event> event);
|
||||
virtual Time DoStartReceivePayload (Ptr<Event> event);
|
||||
|
||||
/**
|
||||
* Perform amendment-specific actions before resetting PHY at
|
||||
|
||||
@@ -502,8 +502,7 @@ void
|
||||
WifiPhyStateHelper::SwitchFromRxEndOk (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
NS_ASSERT (Abs (m_endRx - Simulator::Now ()) < MicroSeconds (1)); //1us corresponds to the maximum propagation delay (delay spread)
|
||||
//TODO: a better fix would be to call the function once all HE TB PPDUs are received
|
||||
NS_ASSERT (m_endRx == Simulator::Now ());
|
||||
NotifyRxEndOk ();
|
||||
DoSwitchFromRx ();
|
||||
}
|
||||
@@ -512,8 +511,7 @@ void
|
||||
WifiPhyStateHelper::SwitchFromRxEndError (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
NS_ASSERT (Abs (m_endRx - Simulator::Now ()) < MicroSeconds (1)); //1us corresponds to the maximum propagation delay (delay spread)
|
||||
//TODO: a better fix would be to call the function once all HE TB PPDUs are received
|
||||
NS_ASSERT (m_endRx == Simulator::Now ());
|
||||
NotifyRxEndError ();
|
||||
DoSwitchFromRx ();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user