Bug 853: Consider mandatory rates for Wi-Fi control responses
This changeset modifies the GetControlAnswerMode() method of class
WifiRemoteStationManager to correctly identify rates within the same
modulation class as the received frame, and then adds a search for a
suitable mandatory rate in the case where no suitable (per IEEE Std.
802.11-2007, Section 9.6) basic rate has been found.
I've also taken the opportunity to "tidy" the code up a bit -
primarily through renaming of variables to something more in line with
the nomenclature used in the standard.
Note that this change exposes issues in some of the test and example
code that uses the Wi-Fi models. These issues are addressed in a
following changelist.
--- a/src/devices/wifi/arf-wifi-manager.cc Wed Jun 23 06:43:21 2010 +0200
+++ b/src/devices/wifi/arf-wifi-manager.cc Wed Jun 23 08:47:29 2010 +0100
@@ -156,7 +156,7 @@
NS_LOG_DEBUG ("station=" << station << " data ok success=" << station->m_success << ", timer=" << station->m_timer);
if ((station->m_success == m_successThreshold ||
station->m_timer == m_timerThreshold) &&
- (station->m_rate < (station->m_state->m_modes.size () - 1)))
+ (station->m_rate < (station->m_state->m_operationalRateSet.size () - 1)))
{
NS_LOG_DEBUG ("station="<<station<<" inc rate");
station->m_rate++;
--- a/src/devices/wifi/wifi-mode.h Wed Jun 23 06:43:21 2010 +0200
+++ b/src/devices/wifi/wifi-mode.h Wed Jun 23 08:47:29 2010 +0100
@@ -163,6 +163,15 @@
ATTRIBUTE_HELPER_HEADER (WifiMode);
/**
+ * In various parts of the code, folk are interested in maintaining a
+ * list of transmission modes. The vector class provides a good basis
+ * for this, but we here add some syntactic sugar by defining a
+ * WifiModeList type, and a corresponding iterator.
+ */
+typedef std::vector<WifiMode> WifiModeList;
+typedef WifiModeList::const_iterator WifiModeListIterator;
+
+/**
* \brief create WifiMode class instances and keep track of them.
*
* This factory ensures that each WifiMode created has a unique name
--- a/src/devices/wifi/wifi-phy.h Wed Jun 23 06:43:21 2010 +0200
+++ b/src/devices/wifi/wifi-phy.h Wed Jun 23 08:47:29 2010 +0100
@@ -240,14 +240,42 @@
* the transmission of these bytes.
*/
virtual Time CalculateTxDuration (uint32_t size, WifiMode payloadMode, enum WifiPreamble preamble) const = 0;
-
+
/**
+ * The WifiPhy::GetNModes() and WifiPhy::GetMode() methods are used
+ * (e.g., by a WifiRemoteStationManager) to determine the set of
+ * transmission/reception modes that this WifiPhy(-derived class)
+ * can support - a set of WifiMode objects which we call the
+ * DeviceRateSet, and which is stored as WifiPhy::m_deviceRateSet.
+ *
+ * It is important to note that the DeviceRateSet is a superset (not
+ * necessarily proper) of the OperationalRateSet (which is
+ * logically, if not actually, a property of the associated
+ * WifiRemoteStationManager), which itself is a superset (again, not
+ * necessarily proper) of the BSSBasicRateSet.
+ *
* \returns the number of transmission modes supported by this PHY.
+ *
+ * \sa WifiPhy::GetMode()
*/
virtual uint32_t GetNModes (void) const = 0;
/**
+ * The WifiPhy::GetNModes() and WifiPhy::GetMode() methods are used
+ * (e.g., by a WifiRemoteStationManager) to determine the set of
+ * transmission/reception modes that this WifiPhy(-derived class)
+ * can support - a set of WifiMode objects which we call the
+ * DeviceRateSet, and which is stored as WifiPhy::m_deviceRateSet.
+ *
+ * It is important to note that the DeviceRateSet is a superset (not
+ * necessarily proper) of the OperationalRateSet (which is
+ * logically, if not actually, a property of the associated
+ * WifiRemoteStationManager), which itself is a superset (again, not
+ * necessarily proper) of the BSSBasicRateSet.
+ *
* \param mode index in array of supported modes
* \returns the mode whose index is specified.
+ *
+ * \sa WifiPhy::GetNModes()
*/
virtual WifiMode GetMode (uint32_t mode) const = 0;
/**
--- a/src/devices/wifi/wifi-remote-station-manager.cc Wed Jun 23 06:43:21 2010 +0200
+++ b/src/devices/wifi/wifi-remote-station-manager.cc Wed Jun 23 08:47:29 2010 +0100
@@ -205,6 +205,12 @@
void
WifiRemoteStationManager::SetupPhy (Ptr<WifiPhy> 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);
Reset ();
}
@@ -255,7 +261,7 @@
{
NS_ASSERT (!address.IsGroup ());
WifiRemoteStationState *state = LookupState (address);
- state->m_modes.clear ();
+ state->m_operationalRateSet.clear ();
AddSupportedMode (address, GetDefaultMode ());
}
void
@@ -263,7 +269,7 @@
{
NS_ASSERT (!address.IsGroup ());
WifiRemoteStationState *state = LookupState (address);
- for (WifiRemoteStationState::SupportedModes::const_iterator i = state->m_modes.begin (); i != state->m_modes.end (); i++)
+ for (WifiModeListIterator i = state->m_operationalRateSet.begin (); i != state->m_operationalRateSet.end (); i++)
{
if ((*i) == mode)
{
@@ -271,7 +277,7 @@
return;
}
}
- state->m_modes.push_back (mode);
+ state->m_operationalRateSet.push_back (mode);
}
bool
WifiRemoteStationManager::IsBrandNew (Mac48Address address) const
@@ -533,39 +539,105 @@
WifiRemoteStationManager::GetControlAnswerMode (Mac48Address address, 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.
+ * The standard has relatively unambiguous rules for selecting a
+ * control response rate (the below is quoted from IEEE 802.11-2007,
+ * 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), 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 9.12) and that is of the same
+ * modulation class (see 9.6.1) as the received frame...
*/
WifiMode mode = GetDefaultMode ();
+ bool found = false;
// First, search the BSS Basic Rate set
- for (WifiRemoteStationManager::BasicModesIterator i = BeginBasicModes (); i != EndBasicModes (); i++)
+ for (WifiModeListIterator i = m_bssBasicRateSet.begin ();
+ i != m_bssBasicRateSet.end (); i++)
{
- if (i->GetPhyRate () > mode.GetPhyRate () &&
- i->GetPhyRate () <= reqMode.GetPhyRate () &&
- i->GetModulationClass () == reqMode.GetModulationClass ())
+ if ((!found || i->GetPhyRate () > mode.GetPhyRate ())
+ && i->GetPhyRate () <= reqMode.GetPhyRate ()
+ && i->GetModulationClass () == reqMode.GetModulationClass ())
{
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;
}
}
- // no need to search Mandatory rate set because it is included
- // within the Basic rate set.
+
+ // If we found a suitable rate in the BSSBasicRateSet, then we are
+ // done and can return that mode.
+ if (found)
+ {
+ 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 () > mode.GetPhyRate ())
+ && thismode.GetPhyRate () <= reqMode.GetPhyRate ()
+ && thismode.GetModulationClass () == reqMode.GetModulationClass ())
+ {
+ 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
+ << ". Check standard and selected rates match.");
+ }
+
return mode;
}
@@ -602,7 +674,7 @@
WifiRemoteStationState *state = new WifiRemoteStationState ();
state->m_state = WifiRemoteStationState::BRAND_NEW;
state->m_address = address;
- state->m_modes.push_back (GetDefaultMode ());
+ state->m_operationalRateSet.push_back (GetDefaultMode ());
const_cast<WifiRemoteStationManager *> (this)->m_states.push_back (state);
return state;
}
@@ -657,8 +729,8 @@
delete (*i);
}
m_stations.clear ();
- m_basicModes.clear ();
- m_basicModes.push_back (m_defaultTxMode);
+ m_bssBasicRateSet.clear ();
+ m_bssBasicRateSet.push_back (m_defaultTxMode);
NS_ASSERT (m_defaultTxMode.IsMandatory ());
}
void
@@ -671,30 +743,19 @@
return;
}
}
- m_basicModes.push_back (mode);
+ m_bssBasicRateSet.push_back (mode);
}
uint32_t
WifiRemoteStationManager::GetNBasicModes (void) const
{
- return m_basicModes.size ();
+ return m_bssBasicRateSet.size ();
}
WifiMode
WifiRemoteStationManager::GetBasicMode (uint32_t i) const
{
- NS_ASSERT (i < m_basicModes.size ());
- return m_basicModes[i];
+ NS_ASSERT (i < m_bssBasicRateSet.size ());
+ return m_bssBasicRateSet[i];
}
-WifiRemoteStationManager::BasicModesIterator
-WifiRemoteStationManager::BeginBasicModes (void) const
-{
- return m_basicModes.begin ();
-}
-WifiRemoteStationManager::BasicModesIterator
-WifiRemoteStationManager::EndBasicModes (void) const
-{
- return m_basicModes.end ();
-}
-
WifiMode
WifiRemoteStationManager::GetNonUnicastMode (void) const
{
@@ -737,12 +798,12 @@
WifiRemoteStationManager::GetSupported (const WifiRemoteStation *station, uint32_t i) const
{
NS_ASSERT (i < GetNSupported (station));
- return station->m_state->m_modes[i];
+ return station->m_state->m_operationalRateSet[i];
}
uint32_t
WifiRemoteStationManager::GetNSupported (const WifiRemoteStation *station) const
{
- return station->m_state->m_modes.size ();
+ return station->m_state->m_operationalRateSet.size ();
}
//WifiRemoteStationInfo constructor
--- a/src/devices/wifi/wifi-remote-station-manager.h Wed Jun 23 06:43:21 2010 +0200
+++ b/src/devices/wifi/wifi-remote-station-manager.h Wed Jun 23 08:47:29 2010 +0100
@@ -79,11 +79,7 @@
*/
class WifiRemoteStationManager : public Object
{
-private:
- typedef std::vector<WifiMode> BasicModes;
public:
- typedef BasicModes::const_iterator BasicModesIterator;
-
static TypeId GetTypeId (void);
WifiRemoteStationManager ();
@@ -113,8 +109,6 @@
WifiMode GetDefaultMode (void) const;
uint32_t GetNBasicModes (void) const;
WifiMode GetBasicMode (uint32_t i) const;
- BasicModesIterator BeginBasicModes (void) const;
- BasicModesIterator EndBasicModes (void) const;
WifiMode GetNonUnicastMode (void) const;
@@ -405,8 +399,27 @@
StationStates m_states;
Stations m_stations;
+ /**
+ * This is a pointer to the WifiPhy associated with this
+ * WifiRemoteStationManager that is set on call to
+ * WifiRemoteStationManager::SetupPhy(). Through this pointer the
+ * station manager can determine PHY characteristics, such as the
+ * set of all transmission rates that may be supported (the
+ * "DeviceRateSet").
+ */
+ Ptr<WifiPhy> m_wifiPhy;
WifiMode m_defaultTxMode;
- BasicModes m_basicModes;
+
+ /**
+ * This member is the list of WifiMode objects that comprise the
+ * BSSBasicRateSet parameter. This list is constructed through calls
+ * to WifiRemoteStationManager::AddBasicMode(), and an API that
+ * allows external access to it is available through
+ * WifiRemoteStationManager::GetNBasicModes() and
+ * WifiRemoteStationManager::GetBasicMode().
+ */
+ WifiModeList m_bssBasicRateSet;
+
bool m_isLowLatency;
uint32_t m_maxSsrc;
uint32_t m_maxSlrc;
@@ -437,7 +450,6 @@
struct WifiRemoteStationState
{
- typedef std::vector<WifiMode> SupportedModes;
enum
{
BRAND_NEW,
@@ -445,7 +457,18 @@
WAIT_ASSOC_TX_OK,
GOT_ASSOC_TX_OK
} m_state;
- SupportedModes m_modes;
+
+ /**
+ * This member is the list of WifiMode objects that comprise the
+ * OperationalRateSet parameter for this remote station. This list
+ * is constructed through calls to
+ * WifiRemoteStationManager::AddSupportedMode(), and an API that
+ * allows external access to it is available through
+ * WifiRemoteStationManager::GetNSupported() and
+ * WifiRemoteStationManager::GetSupported().
+ */
+ WifiModeList m_operationalRateSet;
+
Mac48Address m_address;
WifiRemoteStationInfo m_info;
};
--- a/src/devices/wifi/yans-wifi-phy.cc Wed Jun 23 06:43:21 2010 +0200
+++ b/src/devices/wifi/yans-wifi-phy.cc Wed Jun 23 08:47:29 2010 +0100
@@ -145,7 +145,7 @@
{
NS_LOG_FUNCTION (this);
m_channel = 0;
- m_modes.clear ();
+ m_deviceRateSet.clear ();
m_device = 0;
m_mobility = 0;
m_state = 0;
@@ -516,12 +516,12 @@
uint32_t
YansWifiPhy::GetNModes (void) const
{
- return m_modes.size ();
+ return m_deviceRateSet.size ();
}
WifiMode
YansWifiPhy::GetMode (uint32_t mode) const
{
- return m_modes[mode];
+ return m_deviceRateSet[mode];
}
uint32_t
YansWifiPhy::GetNTxPower (void) const
@@ -535,14 +535,14 @@
NS_LOG_FUNCTION (this);
m_channelStartingFrequency = 5e3; // 5.000 GHz
- m_modes.push_back (WifiPhy::GetOfdmRate6Mbps ());
- m_modes.push_back (WifiPhy::GetOfdmRate9Mbps ());
- m_modes.push_back (WifiPhy::GetOfdmRate12Mbps ());
- m_modes.push_back (WifiPhy::GetOfdmRate18Mbps ());
- m_modes.push_back (WifiPhy::GetOfdmRate24Mbps ());
- m_modes.push_back (WifiPhy::GetOfdmRate36Mbps ());
- m_modes.push_back (WifiPhy::GetOfdmRate48Mbps ());
- m_modes.push_back (WifiPhy::GetOfdmRate54Mbps ());
+ m_deviceRateSet.push_back (WifiPhy::GetOfdmRate6Mbps ());
+ m_deviceRateSet.push_back (WifiPhy::GetOfdmRate9Mbps ());
+ m_deviceRateSet.push_back (WifiPhy::GetOfdmRate12Mbps ());
+ m_deviceRateSet.push_back (WifiPhy::GetOfdmRate18Mbps ());
+ m_deviceRateSet.push_back (WifiPhy::GetOfdmRate24Mbps ());
+ m_deviceRateSet.push_back (WifiPhy::GetOfdmRate36Mbps ());
+ m_deviceRateSet.push_back (WifiPhy::GetOfdmRate48Mbps ());
+ m_deviceRateSet.push_back (WifiPhy::GetOfdmRate54Mbps ());
}
@@ -552,10 +552,10 @@
NS_LOG_FUNCTION (this);
m_channelStartingFrequency = 2412; // 2.412 GHz
- m_modes.push_back (WifiPhy::GetDsssRate1Mbps ());
- m_modes.push_back (WifiPhy::GetDsssRate2Mbps ());
- m_modes.push_back (WifiPhy::GetDsssRate5_5Mbps ());
- m_modes.push_back (WifiPhy::GetDsssRate11Mbps ());
+ m_deviceRateSet.push_back (WifiPhy::GetDsssRate1Mbps ());
+ m_deviceRateSet.push_back (WifiPhy::GetDsssRate2Mbps ());
+ m_deviceRateSet.push_back (WifiPhy::GetDsssRate5_5Mbps ());
+ m_deviceRateSet.push_back (WifiPhy::GetDsssRate11Mbps ());
}
void
@@ -564,14 +564,14 @@
NS_LOG_FUNCTION (this);
m_channelStartingFrequency = 5e3; // 5.000 GHz, suppose 802.11a
- m_modes.push_back (WifiPhy::GetOfdmRate3MbpsBW10MHz ());
- m_modes.push_back (WifiPhy::GetOfdmRate4_5MbpsBW10MHz ());
- m_modes.push_back (WifiPhy::GetOfdmRate6MbpsBW10MHz ());
- m_modes.push_back (WifiPhy::GetOfdmRate9MbpsBW10MHz ());
- m_modes.push_back (WifiPhy::GetOfdmRate12MbpsBW10MHz ());
- m_modes.push_back (WifiPhy::GetOfdmRate18MbpsBW10MHz ());
- m_modes.push_back (WifiPhy::GetOfdmRate24MbpsBW10MHz ());
- m_modes.push_back (WifiPhy::GetOfdmRate27MbpsBW10MHz ());
+ m_deviceRateSet.push_back (WifiPhy::GetOfdmRate3MbpsBW10MHz ());
+ m_deviceRateSet.push_back (WifiPhy::GetOfdmRate4_5MbpsBW10MHz ());
+ m_deviceRateSet.push_back (WifiPhy::GetOfdmRate6MbpsBW10MHz ());
+ m_deviceRateSet.push_back (WifiPhy::GetOfdmRate9MbpsBW10MHz ());
+ m_deviceRateSet.push_back (WifiPhy::GetOfdmRate12MbpsBW10MHz ());
+ m_deviceRateSet.push_back (WifiPhy::GetOfdmRate18MbpsBW10MHz ());
+ m_deviceRateSet.push_back (WifiPhy::GetOfdmRate24MbpsBW10MHz ());
+ m_deviceRateSet.push_back (WifiPhy::GetOfdmRate27MbpsBW10MHz ());
}
void
@@ -580,14 +580,14 @@
NS_LOG_FUNCTION (this);
m_channelStartingFrequency = 5e3; // 5.000 GHz, suppose 802.11a
- m_modes.push_back (WifiPhy::GetOfdmRate1_5MbpsBW5MHz ());
- m_modes.push_back (WifiPhy::GetOfdmRate2_25MbpsBW5MHz ());
- m_modes.push_back (WifiPhy::GetOfdmRate3MbpsBW5MHz ());
- m_modes.push_back (WifiPhy::GetOfdmRate4_5MbpsBW5MHz ());
- m_modes.push_back (WifiPhy::GetOfdmRate6MbpsBW5MHz ());
- m_modes.push_back (WifiPhy::GetOfdmRate9MbpsBW5MHz ());
- m_modes.push_back (WifiPhy::GetOfdmRate12MbpsBW5MHz ());
- m_modes.push_back (WifiPhy::GetOfdmRate13_5MbpsBW5MHz ());
+ m_deviceRateSet.push_back (WifiPhy::GetOfdmRate1_5MbpsBW5MHz ());
+ m_deviceRateSet.push_back (WifiPhy::GetOfdmRate2_25MbpsBW5MHz ());
+ m_deviceRateSet.push_back (WifiPhy::GetOfdmRate3MbpsBW5MHz ());
+ m_deviceRateSet.push_back (WifiPhy::GetOfdmRate4_5MbpsBW5MHz ());
+ m_deviceRateSet.push_back (WifiPhy::GetOfdmRate6MbpsBW5MHz ());
+ m_deviceRateSet.push_back (WifiPhy::GetOfdmRate9MbpsBW5MHz ());
+ m_deviceRateSet.push_back (WifiPhy::GetOfdmRate12MbpsBW5MHz ());
+ m_deviceRateSet.push_back (WifiPhy::GetOfdmRate13_5MbpsBW5MHz ());
}
void
@@ -595,11 +595,11 @@
{
NS_LOG_FUNCTION (this);
m_channelStartingFrequency = 5e3; // 5.000 GHz
- m_modes.push_back (WifiPhy::GetOfdmRate6Mbps ());
- m_modes.push_back (WifiPhy::GetOfdmRate12Mbps ());
- m_modes.push_back (WifiPhy::GetOfdmRate18Mbps ());
- m_modes.push_back (WifiPhy::GetOfdmRate36Mbps ());
- m_modes.push_back (WifiPhy::GetOfdmRate54Mbps ());
+ m_deviceRateSet.push_back (WifiPhy::GetOfdmRate6Mbps ());
+ m_deviceRateSet.push_back (WifiPhy::GetOfdmRate12Mbps ());
+ m_deviceRateSet.push_back (WifiPhy::GetOfdmRate18Mbps ());
+ m_deviceRateSet.push_back (WifiPhy::GetOfdmRate36Mbps ());
+ m_deviceRateSet.push_back (WifiPhy::GetOfdmRate54Mbps ());
}
void
@@ -608,14 +608,14 @@
NS_LOG_FUNCTION (this);
m_channelStartingFrequency = 5e3; // 802.11p works over the 5Ghz freq range
- m_modes.push_back (WifiPhy::GetOfdmRate3MbpsBW10MHz ());
- m_modes.push_back (WifiPhy::GetOfdmRate4_5MbpsBW10MHz ());
- m_modes.push_back (WifiPhy::GetOfdmRate6MbpsBW10MHz ());
- m_modes.push_back (WifiPhy::GetOfdmRate9MbpsBW10MHz ());
- m_modes.push_back (WifiPhy::GetOfdmRate12MbpsBW10MHz ());
- m_modes.push_back (WifiPhy::GetOfdmRate18MbpsBW10MHz ());
- m_modes.push_back (WifiPhy::GetOfdmRate24MbpsBW10MHz ());
- m_modes.push_back (WifiPhy::GetOfdmRate27MbpsBW10MHz ());
+ m_deviceRateSet.push_back (WifiPhy::GetOfdmRate3MbpsBW10MHz ());
+ m_deviceRateSet.push_back (WifiPhy::GetOfdmRate4_5MbpsBW10MHz ());
+ m_deviceRateSet.push_back (WifiPhy::GetOfdmRate6MbpsBW10MHz ());
+ m_deviceRateSet.push_back (WifiPhy::GetOfdmRate9MbpsBW10MHz ());
+ m_deviceRateSet.push_back (WifiPhy::GetOfdmRate12MbpsBW10MHz ());
+ m_deviceRateSet.push_back (WifiPhy::GetOfdmRate18MbpsBW10MHz ());
+ m_deviceRateSet.push_back (WifiPhy::GetOfdmRate24MbpsBW10MHz ());
+ m_deviceRateSet.push_back (WifiPhy::GetOfdmRate27MbpsBW10MHz ());
}
void
@@ -624,14 +624,14 @@
NS_LOG_FUNCTION (this);
m_channelStartingFrequency = 5e3; // 802.11p works over the 5Ghz freq range
- m_modes.push_back (WifiPhy::GetOfdmRate3MbpsBW10MHz ());
- m_modes.push_back (WifiPhy::GetOfdmRate4_5MbpsBW10MHz ());
- m_modes.push_back (WifiPhy::GetOfdmRate6MbpsBW10MHz ());
- m_modes.push_back (WifiPhy::GetOfdmRate9MbpsBW10MHz ());
- m_modes.push_back (WifiPhy::GetOfdmRate12MbpsBW10MHz ());
- m_modes.push_back (WifiPhy::GetOfdmRate18MbpsBW10MHz ());
- m_modes.push_back (WifiPhy::GetOfdmRate24MbpsBW10MHz ());
- m_modes.push_back (WifiPhy::GetOfdmRate27MbpsBW10MHz ());
+ m_deviceRateSet.push_back (WifiPhy::GetOfdmRate3MbpsBW10MHz ());
+ m_deviceRateSet.push_back (WifiPhy::GetOfdmRate4_5MbpsBW10MHz ());
+ m_deviceRateSet.push_back (WifiPhy::GetOfdmRate6MbpsBW10MHz ());
+ m_deviceRateSet.push_back (WifiPhy::GetOfdmRate9MbpsBW10MHz ());
+ m_deviceRateSet.push_back (WifiPhy::GetOfdmRate12MbpsBW10MHz ());
+ m_deviceRateSet.push_back (WifiPhy::GetOfdmRate18MbpsBW10MHz ());
+ m_deviceRateSet.push_back (WifiPhy::GetOfdmRate24MbpsBW10MHz ());
+ m_deviceRateSet.push_back (WifiPhy::GetOfdmRate27MbpsBW10MHz ());
}
void
--- a/src/devices/wifi/yans-wifi-phy.h Wed Jun 23 06:43:21 2010 +0200
+++ b/src/devices/wifi/yans-wifi-phy.h Wed Jun 23 08:47:29 2010 +0100
@@ -143,9 +143,6 @@
virtual void ConfigureStandard (enum WifiPhyStandard standard);
private:
- typedef std::vector<WifiMode> Modes;
-
-private:
YansWifiPhy (const YansWifiPhy &o);
virtual void DoDispose (void);
void Configure80211a (void);
@@ -176,7 +173,45 @@
uint16_t m_channelNumber;
Ptr<Object> m_device;
Ptr<Object> m_mobility;
- Modes m_modes;
+
+ /**
+ * This vector holds the set of transmission modes that this
+ * WifiPhy(-derived class) can support. In conversation we call this
+ * the DeviceRateSet (not a term you'll find in the standard), and
+ * it is a superset of standard-defined parameters such as the
+ * OperationalRateSet, and the BSSBasicRateSet (which, themselves,
+ * have a superset/subset relationship).
+ *
+ * Mandatory rates relevant to this WifiPhy can be found by
+ * iterating over this vector looking for WifiMode objects for which
+ * WifiMode::IsMandatory() is true.
+ *
+ * A quick note is appropriate here (well, here is as good a place
+ * as any I can find)...
+ *
+ * In the standard there is no text that explicitly precludes
+ * production of a device that does not support some rates that are
+ * mandatory (according to the standard) for PHYs that the device
+ * happens to fully or partially support.
+ *
+ * This approach is taken by some devices which choose to only support,
+ * for example, 6 and 9 Mbps ERP-OFDM rates for cost and power
+ * consumption reasons (i.e., these devices don't need to be designed
+ * for and waste current on the increased linearity requirement of
+ * higher-order constellations when 6 and 9 Mbps more than meet their
+ * data requirements). The wording of the standard allows such devices
+ * to have an OperationalRateSet which includes 6 and 9 Mbps ERP-OFDM
+ * rates, despite 12 and 24 Mbps being "mandatory" rates for the
+ * ERP-OFDM PHY.
+ *
+ * Now this doesn't actually have any impact on code, yet. It is,
+ * however, something that we need to keep in mind for the
+ * future. Basically, the key point is that we can't be making
+ * assumptions like "the Operational Rate Set will contain all the
+ * mandatory rates".
+ */
+ WifiModeList m_deviceRateSet;
+
EventId m_endRxEvent;
UniformVariable m_random;
/// Standard-dependent center frequency of 0-th channel, MHz