wifi tx duration calculations moved from InterferenceHelper to WifiPhy

This commit is contained in:
Nicola Baldo
2011-05-09 22:03:43 +02:00
parent 041b7f3341
commit 7ae478396b
9 changed files with 269 additions and 235 deletions

View File

@@ -83,6 +83,16 @@ objects. The implementation of <b>int64x64_t</b> is based on the previously-exis
<h2>Changes to existing API:</h2>
<ul>
<li><b>Wifi TX duration calculation moved from InterferenceHelper to WifiPhy</b>
<p>The following static methods have been moved from the InterferenceHelper class to the WifiPhy class:
<pre>
static Time CalculateTxDuration (uint32_t size, WifiMode payloadMode, enum WifiPreamble preamble);
static WifiMode GetPlcpHeaderMode (WifiMode payloadMode, WifiPreamble preamble);
static uint32_t GetPlcpHeaderDurationMicroSeconds (WifiMode payloadMode, WifiPreamble preamble);
static uint32_t GetPlcpPreambleDurationMicroSeconds (WifiMode payloadMode, WifiPreamble preamble);
static uint32_t GetPayloadDurationMicroSeconds (uint32_t size, WifiMode payloadMode);
</pre>
</p></li>
<li><b>Test cases no longer return a boolean value</b>
<p>Unit test case DoRun() functions no longer return a bool value. Now, they don't return a value at all. The motivation for this change was to disallow users from merely returning "true" from a test case to force an error to be recorded. Instead, test case macros should be used.
</p></li>

View File

@@ -189,211 +189,6 @@ InterferenceHelper::GetEnergyDuration (double energyW)
return end > now ? end - now : MicroSeconds (0);
}
WifiMode
InterferenceHelper::GetPlcpHeaderMode (WifiMode payloadMode, WifiPreamble preamble)
{
switch (payloadMode.GetModulationClass ())
{
case WIFI_MOD_CLASS_OFDM:
{
switch (payloadMode.GetBandwidth ())
{
case 5000000:
return WifiPhy::GetOfdmRate1_5MbpsBW5MHz ();
case 10000000:
return WifiPhy::GetOfdmRate3MbpsBW10MHz ();
default:
// IEEE Std 802.11-2007, 17.3.2
// actually this is only the first part of the PlcpHeader,
// because the last 16 bits of the PlcpHeader are using the
// same mode of the payload
return WifiPhy::GetOfdmRate6Mbps ();
}
}
case WIFI_MOD_CLASS_ERP_OFDM:
return WifiPhy::GetErpOfdmRate6Mbps ();
case WIFI_MOD_CLASS_DSSS:
if (preamble == WIFI_PREAMBLE_LONG)
{
// IEEE Std 802.11-2007, sections 15.2.3 and 18.2.2.1
return WifiPhy::GetDsssRate1Mbps ();
}
else // WIFI_PREAMBLE_SHORT
{
// IEEE Std 802.11-2007, section 18.2.2.2
return WifiPhy::GetDsssRate2Mbps ();
}
default:
NS_FATAL_ERROR ("unsupported modulation class");
return WifiMode ();
}
}
uint32_t
InterferenceHelper::GetPlcpHeaderDurationMicroSeconds (WifiMode payloadMode, WifiPreamble preamble)
{
switch (payloadMode.GetModulationClass ())
{
case WIFI_MOD_CLASS_OFDM:
{
switch (payloadMode.GetBandwidth ())
{
case 20000000:
default:
// IEEE Std 802.11-2007, section 17.3.3 and figure 17-4
// also section 17.3.2.3, table 17-4
// We return the duration of the SIGNAL field only, since the
// SERVICE field (which strictly speaking belongs to the PLCP
// header, see section 17.3.2 and figure 17-1) is sent using the
// payload mode.
return 4;
case 10000000:
// IEEE Std 802.11-2007, section 17.3.2.3, table 17-4
return 8;
case 5000000:
// IEEE Std 802.11-2007, section 17.3.2.3, table 17-4
return 16;
}
}
case WIFI_MOD_CLASS_ERP_OFDM:
return 16;
case WIFI_MOD_CLASS_DSSS:
if (preamble == WIFI_PREAMBLE_SHORT)
{
// IEEE Std 802.11-2007, section 18.2.2.2 and figure 18-2
return 24;
}
else // WIFI_PREAMBLE_LONG
{
// IEEE Std 802.11-2007, sections 18.2.2.1 and figure 18-1
return 48;
}
default:
NS_FATAL_ERROR ("unsupported modulation class");
return 0;
}
}
uint32_t
InterferenceHelper::GetPlcpPreambleDurationMicroSeconds (WifiMode payloadMode, WifiPreamble preamble)
{
switch (payloadMode.GetModulationClass ())
{
case WIFI_MOD_CLASS_OFDM:
{
switch (payloadMode.GetBandwidth ())
{
case 20000000:
default:
// IEEE Std 802.11-2007, section 17.3.3, figure 17-4
// also section 17.3.2.3, table 17-4
return 16;
case 10000000:
// IEEE Std 802.11-2007, section 17.3.3, table 17-4
// also section 17.3.2.3, table 17-4
return 32;
case 5000000:
// IEEE Std 802.11-2007, section 17.3.3
// also section 17.3.2.3, table 17-4
return 64;
}
}
case WIFI_MOD_CLASS_ERP_OFDM:
return 4;
case WIFI_MOD_CLASS_DSSS:
if (preamble == WIFI_PREAMBLE_SHORT)
{
// IEEE Std 802.11-2007, section 18.2.2.2 and figure 18-2
return 72;
}
else // WIFI_PREAMBLE_LONG
{
// IEEE Std 802.11-2007, sections 18.2.2.1 and figure 18-1
return 144;
}
default:
NS_FATAL_ERROR ("unsupported modulation class");
return 0;
}
}
uint32_t
InterferenceHelper::GetPayloadDurationMicroSeconds (uint32_t size, WifiMode payloadMode)
{
NS_LOG_FUNCTION (size << payloadMode);
switch (payloadMode.GetModulationClass ())
{
case WIFI_MOD_CLASS_OFDM:
case WIFI_MOD_CLASS_ERP_OFDM:
{
// IEEE Std 802.11-2007, section 17.3.2.3, table 17-4
// corresponds to T_{SYM} in the table
uint32_t symbolDurationUs;
switch (payloadMode.GetBandwidth ())
{
case 20000000:
default:
symbolDurationUs = 4;
break;
case 10000000:
symbolDurationUs = 8;
break;
case 5000000:
symbolDurationUs = 16;
break;
}
// IEEE Std 802.11-2007, section 17.3.2.2, table 17-3
// corresponds to N_{DBPS} in the table
double numDataBitsPerSymbol = payloadMode.GetDataRate () * symbolDurationUs / 1e6;
// IEEE Std 802.11-2007, section 17.3.5.3, equation (17-11)
uint32_t numSymbols = lrint (ceil ((16 + size * 8.0 + 6.0) / numDataBitsPerSymbol));
// Add signal extension for ERP PHY
if (payloadMode.GetModulationClass () == WIFI_MOD_CLASS_ERP_OFDM)
{
return numSymbols * symbolDurationUs + 6;
}
else
{
return numSymbols * symbolDurationUs;
}
}
case WIFI_MOD_CLASS_DSSS:
// IEEE Std 802.11-2007, section 18.2.3.5
NS_LOG_LOGIC (" size=" << size
<< " mode=" << payloadMode
<< " rate=" << payloadMode.GetDataRate () );
return lrint (ceil ((size * 8.0) / (payloadMode.GetDataRate () / 1.0e6)));
default:
NS_FATAL_ERROR ("unsupported modulation class");
return 0;
}
}
Time
InterferenceHelper::CalculateTxDuration (uint32_t size, WifiMode payloadMode, WifiPreamble preamble)
{
uint32_t duration = GetPlcpPreambleDurationMicroSeconds (payloadMode, preamble)
+ GetPlcpHeaderDurationMicroSeconds (payloadMode, preamble)
+ GetPayloadDurationMicroSeconds (size, payloadMode);
return MicroSeconds (duration);
}
void
InterferenceHelper::AppendEvent (Ptr<InterferenceHelper::Event> event)
{
@@ -470,9 +265,9 @@ InterferenceHelper::CalculatePer (Ptr<const InterferenceHelper::Event> event, Ni
Time previous = (*j).GetTime ();
WifiMode payloadMode = event->GetPayloadMode ();
WifiPreamble preamble = event->GetPreambleType ();
WifiMode headerMode = GetPlcpHeaderMode (payloadMode, preamble);
Time plcpHeaderStart = (*j).GetTime () + MicroSeconds (GetPlcpPreambleDurationMicroSeconds (payloadMode, preamble));
Time plcpPayloadStart = plcpHeaderStart + MicroSeconds (GetPlcpHeaderDurationMicroSeconds (payloadMode, preamble));
WifiMode headerMode = WifiPhy::GetPlcpHeaderMode (payloadMode, preamble);
Time plcpHeaderStart = (*j).GetTime () + MicroSeconds (WifiPhy::GetPlcpPreambleDurationMicroSeconds (payloadMode, preamble));
Time plcpPayloadStart = plcpHeaderStart + MicroSeconds (WifiPhy::GetPlcpHeaderDurationMicroSeconds (payloadMode, preamble));
double noiseInterferenceW = (*j).GetDelta ();
double powerW = event->GetRxPowerW ();

View File

@@ -88,11 +88,6 @@ private:
Time GetEnergyDuration (double energyW);
static WifiMode GetPlcpHeaderMode (WifiMode payloadMode, WifiPreamble preamble);
static uint32_t GetPlcpHeaderDurationMicroSeconds (WifiMode payloadMode, WifiPreamble preamble);
static uint32_t GetPlcpPreambleDurationMicroSeconds (WifiMode mode, WifiPreamble preamble);
static uint32_t GetPayloadDurationMicroSeconds (uint32_t size, WifiMode payloadMode);
static Time CalculateTxDuration (uint32_t size, WifiMode payloadMode, WifiPreamble preamble);
Ptr<InterferenceHelper::Event> Add (uint32_t size, WifiMode payloadMode,
enum WifiPreamble preamble,
Time duration, double rxPower);

View File

@@ -94,6 +94,213 @@ WifiPhy::~WifiPhy ()
NS_LOG_FUNCTION (this);
}
WifiMode
WifiPhy::GetPlcpHeaderMode (WifiMode payloadMode, WifiPreamble preamble)
{
switch (payloadMode.GetModulationClass ())
{
case WIFI_MOD_CLASS_OFDM:
{
switch (payloadMode.GetBandwidth ())
{
case 5000000:
return WifiPhy::GetOfdmRate1_5MbpsBW5MHz ();
case 10000000:
return WifiPhy::GetOfdmRate3MbpsBW10MHz ();
default:
// IEEE Std 802.11-2007, 17.3.2
// actually this is only the first part of the PlcpHeader,
// because the last 16 bits of the PlcpHeader are using the
// same mode of the payload
return WifiPhy::GetOfdmRate6Mbps ();
}
}
case WIFI_MOD_CLASS_ERP_OFDM:
return WifiPhy::GetErpOfdmRate6Mbps ();
case WIFI_MOD_CLASS_DSSS:
if (preamble == WIFI_PREAMBLE_LONG)
{
// IEEE Std 802.11-2007, sections 15.2.3 and 18.2.2.1
return WifiPhy::GetDsssRate1Mbps ();
}
else // WIFI_PREAMBLE_SHORT
{
// IEEE Std 802.11-2007, section 18.2.2.2
return WifiPhy::GetDsssRate2Mbps ();
}
default:
NS_FATAL_ERROR ("unsupported modulation class");
return WifiMode ();
}
}
uint32_t
WifiPhy::GetPlcpHeaderDurationMicroSeconds (WifiMode payloadMode, WifiPreamble preamble)
{
switch (payloadMode.GetModulationClass ())
{
case WIFI_MOD_CLASS_OFDM:
{
switch (payloadMode.GetBandwidth ())
{
case 20000000:
default:
// IEEE Std 802.11-2007, section 17.3.3 and figure 17-4
// also section 17.3.2.3, table 17-4
// We return the duration of the SIGNAL field only, since the
// SERVICE field (which strictly speaking belongs to the PLCP
// header, see section 17.3.2 and figure 17-1) is sent using the
// payload mode.
return 4;
case 10000000:
// IEEE Std 802.11-2007, section 17.3.2.3, table 17-4
return 8;
case 5000000:
// IEEE Std 802.11-2007, section 17.3.2.3, table 17-4
return 16;
}
}
case WIFI_MOD_CLASS_ERP_OFDM:
return 16;
case WIFI_MOD_CLASS_DSSS:
if (preamble == WIFI_PREAMBLE_SHORT)
{
// IEEE Std 802.11-2007, section 18.2.2.2 and figure 18-2
return 24;
}
else // WIFI_PREAMBLE_LONG
{
// IEEE Std 802.11-2007, sections 18.2.2.1 and figure 18-1
return 48;
}
default:
NS_FATAL_ERROR ("unsupported modulation class");
return 0;
}
}
uint32_t
WifiPhy::GetPlcpPreambleDurationMicroSeconds (WifiMode payloadMode, WifiPreamble preamble)
{
switch (payloadMode.GetModulationClass ())
{
case WIFI_MOD_CLASS_OFDM:
{
switch (payloadMode.GetBandwidth ())
{
case 20000000:
default:
// IEEE Std 802.11-2007, section 17.3.3, figure 17-4
// also section 17.3.2.3, table 17-4
return 16;
case 10000000:
// IEEE Std 802.11-2007, section 17.3.3, table 17-4
// also section 17.3.2.3, table 17-4
return 32;
case 5000000:
// IEEE Std 802.11-2007, section 17.3.3
// also section 17.3.2.3, table 17-4
return 64;
}
}
case WIFI_MOD_CLASS_ERP_OFDM:
return 4;
case WIFI_MOD_CLASS_DSSS:
if (preamble == WIFI_PREAMBLE_SHORT)
{
// IEEE Std 802.11-2007, section 18.2.2.2 and figure 18-2
return 72;
}
else // WIFI_PREAMBLE_LONG
{
// IEEE Std 802.11-2007, sections 18.2.2.1 and figure 18-1
return 144;
}
default:
NS_FATAL_ERROR ("unsupported modulation class");
return 0;
}
}
uint32_t
WifiPhy::GetPayloadDurationMicroSeconds (uint32_t size, WifiMode payloadMode)
{
NS_LOG_FUNCTION (size << payloadMode);
switch (payloadMode.GetModulationClass ())
{
case WIFI_MOD_CLASS_OFDM:
case WIFI_MOD_CLASS_ERP_OFDM:
{
// IEEE Std 802.11-2007, section 17.3.2.3, table 17-4
// corresponds to T_{SYM} in the table
uint32_t symbolDurationUs;
switch (payloadMode.GetBandwidth ())
{
case 20000000:
default:
symbolDurationUs = 4;
break;
case 10000000:
symbolDurationUs = 8;
break;
case 5000000:
symbolDurationUs = 16;
break;
}
// IEEE Std 802.11-2007, section 17.3.2.2, table 17-3
// corresponds to N_{DBPS} in the table
double numDataBitsPerSymbol = payloadMode.GetDataRate () * symbolDurationUs / 1e6;
// IEEE Std 802.11-2007, section 17.3.5.3, equation (17-11)
uint32_t numSymbols = lrint (ceil ((16 + size * 8.0 + 6.0) / numDataBitsPerSymbol));
// Add signal extension for ERP PHY
if (payloadMode.GetModulationClass () == WIFI_MOD_CLASS_ERP_OFDM)
{
return numSymbols * symbolDurationUs + 6;
}
else
{
return numSymbols * symbolDurationUs;
}
}
case WIFI_MOD_CLASS_DSSS:
// IEEE Std 802.11-2007, section 18.2.3.5
NS_LOG_LOGIC (" size=" << size
<< " mode=" << payloadMode
<< " rate=" << payloadMode.GetDataRate () );
return lrint (ceil ((size * 8.0) / (payloadMode.GetDataRate () / 1.0e6)));
default:
NS_FATAL_ERROR ("unsupported modulation class");
return 0;
}
}
Time
WifiPhy::CalculateTxDuration (uint32_t size, WifiMode payloadMode, WifiPreamble preamble)
{
uint32_t duration = GetPlcpPreambleDurationMicroSeconds (payloadMode, preamble)
+ GetPlcpHeaderDurationMicroSeconds (payloadMode, preamble)
+ GetPayloadDurationMicroSeconds (size, payloadMode);
return MicroSeconds (duration);
}
void
WifiPhy::NotifyTxBegin (Ptr<const Packet> packet)
{

View File

@@ -239,10 +239,44 @@ public:
* \param size the number of bytes in the packet to send
* \param payloadMode the transmission mode to use for this packet
* \param preamble the type of preamble to use for this packet.
* \returns the total amount of time this PHY will stay busy for
* \return the total amount of time this PHY will stay busy for
* the transmission of these bytes.
*/
virtual Time CalculateTxDuration (uint32_t size, WifiMode payloadMode, enum WifiPreamble preamble) const = 0;
static Time CalculateTxDuration (uint32_t size, WifiMode payloadMode, enum WifiPreamble preamble);
/**
* \param payloadMode the WifiMode use for the transmission of the payload
* \param preamble the type of preamble
*
* \return the WifiMode used for the transmission of the PLCP header
*/
static WifiMode GetPlcpHeaderMode (WifiMode payloadMode, WifiPreamble preamble);
/**
*
*
* \param payloadMode the WifiMode use for the transmission of the payload
* \param preamble the type of preamble
*
* \return the duration of the PLCP header in microseconds
*/
static uint32_t GetPlcpHeaderDurationMicroSeconds (WifiMode payloadMode, WifiPreamble preamble);
/**
* \param payloadMode the WifiMode use for the transmission of the payload
* \param preamble the type of preamble
*
* \return the duration of the PLCP preamble in microseconds
*/
static uint32_t GetPlcpPreambleDurationMicroSeconds (WifiMode payloadMode, WifiPreamble preamble);
/**
* \param payloadMode the WifiMode use for the transmission of the payload
* \param preamble the type of preamble
*
* \return the duration of the payload in microseconds
*/
static uint32_t GetPayloadDurationMicroSeconds (uint32_t size, WifiMode payloadMode);
/**
* The WifiPhy::GetNModes() and WifiPhy::GetMode() methods are used

View File

@@ -717,12 +717,6 @@ YansWifiPhy::GetLastRxStartTime (void) const
return m_state->GetLastRxStartTime ();
}
Time
YansWifiPhy::CalculateTxDuration (uint32_t size, WifiMode payloadMode, enum WifiPreamble preamble) const
{
return m_interference.CalculateTxDuration (size, payloadMode, preamble);
}
double
YansWifiPhy::DbToRatio (double dB) const
{

View File

@@ -135,7 +135,6 @@ public:
virtual Time GetStateDuration (void);
virtual Time GetDelayUntilIdle (void);
virtual Time GetLastRxStartTime (void) const;
virtual Time CalculateTxDuration (uint32_t size, WifiMode payloadMode, enum WifiPreamble preamble) const;
virtual uint32_t GetNModes (void) const;
virtual WifiMode GetMode (uint32_t mode) const;
virtual double CalculateSnr (WifiMode txMode, double ber) const;

View File

@@ -29,11 +29,11 @@ NS_LOG_COMPONENT_DEFINE ("InterferenceHelperTxDurationTest");
namespace ns3 {
class InterferenceHelperTxDurationTest : public TestCase
class TxDurationTest : public TestCase
{
public:
InterferenceHelperTxDurationTest ();
virtual ~InterferenceHelperTxDurationTest ();
TxDurationTest ();
virtual ~TxDurationTest ();
virtual void DoRun (void);
private:
@@ -65,20 +65,20 @@ private:
};
InterferenceHelperTxDurationTest::InterferenceHelperTxDurationTest ()
: TestCase ("InterferenceHelper TX Duration")
TxDurationTest::TxDurationTest ()
: TestCase ("Wifi TX Duration")
{
}
InterferenceHelperTxDurationTest::~InterferenceHelperTxDurationTest ()
TxDurationTest::~TxDurationTest ()
{
}
bool
InterferenceHelperTxDurationTest::CheckPayloadDuration (uint32_t size, WifiMode payloadMode, uint32_t knownDurationMicroSeconds)
TxDurationTest::CheckPayloadDuration (uint32_t size, WifiMode payloadMode, uint32_t knownDurationMicroSeconds)
{
uint32_t calculatedDurationMicroSeconds = InterferenceHelper::GetPayloadDurationMicroSeconds (size, payloadMode);
uint32_t calculatedDurationMicroSeconds = WifiPhy::GetPayloadDurationMicroSeconds (size, payloadMode);
if (calculatedDurationMicroSeconds != knownDurationMicroSeconds)
{
std::cerr << " size=" << size
@@ -92,9 +92,9 @@ InterferenceHelperTxDurationTest::CheckPayloadDuration (uint32_t size, WifiMode
}
bool
InterferenceHelperTxDurationTest::CheckTxDuration (uint32_t size, WifiMode payloadMode, WifiPreamble preamble, uint32_t knownDurationMicroSeconds)
TxDurationTest::CheckTxDuration (uint32_t size, WifiMode payloadMode, WifiPreamble preamble, uint32_t knownDurationMicroSeconds)
{
uint32_t calculatedDurationMicroSeconds = InterferenceHelper::CalculateTxDuration (size, payloadMode, preamble).GetMicroSeconds ();
uint32_t calculatedDurationMicroSeconds = WifiPhy::CalculateTxDuration (size, payloadMode, preamble).GetMicroSeconds ();
if (calculatedDurationMicroSeconds != knownDurationMicroSeconds)
{
std::cerr << " size=" << size
@@ -109,7 +109,7 @@ InterferenceHelperTxDurationTest::CheckTxDuration (uint32_t size, WifiMode paylo
}
void
InterferenceHelperTxDurationTest::DoRun (void)
TxDurationTest::DoRun (void)
{
bool retval = true;
@@ -188,7 +188,7 @@ public:
TxDurationTestSuite::TxDurationTestSuite ()
: TestSuite ("devices-wifi-tx-duration", UNIT)
{
AddTestCase (new InterferenceHelperTxDurationTest);
AddTestCase (new TxDurationTest);
}
static TxDurationTestSuite g_txDurationTestSuite;

View File

@@ -71,7 +71,7 @@ def build(bld):
obj_test.source = [
'test/block-ack-test-suite.cc',
'test/dcf-manager-test.cc',
'test/interference-helper-tx-duration-test.cc',
'test/tx-duration-test.cc',
'test/wifi-test.cc',
]