--- a/src/devices/mesh/dot11s/airtime-metric.cc Thu Feb 25 14:17:21 2010 +0100
+++ b/src/devices/mesh/dot11s/airtime-metric.cc Thu Feb 25 14:57:20 2010 +0100
@@ -34,15 +34,15 @@
"Rate should be estimated using test length.",
UintegerValue (1024),
MakeUintegerAccessor (
- &AirtimeLinkMetricCalculator::m_testLength),
+ &AirtimeLinkMetricCalculator::SetTestLength),
MakeUintegerChecker<uint16_t> (1)
)
- .AddAttribute ( "Dot11MacHeaderLength",
- "Length of the 802.11 header",
- UintegerValue (36),
+ .AddAttribute ( "Dot11MetricTid",
+ "TID used to calculate metric (data rate)",
+ UintegerValue (0),
MakeUintegerAccessor (
- &AirtimeLinkMetricCalculator::m_headerLength),
- MakeUintegerChecker<uint16_t> (0)
+ &AirtimeLinkMetricCalculator::SetHeaderTid),
+ MakeUintegerChecker<uint8_t> (0)
)
.AddAttribute ( "Dot11sMeshHeaderLength",
"Length of the mesh header",
@@ -56,36 +56,26 @@
}
AirtimeLinkMetricCalculator::AirtimeLinkMetricCalculator () :
m_overheadNanosec (0)
-{}
+{
+}
void
-AirtimeLinkMetricCalculator::SetPhyStandard (WifiPhyStandard standard)
+AirtimeLinkMetricCalculator::SetHeaderTid (uint8_t tid)
{
- switch (standard) {
- case WIFI_PHY_STANDARD_80211a:
- case WIFI_PHY_STANDARD_holland:
- // 2 * PREAMBLE + DIFS + SIFS + ACK
- m_overheadNanosec = (2 * 16 + 34 + 16 + 44) * 1000;
- break;
- case WIFI_PHY_STANDARD_80211b:
- m_overheadNanosec = (2 * 144 + 50 + 16 + 304) * 1000;
- break;
- case WIFI_PHY_STANDARD_80211_10Mhz:
- m_overheadNanosec = (2 * 32 + 58 + 32 + 88) * 1000;
- break;
- case WIFI_PHY_STANDARD_80211_5Mhz:
- m_overheadNanosec = (2 * 64 + 106 + 64 + 176) * 1000;
- break;
- default:
- NS_ASSERT (false);
- break;
- }
+ m_testHeader.SetDsFrom ();
+ m_testHeader.SetDsTo ();
+ m_testHeader.SetQosTid (tid);
+}
+void
+AirtimeLinkMetricCalculator::SetTestLength (uint16_t testLength)
+{
+ m_testFrame = Create<Packet> (testLength + 6 /*Mesh header*/ + 36/*802.11 header*/);
}
uint32_t
AirtimeLinkMetricCalculator::CalculateMetric (Mac48Address peerAddress, Ptr<MeshWifiInterfaceMac> mac)
{
/* Airtime link metric is defined in 11B.10 of 802.11s Draft D3.0 as:
*
- * airtime = (O + Bt/r)* (1 + average retry counter), where
+ * airtime = (O + Bt/r) / (1 - frame error rate), where
* o -- the PHY dependent channel access which includes frame headers, training sequences,
* access protocol frames, etc.
* bt -- the test packet length in bits (8192 by default),
@@ -93,22 +83,23 @@
*
* Final result is expressed in units of 0.01 Time Unit = 10.24 us (as required by 802.11s draft)
*/
-
- //const double sec2ns = 1e9; // seconds -> nanoseconds conversion factor
- //const double ns2tu = 10240; // nanoseconds -> 0.01 TU conversion factor
-
- // WifiRemoteStation * station = mac->GetStationManager ()->Lookup (peerAddress);
- //NS_ASSERT (station != 0);
- //NS_ASSERT (m_overheadNanosec != 0);
- //Ptr<Packet> test_frame = Create<Packet> (m_testLength + m_meshHeaderLength);
- //uint32_t rate = station->GetDataMode (peerAddress, test_frame, m_testLength + m_meshHeaderLength).GetDataRate ();
- //uint32_t payload_nanosec = (uint32_t) ((double) ((m_testLength + m_meshHeaderLength) * 8 /*octets -> bits*/) * sec2ns / ((double) rate));
- //uint32_t header_nanosec = (uint32_t) ((double) (m_headerLength * 8 /*octets -> bits*/* sec2ns)
- // / ((double) mac->GetStationManager () -> GetBasicMode (0).GetDataRate ()));
- //uint32_t metric = (uint32_t) (((double) (payload_nanosec + header_nanosec + m_overheadNanosec)) / ns2tu
- // * (station->GetAvgSlrc () + 1));
- //return metric;
- return 0;
+ NS_ASSERT (!peerAddress.IsGroup ());
+ //obtain current rate:
+ WifiMode mode = mac->GetStationManager ()->GetDataMode (peerAddress, &m_testHeader, m_testFrame, m_testFrame->GetSize ());
+ //obtain frame error rate:
+ double failAvg = mac->GetStationManager ()->Lookup (peerAddress, &m_testHeader)->m_state->m_info.GetFrameErrorRate ();
+ NS_ASSERT (failAvg < 1.0);
+ //calculate metric
+ uint32_t metric = (uint32_t)((double)(/*Overhead + payload*/
+ mac->GetPifs () + mac->GetSlot () + mac->GetEifsNoDifs () + //DIFS + SIFS + AckTxTime = PIFS + SLOT + EifsNoDifs
+ mac->GetWifiPhy () ->CalculateTxDuration (m_testFrame->GetSize (), mode, WIFI_PREAMBLE_LONG)
+ ).GetMicroSeconds () / (10.24 * (1.0 - failAvg)));
+ std::cout << "pure overhead is " << (uint32_t)((double)(/*Overhead + payload*/
+ mac->GetPifs () + mac->GetSlot () + mac->GetEifsNoDifs ()
+ ).GetMicroSeconds ()/10.24) << "\n";
+ std::cout << "mode is:" << mode.GetDataRate () << "\n";
+ std::cout << "Metric is :" << metric << "\n";
+ return metric;
}
} //namespace dot11s
} //namespace ns3
--- a/src/devices/mesh/dot11s/airtime-metric.h Thu Feb 25 14:17:21 2010 +0100
+++ b/src/devices/mesh/dot11s/airtime-metric.h Thu Feb 25 14:57:20 2010 +0100
@@ -44,8 +44,9 @@
public:
AirtimeLinkMetricCalculator ();
static TypeId GetTypeId ();
- void SetPhyStandard (WifiPhyStandard standard);
uint32_t CalculateMetric (Mac48Address peerAddress, Ptr<MeshWifiInterfaceMac> mac);
+ void SetTestLength (uint16_t testLength);
+ void SetHeaderTid (uint8_t tid);
private:
/// Overhead expressed in nanoseconds:DIFS + SIFS + 2 * PREAMBLE + ACK
uint32_t m_overheadNanosec;
@@ -55,6 +56,8 @@
uint16_t m_headerLength;
/// meshHeader length (minimum 6 octets)
uint16_t m_meshHeaderLength;
+ Ptr<Packet> m_testFrame;
+ WifiMacHeader m_testHeader;
};
} //namespace dot11s
} //namespace ns3
--- a/src/devices/mesh/dot11s/hwmp-protocol.cc Thu Feb 25 14:17:21 2010 +0100
+++ b/src/devices/mesh/dot11s/hwmp-protocol.cc Thu Feb 25 14:57:20 2010 +0100
@@ -710,7 +710,6 @@
//Installing airtime link metric:
Ptr<AirtimeLinkMetricCalculator> metric = CreateObject <AirtimeLinkMetricCalculator> ();
mac->SetLinkMetricCallback (MakeCallback (&AirtimeLinkMetricCalculator::CalculateMetric, metric));
- metric->SetPhyStandard (mac->GetPhyStandard ());
}
mp->SetRoutingProtocol (this);
// Mesh point aggregates all installed protocols
--- a/src/devices/mesh/mesh-wifi-interface-mac.cc Thu Feb 25 14:17:21 2010 +0100
+++ b/src/devices/mesh/mesh-wifi-interface-mac.cc Thu Feb 25 14:57:20 2010 +0100
@@ -196,6 +196,11 @@
m_dcfManager->SetupPhyListener (phy);
m_low->SetPhy (phy);
}
+Ptr<WifiPhy>
+MeshWifiInterfaceMac::GetWifiPhy () const
+{
+ return m_phy;
+}
void
MeshWifiInterfaceMac::SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> stationManager)
{
--- a/src/devices/mesh/mesh-wifi-interface-mac.h Thu Feb 25 14:17:21 2010 +0100
+++ b/src/devices/mesh/mesh-wifi-interface-mac.h Thu Feb 25 14:57:20 2010 +0100
@@ -91,7 +91,8 @@
virtual void SetAddress (Mac48Address address);
virtual void SetSsid (Ssid ssid);
//\}
-
+ ///Needed to obtain phy to calculate TX-duration
+ Ptr<WifiPhy> GetWifiPhy () const;
///\name Each mesh point interfaces must know the mesh point address
//\{
void SetMeshPointAddress (Mac48Address);
--- a/src/devices/wifi/wifi-remote-station-manager.cc Thu Feb 25 14:17:21 2010 +0100
+++ b/src/devices/wifi/wifi-remote-station-manager.cc Thu Feb 25 14:57:20 2010 +0100
@@ -19,6 +19,7 @@
*/
#include "wifi-remote-station-manager.h"
+#include "ns3/simulator.h"
#include "ns3/assert.h"
#include "ns3/log.h"
#include "ns3/tag.h"
@@ -177,10 +178,6 @@
.AddTraceSource ("MacTxFinalDataFailed",
"The transmission of a data packet has exceeded the maximum number of attempts",
MakeTraceSourceAccessor (&WifiRemoteStationManager::m_macTxFinalDataFailed))
- .AddAttribute("AvgSlrcCoefficient", "The weigh of the slrc count in the slrc avg calculation",
- DoubleValue (0.9),
- MakeDoubleAccessor (&WifiRemoteStationManager::m_avgSlrcCoefficient),
- MakeDoubleChecker<double> ())
;
return tid;
}
@@ -397,6 +394,7 @@
{
NS_ASSERT (!address.IsGroup ());
WifiRemoteStation *station = Lookup (address, header);
+ station->m_state->m_info.NotifyTxSuccess (station->m_ssrc);
station->m_ssrc = 0;
DoReportRtsOk (station, ctsSnr, ctsMode, rtsSnr);
}
@@ -406,7 +404,7 @@
{
NS_ASSERT (!address.IsGroup ());
WifiRemoteStation *station = Lookup (address, header);
- station->m_avgSlrc = station->m_avgSlrc * m_avgSlrcCoefficient + (double) station->m_slrc * (1 - m_avgSlrcCoefficient);
+ station->m_state->m_info.NotifyTxSuccess (station->m_slrc);
station->m_slrc = 0;
DoReportDataOk (station, ackSnr, ackMode, dataSnr);
}
@@ -415,6 +413,7 @@
{
NS_ASSERT (!address.IsGroup ());
WifiRemoteStation *station = Lookup (address, header);
+ station->m_state->m_info.NotifyTxFailed ();
station->m_ssrc = 0;
m_macTxFinalRtsFailed (address);
DoReportFinalRtsFailed (station);
@@ -424,6 +423,7 @@
{
NS_ASSERT (!address.IsGroup ());
WifiRemoteStation *station = Lookup (address, header);
+ station->m_state->m_info.NotifyTxFailed ();
station->m_slrc = 0;
m_macTxFinalDataFailed (address);
DoReportFinalDataFailed (station);
@@ -576,14 +576,6 @@
NS_ASSERT (!address.IsGroup ());
return GetControlAnswerMode (address, dataMode);
}
-double
-WifiRemoteStationManager::GetAvgSlrc (Mac48Address address) const
-{
- NS_FATAL_ERROR ("XXX");
- NS_ASSERT (!address.IsGroup ());
- WifiRemoteStation *station = Lookup (address, (uint8_t)0);
- return station->m_avgSlrc;
-}
WifiRemoteStationState *
WifiRemoteStationManager::LookupState (Mac48Address address) const
@@ -633,7 +625,6 @@
station->m_state = state;
station->m_ssrc = 0;
station->m_slrc = 0;
- station->m_avgSlrc = 0;
// XXX
const_cast<WifiRemoteStationManager *> (this)->m_stations.push_back (station);
return station;
@@ -741,5 +732,40 @@
return station->m_state->m_modes.size ();
}
+//WifiRemoteStationInfo constructor
+WifiRemoteStationInfo::WifiRemoteStationInfo () :
+ m_memoryTime (Seconds (1.0)),
+ m_lastUpdate (Seconds (0.0)),
+ m_failAvg (0.0)
+{}
+double
+WifiRemoteStationInfo::CalculateAveragingCoeffitient ()
+{
+ double retval = exp((double)
+ (m_lastUpdate.GetMicroSeconds () - Simulator::Now ().GetMicroSeconds()) / (double)m_memoryTime.GetMicroSeconds ()
+ );
+ m_lastUpdate = Simulator::Now ();
+ return retval;
+}
+
+void
+WifiRemoteStationInfo::NotifyTxSuccess (uint32_t retryCounter)
+{
+ double coefficient = CalculateAveragingCoeffitient ();
+ m_failAvg = (double)retryCounter / (1 + (double) retryCounter) * (1.0 - coefficient) + coefficient * m_failAvg;
+}
+
+void
+WifiRemoteStationInfo::NotifyTxFailed ()
+{
+ double coefficient = CalculateAveragingCoeffitient ();
+ m_failAvg = (1.0 - coefficient) + coefficient * m_failAvg;
+}
+
+double
+WifiRemoteStationInfo::GetFrameErrorRate () const
+{
+ return m_failAvg;
+}
} // namespace ns3
--- a/src/devices/wifi/wifi-remote-station-manager.h Thu Feb 25 14:17:21 2010 +0100
+++ b/src/devices/wifi/wifi-remote-station-manager.h Thu Feb 25 14:57:20 2010 +0100
@@ -26,6 +26,7 @@
#include "ns3/traced-callback.h"
#include "ns3/packet.h"
#include "ns3/object.h"
+#include "ns3/nstime.h"
#include "wifi-mode.h"
namespace ns3 {
@@ -233,11 +234,8 @@
* handshake.
*/
WifiMode GetAckMode (Mac48Address address, WifiMode dataMode);
- /**
- * \return exponentially weighted average SLRC, this is used by Airtime link metric of 802.11s
- */
- double GetAvgSlrc (Mac48Address address) const;
-
+ /// Find a remote station by its remote address and TID taken from MAC header
+ WifiRemoteStation *Lookup (Mac48Address address, const WifiMacHeader *header) const;
protected:
virtual void DoDispose (void);
// for convenience
@@ -336,7 +334,6 @@
double rxSnr, WifiMode txMode) = 0;
WifiRemoteStationState *LookupState (Mac48Address address) const;
- WifiRemoteStation *Lookup (Mac48Address address, const WifiMacHeader *header) const;
WifiRemoteStation *Lookup (Mac48Address address, uint8_t tid) const;
WifiMode GetControlAnswerMode (Mac48Address address, WifiMode reqMode);
uint32_t GetNFragments (Ptr<const Packet> packet);
@@ -375,6 +372,41 @@
TracedCallback<Mac48Address> m_macTxFinalDataFailed;
};
+/**
+ * \brief Tid independent remote station statistics
+ *
+ * Structure is similar to struct sta_info in Linux kernel (see
+ * net/mac80211/sta_info.h)
+ */
+class WifiRemoteStationInfo
+{
+public:
+ WifiRemoteStationInfo ();
+ /**
+ * \brief Updates average frame error rate when data or RTS
+ * was transmitted successfully.
+ * \param retryCounter is slrc or ssrc value at the moment of
+ * success transmission.
+ */
+ void NotifyTxSuccess (uint32_t retryCounter);
+ /// Updates average frame error rate when final data or RTS has failed.
+ void NotifyTxFailed ();
+ /// Returns frame error rate (probability that frame is corrupted due to transmission error).
+ double GetFrameErrorRate () const;
+private:
+ /**
+ * \brief Calculate averaging coefficient for frame error rate. Depends on time of the last update.
+ * \attention Calling this method twice gives different results,
+ * because it resets time of last update.
+ */
+ double CalculateAveragingCoeffitient ();
+ ///averaging coefficient depends on the memory time
+ Time m_memoryTime;
+ ///when last update has occured
+ Time m_lastUpdate;
+ /// moving percentage of failed frames
+ double m_failAvg;
+};
struct WifiRemoteStationState
{
@@ -388,6 +420,7 @@
} m_state;
SupportedModes m_modes;
Mac48Address m_address;
+ WifiRemoteStationInfo m_info;
};
/**
@@ -403,7 +436,6 @@
struct WifiRemoteStationState *m_state;
uint32_t m_ssrc;
uint32_t m_slrc;
- double m_avgSlrc;
uint8_t m_tid;
};