--- a/src/wifi/model/wifi-phy.cc Wed Jan 28 06:34:11 2015 -0800
+++ b/src/wifi/model/wifi-phy.cc Wed Jan 28 10:11:32 2015 -0800
@@ -107,6 +107,8 @@
WifiPhy::WifiPhy ()
{
NS_LOG_FUNCTION (this);
+ m_totalAmpduSize = 0;
+ m_totalAmpduNumSymbols = 0;
}
WifiPhy::~WifiPhy ()
@@ -114,8 +116,6 @@
NS_LOG_FUNCTION (this);
}
-//Added by Ghada to support 11n
-
//return the L-SIG
WifiMode
WifiPhy::GetMFPlcpHeaderMode (WifiMode payloadMode, WifiPreamble preamble)
@@ -131,7 +131,7 @@
}
}
-Time
+Time
WifiPhy::GetPlcpHtTrainingSymbolDuration (WifiPreamble preamble, WifiTxVector txvector)
{
uint8_t Ndltf, Neltf;
@@ -160,7 +160,7 @@
case WIFI_PREAMBLE_HT_MF:
return MicroSeconds(4 + (4 * Ndltf) + (4 * Neltf));
case WIFI_PREAMBLE_HT_GF:
- return MicroSeconds((4 * Ndltf) + (4 * Neltf));
+ return MicroSeconds((4 * Ndltf) + (4 * Neltf));
default:
// no training for non HT
return MicroSeconds(0);
@@ -183,9 +183,7 @@
// no HT-SIG for non HT
return MicroSeconds(0);
}
-
}
-//end added by Ghada
WifiMode
WifiPhy::GetPlcpHeaderMode (WifiMode payloadMode, WifiPreamble preamble)
@@ -294,6 +292,7 @@
case WIFI_PREAMBLE_HT_MF:
// L-SIG
return MicroSeconds(4);
+ case WIFI_PREAMBLE_NONE:
case WIFI_PREAMBLE_HT_GF:
//L-SIG
return MicroSeconds(0);
@@ -348,8 +347,16 @@
}
}
case WIFI_MOD_CLASS_HT:
- { //IEEE 802.11n Figure 20.1 the training symbols before L_SIG or HT_SIG
- return MicroSeconds(16);
+ {
+ switch (preamble)
+ {
+ case WIFI_PREAMBLE_NONE:
+ //A-MPDU support since MPDUs inside an A-MPDU are sent without a preamble
+ return MicroSeconds(0);
+ default:
+ //IEEE 802.11n Figure 20.1 the training symbols before L_SIG or HT_SIG
+ return MicroSeconds(16);
+ }
}
case WIFI_MOD_CLASS_ERP_OFDM:
return MicroSeconds(16);
@@ -372,7 +379,7 @@
}
Time
-WifiPhy::GetPayloadDuration (uint32_t size, WifiTxVector txvector, double frequency)
+WifiPhy::GetPayloadDuration (uint32_t size, WifiTxVector txvector, WifiPreamble preamble, double frequency, uint8_t packetType, uint8_t incFlag)
{
WifiMode payloadMode=txvector.GetMode();
@@ -406,7 +413,47 @@
double numDataBitsPerSymbol = payloadMode.GetDataRate () * symbolDuration.GetNanoSeconds() / 1e9;
// (Section 18.3.5.4 "Pad bits (PAD)" Equation 18-11; IEEE Std 802.11-2012)
- uint32_t numSymbols = lrint (ceil ((16 + size * 8.0 + 6.0) / numDataBitsPerSymbol));
+ uint32_t numSymbols;
+
+ if (packetType == 1 && preamble != WIFI_PREAMBLE_NONE)
+ {
+ //First packet in an A-MPDU
+ numSymbols= ceil((16 + size * 8.0 + 6) / (numDataBitsPerSymbol));
+ if (incFlag == 1)
+ {
+ m_totalAmpduSize += size;
+ m_totalAmpduNumSymbols += numSymbols;
+ }
+ }
+ else if (packetType == 1 && preamble == WIFI_PREAMBLE_NONE)
+ {
+ //consecutive packets in an A-MPDU
+ numSymbols= ((size * 8.0) / (numDataBitsPerSymbol));
+ if (incFlag == 1)
+ {
+ m_totalAmpduSize += size;
+ m_totalAmpduNumSymbols += numSymbols;
+ }
+ }
+ else if (packetType == 2 && preamble == WIFI_PREAMBLE_NONE)
+ {
+ //last packet in an A-MPDU
+ uint32_t totalAmpduSize = m_totalAmpduSize + size;
+ numSymbols = lrint (ceil((16 + totalAmpduSize * 8.0 + 6) / (numDataBitsPerSymbol)));
+ numSymbols -= m_totalAmpduNumSymbols;
+ if (incFlag == 1)
+ {
+ m_totalAmpduSize = 0;
+ m_totalAmpduNumSymbols = 0;
+ }
+ }
+ else if (packetType == 0 && preamble != WIFI_PREAMBLE_NONE)
+ {
+ //Not an A-MPDU
+ numSymbols = lrint (ceil ((16 + size * 8.0 + 6.0) / (numDataBitsPerSymbol)));
+ }
+ else
+ NS_FATAL_ERROR ("Wrong combination of preamble and packet type");
// Add signal extension for ERP PHY
if (payloadMode.GetModulationClass () == WIFI_MOD_CLASS_ERP_OFDM)
@@ -460,9 +507,49 @@
//check tables 20-35 and 20-36 in the standard to get cases when nes =2
double Nes=1;
// IEEE Std 802.11n, section 20.3.11, equation (20-32)
- uint32_t numSymbols = lrint (m_Stbc*ceil ((16 + size * 8.0 + 6.0*Nes) / (m_Stbc* numDataBitsPerSymbol)));
+ uint32_t numSymbols;
+ if (packetType == 1 && preamble != WIFI_PREAMBLE_NONE)
+ {
+ //First packet in an A-MPDU
+ numSymbols = ceil(m_Stbc*(16 + size * 8.0 + 6*Nes) / (m_Stbc* numDataBitsPerSymbol));
+ if (incFlag == 1)
+ {
+ m_totalAmpduSize += size;
+ m_totalAmpduNumSymbols += numSymbols;
+ }
+ }
+ else if (packetType == 1 && preamble == WIFI_PREAMBLE_NONE)
+ {
+ //consecutive packets in an A-MPDU
+ numSymbols = m_Stbc* ((size * 8.0 ) / (m_Stbc* numDataBitsPerSymbol));
+ if (incFlag == 1)
+ {
+ m_totalAmpduSize += size;
+ m_totalAmpduNumSymbols += numSymbols;
+ }
+ }
+ else if (packetType == 2 && preamble == WIFI_PREAMBLE_NONE)
+ {
+ //last packet in an A-MPDU
+ uint32_t totalAmpduSize = m_totalAmpduSize+size;
+ numSymbols = lrint (m_Stbc* ceil((16 + totalAmpduSize * 8.0 + 6*Nes) / (m_Stbc* numDataBitsPerSymbol)));
+ NS_ASSERT (m_totalAmpduNumSymbols <= numSymbols);
+ numSymbols -= m_totalAmpduNumSymbols;
+ if (incFlag == 1)
+ {
+ m_totalAmpduSize = 0;
+ m_totalAmpduNumSymbols = 0;
+ }
+ }
+ else if (packetType == 0 && preamble != WIFI_PREAMBLE_NONE)
+ //Not an A-MPDU
+ {
+ numSymbols = lrint (m_Stbc*ceil ((16 + size * 8.0 + 6.0*Nes) / (m_Stbc* numDataBitsPerSymbol)));
+ }
+ else
+ NS_FATAL_ERROR ("Wrong combination of preamble and packet type");
- if (frequency >= 2400 && frequency <= 2500) //at 2.4 GHz
+ if (frequency >= 2400 && frequency <= 2500 && ((packetType == 0 && preamble != WIFI_PREAMBLE_NONE) || (packetType == 2 && preamble == WIFI_PREAMBLE_NONE))) //at 2.4 GHz
{
return Time (numSymbols * symbolDuration) + MicroSeconds(6);
}
@@ -470,6 +557,7 @@
{
return Time (numSymbols * symbolDuration);
}
+
}
case WIFI_MOD_CLASS_DSSS:
// (Section 17.2.3.6 "Long PLCP LENGTH field"; IEEE Std 802.11-2012)
@@ -485,19 +573,17 @@
}
Time
-WifiPhy::CalculateTxDuration (uint32_t size, WifiTxVector txvector, WifiPreamble preamble, double frequency)
+WifiPhy::CalculateTxDuration (uint32_t size, WifiTxVector txvector, WifiPreamble preamble, double frequency, uint8_t packetType, uint8_t incFlag)
{
- WifiMode payloadMode = txvector.GetMode ();
+ WifiMode payloadMode=txvector.GetMode();
Time duration = GetPlcpPreambleDuration (payloadMode, preamble)
+ GetPlcpHeaderDuration (payloadMode, preamble)
+ GetPlcpHtSigHeaderDuration (payloadMode, preamble)
+ GetPlcpHtTrainingSymbolDuration (preamble, txvector)
- + GetPayloadDuration (size, txvector, frequency);
+ + GetPayloadDuration (size, txvector, preamble, frequency, packetType, incFlag);
return duration;
}
-
-
void
WifiPhy::NotifyTxBegin (Ptr<const Packet> packet)
{