wifi: Handle reception of MU PPDUs
This commit is contained in:
@@ -232,11 +232,10 @@ InterferenceHelper::AppendEvent (Ptr<Event> event)
|
||||
}
|
||||
|
||||
double
|
||||
InterferenceHelper::CalculateSnr (double signal, double noiseInterference, WifiTxVector txVector) const
|
||||
InterferenceHelper::CalculateSnr (double signal, double noiseInterference, uint16_t channelWidth, uint8_t nss) const
|
||||
{
|
||||
//thermal noise at 290K in J/s = W
|
||||
static const double BOLTZMANN = 1.3803e-23;
|
||||
uint16_t channelWidth = txVector.GetChannelWidth ();
|
||||
//Nt is the power of thermal noise in W
|
||||
double Nt = BOLTZMANN * 290 * channelWidth * 1e6;
|
||||
//receiver noise Floor (W) which accounts for thermal noise and non-idealities of the receiver
|
||||
@@ -245,9 +244,9 @@ InterferenceHelper::CalculateSnr (double signal, double noiseInterference, WifiT
|
||||
double snr = signal / noise; //linear scale
|
||||
NS_LOG_DEBUG ("bandwidth(MHz)=" << channelWidth << ", signal(W)= " << signal << ", noise(W)=" << noiseFloor << ", interference(W)=" << noiseInterference << ", snr=" << RatioToDb(snr) << "dB");
|
||||
double gain = 1;
|
||||
if (m_numRxAntennas > txVector.GetNss ())
|
||||
if (m_numRxAntennas > nss)
|
||||
{
|
||||
gain = static_cast<double>(m_numRxAntennas) / txVector.GetNss (); //compute gain offered by diversity for AWGN
|
||||
gain = static_cast<double>(m_numRxAntennas) / nss; //compute gain offered by diversity for AWGN
|
||||
}
|
||||
NS_LOG_DEBUG ("SNR improvement thanks to diversity: " << 10 * std::log10 (gain) << "dB");
|
||||
snr *= gain;
|
||||
@@ -327,7 +326,7 @@ InterferenceHelper::CalculatePayloadPer (Ptr<const Event> event, uint16_t staId,
|
||||
Time current = j->first;
|
||||
NS_LOG_DEBUG ("previous= " << previous << ", current=" << current);
|
||||
NS_ASSERT (current >= previous);
|
||||
double snr = CalculateSnr (powerW, noiseInterferenceW, txVector);
|
||||
double snr = CalculateSnr (powerW, noiseInterferenceW, txVector.GetChannelWidth (), txVector.GetNss (staId));
|
||||
//Case 1: Both previous and current point to the windowed payload
|
||||
if (previous >= windowStart)
|
||||
{
|
||||
@@ -373,7 +372,7 @@ InterferenceHelper::CalculateNonHtPhyHeaderPer (Ptr<const Event> event, NiChange
|
||||
Time current = j->first;
|
||||
NS_LOG_DEBUG ("previous= " << previous << ", current=" << current);
|
||||
NS_ASSERT (current >= previous);
|
||||
double snr = CalculateSnr (powerW, noiseInterferenceW, txVector);
|
||||
double snr = CalculateSnr (powerW, noiseInterferenceW, txVector.GetChannelWidth (), 1);
|
||||
//Case 1: previous and current after payload start
|
||||
if (previous >= phyPayloadStart)
|
||||
{
|
||||
@@ -502,7 +501,7 @@ InterferenceHelper::CalculateHtPhyHeaderPer (Ptr<const Event> event, NiChanges *
|
||||
Time current = j->first;
|
||||
NS_LOG_DEBUG ("previous= " << previous << ", current=" << current);
|
||||
NS_ASSERT (current >= previous);
|
||||
double snr = CalculateSnr (powerW, noiseInterferenceW, txVector);
|
||||
double snr = CalculateSnr (powerW, noiseInterferenceW, txVector.GetChannelWidth (), 1);
|
||||
//Case 1: previous and current after payload start: nothing to do
|
||||
if (previous >= phyPayloadStart)
|
||||
{
|
||||
@@ -739,7 +738,8 @@ InterferenceHelper::CalculatePayloadSnrPer (Ptr<Event> event, uint16_t staId,
|
||||
double noiseInterferenceW = CalculateNoiseInterferenceW (event, &ni);
|
||||
double snr = CalculateSnr (event->GetRxPowerW (),
|
||||
noiseInterferenceW,
|
||||
event->GetTxVector ());
|
||||
event->GetTxVector ().GetChannelWidth (),
|
||||
event->GetTxVector ().GetNss (staId));
|
||||
|
||||
/* calculate the SNIR at the start of the MPDU (located through windowing) and accumulate
|
||||
* all SNIR changes in the SNIR vector.
|
||||
@@ -753,13 +753,14 @@ InterferenceHelper::CalculatePayloadSnrPer (Ptr<Event> event, uint16_t staId,
|
||||
}
|
||||
|
||||
double
|
||||
InterferenceHelper::CalculateSnr (Ptr<Event> event) const
|
||||
InterferenceHelper::CalculateSnr (Ptr<Event> event, uint8_t nss) const
|
||||
{
|
||||
NiChanges ni;
|
||||
double noiseInterferenceW = CalculateNoiseInterferenceW (event, &ni);
|
||||
double snr = CalculateSnr (event->GetRxPowerW (),
|
||||
noiseInterferenceW,
|
||||
event->GetTxVector ());
|
||||
event->GetTxVector ().GetChannelWidth (),
|
||||
nss);
|
||||
return snr;
|
||||
}
|
||||
|
||||
@@ -770,7 +771,8 @@ InterferenceHelper::CalculateNonHtPhyHeaderSnrPer (Ptr<Event> event) const
|
||||
double noiseInterferenceW = CalculateNoiseInterferenceW (event, &ni);
|
||||
double snr = CalculateSnr (event->GetRxPowerW (),
|
||||
noiseInterferenceW,
|
||||
event->GetTxVector ());
|
||||
event->GetTxVector ().GetChannelWidth (),
|
||||
1);
|
||||
|
||||
/* calculate the SNIR at the start of the PHY header and accumulate
|
||||
* all SNIR changes in the SNIR vector.
|
||||
@@ -790,7 +792,8 @@ InterferenceHelper::CalculateHtPhyHeaderSnrPer (Ptr<Event> event) const
|
||||
double noiseInterferenceW = CalculateNoiseInterferenceW (event, &ni);
|
||||
double snr = CalculateSnr (event->GetRxPowerW (),
|
||||
noiseInterferenceW,
|
||||
event->GetTxVector ());
|
||||
event->GetTxVector ().GetChannelWidth (),
|
||||
1);
|
||||
|
||||
/* calculate the SNIR at the start of the PHY header and accumulate
|
||||
* all SNIR changes in the SNIR vector.
|
||||
|
||||
@@ -201,10 +201,11 @@ public:
|
||||
* Calculate the SNIR for the event (starting from now until the event end).
|
||||
*
|
||||
* \param event the event corresponding to the first time the corresponding PPDU arrives
|
||||
* \param nss the number of spatial streams
|
||||
*
|
||||
* \return the SNR for the PPDU in linear scale
|
||||
*/
|
||||
double CalculateSnr (Ptr<Event> event) const;
|
||||
double CalculateSnr (Ptr<Event> event, uint8_t nss) const;
|
||||
/**
|
||||
* Calculate the SNIR at the start of the non-HT PHY header and accumulate
|
||||
* all SNIR changes in the SNIR vector.
|
||||
@@ -244,11 +245,12 @@ protected:
|
||||
*
|
||||
* \param signal signal power, W
|
||||
* \param noiseInterference noise and interference power, W
|
||||
* \param txVector the TXVECTOR
|
||||
* \param channelWidth signal width (MHz)
|
||||
* \param nss the number of spatial streams
|
||||
*
|
||||
* \return SNR in linear scale
|
||||
*/
|
||||
double CalculateSnr (double signal, double noiseInterference, WifiTxVector txVector) const;
|
||||
double CalculateSnr (double signal, double noiseInterference, uint16_t channelWidth, uint8_t nss) const;
|
||||
/**
|
||||
* Calculate the success rate of the chunk given the SINR, duration, and Wi-Fi mode.
|
||||
* The duration and mode are used to calculate how many bits are present in the chunk.
|
||||
|
||||
@@ -3027,10 +3027,10 @@ WifiPhy::StartReceivePayload (Ptr<Event> event)
|
||||
NS_LOG_FUNCTION (this << *event);
|
||||
NS_ASSERT (m_endPhyRxEvent.IsExpired ());
|
||||
NS_ASSERT (m_endRxEvent.IsExpired ());
|
||||
WifiTxVector txVector = event->GetTxVector ();
|
||||
WifiMode txMode = txVector.GetMode ();
|
||||
bool canReceivePayload;
|
||||
if (txMode.GetModulationClass () >= WIFI_MOD_CLASS_HT)
|
||||
bool canReceivePayload = false;
|
||||
Ptr<const WifiPpdu> ppdu = event->GetPpdu ();
|
||||
WifiModulationClass modulation = ppdu->GetModulation ();
|
||||
if (modulation >= WIFI_MOD_CLASS_HT)
|
||||
{
|
||||
InterferenceHelper::SnrPer snrPer;
|
||||
snrPer = m_interference.CalculateHtPhyHeaderSnrPer (event);
|
||||
@@ -3042,67 +3042,68 @@ WifiPhy::StartReceivePayload (Ptr<Event> event)
|
||||
//If we are here, this means non-HT PHY header was already successfully received
|
||||
canReceivePayload = true;
|
||||
}
|
||||
WifiTxVector txVector = event->GetTxVector ();
|
||||
Time payloadDuration = event->GetEndTime () - event->GetStartTime () - CalculatePhyPreambleAndHeaderDuration (txVector);
|
||||
bool success = false;
|
||||
if (canReceivePayload) //PHY reception succeeded
|
||||
{
|
||||
uint8_t nss = txVector.GetNssMax();
|
||||
if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_MU)
|
||||
Ptr<const WifiPsdu> psdu = GetAddressedPsduInPpdu (ppdu);
|
||||
if (psdu)
|
||||
{
|
||||
uint16_t myStaId = 0; //FIXME
|
||||
for (auto info : txVector.GetHeMuUserInfoMap ())
|
||||
WifiMode txMode = txVector.GetPreambleType () == WIFI_PREAMBLE_HE_MU ? txVector.GetMode (GetStaId ()) : txVector.GetMode ();
|
||||
uint8_t nss = txVector.GetNssMax();
|
||||
if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_MU)
|
||||
{
|
||||
if (info.first == myStaId)
|
||||
uint16_t staId = GetStaId ();
|
||||
for (const auto & info : txVector.GetHeMuUserInfoMap ())
|
||||
{
|
||||
nss = info.second.nss; //no need to look at other PSDUs
|
||||
break;
|
||||
if (info.first == staId)
|
||||
{
|
||||
nss = info.second.nss; //no need to look at other PSDUs
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nss > GetMaxSupportedRxSpatialStreams ())
|
||||
{
|
||||
NS_LOG_DEBUG ("Packet reception could not be started because not enough RX antennas");
|
||||
NotifyRxDrop (GetAddressedPsduInPpdu (event->GetPpdu ()), UNSUPPORTED_SETTINGS);
|
||||
}
|
||||
else if ((txVector.GetChannelWidth () >= 40) && (txVector.GetChannelWidth () > GetChannelWidth ()))
|
||||
{
|
||||
NS_LOG_DEBUG ("Packet reception could not be started because not enough channel width");
|
||||
NotifyRxDrop (GetAddressedPsduInPpdu (event->GetPpdu ()), UNSUPPORTED_SETTINGS);
|
||||
}
|
||||
else if (!IsModeSupported (txMode) && !IsMcsSupported (txMode))
|
||||
{
|
||||
NS_LOG_DEBUG ("Drop packet because it was sent using an unsupported mode (" << txMode << ")");
|
||||
NotifyRxDrop (GetAddressedPsduInPpdu (event->GetPpdu ()), UNSUPPORTED_SETTINGS);
|
||||
if (nss > GetMaxSupportedRxSpatialStreams ())
|
||||
{
|
||||
NS_LOG_DEBUG ("Packet reception could not be started because not enough RX antennas");
|
||||
NotifyRxDrop (psdu, UNSUPPORTED_SETTINGS);
|
||||
}
|
||||
else if ((txVector.GetChannelWidth () >= 40) && (txVector.GetChannelWidth () > GetChannelWidth ()))
|
||||
{
|
||||
NS_LOG_DEBUG ("Packet reception could not be started because not enough channel width");
|
||||
NotifyRxDrop (psdu, UNSUPPORTED_SETTINGS);
|
||||
}
|
||||
else if (IsModeSupported (txMode) || IsMcsSupported (txMode))
|
||||
{
|
||||
m_statusPerMpdu.clear();
|
||||
if (psdu->GetNMpdus () > 1)
|
||||
{
|
||||
ScheduleEndOfMpdus (event);
|
||||
}
|
||||
m_state->SwitchToRx (payloadDuration);
|
||||
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_endRxEvent = Simulator::Schedule (payloadDuration, &WifiPhy::EndReceive, this, event);
|
||||
success = true;
|
||||
NS_LOG_DEBUG ("Receiving PSDU");
|
||||
}
|
||||
else //mode is not allowed
|
||||
{
|
||||
NS_LOG_DEBUG ("Drop packet because it was sent using an unsupported mode (" << txMode << ")");
|
||||
NotifyRxDrop (psdu, UNSUPPORTED_SETTINGS);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_statusPerMpdu.clear();
|
||||
if (event->GetPpdu ()->GetPsdu ()->GetNMpdus () > 1)
|
||||
{
|
||||
ScheduleEndOfMpdus (event);
|
||||
}
|
||||
m_state->SwitchToRx (payloadDuration);
|
||||
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;
|
||||
params.rssiW = event->GetRxPowerW ();
|
||||
params.bssColor = event->GetTxVector ().GetBssColor ();
|
||||
NotifyEndOfHePreamble (params);
|
||||
}
|
||||
return;
|
||||
NS_ASSERT (ppdu->IsMu ());
|
||||
NS_LOG_DEBUG ("Receiving MU PPDU without any PSDU for this STA");
|
||||
}
|
||||
if (modulation == WIFI_MOD_CLASS_HE)
|
||||
{
|
||||
HePreambleParameters params;
|
||||
params.rssiW = event->GetRxPowerW ();
|
||||
params.bssColor = event->GetTxVector ().GetBssColor ();
|
||||
NotifyEndOfHePreamble (params);
|
||||
}
|
||||
}
|
||||
else //PHY reception failed
|
||||
@@ -3110,7 +3111,10 @@ WifiPhy::StartReceivePayload (Ptr<Event> event)
|
||||
NS_LOG_DEBUG ("Drop packet because HT PHY header reception failed");
|
||||
NotifyRxDrop (GetAddressedPsduInPpdu (event->GetPpdu ()), SIG_A_FAILURE);
|
||||
}
|
||||
m_endRxEvent = Simulator::Schedule (payloadDuration, &WifiPhy::ResetReceive, this, event);
|
||||
if (!success)
|
||||
{
|
||||
m_endRxEvent = Simulator::Schedule (payloadDuration, &WifiPhy::ResetReceive, this, event);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -3158,7 +3162,9 @@ WifiPhy::EndOfMpdu (Ptr<Event> event, Ptr<const WifiPsdu> psdu, size_t mpduIndex
|
||||
{
|
||||
NS_LOG_FUNCTION (this << *event << mpduIndex << relativeStart << mpduDuration);
|
||||
Ptr<const WifiPpdu> ppdu = event->GetPpdu ();
|
||||
uint16_t staId = SU_STA_ID;
|
||||
uint16_t staId = GetStaId ();
|
||||
WifiTxVector txVector = event->GetTxVector ();
|
||||
double snr = m_interference.CalculateSnr (event, txVector.GetNss (staId));
|
||||
|
||||
std::pair<bool, SignalNoiseDbm> rxInfo = GetReceptionStatus (psdu, event, staId, relativeStart, mpduDuration);
|
||||
NS_LOG_DEBUG ("Extracted MPDU #" << mpduIndex << ": duration: " << mpduDuration.GetNanoSeconds () << "ns" <<
|
||||
@@ -3169,7 +3175,7 @@ WifiPhy::EndOfMpdu (Ptr<Event> event, Ptr<const WifiPsdu> psdu, size_t mpduIndex
|
||||
|
||||
if (rxInfo.first)
|
||||
{
|
||||
m_state->ContinueRxNextMpdu (Copy (psdu), m_interference.CalculateSnr (event), event->GetTxVector ());
|
||||
m_state->ContinueRxNextMpdu (Copy (psdu), snr, event->GetTxVector ());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3181,18 +3187,19 @@ WifiPhy::EndReceive (Ptr<Event> event)
|
||||
NS_ASSERT (GetLastRxEndTime () == Simulator::Now ());
|
||||
NS_ASSERT (event->GetEndTime () == Simulator::Now ());
|
||||
|
||||
uint16_t staId = GetStaId ();
|
||||
Ptr<const WifiPsdu> psdu = GetAddressedPsduInPpdu (event->GetPpdu ());
|
||||
if (psdu->GetNMpdus () == 1)
|
||||
{
|
||||
//We do not enter here for A-MPDU since this is done in WifiPhy::EndOfMpdu
|
||||
uint16_t staId = SU_STA_ID;
|
||||
std::pair<bool, SignalNoiseDbm> rxInfo = GetReceptionStatus (psdu, event, staId, NanoSeconds (0), psduDuration);
|
||||
m_signalNoise = rxInfo.second;
|
||||
m_statusPerMpdu.push_back (rxInfo.first);
|
||||
}
|
||||
|
||||
NotifyRxEnd (psdu);
|
||||
double snr = m_interference.CalculateSnr (event);
|
||||
WifiTxVector txVector = event->GetTxVector ();
|
||||
double snr = m_interference.CalculateSnr (event, txVector.GetNss (staId));
|
||||
if (std::count (m_statusPerMpdu.begin (), m_statusPerMpdu.end (), true))
|
||||
{
|
||||
//At least one MPDU has been successfully received
|
||||
|
||||
@@ -348,7 +348,7 @@ WifiErrorRateModelsTestCaseMimo::DoRun (void)
|
||||
|
||||
// SISO: initial SNR set to 4dB
|
||||
double initialSnr = 4.0;
|
||||
double snr = interference.CalculateSnr (0.001, 0.001 / DbToRatio (initialSnr), txVector);
|
||||
double snr = interference.CalculateSnr (0.001, 0.001 / DbToRatio (initialSnr), txVector.GetChannelWidth (), txVector.GetNss ());
|
||||
NS_TEST_ASSERT_MSG_EQ_TOL (RatioToDb (snr), initialSnr, 0.1, "Attempt to set initial SNR to known value failed");
|
||||
Time duration = MilliSeconds (2);
|
||||
double chunkSuccess = interference.CalculateChunkSuccessRate (snr, duration, mode, txVector);
|
||||
@@ -358,7 +358,7 @@ WifiErrorRateModelsTestCaseMimo::DoRun (void)
|
||||
// MIMO 2x1:2: expect no SNR gain in AWGN channel
|
||||
txVector.SetNss (2);
|
||||
txVector.SetNTx (2);
|
||||
snr = interference.CalculateSnr (0.001, 0.001 / DbToRatio (initialSnr), txVector);
|
||||
snr = interference.CalculateSnr (0.001, 0.001 / DbToRatio (initialSnr), txVector.GetChannelWidth (), txVector.GetNss ());
|
||||
NS_TEST_ASSERT_MSG_EQ_TOL (RatioToDb (snr), initialSnr, 0.1, "SNR not within tolerance for 2x1:2 MIMO");
|
||||
chunkSuccess = interference.CalculateChunkSuccessRate (snr, duration, mode, txVector);
|
||||
NS_TEST_ASSERT_MSG_EQ_TOL (chunkSuccess, 0.905685, 0.000001, "CSR not within tolerance for SISO");
|
||||
@@ -367,7 +367,7 @@ WifiErrorRateModelsTestCaseMimo::DoRun (void)
|
||||
txVector.SetNss (1);
|
||||
txVector.SetNTx (1);
|
||||
interference.SetNumberOfReceiveAntennas (2);
|
||||
snr = interference.CalculateSnr (0.001, 0.001 / DbToRatio (initialSnr), txVector);
|
||||
snr = interference.CalculateSnr (0.001, 0.001 / DbToRatio (initialSnr), txVector.GetChannelWidth (), txVector.GetNss ());
|
||||
NS_TEST_ASSERT_MSG_EQ_TOL (RatioToDb (snr), initialSnr + 3, 0.1, "SNR not within tolerance for 1x2:1 MIMO");
|
||||
chunkSuccess = interference.CalculateChunkSuccessRate (snr, duration, mode, txVector);
|
||||
NS_TEST_ASSERT_MSG_GT (chunkSuccess, sisoChunkSuccess, "CSR not within tolerance for 1x2:1 MIMO");
|
||||
@@ -376,7 +376,7 @@ WifiErrorRateModelsTestCaseMimo::DoRun (void)
|
||||
txVector.SetNss (1);
|
||||
txVector.SetNTx (2);
|
||||
interference.SetNumberOfReceiveAntennas (2);
|
||||
snr = interference.CalculateSnr (0.001, 0.001 / DbToRatio (initialSnr), txVector);
|
||||
snr = interference.CalculateSnr (0.001, 0.001 / DbToRatio (initialSnr), txVector.GetChannelWidth (), txVector.GetNss ());
|
||||
NS_TEST_ASSERT_MSG_EQ_TOL (RatioToDb (snr), initialSnr + 3, 0.1, "SNR not equal within tolerance for 2x2:1 MIMO");
|
||||
chunkSuccess = interference.CalculateChunkSuccessRate (snr, duration, mode, txVector);
|
||||
NS_TEST_ASSERT_MSG_GT (chunkSuccess, sisoChunkSuccess, "CSR not within tolerance for 2x2:1 MIMO");
|
||||
@@ -385,7 +385,7 @@ WifiErrorRateModelsTestCaseMimo::DoRun (void)
|
||||
txVector.SetNss (2);
|
||||
txVector.SetNTx (2);
|
||||
interference.SetNumberOfReceiveAntennas (2);
|
||||
snr = interference.CalculateSnr (0.001, 0.001 / DbToRatio (initialSnr), txVector);
|
||||
snr = interference.CalculateSnr (0.001, 0.001 / DbToRatio (initialSnr), txVector.GetChannelWidth (), txVector.GetNss ());
|
||||
NS_TEST_ASSERT_MSG_EQ_TOL (RatioToDb (snr), initialSnr, 0.1, "SNR not equal within tolerance for 2x2:2 MIMO");
|
||||
chunkSuccess = interference.CalculateChunkSuccessRate (snr, duration, mode, txVector);
|
||||
NS_TEST_ASSERT_MSG_EQ_TOL (chunkSuccess, sisoChunkSuccess, 0.000001, "CSR not within tolerance for 2x2:2 MIMO");
|
||||
@@ -394,7 +394,7 @@ WifiErrorRateModelsTestCaseMimo::DoRun (void)
|
||||
txVector.SetNss (1);
|
||||
txVector.SetNTx (3);
|
||||
interference.SetNumberOfReceiveAntennas (3);
|
||||
snr = interference.CalculateSnr (0.001, 0.001 / DbToRatio (initialSnr), txVector);
|
||||
snr = interference.CalculateSnr (0.001, 0.001 / DbToRatio (initialSnr), txVector.GetChannelWidth (), txVector.GetNss ());
|
||||
NS_TEST_ASSERT_MSG_EQ_TOL (RatioToDb (snr), initialSnr + 4.8, 0.1, "SNR not within tolerance for 3x3:1 MIMO");
|
||||
chunkSuccess = interference.CalculateChunkSuccessRate (snr, duration, mode, txVector);
|
||||
NS_TEST_ASSERT_MSG_GT (chunkSuccess, sisoChunkSuccess, "CSR not within tolerance for 3x3:1 MIMO");
|
||||
@@ -403,7 +403,7 @@ WifiErrorRateModelsTestCaseMimo::DoRun (void)
|
||||
txVector.SetNss (2);
|
||||
txVector.SetNTx (3);
|
||||
interference.SetNumberOfReceiveAntennas (3);
|
||||
snr = interference.CalculateSnr (0.001, 0.001 / DbToRatio (initialSnr), txVector);
|
||||
snr = interference.CalculateSnr (0.001, 0.001 / DbToRatio (initialSnr), txVector.GetChannelWidth (), txVector.GetNss ());
|
||||
NS_TEST_ASSERT_MSG_EQ_TOL (RatioToDb (snr), initialSnr + 1.8, 0.1, "SNR not within tolerance for 3x3:2 MIMO");
|
||||
chunkSuccess = interference.CalculateChunkSuccessRate (snr, duration, mode, txVector);
|
||||
NS_TEST_ASSERT_MSG_GT (chunkSuccess, sisoChunkSuccess, "CSR not within tolerance for 3x3:2 MIMO");
|
||||
@@ -412,7 +412,7 @@ WifiErrorRateModelsTestCaseMimo::DoRun (void)
|
||||
txVector.SetNss (3);
|
||||
txVector.SetNTx (3);
|
||||
interference.SetNumberOfReceiveAntennas (3);
|
||||
snr = interference.CalculateSnr (0.001, 0.001 / DbToRatio (initialSnr), txVector);
|
||||
snr = interference.CalculateSnr (0.001, 0.001 / DbToRatio (initialSnr), txVector.GetChannelWidth (), txVector.GetNss ());
|
||||
NS_TEST_ASSERT_MSG_EQ_TOL (RatioToDb (snr), initialSnr, 0.1, "SNR not within tolerance for 3x3:3 MIMO");
|
||||
chunkSuccess = interference.CalculateChunkSuccessRate (snr, duration, mode, txVector);
|
||||
NS_TEST_ASSERT_MSG_EQ_TOL (chunkSuccess, sisoChunkSuccess, 0.000001, "CSR not equal within tolerance for 3x3:3 MIMO");
|
||||
@@ -421,7 +421,7 @@ WifiErrorRateModelsTestCaseMimo::DoRun (void)
|
||||
txVector.SetNss (1);
|
||||
txVector.SetNTx (4);
|
||||
interference.SetNumberOfReceiveAntennas (4);
|
||||
snr = interference.CalculateSnr (0.001, 0.001 / DbToRatio (initialSnr), txVector);
|
||||
snr = interference.CalculateSnr (0.001, 0.001 / DbToRatio (initialSnr), txVector.GetChannelWidth (), txVector.GetNss ());
|
||||
NS_TEST_ASSERT_MSG_EQ_TOL (RatioToDb (snr), initialSnr + 6, 0.1, "SNR not within tolerance for 4x4:1 MIMO");
|
||||
chunkSuccess = interference.CalculateChunkSuccessRate (snr, duration, mode, txVector);
|
||||
NS_TEST_ASSERT_MSG_GT (chunkSuccess, sisoChunkSuccess, "CSR not within tolerance for 4x4:1 MIMO");
|
||||
@@ -430,7 +430,7 @@ WifiErrorRateModelsTestCaseMimo::DoRun (void)
|
||||
txVector.SetNss (2);
|
||||
txVector.SetNTx (4);
|
||||
interference.SetNumberOfReceiveAntennas (4);
|
||||
snr = interference.CalculateSnr (0.001, 0.001 / DbToRatio (initialSnr), txVector);
|
||||
snr = interference.CalculateSnr (0.001, 0.001 / DbToRatio (initialSnr), txVector.GetChannelWidth (), txVector.GetNss ());
|
||||
NS_TEST_ASSERT_MSG_EQ_TOL (RatioToDb (snr), initialSnr + 3, 0.1, "SNR not within tolerance for 4x4:2 MIMO");
|
||||
chunkSuccess = interference.CalculateChunkSuccessRate (snr, duration, mode, txVector);
|
||||
NS_TEST_ASSERT_MSG_GT (chunkSuccess, sisoChunkSuccess, "CSR not within tolerance for 4x4:2 MIMO");
|
||||
@@ -439,7 +439,7 @@ WifiErrorRateModelsTestCaseMimo::DoRun (void)
|
||||
txVector.SetNss (3);
|
||||
txVector.SetNTx (4);
|
||||
interference.SetNumberOfReceiveAntennas (4);
|
||||
snr = interference.CalculateSnr (0.001, 0.001 / DbToRatio (initialSnr), txVector);
|
||||
snr = interference.CalculateSnr (0.001, 0.001 / DbToRatio (initialSnr), txVector.GetChannelWidth (), txVector.GetNss ());
|
||||
NS_TEST_ASSERT_MSG_EQ_TOL (RatioToDb (snr), initialSnr + 1.2, 0.1, "SNR not within tolerance for 4x4:3 MIMO");
|
||||
chunkSuccess = interference.CalculateChunkSuccessRate (snr, duration, mode, txVector);
|
||||
NS_TEST_ASSERT_MSG_GT (chunkSuccess, sisoChunkSuccess, "CSR not within tolerance for 4x4:1 MIMO");
|
||||
@@ -448,7 +448,7 @@ WifiErrorRateModelsTestCaseMimo::DoRun (void)
|
||||
txVector.SetNss (4);
|
||||
txVector.SetNTx (4);
|
||||
interference.SetNumberOfReceiveAntennas (4);
|
||||
snr = interference.CalculateSnr (0.001, 0.001 / DbToRatio (initialSnr), txVector);
|
||||
snr = interference.CalculateSnr (0.001, 0.001 / DbToRatio (initialSnr), txVector.GetChannelWidth (), txVector.GetNss ());
|
||||
NS_TEST_ASSERT_MSG_EQ_TOL (RatioToDb (snr), initialSnr, 0.1, "SNR not within tolerance for 4x4:4 MIMO");
|
||||
chunkSuccess = interference.CalculateChunkSuccessRate (snr, duration, mode, txVector);
|
||||
NS_TEST_ASSERT_MSG_EQ_TOL (chunkSuccess, sisoChunkSuccess, 0.000001, "CSR not within tolerance for 4x4:4 MIMO");
|
||||
|
||||
Reference in New Issue
Block a user