src/wifi/model/wifi-phy.cc
changeset 11174 780a43e4980c
parent 11119 067928a573cd
child 11196 9d8c60f0db81
--- 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)
 {