diff --git a/src/devices/wifi/dca-txop.cc b/src/devices/wifi/dca-txop.cc --- a/src/devices/wifi/dca-txop.cc +++ b/src/devices/wifi/dca-txop.cc @@ -279,14 +279,14 @@ DcaTxop::NeedRtsRetransmission (void) { WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ()); - return station->NeedRtsRetransmission (m_currentPacket); + return station->NeedRtsRetransmission (&m_currentHdr); } bool DcaTxop::NeedDataRetransmission (void) { WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ()); - return station->NeedDataRetransmission (m_currentPacket); + return station->NeedDataRetransmission (&m_currentHdr); } bool DcaTxop::NeedFragmentation (void) diff --git a/src/devices/wifi/edca-txop-n.cc b/src/devices/wifi/edca-txop-n.cc --- a/src/devices/wifi/edca-txop-n.cc +++ b/src/devices/wifi/edca-txop-n.cc @@ -413,7 +413,15 @@ { MY_DEBUG ("Cts Fail"); WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ()); - station->ReportFinalRtsFailed (); + if (m_currentHdr.IsQosData ()) + { + uint8_t tid = m_currentHdr.GetQosTid (); + station->ReportFinalRtsFailed (QosUtilsMapTidToAc (tid)); + } + else + { + station->ReportFinalRtsFailed (); + } if (!m_txFailedCallback.IsNull ()) { m_txFailedCallback (m_currentHdr); @@ -483,7 +491,15 @@ { MY_DEBUG ("Ack Fail"); WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ()); - station->ReportFinalDataFailed (); + if (m_currentHdr.IsQosData ()) + { + uint8_t tid = m_currentHdr.GetQosTid (); + station->ReportFinalDataFailed (QosUtilsMapTidToAc (tid)); + } + else + { + station->ReportFinalDataFailed (); + } if (!m_txFailedCallback.IsNull ()) { m_txFailedCallback (m_currentHdr); @@ -543,14 +559,14 @@ EdcaTxopN::NeedRtsRetransmission (void) { WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ()); - return station->NeedRtsRetransmission (m_currentPacket); + return station->NeedRtsRetransmission (&m_currentHdr); } bool EdcaTxopN::NeedDataRetransmission (void) { WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ()); - return station->NeedDataRetransmission (m_currentPacket); + return station->NeedDataRetransmission (&m_currentHdr); } void diff --git a/src/devices/wifi/mac-low.cc b/src/devices/wifi/mac-low.cc --- a/src/devices/wifi/mac-low.cc +++ b/src/devices/wifi/mac-low.cc @@ -591,8 +591,15 @@ packet->RemovePacketTag (tag); WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ()); station->ReportRxOk (rxSnr, txMode); - station->ReportRtsOk (rxSnr, txMode, tag.Get ()); - + if (m_currentHdr.IsQosData ()) + { + uint8_t tid = m_currentHdr.GetQosTid (); + station->ReportRtsOk (rxSnr, txMode, tag.Get (), QosUtilsMapTidToAc (tid)); + } + else + { + station->ReportRtsOk (rxSnr, txMode, tag.Get ()); + } m_ctsTimeoutEvent.Cancel (); NotifyCtsTimeoutResetNow (); m_listener->GotCts (rxSnr, txMode); @@ -615,7 +622,15 @@ packet->RemovePacketTag (tag); WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ()); station->ReportRxOk (rxSnr, txMode); - station->ReportDataOk (rxSnr, txMode, tag.Get ()); + if (m_currentHdr.IsQosData ()) + { + uint8_t tid = m_currentHdr.GetQosTid (); + station->ReportDataOk (rxSnr, txMode, tag.Get (), QosUtilsMapTidToAc (tid)); + } + else + { + station->ReportDataOk (rxSnr, txMode, tag.Get ()); + } bool gotAck = false; if (m_txParams.MustWaitNormalAck () && m_normalAckTimeoutEvent.IsRunning ()) @@ -930,7 +945,15 @@ // we should restart a new cts timeout now until the expected // end of rx if there was a rx start before now. WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ()); - station->ReportRtsFailed (); + if (m_currentHdr.IsQosData ()) + { + uint8_t tid = m_currentHdr.GetQosTid (); + station->ReportRtsFailed (QosUtilsMapTidToAc (tid)); + } + else + { + station->ReportRtsFailed (); + } m_currentPacket = 0; MacLowTransmissionListener *listener = m_listener; m_listener = 0; @@ -945,7 +968,15 @@ // we should restart a new ack timeout now until the expected // end of rx if there was a rx start before now. WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ()); - station->ReportDataFailed (); + if (m_currentHdr.IsQosData ()) + { + uint8_t tid = m_currentHdr.GetQosTid (); + station->ReportDataFailed (QosUtilsMapTidToAc (tid)); + } + else + { + station->ReportDataFailed (); + } MacLowTransmissionListener *listener = m_listener; m_listener = 0; listener->MissedAck (); @@ -955,7 +986,15 @@ { NS_LOG_FUNCTION (this); WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ()); - station->ReportDataFailed (); + if (m_currentHdr.IsQosData ()) + { + uint8_t tid = m_currentHdr.GetQosTid (); + station->ReportDataFailed (QosUtilsMapTidToAc (tid)); + } + else + { + station->ReportDataFailed (); + } MacLowTransmissionListener *listener = m_listener; m_listener = 0; if (m_phy->IsStateIdle ()) @@ -973,7 +1012,15 @@ { NS_LOG_FUNCTION (this); WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ()); - station->ReportDataFailed (); + if (m_currentHdr.IsQosData ()) + { + uint8_t tid = m_currentHdr.GetQosTid (); + station->ReportDataFailed (QosUtilsMapTidToAc (tid)); + } + else + { + station->ReportDataFailed (); + } MacLowTransmissionListener *listener = m_listener; m_listener = 0; if (m_phy->IsStateIdle ()) diff --git a/src/devices/wifi/wifi-remote-station-manager.cc b/src/devices/wifi/wifi-remote-station-manager.cc --- a/src/devices/wifi/wifi-remote-station-manager.cc +++ b/src/devices/wifi/wifi-remote-station-manager.cc @@ -462,10 +462,34 @@ { static TypeId tid = TypeId ("ns3::WifiRemoteStation") .SetParent () - .AddTraceSource ("Ssrc", "The value of the ssrc counter: indicates the number of retransmissions of RTS.", + .AddTraceSource ("Ssrc", "The value of the ssrc counter: indicates the number of retransmissions of RTS for non-QoS packets.", MakeTraceSourceAccessor (&WifiRemoteStation::m_ssrc)) - .AddTraceSource ("Slrc", "The value of the slrc counter: indicates the number of retransmissions of DATA.", + .AddTraceSource ("Slrc", "The value of the slrc counter: indicates the number of retransmissions of DATA for non-QoS packets.", MakeTraceSourceAccessor (&WifiRemoteStation::m_slrc)) + .AddTraceSource ("voSsrc", "The value of the ssrc counter for AC_VO access class: indicates the number of retransmissions of RTS for\ + packets belonging to voice access class.", + MakeTraceSourceAccessor (&WifiRemoteStation::m_voSsrc)) + .AddTraceSource ("voSlrc", "The value of the slrc counter AC_VO access class: indicates the number of retransmissions of DATA packets\ + belonging to voice access class.", + MakeTraceSourceAccessor (&WifiRemoteStation::m_voSlrc)) + .AddTraceSource ("viSsrc", "The value of the ssrc counter for AC_VI access class: indicates the number of retransmissions of RTS for\ + packets belonging to voice access class.", + MakeTraceSourceAccessor (&WifiRemoteStation::m_viSsrc)) + .AddTraceSource ("viSlrc", "The value of the slrc counter AC_VI access class: indicates the number of retransmissions of DATA packets\ + belonging to voice access class.", + MakeTraceSourceAccessor (&WifiRemoteStation::m_viSlrc)) + .AddTraceSource ("beSsrc", "The value of the ssrc counter for AC_BE access class: indicates the number of retransmissions of RTS for\ + packets belonging to voice access class.", + MakeTraceSourceAccessor (&WifiRemoteStation::m_beSsrc)) + .AddTraceSource ("beSlrc", "The value of the slrc counter AC_BE access class: indicates the number of retransmissions of DATA packets\ + belonging to voice access class.", + MakeTraceSourceAccessor (&WifiRemoteStation::m_beSlrc)) + .AddTraceSource ("bkSsrc", "The value of the ssrc counter for AC_BK access class: indicates the number of retransmissions of RTS for\ + packets belonging to voice access class.", + MakeTraceSourceAccessor (&WifiRemoteStation::m_bkSsrc)) + .AddTraceSource ("bkSlrc", "The value of the slrc counter AC_BK access class: indicates the number of retransmissions of DATA packets\ + belonging to voice access class.", + MakeTraceSourceAccessor (&WifiRemoteStation::m_bkSlrc)) ; return tid; } @@ -474,9 +498,27 @@ : m_state (BRAND_NEW), m_ssrc (0), m_slrc (0), + m_voSsrc (0), + m_voSlrc (0), + m_viSsrc (0), + m_viSlrc (0), + m_beSsrc (0), + m_beSlrc (0), + m_bkSsrc (0), + m_bkSlrc (0), m_avgSlrcCoefficient(0.9), m_avgSlrc (0) -{} +{ + m_qosSsrc.insert (std::make_pair (AC_VO, &m_voSsrc)); + m_qosSsrc.insert (std::make_pair (AC_VI, &m_viSsrc)); + m_qosSsrc.insert (std::make_pair (AC_BE, &m_beSsrc)); + m_qosSsrc.insert (std::make_pair (AC_BK, &m_bkSsrc)); + + m_qosSlrc.insert (std::make_pair (AC_VO, &m_voSlrc)); + m_qosSlrc.insert (std::make_pair (AC_VI, &m_viSlrc)); + m_qosSlrc.insert (std::make_pair (AC_BE, &m_beSlrc)); + m_qosSlrc.insert (std::make_pair (AC_BK, &m_bkSlrc)); +} WifiRemoteStation::~WifiRemoteStation () {} @@ -675,15 +717,31 @@ } } bool -WifiRemoteStation::NeedRtsRetransmission (Ptr packet) +WifiRemoteStation::NeedRtsRetransmission (const WifiMacHeader *hdr) { - return (m_ssrc < GetManager ()->GetMaxSsrc ()); + if (hdr->IsQosData ()) + { + AccessClass ac = QosUtilsMapTidToAc (hdr->GetQosTid ()); + return ((*m_qosSsrc.find (ac)->second) < GetManager ()->GetMaxSsrc ()); + } + else + { + return (m_ssrc < GetManager ()->GetMaxSsrc ()); + } } bool -WifiRemoteStation::NeedDataRetransmission (Ptr packet) +WifiRemoteStation::NeedDataRetransmission (const WifiMacHeader *hdr) { - return (m_slrc < GetManager ()->GetMaxSlrc ()); + if (hdr->IsQosData ()) + { + AccessClass ac = QosUtilsMapTidToAc (hdr->GetQosTid ()); + return ((*m_qosSlrc.find (ac)->second) < GetManager ()->GetMaxSlrc ()); + } + else + { + return (m_slrc < GetManager ()->GetMaxSlrc ()); + } } bool @@ -745,55 +803,128 @@ } void -WifiRemoteStation::ReportRtsFailed (void) +WifiRemoteStation::ReportRtsFailed (enum AccessClass ac) { - m_ssrc++; + if (ac == AC_UNDEF) + { + NS_LOG_INFO ("Access class not supported"); + NS_ASSERT (false); + } + else if (ac == AC_BE_NQOS) + { + m_ssrc++; + } + else + { + (*m_qosSsrc.find (ac)->second)++; + } GetManager ()->NotifyTxRtsFailed (m_address); DoReportRtsFailed (); } void -WifiRemoteStation::ReportDataFailed (void) +WifiRemoteStation::ReportDataFailed (enum AccessClass ac) { - m_slrc++; + if (ac == AC_UNDEF) + { + NS_LOG_INFO ("Access class not supported"); + NS_ASSERT (false); + } + else if (ac == AC_BE_NQOS) + { + m_slrc++; + } + else + { + (*m_qosSlrc.find (ac)->second)++; + } GetManager ()->NotifyTxDataFailed (m_address); DoReportDataFailed (); } void -WifiRemoteStation::ReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr) +WifiRemoteStation::ReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr, enum AccessClass ac) { - m_ssrc = 0; + if (ac == AC_UNDEF) + { + NS_LOG_INFO ("Access class not supported"); + NS_ASSERT (false); + } + else if (ac == AC_BE_NQOS) + { + m_ssrc = 0; + } + else + { + *m_qosSsrc.find (ac)->second = 0; + } DoReportRtsOk (ctsSnr, ctsMode, rtsSnr); } void -WifiRemoteStation::ReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr) +WifiRemoteStation::ReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr, enum AccessClass ac) { m_avgSlrc = m_avgSlrc * m_avgSlrcCoefficient + (double) m_slrc * (1 - m_avgSlrcCoefficient); - m_slrc = 0; + if (ac == AC_UNDEF) + { + NS_LOG_INFO ("Access class not supported"); + NS_ASSERT (false); + } + else if (ac == AC_BE_NQOS) + { + m_slrc = 0; + } + else + { + *m_qosSlrc.find (ac)->second = 0; + } DoReportDataOk (ackSnr, ackMode, dataSnr); } void -WifiRemoteStation::ReportFinalRtsFailed (void) +WifiRemoteStation::ReportFinalRtsFailed (enum AccessClass ac) { - m_ssrc = 0; + if (ac == AC_UNDEF) + { + NS_LOG_INFO ("Access class not supported"); + NS_ASSERT (false); + } + else if (ac == AC_BE_NQOS) + { + m_ssrc = 0; + } + else + { + *m_qosSsrc.find (ac)->second = 0; + } GetManager ()->NotifyTxFinalRtsFailed (m_address); DoReportFinalRtsFailed (); } void -WifiRemoteStation::ReportFinalDataFailed (void) +WifiRemoteStation::ReportFinalDataFailed (enum AccessClass ac) { - m_slrc = 0; + if (ac == AC_UNDEF) + { + NS_LOG_INFO ("Access class not supported"); + NS_ASSERT (false); + } + else if (ac == AC_BE_NQOS) + { + m_slrc = 0; + } + else + { + *m_qosSlrc.find (ac)->second = 0; + } GetManager ()->NotifyTxFinalDataFailed (m_address); DoReportFinalDataFailed (); } void -WifiRemoteStation::ReportRxOk (double rxSnr, WifiMode txMode) +WifiRemoteStation::ReportRxOk (double rxSnr, WifiMode txMode, enum AccessClass ac) { + //How should we use 'ac' parameter here? DoReportRxOk (rxSnr, txMode); } } // namespace ns3 diff --git a/src/devices/wifi/wifi-remote-station-manager.h b/src/devices/wifi/wifi-remote-station-manager.h --- a/src/devices/wifi/wifi-remote-station-manager.h +++ b/src/devices/wifi/wifi-remote-station-manager.h @@ -1,6 +1,7 @@ /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ /* * Copyright (c) 2005,2006,2007 INRIA + * Copyright (c) 2009 MIRKO BANCHI * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -16,17 +17,21 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Author: Mathieu Lacage + * Author: Mirko Banchi */ #ifndef WIFI_REMOTE_STATION_MANAGER_H #define WIFI_REMOTE_STATION_MANAGER_H #include #include +#include #include "ns3/mac48-address.h" #include "ns3/packet.h" #include "ns3/object.h" #include "ns3/traced-value.h" +#include "ns3/wifi-mac-header.h" #include "wifi-mode.h" +#include "qos-utils.h" namespace ns3 { @@ -224,35 +229,47 @@ */ WifiMode GetRtsMode (Ptr packet); /** + * \param ac Represents access class of the packet for which a rts was transmitted. + * * Should be invoked whenever the RtsTimeout associated to a transmission * attempt expires. */ - void ReportRtsFailed (void); + void ReportRtsFailed (enum AccessClass ac = AC_BE_NQOS); /** + * \param ac Access class which failed data belongs. + * * Should be invoked whenever the AckTimeout associated to a transmission * attempt expires. */ - void ReportDataFailed (void); + void ReportDataFailed (enum AccessClass ac = AC_BE_NQOS); /** + * \param ac Represents access class of the packet for which the rts was transmitted. + * * Should be invoked whenever we receive the Cts associated to an RTS * we just sent. */ - void ReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr); + void ReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr, enum AccessClass ac = AC_BE_NQOS); /** + * \param ac Access class which correct received data belongs. + * * Should be invoked whenever we receive the Ack associated to a data packet * we just sent. */ - void ReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr); + void ReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr, enum AccessClass ac = AC_BE_NQOS); /** + * \param ac Represents access class of the packet for which a rts was transmitted. + * * Should be invoked after calling ReportRtsFailed if * NeedRtsRetransmission returns false */ - void ReportFinalRtsFailed (void); + void ReportFinalRtsFailed (enum AccessClass ac = AC_BE_NQOS); /** + * \param ac Access class which failed data belongs. + * * Should be invoked after calling ReportDataFailed if * NeedDataRetransmission returns false */ - void ReportFinalDataFailed (void); + void ReportFinalDataFailed (enum AccessClass ac = AC_BE_NQOS); /** * \param rxSnr the snr of the packet received @@ -260,7 +277,7 @@ * * Should be invoked whenever a packet is successfully received. */ - void ReportRxOk (double rxSnr, WifiMode txMode); + void ReportRxOk (double rxSnr, WifiMode txMode, enum AccessClass ac = AC_BE_NQOS); /** * \param packet the packet to send @@ -269,17 +286,17 @@ */ virtual bool NeedRts (Ptr packet); /** - * \param packet the packet to send + * \param hdr the header of the packet to send * \returns true if we want to restart a failed RTS/CTS * handshake, false otherwise. */ - virtual bool NeedRtsRetransmission (Ptr packet); + virtual bool NeedRtsRetransmission (const WifiMacHeader *hdr); /** - * \param packet the packet to send + * \param hdr the header of the packet to send * \returns true if we want to resend a packet * after a failed transmission attempt, false otherwise. */ - virtual bool NeedDataRetransmission (Ptr packet); + virtual bool NeedDataRetransmission (const WifiMacHeader *hdr); /** * \param packet the packet to send @@ -361,6 +378,21 @@ SupportedModes m_modes; TracedValue m_ssrc; TracedValue m_slrc; + /* voice access class retry counters */ + TracedValue m_voSsrc; + TracedValue m_voSlrc; + /* video access class retry counters */ + TracedValue m_viSsrc; + TracedValue m_viSlrc; + /* best-effort access class retry counters */ + TracedValue m_beSsrc; + TracedValue m_beSlrc; + /* background access class retry counters */ + TracedValue m_bkSsrc; + TracedValue m_bkSlrc; + /* next two maps are defined for an easy access to qos retry counters */ + std::map* > m_qosSsrc; + std::map* > m_qosSlrc; double m_avgSlrcCoefficient; double m_avgSlrc; Mac48Address m_address;