wifi: Move computation logic from WifiMode to PhyEntity by using callbacks

This commit is contained in:
Muhammad Iqbal CR
2021-01-15 16:51:29 +01:00
committed by Rediet
parent 8535c9dc00
commit 08c16dc614
8 changed files with 203 additions and 457 deletions

View File

@@ -285,8 +285,12 @@ DsssPhy::CreateDsssMode (std::string uniqueName,
return WifiModeFactory::CreateWifiMode (uniqueName,
modClass,
true,
GetCodeRate (uniqueName),
GetConstellationSize (uniqueName));
MakeBoundCallback (&GetCodeRate, uniqueName),
MakeBoundCallback (&GetConstellationSize, uniqueName),
MakeBoundCallback (&GetDataRate, uniqueName, modClass),
MakeBoundCallback (&GetDataRate, uniqueName, modClass), //PhyRate is equivalent to DataRate
MakeCallback (&GetDataRateFromTxVector),
MakeCallback (&IsModeAllowed));
}
WifiCodeRate

View File

@@ -163,8 +163,12 @@ ErpOfdmPhy::CreateErpOfdmMode (std::string uniqueName, bool isMandatory)
return WifiModeFactory::CreateWifiMode (uniqueName,
WIFI_MOD_CLASS_ERP_OFDM,
isMandatory,
GetCodeRate (uniqueName),
GetConstellationSize (uniqueName));
MakeBoundCallback (&GetCodeRate, uniqueName),
MakeBoundCallback (&GetConstellationSize, uniqueName),
MakeBoundCallback (&GetPhyRate, uniqueName),
MakeBoundCallback (&GetDataRate, uniqueName),
MakeCallback (&GetDataRateFromTxVector),
MakeCallback (&IsModeAllowed));
}
WifiCodeRate

View File

@@ -999,7 +999,14 @@ HePhy::CreateHeMcs (uint8_t index)
NS_ASSERT_MSG (index <= 11, "HeMcs index must be <= 11!");
return WifiModeFactory::CreateWifiMcs ("HeMcs" + std::to_string (index),
index,
WIFI_MOD_CLASS_HE);
WIFI_MOD_CLASS_HE,
MakeBoundCallback (&GetCodeRate, index),
MakeBoundCallback (&GetConstellationSize, index),
MakeBoundCallback (&GetPhyRate, index),
MakeBoundCallback (&GetDataRate, index),
MakeCallback (&GetDataRateFromTxVector),
MakeBoundCallback (&GetNonHtReferenceRate, index),
MakeCallback (&IsModeAllowed));
}
WifiCodeRate

View File

@@ -560,7 +560,14 @@ HtPhy::CreateHtMcs (uint8_t index)
NS_ASSERT_MSG (index <= 31, "HtMcs index must be <= 31!");
return WifiModeFactory::CreateWifiMcs ("HtMcs" + std::to_string (index),
index,
WIFI_MOD_CLASS_HT);
WIFI_MOD_CLASS_HT,
MakeBoundCallback (&GetHtCodeRate, index),
MakeBoundCallback (&GetHtConstellationSize, index),
MakeBoundCallback (&GetPhyRate, index),
MakeBoundCallback (&GetDataRate, index),
MakeCallback (&GetDataRateFromTxVector),
MakeBoundCallback (&GetNonHtReferenceRate, index),
MakeCallback (&IsModeAllowed));
}
WifiCodeRate

View File

@@ -496,8 +496,12 @@ OfdmPhy::CreateOfdmMode (std::string uniqueName, bool isMandatory)
return WifiModeFactory::CreateWifiMode (uniqueName,
WIFI_MOD_CLASS_OFDM,
isMandatory,
GetCodeRate (uniqueName),
GetConstellationSize (uniqueName));
MakeBoundCallback (&GetCodeRate, uniqueName),
MakeBoundCallback (&GetConstellationSize, uniqueName),
MakeBoundCallback (&GetPhyRate, uniqueName),
MakeBoundCallback (&GetDataRate, uniqueName),
MakeCallback (&GetDataRateFromTxVector),
MakeCallback (&IsModeAllowed));
}
WifiCodeRate

View File

@@ -376,7 +376,14 @@ VhtPhy::CreateVhtMcs (uint8_t index)
NS_ASSERT_MSG (index <= 9, "VhtMcs index must be <= 9!");
return WifiModeFactory::CreateWifiMcs ("VhtMcs" + std::to_string (index),
index,
WIFI_MOD_CLASS_VHT);
WIFI_MOD_CLASS_VHT,
MakeBoundCallback (&GetCodeRate, index),
MakeBoundCallback (&GetConstellationSize, index),
MakeBoundCallback (&GetPhyRate, index),
MakeBoundCallback (&GetDataRate, index),
MakeCallback (&GetDataRateFromTxVector),
MakeBoundCallback (&GetNonHtReferenceRate, index),
MakeBoundCallback (&IsModeAllowed, index));
}
WifiCodeRate

View File

@@ -55,45 +55,14 @@ bool
WifiMode::IsAllowed (uint16_t channelWidth, uint8_t nss) const
{
WifiModeFactory::WifiModeItem *item = WifiModeFactory::GetFactory ()->Get (m_uid);
if (item->modClass == WIFI_MOD_CLASS_VHT)
{
if (item->mcsValue == 9 && channelWidth == 20 && nss != 3)
{
return false;
}
if (item->mcsValue == 6 && channelWidth == 80 && nss == 3)
{
return false;
}
}
return true;
return item->IsModeAllowedCallback (channelWidth, nss);
}
uint64_t
WifiMode::GetPhyRate (uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
{
uint64_t dataRate, phyRate;
dataRate = GetDataRate (channelWidth, guardInterval, nss);
switch (GetCodeRate ())
{
case WIFI_CODE_RATE_5_6:
phyRate = dataRate * 6 / 5;
break;
case WIFI_CODE_RATE_3_4:
phyRate = dataRate * 4 / 3;
break;
case WIFI_CODE_RATE_2_3:
phyRate = dataRate * 3 / 2;
break;
case WIFI_CODE_RATE_1_2:
phyRate = dataRate * 2 / 1;
break;
case WIFI_CODE_RATE_UNDEFINED:
default:
phyRate = dataRate;
break;
}
return phyRate;
WifiModeFactory::WifiModeItem *item = WifiModeFactory::GetFactory ()->Get (m_uid);
return item->GetPhyRateCallback (channelWidth, guardInterval, nss);
}
uint64_t
@@ -111,13 +80,8 @@ WifiMode::GetDataRate (uint16_t channelWidth) const
uint64_t
WifiMode::GetDataRate (WifiTxVector txVector, uint16_t staId) const
{
uint16_t bw = txVector.GetChannelWidth ();
uint8_t nss = txVector.GetNss (staId);
if (txVector.IsMu ())
{
bw = HeRu::GetBandwidth (txVector.GetRu (staId).ruType);
}
return GetDataRate (bw, txVector.GetGuardInterval (), nss);
WifiModeFactory::WifiModeItem *item = WifiModeFactory::GetFactory ()->Get (m_uid);
return item->GetDataRateFromTxVectorCallback (txVector, staId);
}
uint64_t
@@ -125,318 +89,21 @@ WifiMode::GetDataRate (uint16_t channelWidth, uint16_t guardInterval, uint8_t ns
{
NS_ASSERT (nss <= 8);
WifiModeFactory::WifiModeItem *item = WifiModeFactory::GetFactory ()->Get (m_uid);
uint64_t dataRate = 0;
uint16_t usableSubCarriers = 0;
double symbolRate = 0;
double codingRate = 0;
uint16_t numberOfBitsPerSubcarrier = static_cast<uint16_t> (log2 (GetConstellationSize ()));
if (item->modClass == WIFI_MOD_CLASS_DSSS)
{
dataRate = ((11000000 / 11) * numberOfBitsPerSubcarrier);
}
else if (item->modClass == WIFI_MOD_CLASS_HR_DSSS)
{
dataRate = ((11000000 / 8) * numberOfBitsPerSubcarrier);
}
else if (item->modClass == WIFI_MOD_CLASS_OFDM || item->modClass == WIFI_MOD_CLASS_ERP_OFDM)
{
usableSubCarriers = 48;
switch (channelWidth)
{
case 20:
default:
symbolRate = (1 / 4.0) * 1e6;
break;
case 10:
symbolRate = (1 / 8.0) * 1e6;
break;
case 5:
symbolRate = (1 / 16.0) * 1e6;
break;
}
switch (GetCodeRate ())
{
case WIFI_CODE_RATE_3_4:
codingRate = (3.0 / 4.0);
break;
case WIFI_CODE_RATE_2_3:
codingRate = (2.0 / 3.0);
break;
case WIFI_CODE_RATE_1_2:
codingRate = (1.0 / 2.0);
break;
case WIFI_CODE_RATE_UNDEFINED:
default:
NS_FATAL_ERROR ("trying to get datarate for a mcs without any coding rate defined");
break;
}
dataRate = lrint (ceil (symbolRate * usableSubCarriers * numberOfBitsPerSubcarrier * codingRate));
}
else if (item->modClass == WIFI_MOD_CLASS_HT || item->modClass == WIFI_MOD_CLASS_VHT)
{
if (item->modClass == WIFI_MOD_CLASS_VHT)
{
NS_ASSERT_MSG (IsAllowed (channelWidth, nss), "VHT MCS " << +item->mcsValue << " forbidden at " << channelWidth << " MHz when NSS is " << +nss);
}
else
{
NS_ASSERT (nss <= 4);
}
NS_ASSERT (guardInterval == 800 || guardInterval == 400);
symbolRate = (1 / (3.2 + (static_cast<double> (guardInterval) / 1000))) * 1e6;
if (item->modClass == WIFI_MOD_CLASS_HT)
{
switch (channelWidth)
{
case 20:
default:
usableSubCarriers = 52;
break;
case 40:
case 80:
case 160:
usableSubCarriers = 108;
break;
}
}
else //WIFI_MOD_CLASS_VHT
{
switch (channelWidth)
{
case 20:
default:
usableSubCarriers = 52;
break;
case 40:
usableSubCarriers = 108;
break;
case 80:
usableSubCarriers = 234;
break;
case 160:
usableSubCarriers = 468;
break;
}
}
switch (GetCodeRate ())
{
case WIFI_CODE_RATE_5_6:
codingRate = (5.0 / 6.0);
break;
case WIFI_CODE_RATE_3_4:
codingRate = (3.0 / 4.0);
break;
case WIFI_CODE_RATE_2_3:
codingRate = (2.0 / 3.0);
break;
case WIFI_CODE_RATE_1_2:
codingRate = (1.0 / 2.0);
break;
case WIFI_CODE_RATE_UNDEFINED:
default:
NS_FATAL_ERROR ("trying to get datarate for a mcs without any coding rate defined with nss: " << +nss);
break;
}
dataRate = lrint (ceil (symbolRate * usableSubCarriers * numberOfBitsPerSubcarrier * codingRate));
}
else if (item->modClass == WIFI_MOD_CLASS_HE)
{
NS_ASSERT (guardInterval == 800 || guardInterval == 1600 || guardInterval == 3200);
symbolRate = (1 / (12.8 + (static_cast<double> (guardInterval) / 1000))) * 1e6;
switch (channelWidth)
{
case 2: //26-tone RU
usableSubCarriers = 24;
break;
case 4: //52-tone RU
usableSubCarriers = 48;
break;
case 8: //106-tone RU
usableSubCarriers = 102;
break;
case 20:
default:
usableSubCarriers = 234;
break;
case 40:
usableSubCarriers = 468;
break;
case 80:
usableSubCarriers = 980;
break;
case 160:
usableSubCarriers = 1960;
break;
}
switch (GetCodeRate ())
{
case WIFI_CODE_RATE_5_6:
codingRate = (5.0 / 6.0);
break;
case WIFI_CODE_RATE_3_4:
codingRate = (3.0 / 4.0);
break;
case WIFI_CODE_RATE_2_3:
codingRate = (2.0 / 3.0);
break;
case WIFI_CODE_RATE_1_2:
codingRate = (1.0 / 2.0);
break;
case WIFI_CODE_RATE_UNDEFINED:
default:
NS_FATAL_ERROR ("trying to get datarate for a mcs without any coding rate defined with nss: " << +nss);
break;
}
dataRate = lrint (ceil (symbolRate * usableSubCarriers * numberOfBitsPerSubcarrier * codingRate));
}
else
{
NS_ASSERT ("undefined datarate for the modulation class!");
}
dataRate *= nss; // number of spatial streams
return dataRate;
return item->GetDataRateCallback (channelWidth, guardInterval, nss);
}
WifiCodeRate
WifiMode::GetCodeRate (void) const
{
WifiModeFactory::WifiModeItem *item = WifiModeFactory::GetFactory ()->Get (m_uid);
if (item->modClass == WIFI_MOD_CLASS_HT)
{
switch (item->mcsValue % 8)
{
case 0:
case 1:
case 3:
return WIFI_CODE_RATE_1_2;
case 2:
case 4:
case 6:
return WIFI_CODE_RATE_3_4;
case 5:
return WIFI_CODE_RATE_2_3;
case 7:
return WIFI_CODE_RATE_5_6;
default:
return WIFI_CODE_RATE_UNDEFINED;
}
}
else if (item->modClass == WIFI_MOD_CLASS_VHT)
{
switch (item->mcsValue)
{
case 0:
case 1:
case 3:
return WIFI_CODE_RATE_1_2;
case 2:
case 4:
case 6:
case 8:
return WIFI_CODE_RATE_3_4;
case 5:
return WIFI_CODE_RATE_2_3;
case 7:
case 9:
return WIFI_CODE_RATE_5_6;
default:
return WIFI_CODE_RATE_UNDEFINED;
}
}
else if (item->modClass == WIFI_MOD_CLASS_HE)
{
switch (item->mcsValue)
{
case 0:
case 1:
case 3:
return WIFI_CODE_RATE_1_2;
case 2:
case 4:
case 6:
case 8:
case 10:
return WIFI_CODE_RATE_3_4;
case 5:
return WIFI_CODE_RATE_2_3;
case 7:
case 9:
case 11:
return WIFI_CODE_RATE_5_6;
default:
return WIFI_CODE_RATE_UNDEFINED;
}
}
else
{
return item->codingRate;
}
return item->GetCodeRateCallback ();
}
uint16_t
WifiMode::GetConstellationSize (void) const
{
WifiModeFactory::WifiModeItem *item = WifiModeFactory::GetFactory ()->Get (m_uid);
if (item->modClass == WIFI_MOD_CLASS_HT)
{
switch (item->mcsValue % 8)
{
case 0:
return 2;
case 1:
case 2:
return 4;
case 3:
case 4:
return 16;
case 5:
case 6:
case 7:
return 64;
default:
return 0;
}
}
else if (item->modClass == WIFI_MOD_CLASS_VHT || item->modClass == WIFI_MOD_CLASS_HE)
{
switch (item->mcsValue)
{
case 0:
return 2;
case 1:
case 2:
return 4;
case 3:
case 4:
return 16;
case 5:
case 6:
case 7:
return 64;
case 8:
case 9:
return 256;
case 10:
case 11:
NS_ASSERT (item->modClass != WIFI_MOD_CLASS_VHT);
return 1024;
default:
return 0;
}
}
else
{
return item->constellationSize;
}
return item->GetConstellationSizeCallback ();
}
std::string
@@ -486,89 +153,9 @@ WifiMode::GetModulationClass () const
uint64_t
WifiMode::GetNonHtReferenceRate (void) const
{
uint64_t dataRate;
WifiModeFactory::WifiModeItem *item = WifiModeFactory::GetFactory ()->Get (m_uid);
if (item->modClass >= WIFI_MOD_CLASS_HT)
{
WifiCodeRate codeRate = GetCodeRate ();
switch (GetConstellationSize ())
{
case 2:
if (codeRate == WIFI_CODE_RATE_1_2)
{
dataRate = 6000000;
}
else if (codeRate == WIFI_CODE_RATE_3_4)
{
dataRate = 9000000;
}
else
{
NS_FATAL_ERROR ("Trying to get reference rate for a MCS with wrong combination of coding rate and modulation");
}
break;
case 4:
if (codeRate == WIFI_CODE_RATE_1_2)
{
dataRate = 12000000;
}
else if (codeRate == WIFI_CODE_RATE_3_4)
{
dataRate = 18000000;
}
else
{
NS_FATAL_ERROR ("Trying to get reference rate for a MCS with wrong combination of coding rate and modulation");
}
break;
case 16:
if (codeRate == WIFI_CODE_RATE_1_2)
{
dataRate = 24000000;
}
else if (codeRate == WIFI_CODE_RATE_3_4)
{
dataRate = 36000000;
}
else
{
NS_FATAL_ERROR ("Trying to get reference rate for a MCS with wrong combination of coding rate and modulation");
}
break;
case 64:
if (codeRate == WIFI_CODE_RATE_1_2 || codeRate == WIFI_CODE_RATE_2_3)
{
dataRate = 48000000;
}
else if (codeRate == WIFI_CODE_RATE_3_4 || codeRate == WIFI_CODE_RATE_5_6)
{
dataRate = 54000000;
}
else
{
NS_FATAL_ERROR ("Trying to get reference rate for a MCS with wrong combination of coding rate and modulation");
}
break;
case 256:
case 1024:
if (codeRate == WIFI_CODE_RATE_3_4 || codeRate == WIFI_CODE_RATE_5_6)
{
dataRate = 54000000;
}
else
{
NS_FATAL_ERROR ("Trying to get reference rate for a MCS with wrong combination of coding rate and modulation");
}
break;
default:
NS_FATAL_ERROR ("Wrong constellation size");
}
}
else
{
NS_FATAL_ERROR ("Trying to get reference rate for a non-HT rate");
}
return dataRate;
NS_ASSERT_MSG (!item->GetNonHtReferenceRateCallback.IsNull (), "Trying to get HT reference rate for a non-HT rate");
return item->GetNonHtReferenceRateCallback ();
}
bool
@@ -674,8 +261,12 @@ WifiMode
WifiModeFactory::CreateWifiMode (std::string uniqueName,
WifiModulationClass modClass,
bool isMandatory,
WifiCodeRate codingRate,
uint16_t constellationSize)
CodeRateCallback codeRateCallback,
ConstellationSizeCallback constellationSizeCallback,
PhyRateCallback phyRateCallback,
DataRateCallback dataRateCallback,
DataRateFromTxVectorCallback dataRateFromTxVectorCallback,
ModeAllowedCallback isModeAllowedCallback)
{
WifiModeFactory *factory = GetFactory ();
uint32_t uid = factory->AllocateUid (uniqueName);
@@ -684,7 +275,6 @@ WifiModeFactory::CreateWifiMode (std::string uniqueName,
item->modClass = modClass;
//The modulation class for this WifiMode must be valid.
NS_ASSERT (modClass != WIFI_MOD_CLASS_UNKNOWN);
item->codingRate = codingRate;
//Check for compatibility between modulation class and coding
//rate. If modulation class is DSSS then coding rate must be
@@ -692,14 +282,20 @@ WifiModeFactory::CreateWifiMode (std::string uniqueName,
//assertion, but it seems better to always give the error (i.e.,
//not only in non-optimised builds) and the cycles that extra test
//here costs are only suffered at simulation setup.
if ((codingRate == WIFI_CODE_RATE_UNDEFINED) && modClass != WIFI_MOD_CLASS_DSSS && modClass != WIFI_MOD_CLASS_HR_DSSS)
if ((codeRateCallback () == WIFI_CODE_RATE_UNDEFINED) && modClass != WIFI_MOD_CLASS_DSSS && modClass != WIFI_MOD_CLASS_HR_DSSS)
{
NS_FATAL_ERROR ("Error in creation of WifiMode named " << uniqueName << std::endl
<< "Code rate must be WIFI_CODE_RATE_UNDEFINED iff Modulation Class is WIFI_MOD_CLASS_DSSS or WIFI_MOD_CLASS_HR_DSSS");
}
item->constellationSize = constellationSize;
item->isMandatory = isMandatory;
item->GetCodeRateCallback = codeRateCallback;
item->GetConstellationSizeCallback = constellationSizeCallback;
item->GetPhyRateCallback = phyRateCallback;
item->GetDataRateCallback = dataRateCallback;
item->GetDataRateFromTxVectorCallback = dataRateFromTxVectorCallback;
item->GetNonHtReferenceRateCallback = MakeNullCallback<uint64_t> ();
item->IsModeAllowedCallback = isModeAllowedCallback;
NS_ASSERT (modClass < WIFI_MOD_CLASS_HT);
//fill unused MCS item with a dummy value
@@ -711,7 +307,14 @@ WifiModeFactory::CreateWifiMode (std::string uniqueName,
WifiMode
WifiModeFactory::CreateWifiMcs (std::string uniqueName,
uint8_t mcsValue,
WifiModulationClass modClass)
WifiModulationClass modClass,
CodeRateCallback codeRateCallback,
ConstellationSizeCallback constellationSizeCallback,
PhyRateCallback phyRateCallback,
DataRateCallback dataRateCallback,
DataRateFromTxVectorCallback dataRateFromTxVectorCallback,
NonHtReferenceRateCallback nonHtReferenceRateCallback,
ModeAllowedCallback isModeAllowedCallback)
{
WifiModeFactory *factory = GetFactory ();
uint32_t uid = factory->AllocateUid (uniqueName);
@@ -722,9 +325,15 @@ WifiModeFactory::CreateWifiMcs (std::string uniqueName,
NS_ASSERT (modClass >= WIFI_MOD_CLASS_HT);
item->mcsValue = mcsValue;
item->GetCodeRateCallback = codeRateCallback;
item->GetConstellationSizeCallback = constellationSizeCallback;
item->GetPhyRateCallback = phyRateCallback;
item->GetDataRateCallback = dataRateCallback;
item->GetDataRateFromTxVectorCallback = dataRateFromTxVectorCallback;
item->GetNonHtReferenceRateCallback = nonHtReferenceRateCallback;
item->IsModeAllowedCallback = isModeAllowedCallback;
//fill unused items with dummy values
item->constellationSize = 0;
item->codingRate = WIFI_CODE_RATE_UNDEFINED;
item->isMandatory = false;
return WifiMode (uid);
@@ -801,10 +410,15 @@ WifiModeFactory::GetFactory (void)
WifiModeItem *item = factory.Get (uid);
item->uniqueUid = "Invalid-WifiMode";
item->modClass = WIFI_MOD_CLASS_UNKNOWN;
item->constellationSize = 0;
item->codingRate = WIFI_CODE_RATE_UNDEFINED;
item->isMandatory = false;
item->mcsValue = 0;
item->GetCodeRateCallback = MakeNullCallback<WifiCodeRate> ();
item->GetConstellationSizeCallback = MakeNullCallback<uint16_t> ();
item->GetPhyRateCallback = MakeNullCallback<uint64_t, uint16_t, uint16_t, uint8_t> ();
item->GetDataRateCallback = MakeNullCallback<uint64_t, uint16_t, uint16_t, uint8_t> ();
item->GetDataRateFromTxVectorCallback = MakeNullCallback<uint64_t, WifiTxVector, uint16_t> ();
item->GetNonHtReferenceRateCallback = MakeNullCallback<uint64_t> ();
item->IsModeAllowedCallback = MakeNullCallback<bool, uint16_t, uint8_t> ();
isFirstTime = false;
}
return &factory;

View File

@@ -24,6 +24,7 @@
#include "wifi-phy-common.h"
#include "ns3/attribute-helper.h"
#include "ns3/callback.h"
#include <vector>
namespace ns3 {
@@ -266,17 +267,84 @@ typedef WifiModeList::const_iterator WifiModeListIterator;
class WifiModeFactory
{
public:
// Typedefs for callbacks used by WifiModeItem
/**
* Typedef for callback used to retrieve code rate of a WifiMode
* \return the code rate of the WifiMode.
*/
typedef Callback<WifiCodeRate> CodeRateCallback;
/**
* Typedef for callback used to retrieve constellation size of a WifiMode
* \return the size of modulation constellation of the WifiMode.
*/
typedef Callback<uint16_t> ConstellationSizeCallback;
/**
* Typedef for callback used to calculate PHY rate of a WifiMode
*
* \param channelWidth the channel width in MHz
* \param guardInterval the guard interval duration in nanoseconds
* \param nss the number of streams
* \return the physical bit rate of the signal in bps.
*/
typedef Callback<uint64_t, uint16_t /* channelWidth */, uint16_t /* guardInterval */, uint8_t /* nss */> PhyRateCallback;
/**
* Typedef for callback used to calculate data rate of a WifiMode
*
* \param channelWidth the channel width in MHz
* \param guardInterval the guard interval duration in nanoseconds
* \param nss the number of streams
* \return the data rate of the signal in bps.
*/
typedef Callback<uint64_t, uint16_t /* channelWidth */, uint16_t /* guardInterval */, uint8_t /* nss */> DataRateCallback;
/**
* Typedef for callback used to calculate data rate of a WifiMode
* from a TXVECTOR. This is mostly useful in HE or later amendments.
* For the others it's a simple wrapper of \see DataRateCallback.
*
* \param txVector the TXVECTOR used for the transmission
* \param staId the station ID
* \return the data rate of the signal in bps.
*/
typedef Callback<uint64_t, WifiTxVector /* txVector */, uint16_t /* staId */> DataRateFromTxVectorCallback;
/**
* Typedef for callback used to calculate Non-HT Reference Rate of
* an MCS defined in HT or later amendment. For Non-HT modes (DSSS, OFDM,
* etc) this should be defined as null.
*
* \return the rate (in bps) of the non-HT Reference Rate.
*/
typedef Callback<uint64_t> NonHtReferenceRateCallback;
/**
* Typedef for callback used to check whether the combination of <current
* WifiMode, channel width (in MHz), number of stream> is allowed
*
* \param channelWidth the channel width in MHz
* \param nss the number of streams
* \return true if combination of current WifiMode and supplied parameters is allowed.
*/
typedef Callback<bool, uint16_t /* channelWidth */, uint8_t /* nss */> ModeAllowedCallback;
/**
* \param uniqueName the name of the associated WifiMode. This name
* must be unique across _all_ instances.
* \param modClass the class of modulation
* \param isMandatory true if this WifiMode is mandatory, false otherwise.
* \param codingRate if convolutional coding is used for this rate
* then this parameter specifies the convolutional coding rate
* used. If there is no explicit convolutional coding step (e.g.,
* for DSSS rates) then the caller should set this parameter to
* WIFI_CODE_RATE_UNCODED.
* \param constellationSize the order of the constellation used.
* \param codeRateCallback a callback function to retrieve coding rate of
* this WifiMode. If convolutional coding is used for this rate
* then the callback returns the convolutional coding rate used. If
* there is no explicit convolutional coding step (e.g., for DSSS
* rates) then the callback should returns WIFI_CODE_RATE_UNDEFINED.
* \param constellationSizeCallback a callback function that returns the
* order of the constellation used.
* \param phyRateCallback a callback function to calculate the PHY rate (in
* bps) of this WifiMode.
* \param dataRateCallback a callback function to calculate the data rate
* (in bps) of this WifiMode.
* \param dataRateFromTxVectorCallback a callback function to calculate the data rate
* (in bps) of this WifiMode using a TXVECTOR as input.
* \param isModeAllowedCallback a callback function to check whether a
* specific combination of this WifiMode, channel width (MHz), and
* NSS are allowed.
*
* \return WifiMode
*
@@ -285,22 +353,48 @@ public:
static WifiMode CreateWifiMode (std::string uniqueName,
WifiModulationClass modClass,
bool isMandatory,
WifiCodeRate codingRate,
uint16_t constellationSize);
CodeRateCallback codeRateCallback,
ConstellationSizeCallback constellationSizeCallback,
PhyRateCallback phyRateCallback,
DataRateCallback dataRateCallback,
DataRateFromTxVectorCallback dataRateFromTxVectorCallback,
ModeAllowedCallback isModeAllowedCallback);
/**
* \param uniqueName the name of the associated WifiMode. This name
* must be unique across _all_ instances.
* \param mcsValue the MCS value
* \param modClass the class of modulation
* \param codeRateCallback a callback function that returns the coding rate
* of this WifiMode.
* \param constellationSizeCallback a callback function that returns the size
* of modulation constellation of this WifiMode.
* \param phyRateCallback a callback function to calculate the PHY rate (in
* bps) of this WifiMode.
* \param dataRateCallback a callback function to calculate the data rate (in
* bps) of this WifiMode.
* \param dataRateFromTxVectorCallback a callback function to calculate the data rate
* (in bps) of this WifiMode using a TXVECTOR as input.
* \param nonHtReferenceRateCallback a callback function to calculate the rate
* (in bps) of the non-HT Reference Rate of this WifiMode.
* \param isModeAllowedCallback a callback function to calculate whether a
* combination of <MCS index, channel width (MHz), number of spatial
* stream> is allowed for this WifiMode.
*
* \return WifiMode
*
* Create a HT WifiMode.
* Create a HT or later WifiMode.
*/
static WifiMode CreateWifiMcs (std::string uniqueName,
uint8_t mcsValue,
WifiModulationClass modClass);
WifiModulationClass modClass,
CodeRateCallback codeRateCallback,
ConstellationSizeCallback constellationSizeCallback,
PhyRateCallback phyRateCallback,
DataRateCallback dataRateCallback,
DataRateFromTxVectorCallback dataRateFromTxVectorCallback,
NonHtReferenceRateCallback nonHtReferenceRateCallback,
ModeAllowedCallback isModeAllowedCallback);
private:
@@ -323,12 +417,17 @@ private:
*/
struct WifiModeItem
{
std::string uniqueUid; ///< unique UID
std::string uniqueUid; ///< unique UID
WifiModulationClass modClass; ///< modulation class
uint16_t constellationSize; ///< constellation size
WifiCodeRate codingRate; ///< coding rate
bool isMandatory; ///< flag to indicate whether this mode is mandatory
uint8_t mcsValue; ///< MCS value
bool isMandatory; ///< flag to indicate whether this mode is mandatory
uint8_t mcsValue; ///< MCS value
CodeRateCallback GetCodeRateCallback; ///< Callback to retrieve code rate of this WifiModeItem
ConstellationSizeCallback GetConstellationSizeCallback; ///< Callback to retrieve constellation size of this WifiModeItem
PhyRateCallback GetPhyRateCallback; ///< Callback to calculate PHY rate in bps of this WifiModeItem
DataRateCallback GetDataRateCallback; ///< Callback to calculate data rate in bps of this WifiModeItem
DataRateFromTxVectorCallback GetDataRateFromTxVectorCallback; ///< Callback to calculate data rate in bps of this WifiModeItem using a TXVECTOR as input
NonHtReferenceRateCallback GetNonHtReferenceRateCallback; ///< Callback to calculate non-HT reference rate of this WifiModeItem
ModeAllowedCallback IsModeAllowedCallback; ///< Callback to check whether the combination of <MCS, channel width (MHz), NSS> is allowed
};
/**