diff --git a/src/devices/wifi/arf-wifi-manager.cc b/src/devices/wifi/arf-wifi-manager.cc index dec47835e..9a4568590 100644 --- a/src/devices/wifi/arf-wifi-manager.cc +++ b/src/devices/wifi/arf-wifi-manager.cc @@ -156,7 +156,7 @@ void ArfWifiManager::DoReportDataOk (WifiRemoteStation *st, 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="<m_rate++; diff --git a/src/devices/wifi/wifi-mode.h b/src/devices/wifi/wifi-mode.h index 7c16d26d8..6175ce8c1 100644 --- a/src/devices/wifi/wifi-mode.h +++ b/src/devices/wifi/wifi-mode.h @@ -162,6 +162,15 @@ std::istream & operator >> (std::istream &is, WifiMode &mode); 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 WifiModeList; +typedef WifiModeList::const_iterator WifiModeListIterator; + /** * \brief create WifiMode class instances and keep track of them. * diff --git a/src/devices/wifi/wifi-phy.h b/src/devices/wifi/wifi-phy.h index 5fb20baa7..f3bb17b52 100644 --- a/src/devices/wifi/wifi-phy.h +++ b/src/devices/wifi/wifi-phy.h @@ -240,14 +240,42 @@ public: * 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; /** diff --git a/src/devices/wifi/wifi-remote-station-manager.cc b/src/devices/wifi/wifi-remote-station-manager.cc index 2491deb1c..a59fad07b 100644 --- a/src/devices/wifi/wifi-remote-station-manager.cc +++ b/src/devices/wifi/wifi-remote-station-manager.cc @@ -205,6 +205,12 @@ WifiRemoteStationManager::DoDispose (void) 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); Reset (); } @@ -255,7 +261,7 @@ WifiRemoteStationManager::Reset (Mac48Address address) { NS_ASSERT (!address.IsGroup ()); WifiRemoteStationState *state = LookupState (address); - state->m_modes.clear (); + state->m_operationalRateSet.clear (); AddSupportedMode (address, GetDefaultMode ()); } void @@ -263,7 +269,7 @@ WifiRemoteStationManager::AddSupportedMode (Mac48Address address, WifiMode mode) { 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 @@ WifiRemoteStationManager::AddSupportedMode (Mac48Address address, WifiMode mode) return; } } - state->m_modes.push_back (mode); + state->m_operationalRateSet.push_back (mode); } bool WifiRemoteStationManager::IsBrandNew (Mac48Address address) const @@ -533,39 +539,105 @@ WifiMode 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 @@ WifiRemoteStationManager::LookupState (Mac48Address address) const 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 (this)->m_states.push_back (state); return state; } @@ -657,8 +729,8 @@ WifiRemoteStationManager::Reset (void) 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 @@ WifiRemoteStationManager::AddBasicMode (WifiMode mode) 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 @@ WifiMode 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 diff --git a/src/devices/wifi/wifi-remote-station-manager.h b/src/devices/wifi/wifi-remote-station-manager.h index 6d62cf1ec..fb3f5848c 100644 --- a/src/devices/wifi/wifi-remote-station-manager.h +++ b/src/devices/wifi/wifi-remote-station-manager.h @@ -79,11 +79,7 @@ private: */ class WifiRemoteStationManager : public Object { -private: - typedef std::vector BasicModes; public: - typedef BasicModes::const_iterator BasicModesIterator; - static TypeId GetTypeId (void); WifiRemoteStationManager (); @@ -113,8 +109,6 @@ public: 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 @@ private: 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 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 @@ private: struct WifiRemoteStationState { - typedef std::vector SupportedModes; enum { BRAND_NEW, @@ -445,7 +457,18 @@ struct WifiRemoteStationState 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; }; diff --git a/src/devices/wifi/yans-wifi-phy.cc b/src/devices/wifi/yans-wifi-phy.cc index 905831e4f..b44379237 100644 --- a/src/devices/wifi/yans-wifi-phy.cc +++ b/src/devices/wifi/yans-wifi-phy.cc @@ -145,7 +145,7 @@ YansWifiPhy::DoDispose (void) { 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 @@ YansWifiPhy::SendPacket (Ptr packet, WifiMode txMode, WifiPreamble 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 @@ YansWifiPhy::Configure80211a (void) 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 @@ YansWifiPhy::Configure80211b (void) 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 @@ YansWifiPhy::Configure80211_10Mhz (void) 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 @@ YansWifiPhy::Configure80211_5Mhz (void) 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 @@ YansWifiPhy::ConfigureHolland (void) { 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 @@ YansWifiPhy::Configure80211p_CCH (void) 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 @@ YansWifiPhy::Configure80211p_SCH (void) 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 diff --git a/src/devices/wifi/yans-wifi-phy.h b/src/devices/wifi/yans-wifi-phy.h index 60d2b1e18..b855fb437 100644 --- a/src/devices/wifi/yans-wifi-phy.h +++ b/src/devices/wifi/yans-wifi-phy.h @@ -142,9 +142,6 @@ public: virtual Ptr GetChannel (void) const; virtual void ConfigureStandard (enum WifiPhyStandard standard); -private: - typedef std::vector Modes; - private: YansWifiPhy (const YansWifiPhy &o); virtual void DoDispose (void); @@ -176,7 +173,45 @@ private: uint16_t m_channelNumber; Ptr m_device; Ptr 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