From f807067337d884c7c70fbc38fc9115d419c3287d Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Mon, 8 Oct 2007 15:43:19 +0200 Subject: [PATCH] use WifiMode rather than mode indexes in MacStations API. --- src/devices/wifi/mac-stations.cc | 127 +++++++++++++++++++++++++++++-- src/devices/wifi/mac-stations.h | 40 +++++++--- 2 files changed, 151 insertions(+), 16 deletions(-) diff --git a/src/devices/wifi/mac-stations.cc b/src/devices/wifi/mac-stations.cc index 241ce34e8..928d97b15 100644 --- a/src/devices/wifi/mac-stations.cc +++ b/src/devices/wifi/mac-stations.cc @@ -20,6 +20,7 @@ */ #include "mac-stations.h" +#include "ns3/assert.h" namespace ns3 { @@ -32,8 +33,9 @@ public: namespace ns3 { -MacStations::MacStations () - : m_nonUnicast (0) +MacStations::MacStations (WifiMode defaultTxMode) + : m_nonUnicast (0), + m_defaultTxMode (defaultTxMode) {} MacStations::~MacStations () @@ -61,7 +63,7 @@ MacStations::Lookup (Mac48Address address) return (*i).second; } } - MacStation *station = CreateStation (); + MacStation *station = CreateStation (m_defaultTxMode); m_stations.push_back (std::make_pair (address, station)); return station; } @@ -80,11 +82,17 @@ MacStations::LookupNonUnicast (void) namespace ns3 { -MacStation::MacStation () - : m_state (DISASSOC) +MacStation::WifiRate::WifiRate (WifiMode _mode, bool _isBasic) + : mode (_mode), isBasic (_isBasic) {} - +MacStation::MacStation (WifiMode txMode) + : m_state (DISASSOC), + m_defaultTxMode (txMode) +{ + NS_ASSERT (m_defaultTxMode.IsMandatory ()); + ResetModes (); +} MacStation::~MacStation () {} @@ -119,5 +127,112 @@ MacStation::RecordDisassociated (void) m_state = DISASSOC; } +void +MacStation::ResetModes (void) +{ + m_rates.clear (); + AddBasicMode (m_defaultTxMode); +} +void +MacStation::AddBasicMode (WifiMode mode) +{ + if (IsIn (mode)) + { + return; + } + m_rates.push_back (WifiRate (mode, true)); +} +void +MacStation::AddExtendedMode (WifiMode mode) +{ + if (IsIn (mode)) + { + return; + } + m_rates.push_back (WifiRate (mode, false)); +} + +bool +MacStation::IsIn (WifiMode mode) const +{ + for (WifiRates::const_iterator i = m_rates.begin (); i != m_rates.end (); i++) + { + if (i->mode == mode) + { + return true; + } + } + return false; +} + +WifiMode +MacStation::GetControlAnswerMode (WifiMode reqMode) +{ + /** + * see ieee 802.11e, section 9.6: + * + * 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) + * frames, other than the Block-Ack 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 9.79.12) and that is of the + * same modulation type as the received frame. If no rate in the + * basic rate set 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 type 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. + */ + WifiMode mode = m_defaultTxMode; + bool found = false; + + // First, search the BSS Basic Rate set + for (WifiRates::const_iterator i = m_rates.begin (); i != m_rates.end (); i++) + { + if (i->mode.GetPhyRate () > mode.GetPhyRate () && + i->mode.GetPhyRate () <= reqMode.GetPhyRate () && + i->mode.GetModulationType () == reqMode.GetModulationType () && + i->isBasic) + { + mode = i->mode; + found = true; + } + } + if (found) + { + return mode; + } + // Then, search the mandatory rates. + for (WifiRates::const_iterator i = m_rates.begin (); i != m_rates.end (); i++) + { + if (i->mode.GetPhyRate () > mode.GetPhyRate () && + i->mode.GetPhyRate () <= reqMode.GetPhyRate () && + i->mode.GetModulationType () == reqMode.GetModulationType () && + i->mode.IsMandatory ()) + { + mode = i->mode; + } + } + return mode; +} + +WifiMode +MacStation::GetCtsMode (WifiMode rtsMode) +{ + return GetControlAnswerMode (rtsMode); +} +WifiMode +MacStation::GetAckMode (WifiMode dataMode) +{ + return GetControlAnswerMode (dataMode); +} + + + } // namespace ns3 diff --git a/src/devices/wifi/mac-stations.h b/src/devices/wifi/mac-stations.h index 62a559f92..79b5bfb2a 100644 --- a/src/devices/wifi/mac-stations.h +++ b/src/devices/wifi/mac-stations.h @@ -24,6 +24,7 @@ #include #include #include "ns3/mac48-address.h" +#include "wifi-mode.h" namespace ns3 { @@ -31,7 +32,7 @@ class MacStation; class MacStations { public: - MacStations (); + MacStations (WifiMode defaultTxMode); virtual ~MacStations (); MacStation *Lookup (Mac48Address address); @@ -39,9 +40,10 @@ public: private: typedef std::list > Stations; typedef std::list >::iterator StationsI; - virtual class MacStation *CreateStation (void) = 0; + virtual class MacStation *CreateStation (WifiMode mode) = 0; Stations m_stations; MacStation *m_nonUnicast; + WifiMode m_defaultTxMode; }; } // namespace ns3 @@ -50,10 +52,13 @@ namespace ns3 { class MacStation { public: - MacStation (); - + MacStation (WifiMode defaultTxMode); virtual ~MacStation (); + void ResetModes (void); + void AddBasicMode (WifiMode mode); + void AddExtendedMode (WifiMode mode); + bool IsAssociated (void) const; bool IsWaitAssocTxOk (void) const; void RecordWaitAssocTxOk (void); @@ -62,23 +67,38 @@ public: void RecordDisassociated (void); // reception-related method - virtual void ReportRxOk (double rxSnr, uint8_t txMode) = 0; + virtual void ReportRxOk (double rxSnr, WifiMode txMode) = 0; // transmission-related methods virtual void ReportRtsFailed (void) = 0; virtual void ReportDataFailed (void) = 0; - virtual void ReportRtsOk (double ctsSnr, uint8_t ctsMode, uint8_t rtsSnr) = 0; - virtual void ReportDataOk (double ackSnr, uint8_t ackMode, uint8_t dataSnr) = 0; - virtual uint8_t GetDataMode (int size) = 0; - virtual uint8_t GetRtsMode (void) = 0; - virtual uint8_t SnrToSnr (double snr) = 0; + virtual void ReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr) = 0; + virtual void ReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr) = 0; + virtual WifiMode GetDataMode (uint32_t size) = 0; + virtual WifiMode GetRtsMode (void) = 0; + + WifiMode GetCtsMode (WifiMode rtsMode); + WifiMode GetAckMode (WifiMode dataMode); private: + struct WifiRate { + WifiRate (WifiMode mode, bool isBasic); + WifiMode mode; + bool isBasic; + }; + typedef std::vector WifiRates; +protected: + +private: + bool IsIn (WifiMode mode) const; + WifiMode GetControlAnswerMode (WifiMode reqMode); enum { DISASSOC, WAIT_ASSOC_TX_OK, GOT_ASSOC_TX_OK } m_state; + WifiRates m_rates; + WifiMode m_defaultTxMode; }; } // namespace ns3