wifi: (fixes #2733) Support NSS > 1 in ideal wifi manager
This commit is contained in:
@@ -104,6 +104,7 @@ Bugs fixed
|
||||
- Bug 2673 - run-time channel switch does not update WiFi spectrum model
|
||||
- Bug 2717 - Fix mask generation for Ipv4RoutingTableEntry::CreateDefaultRoute
|
||||
- Bug 2722 - 802.11g sends DSSS spectrum signals using CreateOfdmTxPowerSpectralDensity
|
||||
- Bug 2733 - Ideal wifi manager cannot handle NSS higher than 1
|
||||
- Bug 2741 - IPv4 fragmentation fails when last fragment have to be re-fragmented.
|
||||
- Bug 2744 - 802.11n/ac with RTS/CTS is crashing for a large number of nodes
|
||||
- Bug 2757 - 802.11n/ac/ax maximum TXOP is not properly enforced
|
||||
|
||||
@@ -182,6 +182,18 @@ int main (int argc, char *argv[])
|
||||
cmd.AddValue ("infrastructure", "Use infrastructure instead of adhoc", infrastructure);
|
||||
cmd.Parse (argc,argv);
|
||||
|
||||
// Print out some explanation of what this program does
|
||||
std::cout << std::endl << "This program demonstrates and plots the operation of different " << std::endl;
|
||||
std::cout << "Wi-Fi rate controls on different station configurations," << std::endl;
|
||||
std::cout << "by stepping down the received signal strength across a wide range" << std::endl;
|
||||
std::cout << "and observing the adjustment of the rate." << std::endl;
|
||||
std::cout << "Run 'wifi-manager-example --PrintHelp' to show program options."<< std::endl << std::endl;
|
||||
|
||||
if (infrastructure == false)
|
||||
{
|
||||
NS_ABORT_MSG_IF (serverNss != clientNss, "In ad hoc mode, we assume sender and receiver are similarly configured");
|
||||
}
|
||||
|
||||
if (standard == "802.11b")
|
||||
{
|
||||
NS_ABORT_MSG_IF (serverChannelWidth != 22 && serverChannelWidth != 22, "Invalid channel width for standard " << standard);
|
||||
|
||||
@@ -38,6 +38,9 @@ struct IdealWifiRemoteStation : public WifiRemoteStation
|
||||
WifiMode m_lastMode; //!< Mode most recently used to the remote station
|
||||
};
|
||||
|
||||
// To avoid using the cache before a valid value has been cached
|
||||
static const double CACHE_INITIAL_VALUE = -100;
|
||||
|
||||
NS_OBJECT_ENSURE_REGISTERED (IdealWifiManager);
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("IdealWifiManager");
|
||||
@@ -148,8 +151,7 @@ IdealWifiManager::DoInitialize ()
|
||||
{
|
||||
guardInterval = GetPhy ()->GetGuardInterval ().GetNanoSeconds ();
|
||||
}
|
||||
uint8_t maxNss = GetPhy ()->GetMaxSupportedTxSpatialStreams ();
|
||||
for (uint8_t i = 1; i <= maxNss; i++)
|
||||
for (uint8_t i = 1; i <= GetPhy ()->GetMaxSupportedTxSpatialStreams (); i++)
|
||||
{
|
||||
NS_LOG_DEBUG ("Initialize, adding mode = " << mode.GetUniqueName () <<
|
||||
" channel width " << (uint16_t) j <<
|
||||
@@ -204,7 +206,7 @@ IdealWifiManager::DoCreateStation (void) const
|
||||
NS_LOG_FUNCTION (this);
|
||||
IdealWifiRemoteStation *station = new IdealWifiRemoteStation ();
|
||||
station->m_lastSnrObserved = 0.0;
|
||||
station->m_lastSnrCached = 0.0;
|
||||
station->m_lastSnrCached = CACHE_INITIAL_VALUE;
|
||||
station->m_lastMode = GetDefaultMode ();
|
||||
station->m_nss = 1;
|
||||
return station;
|
||||
@@ -280,17 +282,17 @@ IdealWifiManager::DoGetDataTxVector (WifiRemoteStation *st)
|
||||
NS_LOG_FUNCTION (this << st);
|
||||
IdealWifiRemoteStation *station = (IdealWifiRemoteStation *)st;
|
||||
//We search within the Supported rate set the mode with the
|
||||
//highest snr threshold possible which is smaller than m_lastSnr
|
||||
//highest data rate for which the snr threshold is smaller than m_lastSnr
|
||||
//to ensure correct packet delivery.
|
||||
double maxThreshold = 0.0;
|
||||
WifiMode maxMode = GetDefaultMode ();
|
||||
WifiTxVector txVector;
|
||||
WifiMode mode;
|
||||
uint64_t bestRate = 0;
|
||||
uint8_t selectedNss = 1;
|
||||
uint16_t guardInterval;
|
||||
uint8_t channelWidth = std::min (GetChannelWidth (station), GetPhy ()->GetChannelWidth ());
|
||||
txVector.SetChannelWidth (channelWidth);
|
||||
if (station->m_lastSnrObserved == station->m_lastSnrCached)
|
||||
if (station->m_lastSnrCached != CACHE_INITIAL_VALUE && station->m_lastSnrObserved == station->m_lastSnrCached)
|
||||
{
|
||||
// SNR has not changed, so skip the search and use the last
|
||||
// mode selected
|
||||
@@ -298,7 +300,8 @@ IdealWifiManager::DoGetDataTxVector (WifiRemoteStation *st)
|
||||
selectedNss = station->m_nss;
|
||||
NS_LOG_DEBUG ("Using cached mode = " << maxMode.GetUniqueName () <<
|
||||
" last snr observed " << station->m_lastSnrObserved <<
|
||||
" cached " << station->m_lastSnrCached);
|
||||
" cached " << station->m_lastSnrCached <<
|
||||
" nss " << (uint16_t) selectedNss);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -326,7 +329,8 @@ IdealWifiManager::DoGetDataTxVector (WifiRemoteStation *st)
|
||||
// Derive NSS from the MCS index. There is a different mode for each possible NSS value.
|
||||
uint8_t nss = (mode.GetMcsValue () / 8) + 1;
|
||||
txVector.SetNss (nss);
|
||||
if (WifiPhy::IsValidTxVector (txVector) == false)
|
||||
if (WifiPhy::IsValidTxVector (txVector) == false ||
|
||||
nss > GetNumberOfSupportedStreams (st))
|
||||
{
|
||||
NS_LOG_DEBUG ("Skipping mode " << mode.GetUniqueName () <<
|
||||
" nss " << (uint16_t) nss << " width " <<
|
||||
@@ -334,18 +338,20 @@ IdealWifiManager::DoGetDataTxVector (WifiRemoteStation *st)
|
||||
continue;
|
||||
}
|
||||
double threshold = GetSnrThreshold (txVector);
|
||||
NS_LOG_DEBUG ("Testing mode = " << mode.GetUniqueName () <<
|
||||
" threshold " << threshold << " maxThreshold " <<
|
||||
maxThreshold << " last snr observed " <<
|
||||
uint64_t dataRate = mode.GetDataRate (txVector.GetChannelWidth (), txVector.GetGuardInterval (), nss);
|
||||
NS_LOG_DEBUG ("Testing mode " << mode.GetUniqueName () <<
|
||||
" data rate " << dataRate <<
|
||||
" threshold " << threshold << " last snr observed " <<
|
||||
station->m_lastSnrObserved << " cached " <<
|
||||
station->m_lastSnrCached);
|
||||
if (threshold > maxThreshold && threshold < station->m_lastSnrObserved)
|
||||
if (dataRate > bestRate && threshold < station->m_lastSnrObserved)
|
||||
{
|
||||
NS_LOG_DEBUG ("Candidate mode = " << mode.GetUniqueName () <<
|
||||
" data rate " << dataRate <<
|
||||
" threshold " << threshold <<
|
||||
" last snr observed " <<
|
||||
station->m_lastSnrObserved);
|
||||
maxThreshold = threshold;
|
||||
bestRate = dataRate;
|
||||
maxMode = mode;
|
||||
selectedNss = nss;
|
||||
}
|
||||
@@ -364,14 +370,8 @@ IdealWifiManager::DoGetDataTxVector (WifiRemoteStation *st)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
uint8_t maxNss = GetPhy ()->GetMaxSupportedTxSpatialStreams ();
|
||||
for (uint8_t nss = 1; nss <= maxNss; nss++)
|
||||
for (uint8_t nss = 1; nss <= GetNumberOfSupportedStreams (station); nss++)
|
||||
{
|
||||
// If the peer does not support more streams, stop searching.
|
||||
if (GetNumberOfSupportedStreams (station) < nss)
|
||||
{
|
||||
break;
|
||||
}
|
||||
txVector.SetNss (nss);
|
||||
if (WifiPhy::IsValidTxVector (txVector) == false)
|
||||
{
|
||||
@@ -381,18 +381,20 @@ IdealWifiManager::DoGetDataTxVector (WifiRemoteStation *st)
|
||||
continue;
|
||||
}
|
||||
double threshold = GetSnrThreshold (txVector);
|
||||
uint64_t dataRate = mode.GetDataRate (txVector.GetChannelWidth (), txVector.GetGuardInterval (), nss);
|
||||
NS_LOG_DEBUG ("Testing mode = " << mode.GetUniqueName () <<
|
||||
" threshold " << threshold << " maxThreshold " <<
|
||||
maxThreshold << " last snr observed " <<
|
||||
" data rate " << dataRate <<
|
||||
" threshold " << threshold << " last snr observed " <<
|
||||
station->m_lastSnrObserved << " cached " <<
|
||||
station->m_lastSnrCached);
|
||||
if (threshold > maxThreshold && threshold < station->m_lastSnrObserved)
|
||||
if (dataRate > bestRate && threshold < station->m_lastSnrObserved)
|
||||
{
|
||||
NS_LOG_DEBUG ("Candidate mode = " << mode.GetUniqueName () <<
|
||||
" data rate " << dataRate <<
|
||||
" threshold " << threshold <<
|
||||
" last snr observed " <<
|
||||
station->m_lastSnrObserved);
|
||||
maxThreshold = threshold;
|
||||
bestRate = dataRate;
|
||||
maxMode = mode;
|
||||
selectedNss = nss;
|
||||
}
|
||||
@@ -407,14 +409,8 @@ IdealWifiManager::DoGetDataTxVector (WifiRemoteStation *st)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
uint8_t maxNss = GetPhy ()->GetMaxSupportedTxSpatialStreams ();
|
||||
for (uint8_t nss = 1; nss <= maxNss; nss++)
|
||||
for (uint8_t nss = 1; nss <= GetNumberOfSupportedStreams (station); nss++)
|
||||
{
|
||||
// If the peer does not support more streams, stop searching.
|
||||
if (GetNumberOfSupportedStreams (station) < nss)
|
||||
{
|
||||
break;
|
||||
}
|
||||
txVector.SetNss (nss);
|
||||
if (WifiPhy::IsValidTxVector (txVector) == false)
|
||||
{
|
||||
@@ -424,18 +420,20 @@ IdealWifiManager::DoGetDataTxVector (WifiRemoteStation *st)
|
||||
continue;
|
||||
}
|
||||
double threshold = GetSnrThreshold (txVector);
|
||||
uint64_t dataRate = mode.GetDataRate (txVector.GetChannelWidth (), txVector.GetGuardInterval (), nss);
|
||||
NS_LOG_DEBUG ("Testing mode = " << mode.GetUniqueName () <<
|
||||
" threshold " << threshold << " maxThreshold " <<
|
||||
maxThreshold << " last snr observed " <<
|
||||
" data rate " << dataRate <<
|
||||
" threshold " << threshold << " last snr observed " <<
|
||||
station->m_lastSnrObserved << " cached " <<
|
||||
station->m_lastSnrCached);
|
||||
if (threshold > maxThreshold && threshold < station->m_lastSnrObserved)
|
||||
if (dataRate > bestRate && threshold < station->m_lastSnrObserved)
|
||||
{
|
||||
NS_LOG_DEBUG ("Candidate mode = " << mode.GetUniqueName () <<
|
||||
" data rate " << dataRate <<
|
||||
" threshold " << threshold <<
|
||||
" last snr observed " <<
|
||||
station->m_lastSnrObserved);
|
||||
maxThreshold = threshold;
|
||||
bestRate = dataRate;
|
||||
maxMode = mode;
|
||||
selectedNss = nss;
|
||||
}
|
||||
@@ -454,17 +452,19 @@ IdealWifiManager::DoGetDataTxVector (WifiRemoteStation *st)
|
||||
txVector.SetNss (selectedNss);
|
||||
txVector.SetChannelWidth (GetChannelWidthForMode (mode));
|
||||
double threshold = GetSnrThreshold (txVector);
|
||||
uint64_t dataRate = mode.GetDataRate (txVector.GetChannelWidth (), txVector.GetGuardInterval (), txVector.GetNss ());
|
||||
NS_LOG_DEBUG ("mode = " << mode.GetUniqueName () <<
|
||||
" threshold " << threshold <<
|
||||
" last snr observed " <<
|
||||
station->m_lastSnrObserved);
|
||||
if (threshold > maxThreshold && threshold < station->m_lastSnrObserved)
|
||||
if (dataRate > bestRate && threshold < station->m_lastSnrObserved)
|
||||
{
|
||||
NS_LOG_DEBUG ("Candidate mode = " << mode.GetUniqueName () <<
|
||||
" data rate " << dataRate <<
|
||||
" threshold " << threshold <<
|
||||
" last snr observed " <<
|
||||
station->m_lastSnrObserved);
|
||||
maxThreshold = threshold;
|
||||
bestRate = dataRate;
|
||||
maxMode = mode;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user