/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* * Copyright (c) 2005,2006,2007 INRIA * * 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 * published by the Free Software Foundation; * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Author: Mathieu Lacage */ #include #include "wifi-remote-station-manager.h" #include "ns3/simulator.h" #include "ns3/assert.h" #include "ns3/log.h" #include "ns3/tag.h" #include "ns3/boolean.h" #include "ns3/double.h" #include "ns3/uinteger.h" #include "ns3/wifi-phy.h" #include "ns3/wifi-mac.h" #include "ns3/trace-source-accessor.h" #include "wifi-mac-header.h" #include "wifi-mac-trailer.h" /*************************************************************** * Packet Mode Tagger ***************************************************************/ namespace ns3 { NS_LOG_COMPONENT_DEFINE ("WifiRemoteStationManager"); class HighLatencyDataTxVectorTag : public Tag { public: HighLatencyDataTxVectorTag (); HighLatencyDataTxVectorTag (WifiTxVector dataTxVector); /** * \returns the transmission mode to use to send this packet */ WifiTxVector GetDataTxVector (void) const; static TypeId GetTypeId (void); virtual TypeId GetInstanceTypeId (void) const; virtual uint32_t GetSerializedSize (void) const; virtual void Serialize (TagBuffer i) const; virtual void Deserialize (TagBuffer i); virtual void Print (std::ostream &os) const; private: WifiTxVector m_dataTxVector; }; HighLatencyDataTxVectorTag::HighLatencyDataTxVectorTag () { } HighLatencyDataTxVectorTag::HighLatencyDataTxVectorTag (WifiTxVector dataTxVector) : m_dataTxVector (dataTxVector) { } WifiTxVector HighLatencyDataTxVectorTag::GetDataTxVector (void) const { return m_dataTxVector; } TypeId HighLatencyDataTxVectorTag::GetTypeId (void) { static TypeId tid = TypeId ("ns3::HighLatencyDataTxVectorTag") .SetParent () .SetGroupName ("Wifi") .AddConstructor () ; return tid; } TypeId HighLatencyDataTxVectorTag::GetInstanceTypeId (void) const { return GetTypeId (); } uint32_t HighLatencyDataTxVectorTag::GetSerializedSize (void) const { return sizeof (WifiTxVector); } void HighLatencyDataTxVectorTag::Serialize (TagBuffer i) const { i.Write ((uint8_t *)&m_dataTxVector, sizeof (WifiTxVector)); } void HighLatencyDataTxVectorTag::Deserialize (TagBuffer i) { i.Read ((uint8_t *)&m_dataTxVector, sizeof (WifiTxVector)); } void HighLatencyDataTxVectorTag::Print (std::ostream &os) const { os << "Data=" << m_dataTxVector; } class HighLatencyRtsTxVectorTag : public Tag { public: HighLatencyRtsTxVectorTag (); HighLatencyRtsTxVectorTag (WifiTxVector rtsTxVector); /** * \returns the transmission mode to use to send the RTS prior to the * transmission of the data packet itself. */ WifiTxVector GetRtsTxVector (void) const; static TypeId GetTypeId (void); virtual TypeId GetInstanceTypeId (void) const; virtual uint32_t GetSerializedSize (void) const; virtual void Serialize (TagBuffer i) const; virtual void Deserialize (TagBuffer i); virtual void Print (std::ostream &os) const; private: WifiTxVector m_rtsTxVector; }; HighLatencyRtsTxVectorTag::HighLatencyRtsTxVectorTag () { } HighLatencyRtsTxVectorTag::HighLatencyRtsTxVectorTag (WifiTxVector rtsTxVector) : m_rtsTxVector (rtsTxVector) { } WifiTxVector HighLatencyRtsTxVectorTag::GetRtsTxVector (void) const { return m_rtsTxVector; } TypeId HighLatencyRtsTxVectorTag::GetTypeId (void) { static TypeId tid = TypeId ("ns3::HighLatencyRtsTxVectorTag") .SetParent () .SetGroupName ("Wifi") .AddConstructor () ; return tid; } TypeId HighLatencyRtsTxVectorTag::GetInstanceTypeId (void) const { return GetTypeId (); } uint32_t HighLatencyRtsTxVectorTag::GetSerializedSize (void) const { return sizeof (WifiTxVector); } void HighLatencyRtsTxVectorTag::Serialize (TagBuffer i) const { i.Write ((uint8_t *)&m_rtsTxVector, sizeof (WifiTxVector)); } void HighLatencyRtsTxVectorTag::Deserialize (TagBuffer i) { i.Read ((uint8_t *)&m_rtsTxVector, sizeof (WifiTxVector)); } void HighLatencyRtsTxVectorTag::Print (std::ostream &os) const { os << "Rts=" << m_rtsTxVector; } class HighLatencyCtsToSelfTxVectorTag : public Tag { public: HighLatencyCtsToSelfTxVectorTag (); HighLatencyCtsToSelfTxVectorTag (WifiTxVector ctsToSelfTxVector); /** * \returns the transmission mode to use for the CTS-to-self. */ WifiTxVector GetCtsToSelfTxVector (void) const; static TypeId GetTypeId (void); virtual TypeId GetInstanceTypeId (void) const; virtual uint32_t GetSerializedSize (void) const; virtual void Serialize (TagBuffer i) const; virtual void Deserialize (TagBuffer i); virtual void Print (std::ostream &os) const; private: WifiTxVector m_ctsToSelfTxVector; }; HighLatencyCtsToSelfTxVectorTag::HighLatencyCtsToSelfTxVectorTag () { } HighLatencyCtsToSelfTxVectorTag::HighLatencyCtsToSelfTxVectorTag (WifiTxVector ctsToSelfTxVector) : m_ctsToSelfTxVector (ctsToSelfTxVector) { } WifiTxVector HighLatencyCtsToSelfTxVectorTag::GetCtsToSelfTxVector (void) const { return m_ctsToSelfTxVector; } TypeId HighLatencyCtsToSelfTxVectorTag::GetTypeId (void) { static TypeId tid = TypeId ("ns3::HighLatencyCtsToSelfTxVectorTag") .SetParent () .SetGroupName ("Wifi") .AddConstructor () ; return tid; } TypeId HighLatencyCtsToSelfTxVectorTag::GetInstanceTypeId (void) const { return GetTypeId (); } uint32_t HighLatencyCtsToSelfTxVectorTag::GetSerializedSize (void) const { return sizeof (WifiTxVector); } void HighLatencyCtsToSelfTxVectorTag::Serialize (TagBuffer i) const { i.Write ((uint8_t *)&m_ctsToSelfTxVector, sizeof (WifiTxVector)); } void HighLatencyCtsToSelfTxVectorTag::Deserialize (TagBuffer i) { i.Read ((uint8_t *)&m_ctsToSelfTxVector, sizeof (WifiTxVector)); } void HighLatencyCtsToSelfTxVectorTag::Print (std::ostream &os) const { os << "Cts To Self=" << m_ctsToSelfTxVector; } } //namespace ns3 namespace ns3 { NS_OBJECT_ENSURE_REGISTERED (WifiRemoteStationManager); TypeId WifiRemoteStationManager::GetTypeId (void) { static TypeId tid = TypeId ("ns3::WifiRemoteStationManager") .SetParent () .SetGroupName ("Wifi") .AddAttribute ("IsLowLatency", "If true, we attempt to modelize a so-called low-latency device: a device" " where decisions about tx parameters can be made on a per-packet basis and feedback about the" " transmission of each packet is obtained before sending the next. Otherwise, we modelize a " " high-latency device, that is a device where we cannot update our decision about tx parameters" " after every packet transmission.", BooleanValue (true), //this value is ignored because there is no setter MakeBooleanAccessor (&WifiRemoteStationManager::IsLowLatency), MakeBooleanChecker ()) .AddAttribute ("MaxSsrc", "The maximum number of retransmission attempts for an RTS. This value" " will not have any effect on some rate control algorithms.", UintegerValue (7), MakeUintegerAccessor (&WifiRemoteStationManager::m_maxSsrc), MakeUintegerChecker ()) .AddAttribute ("MaxSlrc", "The maximum number of retransmission attempts for a DATA packet. This value" " will not have any effect on some rate control algorithms.", UintegerValue (7), MakeUintegerAccessor (&WifiRemoteStationManager::m_maxSlrc), MakeUintegerChecker ()) .AddAttribute ("RtsCtsThreshold", "If the size of the data packet + LLC header + MAC header + FCS trailer is bigger than " "this value, we use an RTS/CTS handshake before sending the data, as per IEEE Std. 802.11-2012, Section 9.3.5. " "This value will not have any effect on some rate control algorithms.", UintegerValue (2346), MakeUintegerAccessor (&WifiRemoteStationManager::m_rtsCtsThreshold), MakeUintegerChecker ()) .AddAttribute ("FragmentationThreshold", "If the size of the data packet + LLC header + MAC header + FCS trailer is bigger" "than this value, we fragment it such that the size of the fragments are equal or smaller " "than this value, as per IEEE Std. 802.11-2012, Section 9.5. " "This value will not have any effect on some rate control algorithms.", UintegerValue (2346), MakeUintegerAccessor (&WifiRemoteStationManager::DoSetFragmentationThreshold, &WifiRemoteStationManager::DoGetFragmentationThreshold), MakeUintegerChecker ()) .AddAttribute ("NonUnicastMode", "Wifi mode used for non-unicast transmissions.", WifiModeValue (), MakeWifiModeAccessor (&WifiRemoteStationManager::m_nonUnicastMode), MakeWifiModeChecker ()) .AddAttribute ("DefaultTxPowerLevel", "Default power level to be used for transmissions. " "This is the power level that is used by all those WifiManagers that do not" "implement TX power control.", UintegerValue (0), MakeUintegerAccessor (&WifiRemoteStationManager::m_defaultTxPowerLevel), MakeUintegerChecker ()) .AddTraceSource ("MacTxRtsFailed", "The transmission of a RTS by the MAC layer has failed", MakeTraceSourceAccessor (&WifiRemoteStationManager::m_macTxRtsFailed), "ns3::Mac48Address::TracedCallback") .AddTraceSource ("MacTxDataFailed", "The transmission of a data packet by the MAC layer has failed", MakeTraceSourceAccessor (&WifiRemoteStationManager::m_macTxDataFailed), "ns3::Mac48Address::TracedCallback") .AddTraceSource ("MacTxFinalRtsFailed", "The transmission of a RTS has exceeded the maximum number of attempts", MakeTraceSourceAccessor (&WifiRemoteStationManager::m_macTxFinalRtsFailed), "ns3::Mac48Address::TracedCallback") .AddTraceSource ("MacTxFinalDataFailed", "The transmission of a data packet has exceeded the maximum number of attempts", MakeTraceSourceAccessor (&WifiRemoteStationManager::m_macTxFinalDataFailed), "ns3::Mac48Address::TracedCallback") ; return tid; } WifiRemoteStationManager::WifiRemoteStationManager () : m_htSupported (false), m_vhtSupported (false) { } WifiRemoteStationManager::~WifiRemoteStationManager () { } void WifiRemoteStationManager::DoDispose (void) { for (StationStates::const_iterator i = m_states.begin (); i != m_states.end (); i++) { delete (*i); } m_states.clear (); for (Stations::const_iterator i = m_stations.begin (); i != m_stations.end (); i++) { delete (*i); } m_stations.clear (); } void WifiRemoteStationManager::SetupPhy (Ptr phy) { //We need to track our PHY because it is the object that knows the //full set of transmit rates that are supported. We need to know //this in order to find the relevant mandatory rates when chosing a //transmit rate for automatic control responses like //acknowledgements. m_wifiPhy = phy; m_defaultTxMode = phy->GetMode (0); if (HasHtSupported () || HasVhtSupported ()) { m_defaultTxMcs = phy->GetMcs (0); } Reset (); } void WifiRemoteStationManager::SetupMac (Ptr mac) { //We need to track our MAC because it is the object that knows the //full set of interframe spaces. m_wifiMac = mac; Reset (); } void WifiRemoteStationManager::SetHtSupported (bool enable) { m_htSupported = enable; } void WifiRemoteStationManager::SetMaxSsrc (uint32_t maxSsrc) { m_maxSsrc = maxSsrc; } void WifiRemoteStationManager::SetMaxSlrc (uint32_t maxSlrc) { m_maxSlrc = maxSlrc; } void WifiRemoteStationManager::SetRtsCtsThreshold (uint32_t threshold) { m_rtsCtsThreshold = threshold; } void WifiRemoteStationManager::SetFragmentationThreshold (uint32_t threshold) { DoSetFragmentationThreshold (threshold); } bool WifiRemoteStationManager::HasHtSupported (void) const { return m_htSupported; } void WifiRemoteStationManager::SetVhtSupported (bool enable) { m_vhtSupported = enable; } bool WifiRemoteStationManager::HasVhtSupported (void) const { return m_vhtSupported; } uint32_t WifiRemoteStationManager::GetMaxSsrc (void) const { return m_maxSsrc; } uint32_t WifiRemoteStationManager::GetMaxSlrc (void) const { return m_maxSlrc; } uint32_t WifiRemoteStationManager::GetRtsCtsThreshold (void) const { return m_rtsCtsThreshold; } uint32_t WifiRemoteStationManager::GetFragmentationThreshold (void) const { return DoGetFragmentationThreshold (); } void WifiRemoteStationManager::Reset (Mac48Address address) { NS_LOG_FUNCTION (this << address); NS_ASSERT (!address.IsGroup ()); WifiRemoteStationState *state = LookupState (address); state->m_operationalRateSet.clear (); state->m_operationalMcsSet.clear (); AddSupportedMode (address, GetDefaultMode ()); AddSupportedMcs (address, GetDefaultMcs ()); } void WifiRemoteStationManager::AddSupportedMode (Mac48Address address, WifiMode mode) { NS_LOG_FUNCTION (this << address << mode); NS_ASSERT (!address.IsGroup ()); WifiRemoteStationState *state = LookupState (address); for (WifiModeListIterator i = state->m_operationalRateSet.begin (); i != state->m_operationalRateSet.end (); i++) { if ((*i) == mode) { //already in. return; } } state->m_operationalRateSet.push_back (mode); } void WifiRemoteStationManager::AddAllSupportedModes (Mac48Address address) { NS_ASSERT (!address.IsGroup ()); WifiRemoteStationState *state = LookupState (address); state->m_operationalRateSet.clear (); for (uint32_t i = 0; i < m_wifiPhy->GetNModes (); i++) { state->m_operationalRateSet.push_back (m_wifiPhy->GetMode (i)); } } void WifiRemoteStationManager::AddSupportedMcs (Mac48Address address, WifiMode mcs) { NS_LOG_FUNCTION (this << address << mcs); NS_ASSERT (!address.IsGroup ()); WifiRemoteStationState *state = LookupState (address); for (WifiModeListIterator i = state->m_operationalMcsSet.begin (); i != state->m_operationalMcsSet.end (); i++) { if ((*i) == mcs) { //already in. return; } } state->m_operationalMcsSet.push_back (mcs); } bool WifiRemoteStationManager::IsBrandNew (Mac48Address address) const { if (address.IsGroup ()) { return false; } return LookupState (address)->m_state == WifiRemoteStationState::BRAND_NEW; } std::vector WifiRemoteStationManager::GetRemoteAddresses() const { std::vector remoteAddresses; if( m_wifiMac->GetBssid() == m_wifiMac->GetAddress() )// as an AP { for (StationStates::const_iterator i = m_states.begin (); i != m_states.end (); i++) { if ((*i)->m_state == WifiRemoteStationState::GOT_ASSOC_TX_OK)// the station is associated { NS_LOG_DEBUG ("WifiRemoteStationManager::LookupState returning existing state"); remoteAddresses.push_back((*i)->m_address); } } return remoteAddresses; } else { remoteAddresses.push_back(m_wifiMac->GetBssid()); return remoteAddresses; } } bool WifiRemoteStationManager::IsAssociated (Mac48Address address) const { if (address.IsGroup ()) { return true; } return LookupState (address)->m_state == WifiRemoteStationState::GOT_ASSOC_TX_OK; } bool WifiRemoteStationManager::IsWaitAssocTxOk (Mac48Address address) const { if (address.IsGroup ()) { return false; } return LookupState (address)->m_state == WifiRemoteStationState::WAIT_ASSOC_TX_OK; } void WifiRemoteStationManager::RecordWaitAssocTxOk (Mac48Address address) { NS_ASSERT (!address.IsGroup ()); LookupState (address)->m_state = WifiRemoteStationState::WAIT_ASSOC_TX_OK; //added by zeng: to avoid bugs in association process LookupState (address)->m_assocRespTxRetryCount=0; //end } //added by zeng++++++++++++++ void WifiRemoteStationManager::ReportGotAssocTxFailed (Mac48Address address) { NS_ASSERT (!address.IsGroup ()); NS_LOG_DEBUG("association response not acked,retry="<m_assocRespTxRetryCount); LookupState (address)->m_assocRespTxRetryCount++; } bool WifiRemoteStationManager::NeedAssocRespRetransmission(Mac48Address address) { return LookupState (address)->m_assocRespTxRetryCount < 3; } //end++++++++++++++++++ void WifiRemoteStationManager::RecordGotAssocTxOk (Mac48Address address) { NS_ASSERT (!address.IsGroup ()); LookupState (address)->m_state = WifiRemoteStationState::GOT_ASSOC_TX_OK; //added by zeng: to avoid bugs in association process LookupState (address)->m_assocRespTxRetryCount=0; //end } void WifiRemoteStationManager::RecordGotAssocTxFailed (Mac48Address address) { NS_ASSERT (!address.IsGroup ()); LookupState (address)->m_state = WifiRemoteStationState::DISASSOC; //added by zeng: to avoid bugs in association process LookupState (address)->m_assocRespTxRetryCount=0; //end } void WifiRemoteStationManager::RecordDisassociated (Mac48Address address) { NS_ASSERT (!address.IsGroup ()); LookupState (address)->m_state = WifiRemoteStationState::DISASSOC; } void WifiRemoteStationManager::PrepareForQueue (Mac48Address address, const WifiMacHeader *header, Ptr packet, uint32_t fullPacketSize) { NS_LOG_FUNCTION (this << address << *header << packet << fullPacketSize); if (IsLowLatency () || address.IsGroup ()) { return; } WifiRemoteStation *station = Lookup (address, header); WifiTxVector rts = DoGetRtsTxVector (station); WifiTxVector data = DoGetDataTxVector (station, fullPacketSize); WifiTxVector ctstoself = DoGetCtsToSelfTxVector (); HighLatencyDataTxVectorTag datatag; HighLatencyRtsTxVectorTag rtstag; HighLatencyCtsToSelfTxVectorTag ctstoselftag; //first, make sure that the tag is not here anymore. ConstCast (packet)->RemovePacketTag (datatag); ConstCast (packet)->RemovePacketTag (rtstag); ConstCast (packet)->RemovePacketTag (ctstoselftag); datatag = HighLatencyDataTxVectorTag (data); rtstag = HighLatencyRtsTxVectorTag (rts); ctstoselftag = HighLatencyCtsToSelfTxVectorTag (ctstoself); //and then, add it back packet->AddPacketTag (datatag); packet->AddPacketTag (rtstag); packet->AddPacketTag (ctstoselftag); } WifiTxVector WifiRemoteStationManager::GetDataTxVector (Mac48Address address, const WifiMacHeader *header, Ptr packet, uint32_t fullPacketSize) { NS_LOG_FUNCTION (this << address << *header << packet << fullPacketSize); if (address.IsGroup ()) { WifiTxVector v; v.SetMode (GetNonUnicastMode ()); v.SetTxPowerLevel (m_defaultTxPowerLevel); v.SetChannelWidth (m_wifiPhy->GetChannelWidth ()); v.SetShortGuardInterval (m_wifiPhy->GetGuardInterval ()); v.SetNss (1); v.SetNess (0); v.SetStbc (false); return v; } if (!IsLowLatency ()) { HighLatencyDataTxVectorTag datatag; bool found; found = ConstCast (packet)->PeekPacketTag (datatag); NS_ASSERT (found); //cast found to void, to suppress 'found' set but not used //compiler warning (void) found; return datatag.GetDataTxVector (); } return DoGetDataTxVector (Lookup (address, header), fullPacketSize); } WifiTxVector WifiRemoteStationManager::GetCtsToSelfTxVector (const WifiMacHeader *header, Ptr packet) { NS_LOG_FUNCTION (this << *header << packet); if (!IsLowLatency ()) { HighLatencyCtsToSelfTxVectorTag ctstoselftag; bool found; found = ConstCast (packet)->PeekPacketTag (ctstoselftag); NS_ASSERT (found); //cast found to void, to suppress 'found' set but not used //compiler warning (void) found; return ctstoselftag.GetCtsToSelfTxVector (); } return DoGetCtsToSelfTxVector (); } WifiTxVector WifiRemoteStationManager::DoGetCtsToSelfTxVector (void) { return WifiTxVector (GetDefaultMode (), GetDefaultTxPowerLevel (), 0, m_wifiPhy->GetChannelWidth (), m_wifiPhy->GetGuardInterval (), GetNumberOfTransmitAntennas (), GetNumberOfTransmitAntennas (), false, false); } WifiTxVector WifiRemoteStationManager::GetRtsTxVector (Mac48Address address, const WifiMacHeader *header, Ptr packet) { NS_LOG_FUNCTION (this << address << *header << packet); NS_ASSERT (!address.IsGroup ()); if (!IsLowLatency ()) { HighLatencyRtsTxVectorTag rtstag; bool found; found = ConstCast (packet)->PeekPacketTag (rtstag); NS_ASSERT (found); //cast found to void, to suppress 'found' set but not used //compiler warning (void) found; return rtstag.GetRtsTxVector (); } return DoGetRtsTxVector (Lookup (address, header)); } void WifiRemoteStationManager::ReportRtsFailed (Mac48Address address, const WifiMacHeader *header) { NS_LOG_FUNCTION (this << address << *header); NS_ASSERT (!address.IsGroup ()); WifiRemoteStation *station = Lookup (address, header); station->m_ssrc++; m_macTxRtsFailed (address); DoReportRtsFailed (station); } void WifiRemoteStationManager::ReportDataFailed (Mac48Address address, const WifiMacHeader *header) { NS_LOG_FUNCTION (this << address << *header); NS_ASSERT (!address.IsGroup ()); WifiRemoteStation *station = Lookup (address, header); station->m_slrc++; m_macTxDataFailed (address); DoReportDataFailed (station); } void WifiRemoteStationManager::ReportRtsOk (Mac48Address address, const WifiMacHeader *header, double ctsSnr, WifiMode ctsMode, double rtsSnr) { NS_LOG_FUNCTION (this << address << *header << ctsSnr << ctsMode << rtsSnr); 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); } void WifiRemoteStationManager::ReportDataOk (Mac48Address address, const WifiMacHeader *header, double ackSnr, WifiMode ackMode, double dataSnr) { NS_LOG_FUNCTION (this << address << *header << ackSnr << ackMode << dataSnr); NS_ASSERT (!address.IsGroup ()); WifiRemoteStation *station = Lookup (address, header); station->m_state->m_info.NotifyTxSuccess (station->m_slrc); station->m_slrc = 0; DoReportDataOk (station, ackSnr, ackMode, dataSnr); } void WifiRemoteStationManager::ReportFinalRtsFailed (Mac48Address address, const WifiMacHeader *header) { NS_LOG_FUNCTION (this << address << *header); NS_ASSERT (!address.IsGroup ()); WifiRemoteStation *station = Lookup (address, header); station->m_state->m_info.NotifyTxFailed (); station->m_ssrc = 0; m_macTxFinalRtsFailed (address); DoReportFinalRtsFailed (station); } void WifiRemoteStationManager::ReportFinalDataFailed (Mac48Address address, const WifiMacHeader *header) { NS_LOG_FUNCTION (this << address << *header); NS_ASSERT (!address.IsGroup ()); WifiRemoteStation *station = Lookup (address, header); station->m_state->m_info.NotifyTxFailed (); station->m_slrc = 0; m_macTxFinalDataFailed (address); DoReportFinalDataFailed (station); } void WifiRemoteStationManager::ReportRxOk (Mac48Address address, const WifiMacHeader *header, double rxSnr, WifiMode txMode) { NS_LOG_FUNCTION (this << address << *header << rxSnr << txMode); if (address.IsGroup ()) { return; } WifiRemoteStation *station = Lookup (address, header); DoReportRxOk (station, rxSnr, txMode); } bool WifiRemoteStationManager::NeedRts (Mac48Address address, const WifiMacHeader *header, Ptr packet) { NS_LOG_FUNCTION (this << address << *header << packet); if (address.IsGroup ()) { return false; } bool normally = (packet->GetSize () + header->GetSize () + WIFI_MAC_FCS_LENGTH) > GetRtsCtsThreshold (); return DoNeedRts (Lookup (address, header), packet, normally); } bool WifiRemoteStationManager::NeedCtsToSelf (WifiTxVector txVector) { NS_LOG_FUNCTION (this << txVector); WifiMode mode = txVector.GetMode (); //search for the BSS Basic Rate set, if the used mode is in the basic set then there is no need for Cts To Self for (WifiModeListIterator i = m_bssBasicRateSet.begin (); i != m_bssBasicRateSet.end (); i++) { if (mode == *i) { NS_LOG_DEBUG ("WifiRemoteStationManager::NeedCtsToSelf returning false"); return false; } } if (HasHtSupported ()) { //search for the BSS Basic MCS set, if the used mode is in the basic set then there is no need for Cts To Self for (WifiModeListIterator i = m_bssBasicMcsSet.begin (); i != m_bssBasicMcsSet.end (); i++) { if (mode == *i) { NS_LOG_DEBUG ("WifiRemoteStationManager::NeedCtsToSelf returning false"); return false; } } } NS_LOG_DEBUG ("WifiRemoteStationManager::NeedCtsToSelf returning true"); return true; } bool WifiRemoteStationManager::NeedRtsRetransmission (Mac48Address address, const WifiMacHeader *header, Ptr packet) { NS_LOG_FUNCTION (this << address << packet << *header); NS_ASSERT (!address.IsGroup ()); WifiRemoteStation *station = Lookup (address, header); bool normally = station->m_ssrc < GetMaxSsrc (); NS_LOG_DEBUG ("WifiRemoteStationManager::NeedDataRetransmission count: " << station->m_ssrc << " result: " << std::boolalpha << normally); return DoNeedRtsRetransmission (station, packet, normally); } bool WifiRemoteStationManager::NeedDataRetransmission (Mac48Address address, const WifiMacHeader *header, Ptr packet) { NS_LOG_FUNCTION (this << address << packet << *header); NS_ASSERT (!address.IsGroup ()); WifiRemoteStation *station = Lookup (address, header); bool normally = station->m_slrc < GetMaxSlrc (); NS_LOG_DEBUG ("WifiRemoteStationManager::NeedDataRetransmission count: " << station->m_slrc << " result: " << std::boolalpha << normally); return DoNeedDataRetransmission (station, packet, normally); } bool WifiRemoteStationManager::NeedFragmentation (Mac48Address address, const WifiMacHeader *header, Ptr packet) { NS_LOG_FUNCTION (this << address << packet << *header); if (address.IsGroup ()) { return false; } WifiRemoteStation *station = Lookup (address, header); bool normally = (packet->GetSize () + header->GetSize () + WIFI_MAC_FCS_LENGTH) > GetFragmentationThreshold (); NS_LOG_DEBUG ("WifiRemoteStationManager::NeedFragmentation result: " << std::boolalpha << normally); return DoNeedFragmentation (station, packet, normally); } void WifiRemoteStationManager::DoSetFragmentationThreshold (uint32_t threshold) { NS_LOG_FUNCTION (this << threshold); if (threshold < 256) { /* * ASN.1 encoding of the MAC and PHY MIB (256 ... 8000) */ NS_LOG_WARN ("Fragmentation threshold should be larger than 256. Setting to 256."); m_nextFragmentationThreshold = 256; } else { /* * The length of each fragment shall be an even number of octets, except for the last fragment if an MSDU or * MMPDU, which may be either an even or an odd number of octets. */ if (threshold % 2 != 0) { NS_LOG_WARN ("Fragmentation threshold should be an even number. Setting to " << threshold - 1); m_nextFragmentationThreshold = threshold - 1; } else { m_nextFragmentationThreshold = threshold; } } } void WifiRemoteStationManager::UpdateFragmentationThreshold (void) { m_fragmentationThreshold = m_nextFragmentationThreshold; } uint32_t WifiRemoteStationManager::DoGetFragmentationThreshold (void) const { return m_fragmentationThreshold; } uint32_t WifiRemoteStationManager::GetNFragments (const WifiMacHeader *header, Ptr packet) { NS_LOG_FUNCTION (this << *header << packet); //The number of bytes a fragment can support is (Threshold - WIFI_HEADER_SIZE - WIFI_FCS). uint32_t nFragments = (packet->GetSize () / (GetFragmentationThreshold () - header->GetSize () - WIFI_MAC_FCS_LENGTH)); //If the size of the last fragment is not 0. if ((packet->GetSize () % (GetFragmentationThreshold () - header->GetSize () - WIFI_MAC_FCS_LENGTH)) > 0) { nFragments++; } NS_LOG_DEBUG ("WifiRemoteStationManager::GetNFragments returning " << nFragments); return nFragments; } uint32_t WifiRemoteStationManager::GetFragmentSize (Mac48Address address, const WifiMacHeader *header, Ptr packet, uint32_t fragmentNumber) { NS_LOG_FUNCTION (this << address << *header << packet << fragmentNumber); NS_ASSERT (!address.IsGroup ()); uint32_t nFragment = GetNFragments (header, packet); if (fragmentNumber >= nFragment) { NS_LOG_DEBUG ("WifiRemoteStationManager::GetFragmentSize returning 0"); return 0; } //Last fragment if (fragmentNumber == nFragment - 1) { uint32_t lastFragmentSize = packet->GetSize () - (fragmentNumber * (GetFragmentationThreshold () - header->GetSize () - WIFI_MAC_FCS_LENGTH)); NS_LOG_DEBUG ("WifiRemoteStationManager::GetFragmentSize returning " << lastFragmentSize); return lastFragmentSize; } //All fragments but the last, the number of bytes is (Threshold - WIFI_HEADER_SIZE - WIFI_FCS). else { uint32_t fragmentSize = GetFragmentationThreshold () - header->GetSize () - WIFI_MAC_FCS_LENGTH; NS_LOG_DEBUG ("WifiRemoteStationManager::GetFragmentSize returning " << fragmentSize); return fragmentSize; } } uint32_t WifiRemoteStationManager::GetFragmentOffset (Mac48Address address, const WifiMacHeader *header, Ptr packet, uint32_t fragmentNumber) { NS_LOG_FUNCTION (this << address << *header << packet << fragmentNumber); NS_ASSERT (!address.IsGroup ()); NS_ASSERT (fragmentNumber < GetNFragments (header, packet)); uint32_t fragmentOffset = fragmentNumber * (GetFragmentationThreshold () - header->GetSize () - WIFI_MAC_FCS_LENGTH); NS_LOG_DEBUG ("WifiRemoteStationManager::GetFragmentOffset returning " << fragmentOffset); return fragmentOffset; } bool WifiRemoteStationManager::IsLastFragment (Mac48Address address, const WifiMacHeader *header, Ptr packet, uint32_t fragmentNumber) { NS_LOG_FUNCTION (this << address << *header << packet << fragmentNumber); NS_ASSERT (!address.IsGroup ()); bool isLast = fragmentNumber == (GetNFragments (header, packet) - 1); NS_LOG_DEBUG ("WifiRemoteStationManager::IsLastFragment returning " << std::boolalpha << isLast); return isLast; } WifiMode WifiRemoteStationManager::GetControlAnswerMode (Mac48Address address, WifiMode reqMode) { /** * The standard has relatively unambiguous rules for selecting a * control response rate (the below is quoted from IEEE 802.11-2012, * Section 9.7): * * To allow the transmitting STA to calculate the contents of the * Duration/ID field, a STA responding to a received frame shall * transmit its Control Response frame (either CTS or ACK), other * than the BlockAck control frame, at the highest rate in the * BSSBasicRateSet parameter that is less than or equal to the * rate of the immediately previous frame in the frame exchange * sequence (as defined in Annex G) and that is of the same * modulation class (see Section 9.7.8) as the received frame... */ NS_LOG_FUNCTION (this << address << reqMode); WifiMode mode = GetDefaultMode (); bool found = false; //First, search the BSS Basic Rate set for (WifiModeListIterator i = m_bssBasicRateSet.begin (); i != m_bssBasicRateSet.end (); i++) { if ((!found || i->GetPhyRate (m_wifiPhy->GetChannelWidth (), 0, 1) > mode.GetPhyRate (m_wifiPhy->GetChannelWidth (), 0, 1)) && (i->GetPhyRate (m_wifiPhy->GetChannelWidth (), 0, 1) <= reqMode.GetPhyRate (m_wifiPhy->GetChannelWidth (), 0, 1)) && (i->GetConstellationSize (1) <= reqMode.GetConstellationSize (1)) && ((i->GetModulationClass () == reqMode.GetModulationClass ()) || (reqMode.GetModulationClass () == WIFI_MOD_CLASS_HT) || (reqMode.GetModulationClass () == WIFI_MOD_CLASS_VHT))) { mode = *i; //We've found a potentially-suitable transmit rate, but we //need to continue and consider all the basic rates before //we can be sure we've got the right one. found = true; } } if (HasHtSupported () || HasVhtSupported ()) { if (!found) { mode = GetDefaultMcs (); for (WifiModeListIterator i = m_bssBasicMcsSet.begin (); i != m_bssBasicMcsSet.end (); i++) { if ((!found || i->GetPhyRate (m_wifiPhy->GetChannelWidth (), 0, 1) > mode.GetPhyRate (m_wifiPhy->GetChannelWidth (), 0, 1)) && i->GetPhyRate (m_wifiPhy->GetChannelWidth (), 0, 1) <= reqMode.GetPhyRate (m_wifiPhy->GetChannelWidth (), 0, 1)) //&& thismode.GetModulationClass () == reqMode.GetModulationClass ()) //TODO: check standard { mode = *i; //We've found a potentially-suitable transmit rate, but we //need to continue and consider all the basic rates before //we can be sure we've got the right one. found = true; } } } } //If we found a suitable rate in the BSSBasicRateSet, then we are //done and can return that mode. if (found) { NS_LOG_DEBUG ("WifiRemoteStationManager::GetControlAnswerMode returning " << mode); return mode; } /** * If no suitable basic rate was found, we search the mandatory * rates. The standard (IEEE 802.11-2007, Section 9.6) says: * * ...If no rate contained in the BSSBasicRateSet parameter meets * these conditions, then the control frame sent in response to a * received frame shall be transmitted at the highest mandatory * rate of the PHY that is less than or equal to the rate of the * received frame, and that is of the same modulation class as the * received frame. In addition, the Control Response frame shall * be sent using the same PHY options as the received frame, * unless they conflict with the requirement to use the * BSSBasicRateSet parameter. * * \todo Note that we're ignoring the last sentence for now, because * there is not yet any manipulation here of PHY options. */ for (uint32_t idx = 0; idx < m_wifiPhy->GetNModes (); idx++) { WifiMode thismode = m_wifiPhy->GetMode (idx); /* If the rate: * * - is a mandatory rate for the PHY, and * - is equal to or faster than our current best choice, and * - is less than or equal to the rate of the received frame, and * - is of the same modulation class as the received frame * * ...then it's our best choice so far. */ if (thismode.IsMandatory () && (!found || thismode.GetPhyRate (m_wifiPhy->GetChannelWidth (), 0, 1) > mode.GetPhyRate (m_wifiPhy->GetChannelWidth (), 0, 1)) && (thismode.GetPhyRate (m_wifiPhy->GetChannelWidth (), 0, 1) <= reqMode.GetPhyRate (m_wifiPhy->GetChannelWidth (), 0, 1)) && (thismode.GetConstellationSize (1) <= reqMode.GetConstellationSize (1)) && ((thismode.GetModulationClass () == reqMode.GetModulationClass ()) || (reqMode.GetModulationClass () == WIFI_MOD_CLASS_HT) || (reqMode.GetModulationClass () == WIFI_MOD_CLASS_HT))) { mode = thismode; //As above; we've found a potentially-suitable transmit //rate, but we need to continue and consider all the //mandatory rates before we can be sure we've got the right one. found = true; } } if (HasHtSupported () || HasVhtSupported ()) { for (uint32_t idx = 0; idx < m_wifiPhy->GetNMcs (); idx++) { WifiMode thismode = m_wifiPhy->GetMcs (idx); if (thismode.IsMandatory () && (!found || thismode.GetPhyRate (m_wifiPhy->GetChannelWidth (), 0, 1) > mode.GetPhyRate (m_wifiPhy->GetChannelWidth (), 0, 1)) && thismode.GetPhyRate (m_wifiPhy->GetChannelWidth (), 0, 1) <= reqMode.GetPhyRate (m_wifiPhy->GetChannelWidth (), 0, 1)) //&& thismode.GetModulationClass () == reqMode.GetModulationClass ()) //TODO: check standard { mode = thismode; //As above; we've found a potentially-suitable transmit //rate, but we need to continue and consider all the //mandatory rates before we can be sure we've got the right one. found = true; } } } /** * If we still haven't found a suitable rate for the response then * someone has messed up the simulation config. This probably means * that the WifiPhyStandard is not set correctly, or that a rate that * is not supported by the PHY has been explicitly requested in a * WifiRemoteStationManager (or descendant) configuration. * * Either way, it is serious - we can either disobey the standard or * fail, and I have chosen to do the latter... */ if (!found) { NS_FATAL_ERROR ("Can't find response rate for " << reqMode); } NS_LOG_DEBUG ("WifiRemoteStationManager::GetControlAnswerMode returning " << mode); return mode; } WifiTxVector WifiRemoteStationManager::GetCtsTxVector (Mac48Address address, WifiMode rtsMode) { NS_ASSERT (!address.IsGroup ()); WifiTxVector v; v.SetMode (GetControlAnswerMode (address, rtsMode)); v.SetTxPowerLevel (DoGetCtsTxPowerLevel (address, v.GetMode ())); v.SetChannelWidth (DoGetCtsTxChannelWidth (address, v.GetMode ())); v.SetShortGuardInterval (DoGetCtsTxGuardInterval (address, v.GetMode ())); v.SetNss (DoGetCtsTxNss (address, v.GetMode ())); v.SetNess (DoGetCtsTxNess (address, v.GetMode ())); v.SetStbc (DoGetCtsTxStbc (address, v.GetMode ())); return v; } WifiTxVector WifiRemoteStationManager::GetAckTxVector (Mac48Address address, WifiMode dataMode) { NS_ASSERT (!address.IsGroup ()); WifiTxVector v; v.SetMode (GetControlAnswerMode (address, dataMode)); v.SetTxPowerLevel (DoGetAckTxPowerLevel (address, v.GetMode ())); v.SetChannelWidth (DoGetAckTxChannelWidth (address, v.GetMode ())); v.SetShortGuardInterval (DoGetAckTxGuardInterval (address, v.GetMode ())); v.SetNss (DoGetAckTxNss (address, v.GetMode ())); v.SetNess (DoGetAckTxNess (address, v.GetMode ())); v.SetStbc (DoGetAckTxStbc (address, v.GetMode ())); return v; } WifiTxVector WifiRemoteStationManager::GetBlockAckTxVector (Mac48Address address, WifiMode blockAckReqMode) { NS_ASSERT (!address.IsGroup ()); WifiTxVector v; v.SetMode (GetControlAnswerMode (address, blockAckReqMode)); v.SetTxPowerLevel (DoGetBlockAckTxPowerLevel (address, v.GetMode ())); v.SetChannelWidth (DoGetBlockAckTxChannelWidth (address, v.GetMode ())); v.SetShortGuardInterval (DoGetBlockAckTxGuardInterval (address, v.GetMode ())); v.SetNss (DoGetBlockAckTxNss (address, v.GetMode ())); v.SetNess (DoGetBlockAckTxNess (address, v.GetMode ())); v.SetStbc (DoGetBlockAckTxStbc (address, v.GetMode ())); return v; } uint8_t WifiRemoteStationManager::DoGetCtsTxPowerLevel (Mac48Address address, WifiMode ctsMode) { return m_defaultTxPowerLevel; } uint32_t WifiRemoteStationManager::DoGetCtsTxChannelWidth (Mac48Address address, WifiMode ctsMode) { return m_wifiPhy->GetChannelWidth (); } bool WifiRemoteStationManager::DoGetCtsTxGuardInterval (Mac48Address address, WifiMode ctsMode) { return m_wifiPhy->GetGuardInterval (); } uint8_t WifiRemoteStationManager::DoGetCtsTxNss (Mac48Address address, WifiMode ctsMode) { return 1; } uint8_t WifiRemoteStationManager::DoGetCtsTxNess (Mac48Address address, WifiMode ctsMode) { return 0; } bool WifiRemoteStationManager::DoGetCtsTxStbc (Mac48Address address, WifiMode ctsMode) { return m_wifiPhy->GetStbc (); } uint8_t WifiRemoteStationManager::DoGetAckTxPowerLevel (Mac48Address address, WifiMode ackMode) { return m_defaultTxPowerLevel; } uint32_t WifiRemoteStationManager::DoGetAckTxChannelWidth (Mac48Address address, WifiMode ctsMode) { return m_wifiPhy->GetChannelWidth (); } bool WifiRemoteStationManager::DoGetAckTxGuardInterval (Mac48Address address, WifiMode ackMode) { return m_wifiPhy->GetGuardInterval (); } uint8_t WifiRemoteStationManager::DoGetAckTxNss (Mac48Address address, WifiMode ackMode) { return 1; } uint8_t WifiRemoteStationManager::DoGetAckTxNess (Mac48Address address, WifiMode ackMode) { return 0; } bool WifiRemoteStationManager::DoGetAckTxStbc (Mac48Address address, WifiMode ackMode) { return m_wifiPhy->GetStbc (); } uint8_t WifiRemoteStationManager::DoGetBlockAckTxPowerLevel (Mac48Address address, WifiMode blockAckMode) { return m_defaultTxPowerLevel; } uint32_t WifiRemoteStationManager::DoGetBlockAckTxChannelWidth (Mac48Address address, WifiMode ctsMode) { return m_wifiPhy->GetChannelWidth (); } bool WifiRemoteStationManager::DoGetBlockAckTxGuardInterval (Mac48Address address, WifiMode blockAckMode) { return m_wifiPhy->GetGuardInterval (); } uint8_t WifiRemoteStationManager::DoGetBlockAckTxNss (Mac48Address address, WifiMode blockAckMode) { return 1; } uint8_t WifiRemoteStationManager::DoGetBlockAckTxNess (Mac48Address address, WifiMode blockAckMode) { return 0; } bool WifiRemoteStationManager::DoGetBlockAckTxStbc (Mac48Address address, WifiMode blockAckMode) { return m_wifiPhy->GetStbc (); } uint8_t WifiRemoteStationManager::GetDefaultTxPowerLevel (void) const { return m_defaultTxPowerLevel; } WifiRemoteStationInfo WifiRemoteStationManager::GetInfo (Mac48Address address) { WifiRemoteStationState *state = LookupState (address); return state->m_info; } WifiRemoteStationState * WifiRemoteStationManager::LookupState (Mac48Address address) const { NS_LOG_FUNCTION (this << address); for (StationStates::const_iterator i = m_states.begin (); i != m_states.end (); i++) { if ((*i)->m_address == address) { NS_LOG_DEBUG ("WifiRemoteStationManager::LookupState returning existing state"); return (*i); } } WifiRemoteStationState *state = new WifiRemoteStationState (); state->m_state = WifiRemoteStationState::BRAND_NEW; state->m_address = address; state->m_operationalRateSet.push_back (GetDefaultMode ()); state->m_operationalMcsSet.push_back (GetDefaultMcs ()); state->m_channelWidth = m_wifiPhy->GetChannelWidth (); state->m_shortGuardInterval = m_wifiPhy->GetGuardInterval (); state->m_greenfield = m_wifiPhy->GetGreenfield (); state->m_rx = 1; state->m_tx = 1; state->m_ness = 0; state->m_aggregation = false; state->m_stbc = false; //added by zeng: state->m_assocRespTxRetryCount=0; //end const_cast (this)->m_states.push_back (state); NS_LOG_DEBUG ("WifiRemoteStationManager::LookupState returning new state"); return state; } WifiRemoteStation * WifiRemoteStationManager::Lookup (Mac48Address address, const WifiMacHeader *header) const { uint8_t tid; if (header->IsQosData ()) { tid = header->GetQosTid (); } else { tid = 0; } return Lookup (address, tid); } WifiRemoteStation * WifiRemoteStationManager::Lookup (Mac48Address address, uint8_t tid) const { NS_LOG_FUNCTION (this << address << (uint16_t)tid); for (Stations::const_iterator i = m_stations.begin (); i != m_stations.end (); i++) { if ((*i)->m_tid == tid && (*i)->m_state->m_address == address) { return (*i); } } WifiRemoteStationState *state = LookupState (address); WifiRemoteStation *station = DoCreateStation (); station->m_state = state; station->m_tid = tid; station->m_ssrc = 0; station->m_slrc = 0; const_cast (this)->m_stations.push_back (station); return station; } void WifiRemoteStationManager::AddStationHtCapabilities (Mac48Address from, HtCapabilities htCapabilities) { //Used by all stations to record HT capabilities of remote stations NS_LOG_FUNCTION (this << from << htCapabilities); WifiRemoteStationState *state; state = LookupState (from); state->m_shortGuardInterval = htCapabilities.GetShortGuardInterval20 (); if (htCapabilities.GetSupportedChannelWidth () == 1) { state->m_channelWidth = 40; } else { state->m_channelWidth = 20; } state->m_greenfield = htCapabilities.GetGreenfield (); } void WifiRemoteStationManager::AddStationVhtCapabilities (Mac48Address from, VhtCapabilities vhtCapabilities) { //Used by all stations to record VHT capabilities of remote stations NS_LOG_FUNCTION (this << from << vhtCapabilities); WifiRemoteStationState *state; state = LookupState (from); if (vhtCapabilities.GetSupportedChannelWidthSet () == 1) { state->m_channelWidth = 160; } else { state->m_channelWidth = 80; } //This is a workaround to enable users to force a 20 or 40 MHz channel for a VHT-compliant device, //since IEEE 802.11ac standard says that 20, 40 and 80 MHz channels are mandatory. if (m_wifiPhy->GetChannelWidth () < state->m_channelWidth) { state->m_channelWidth = m_wifiPhy->GetChannelWidth (); } } bool WifiRemoteStationManager::GetGreenfieldSupported (Mac48Address address) const { return LookupState (address)->m_greenfield; } WifiMode WifiRemoteStationManager::GetDefaultMode (void) const { return m_defaultTxMode; } WifiMode WifiRemoteStationManager::GetDefaultMcs (void) const { return m_defaultTxMcs; } void WifiRemoteStationManager::Reset (void) { NS_LOG_FUNCTION (this); for (Stations::const_iterator i = m_stations.begin (); i != m_stations.end (); i++) { delete (*i); } m_stations.clear (); m_bssBasicRateSet.clear (); m_bssBasicRateSet.push_back (m_defaultTxMode); m_bssBasicMcsSet.clear (); m_bssBasicMcsSet.push_back (m_defaultTxMcs); NS_ASSERT (m_defaultTxMode.IsMandatory ()); } void WifiRemoteStationManager::RemoveStation (Mac48Address sta) { NS_LOG_FUNCTION (sta); for (Stations::iterator i = m_stations.begin (); i != m_stations.end (); i++) { if((*i)->m_state->m_address == sta ) { delete (*i); m_stations.erase(i); break; } } } void WifiRemoteStationManager::AddBasicMode (WifiMode mode) { NS_LOG_FUNCTION (this << mode); if (mode.GetModulationClass () == WIFI_MOD_CLASS_HT || mode.GetModulationClass () == WIFI_MOD_CLASS_VHT) { NS_FATAL_ERROR ("It is not allowed to add a (V)HT rate in the BSSBasicRateSet!"); } for (uint32_t i = 0; i < GetNBasicModes (); i++) { if (GetBasicMode (i) == mode) { return; } } m_bssBasicRateSet.push_back (mode); } uint32_t WifiRemoteStationManager::GetNBasicModes (void) const { return m_bssBasicRateSet.size (); } WifiMode WifiRemoteStationManager::GetBasicMode (uint32_t i) const { NS_ASSERT (i < m_bssBasicRateSet.size ()); return m_bssBasicRateSet[i]; } void WifiRemoteStationManager::AddBasicMcs (WifiMode mcs) { NS_LOG_FUNCTION (this << (uint32_t)mcs.GetMcsValue ()); for (uint32_t i = 0; i < GetNBasicMcs (); i++) { if (GetBasicMcs (i) == mcs) { return; } } m_bssBasicMcsSet.push_back (mcs); } uint32_t WifiRemoteStationManager::GetNBasicMcs (void) const { return m_bssBasicMcsSet.size (); } WifiMode WifiRemoteStationManager::GetBasicMcs (uint32_t i) const { NS_ASSERT (i < m_bssBasicMcsSet.size ()); return m_bssBasicMcsSet[i]; } WifiMode WifiRemoteStationManager::GetNonUnicastMode (void) const { if (m_nonUnicastMode == WifiMode ()) { return GetBasicMode (0); } else { return m_nonUnicastMode; } } bool WifiRemoteStationManager::DoNeedRts (WifiRemoteStation *station, Ptr packet, bool normally) { return normally; } bool WifiRemoteStationManager::DoNeedRtsRetransmission (WifiRemoteStation *station, Ptr packet, bool normally) { return normally; } bool WifiRemoteStationManager::DoNeedDataRetransmission (WifiRemoteStation *station, Ptr packet, bool normally) { return normally; } bool WifiRemoteStationManager::DoNeedFragmentation (WifiRemoteStation *station, Ptr packet, bool normally) { return normally; } WifiMode WifiRemoteStationManager::GetSupported (const WifiRemoteStation *station, uint32_t i) const { NS_ASSERT (i < GetNSupported (station)); return station->m_state->m_operationalRateSet[i]; } WifiMode WifiRemoteStationManager::GetMcsSupported (const WifiRemoteStation *station, uint32_t i) const { NS_ASSERT (i < GetNMcsSupported (station)); return station->m_state->m_operationalMcsSet[i]; } uint32_t WifiRemoteStationManager::GetChannelWidth (const WifiRemoteStation *station) const { return station->m_state->m_channelWidth; } bool WifiRemoteStationManager::GetShortGuardInterval (const WifiRemoteStation *station) const { return station->m_state->m_shortGuardInterval; } bool WifiRemoteStationManager::GetGreenfield (const WifiRemoteStation *station) const { return station->m_state->m_greenfield; } bool WifiRemoteStationManager::GetAggregation (const WifiRemoteStation *station) const { return station->m_state->m_aggregation; } bool WifiRemoteStationManager::GetStbc (const WifiRemoteStation *station) const { return station->m_state->m_stbc; } uint32_t WifiRemoteStationManager::GetNumberOfReceiveAntennas (const WifiRemoteStation *station) const { return station->m_state->m_rx; } uint32_t WifiRemoteStationManager::GetNumberOfTransmitAntennas (const WifiRemoteStation *station) const { return station->m_state->m_tx; } uint32_t WifiRemoteStationManager::GetNess (const WifiRemoteStation *station) const { return station->m_state->m_ness; } uint32_t WifiRemoteStationManager::GetShortRetryCount (const WifiRemoteStation *station) const { return station->m_ssrc; } Ptr WifiRemoteStationManager::GetPhy (void) const { return m_wifiPhy; } Ptr WifiRemoteStationManager::GetMac (void) const { return m_wifiMac; } uint32_t WifiRemoteStationManager::GetLongRetryCount (const WifiRemoteStation *station) const { return station->m_slrc; } uint32_t WifiRemoteStationManager::GetNSupported (const WifiRemoteStation *station) const { return station->m_state->m_operationalRateSet.size (); } uint32_t WifiRemoteStationManager::GetNMcsSupported (const WifiRemoteStation *station) const { return station->m_state->m_operationalMcsSet.size (); } void WifiRemoteStationManager::SetDefaultTxPowerLevel (uint8_t txPower) { m_defaultTxPowerLevel = txPower; } uint32_t WifiRemoteStationManager::GetNumberOfTransmitAntennas (void) { return m_wifiPhy->GetNumberOfTransmitAntennas (); } WifiRemoteStationInfo::WifiRemoteStationInfo () : m_memoryTime (Seconds (1.0)), m_lastUpdate (Seconds (0.0)), m_failAvg (0.0) { } double WifiRemoteStationInfo::CalculateAveragingCoefficient () { double retval = std::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 = CalculateAveragingCoefficient (); m_failAvg = (double)retryCounter / (1 + (double)retryCounter) * (1.0 - coefficient) + coefficient * m_failAvg; } void WifiRemoteStationInfo::NotifyTxFailed () { double coefficient = CalculateAveragingCoefficient (); m_failAvg = (1.0 - coefficient) + coefficient * m_failAvg; } double WifiRemoteStationInfo::GetFrameErrorRate () const { return m_failAvg; } WifiRemoteStation::~WifiRemoteStation () { NS_LOG_FUNCTION (this); } } //namespace ns3