diff -r 827246e3bc4c src/mesh/model/dot11s/peer-link-frame.cc --- a/src/mesh/model/dot11s/peer-link-frame.cc Sun Jul 03 12:01:29 2011 +0100 +++ b/src/mesh/model/dot11s/peer-link-frame.cc Mon Jul 04 12:36:56 2011 +1200 @@ -119,8 +119,10 @@ } if ((uint8_t)(WifiActionHeader::PEER_LINK_CLOSE) != m_subtype) { - size += m_rates.GetSerializedSize (); - size += m_rates.extended.GetSerializedSize (); + SupportedRatesIE srIE(&m_rates); + size += srIE.GetSerializedSize (); + ExtendedSupportedRatesIE esrIE(&m_rates); + size += esrIE.GetSerializedSize (); } if ((uint8_t)(WifiActionHeader::PEER_LINK_CONFIRM) != m_subtype) { @@ -152,8 +154,10 @@ } if ((uint8_t)(WifiActionHeader::PEER_LINK_CLOSE) != m_subtype) { - i = m_rates.Serialize (i); - i = m_rates.extended.Serialize (i); + SupportedRatesIE srIE(&m_rates); + i = srIE.Serialize (i); + ExtendedSupportedRatesIE esrIE(&m_rates); + i = esrIE.Serialize (i); } if ((uint8_t)(WifiActionHeader::PEER_LINK_CONFIRM) != m_subtype) { @@ -193,8 +197,10 @@ } if ((uint8_t)(WifiActionHeader::PEER_LINK_CLOSE) != m_subtype) { - i = m_rates.Deserialize (i); - i = m_rates.extended.DeserializeIfPresent (i); + SupportedRatesIE srIE(&m_rates); + i = srIE.Deserialize (i); + ExtendedSupportedRatesIE esrIE(&m_rates); + i = esrIE.DeserializeIfPresent (i); } if ((uint8_t)(WifiActionHeader::PEER_LINK_CONFIRM) != m_subtype) { diff -r 827246e3bc4c src/wifi/model/mgt-headers.cc --- a/src/wifi/model/mgt-headers.cc Sun Jul 03 12:01:29 2011 +0100 +++ b/src/wifi/model/mgt-headers.cc Mon Jul 04 12:36:56 2011 +1200 @@ -61,8 +61,10 @@ { uint32_t size = 0; size += m_ssid.GetSerializedSize (); - size += m_rates.GetSerializedSize (); - size += m_rates.extended.GetSerializedSize (); + SupportedRatesIE srIE(&m_rates); + size += srIE.GetSerializedSize (); + ExtendedSupportedRatesIE esrIE(&m_rates); + size += esrIE.GetSerializedSize (); return size; } TypeId @@ -90,16 +92,20 @@ { Buffer::Iterator i = start; i = m_ssid.Serialize (i); - i = m_rates.Serialize (i); - i = m_rates.extended.Serialize (i); + SupportedRatesIE srIE(&m_rates); + i = srIE.Serialize (i); + ExtendedSupportedRatesIE esrIE(&m_rates); + i = esrIE.Serialize (i); } uint32_t MgtProbeRequestHeader::Deserialize (Buffer::Iterator start) { Buffer::Iterator i = start; i = m_ssid.Deserialize (i); - i = m_rates.Deserialize (i); - i = m_rates.extended.DeserializeIfPresent (i); + SupportedRatesIE srIE(&m_rates); + i = srIE.Deserialize (i); + ExtendedSupportedRatesIE esrIE(&m_rates); + i = esrIE.DeserializeIfPresent (i); return i.GetDistanceFrom (start); } @@ -174,9 +180,11 @@ size += 2; // beacon interval size += m_capability.GetSerializedSize (); size += m_ssid.GetSerializedSize (); - size += m_rates.GetSerializedSize (); + SupportedRatesIE srIE(&m_rates); + size += srIE.GetSerializedSize (); //size += 3; // ds parameter set - size += m_rates.extended.GetSerializedSize (); + ExtendedSupportedRatesIE esrIE(&m_rates); + size += esrIE.GetSerializedSize (); // xxx return size; } @@ -204,9 +212,11 @@ i.WriteHtolsbU16 (m_beaconInterval / 1024); i = m_capability.Serialize (i); i = m_ssid.Serialize (i); - i = m_rates.Serialize (i); + SupportedRatesIE srIE(&m_rates); + i = srIE.Serialize (i); //i.WriteU8 (0, 3); // ds parameter set. - i = m_rates.extended.Serialize (i); + ExtendedSupportedRatesIE esrIE(&m_rates); + i = esrIE.Serialize (i); } uint32_t MgtProbeResponseHeader::Deserialize (Buffer::Iterator start) @@ -217,9 +227,11 @@ m_beaconInterval *= 1024; i = m_capability.Deserialize (i); i = m_ssid.Deserialize (i); - i = m_rates.Deserialize (i); + SupportedRatesIE srIE(&m_rates); + i = srIE.Deserialize (i); //i.Next (3); // ds parameter set - i = m_rates.extended.DeserializeIfPresent (i); + ExtendedSupportedRatesIE esrIE(&m_rates); + i = esrIE.DeserializeIfPresent (i); return i.GetDistanceFrom (start); } @@ -289,8 +301,10 @@ size += m_capability.GetSerializedSize (); size += 2; size += m_ssid.GetSerializedSize (); - size += m_rates.GetSerializedSize (); - size += m_rates.extended.GetSerializedSize (); + SupportedRatesIE srIE(&m_rates); + size += srIE.GetSerializedSize (); + ExtendedSupportedRatesIE esrIE(&m_rates); + size += esrIE.GetSerializedSize (); return size; } void @@ -306,8 +320,10 @@ i = m_capability.Serialize (i); i.WriteHtolsbU16 (m_listenInterval); i = m_ssid.Serialize (i); - i = m_rates.Serialize (i); - i = m_rates.extended.Serialize (i); + SupportedRatesIE srIE(&m_rates); + i = srIE.Serialize (i); + ExtendedSupportedRatesIE esrIE(&m_rates); + i = esrIE.Serialize (i); } uint32_t MgtAssocRequestHeader::Deserialize (Buffer::Iterator start) @@ -316,8 +332,10 @@ i = m_capability.Deserialize (i); m_listenInterval = i.ReadLsbtohU16 (); i = m_ssid.Deserialize (i); - i = m_rates.Deserialize (i); - i = m_rates.extended.DeserializeIfPresent (i); + SupportedRatesIE srIE(&m_rates); + i = srIE.Deserialize (i); + ExtendedSupportedRatesIE esrIE(&m_rates); + i = esrIE.DeserializeIfPresent (i); return i.GetDistanceFrom (start); } @@ -377,8 +395,10 @@ size += m_capability.GetSerializedSize (); size += m_code.GetSerializedSize (); size += 2; // aid - size += m_rates.GetSerializedSize (); - size += m_rates.extended.GetSerializedSize (); + SupportedRatesIE srIE(&m_rates); + size += srIE.GetSerializedSize (); + ExtendedSupportedRatesIE esrIE(&m_rates); + size += esrIE.GetSerializedSize (); return size; } @@ -395,8 +415,10 @@ i = m_capability.Serialize (i); i = m_code.Serialize (i); i.WriteHtolsbU16 (m_aid); - i = m_rates.Serialize (i); - i = m_rates.extended.Serialize (i); + SupportedRatesIE srIE(&m_rates); + i = srIE.Serialize (i); + ExtendedSupportedRatesIE esrIE(&m_rates); + i = esrIE.Serialize (i); } uint32_t MgtAssocResponseHeader::Deserialize (Buffer::Iterator start) @@ -405,8 +427,10 @@ i = m_capability.Deserialize (i); i = m_code.Deserialize (i); m_aid = i.ReadLsbtohU16 (); - i = m_rates.Deserialize (i); - i = m_rates.extended.DeserializeIfPresent (i); + SupportedRatesIE srIE(&m_rates); + i = srIE.Deserialize (i); + ExtendedSupportedRatesIE esrIE(&m_rates); + i = esrIE.DeserializeIfPresent (i); return i.GetDistanceFrom (start); } /********************************************************** diff -r 827246e3bc4c src/wifi/model/supported-rates.cc --- a/src/wifi/model/supported-rates.cc Sun Jul 03 12:01:29 2011 +0100 +++ b/src/wifi/model/supported-rates.cc Mon Jul 04 12:36:56 2011 +1200 @@ -27,8 +27,7 @@ namespace ns3 { SupportedRates::SupportedRates () - : extended (this), - m_nRates (0) + : m_nRates (0) { } @@ -102,44 +101,71 @@ return (m_rates[i] & 0x7f) * 500000; } +SupportedRatesIE::SupportedRatesIE (SupportedRates *rates) +{ + m_supportedRatesStore = rates; + m_supportedRatesStoreReadOnly = rates; +} + +SupportedRatesIE::SupportedRatesIE (const SupportedRates *rates) +{ + m_supportedRatesStoreReadOnly = rates; + m_supportedRatesStore = NULL; +} + WifiInformationElementId -SupportedRates::ElementId () const +SupportedRatesIE::ElementId () const { return IE_SUPPORTED_RATES; } uint8_t -SupportedRates::GetInformationFieldSize () const +SupportedRatesIE::GetInformationFieldSize () const { + // Confirm that we have a pointer to a SupportedRates object. We're + // happy to treat it as const in this method. + NS_ASSERT (m_supportedRatesStoreReadOnly); // The Supported Rates Information Element contains only the first 8 // supported rates - the remainder appear in the Extended Supported // Rates Information Element. - return m_nRates > 8 ? 8 : m_nRates; + return std::max((int)m_supportedRatesStoreReadOnly->m_nRates, 8); } void -SupportedRates::SerializeInformationField (Buffer::Iterator start) const +SupportedRatesIE::SerializeInformationField (Buffer::Iterator start) const { + // Confirm that we have a pointer to a SupportedRates object. We're + // happy to treat it as const in this method. + NS_ASSERT (m_supportedRatesStoreReadOnly); // The Supported Rates Information Element contains only the first 8 // supported rates - the remainder appear in the Extended Supported // Rates Information Element. - start.Write (m_rates, m_nRates > 8 ? 8 : m_nRates); + start.Write (m_supportedRatesStoreReadOnly->m_rates, + std::max((int)m_supportedRatesStoreReadOnly->m_nRates, 8)); } uint8_t -SupportedRates::DeserializeInformationField (Buffer::Iterator start, - uint8_t length) +SupportedRatesIE::DeserializeInformationField (Buffer::Iterator start, + uint8_t length) { + // Confirm that we have a pointer to a SupportedRates object that we + // can modify (as opposed to one we have to treat as const). + NS_ASSERT (m_supportedRatesStore); NS_ASSERT (length <= 8); - m_nRates = length; - start.Read (m_rates, m_nRates); - return m_nRates; + m_supportedRatesStore->m_nRates = length; + start.Read (m_supportedRatesStore->m_rates, m_supportedRatesStore->m_nRates); + return m_supportedRatesStore->m_nRates; } -ExtendedSupportedRatesIE::ExtendedSupportedRatesIE () + + +ExtendedSupportedRatesIE::ExtendedSupportedRatesIE (SupportedRates *rates) { + m_supportedRatesStore = rates; + m_supportedRatesStoreReadOnly = rates; } -ExtendedSupportedRatesIE::ExtendedSupportedRatesIE (SupportedRates *sr) +ExtendedSupportedRatesIE::ExtendedSupportedRatesIE (const SupportedRates *rates) { - m_supportedRates = sr; + m_supportedRatesStoreReadOnly = rates; + m_supportedRatesStore = NULL; } WifiInformationElementId @@ -151,21 +177,27 @@ uint8_t ExtendedSupportedRatesIE::GetInformationFieldSize () const { + // Confirm that we have a pointer to a SupportedRates object. We're + // happy to treat it as const in this method. + NS_ASSERT (m_supportedRatesStoreReadOnly); // If there are 8 or fewer rates then we don't need an Extended // Supported Rates IE and so could return zero here, but we're // overriding the GetSerializedSize() method, so if this function is // invoked in that case then it indicates a programming error. Hence // we have an assertion on that condition. - NS_ASSERT (m_supportedRates->m_nRates > 8); + NS_ASSERT (m_supportedRatesStoreReadOnly->m_nRates > 8); // The number of rates we have beyond the initial 8 is the size of // the information field. - return (m_supportedRates->m_nRates - 8); + return (m_supportedRatesStoreReadOnly->m_nRates - 8); } void ExtendedSupportedRatesIE::SerializeInformationField (Buffer::Iterator start) const { + // Confirm that we have a pointer to a SupportedRates object. We're + // happy to treat it as const in this method. + NS_ASSERT (m_supportedRatesStoreReadOnly); // If there are 8 or fewer rates then there should be no Extended // Supported Rates Information Element at all so being here would // seemingly indicate a programming error. @@ -173,16 +205,20 @@ // Our overridden version of the Serialize() method should ensure // that this routine is never invoked in that case (by ensuring that // WifiInformationElement::Serialize() is not invoked). - NS_ASSERT (m_supportedRates->m_nRates > 8); - start.Write (m_supportedRates->m_rates + 8, m_supportedRates->m_nRates - 8); + NS_ASSERT (m_supportedRatesStoreReadOnly->m_nRates > 8); + start.Write (m_supportedRatesStoreReadOnly->m_rates + 8, + m_supportedRatesStoreReadOnly->m_nRates - 8); } Buffer::Iterator ExtendedSupportedRatesIE::Serialize (Buffer::Iterator start) const { + // Confirm that we have a pointer to a SupportedRates object. We're + // happy to treat it as const in this method. + NS_ASSERT (m_supportedRatesStoreReadOnly); // If there are 8 or fewer rates then we don't need an Extended // Supported Rates IE, so we don't serialise anything. - if (m_supportedRates->m_nRates <= 8) + if (m_supportedRatesStoreReadOnly->m_nRates <= 8) { return start; } @@ -194,9 +230,12 @@ uint16_t ExtendedSupportedRatesIE::GetSerializedSize () const { + // Confirm that we have a pointer to a SupportedRates object. We're + // happy to treat it as const in this method. + NS_ASSERT (m_supportedRatesStoreReadOnly); // If there are 8 or fewer rates then we don't need an Extended // Supported Rates IE, so it's serialised length will be zero. - if (m_supportedRates->m_nRates <= 8) + if (m_supportedRatesStoreReadOnly->m_nRates <= 8) { return 0; } @@ -210,10 +249,14 @@ ExtendedSupportedRatesIE::DeserializeInformationField (Buffer::Iterator start, uint8_t length) { + // Confirm that we have a pointer to a SupportedRates object that we + // can modify (as opposed to one we have to treat as const). + NS_ASSERT (m_supportedRatesStore); NS_ASSERT (length > 0); - NS_ASSERT (m_supportedRates->m_nRates + length <= MAX_SUPPORTED_RATES); - start.Read (m_supportedRates->m_rates + m_supportedRates->m_nRates, length); - m_supportedRates->m_nRates += length; + NS_ASSERT (m_supportedRatesStore->m_nRates + length <= MAX_SUPPORTED_RATES); + start.Read (m_supportedRatesStore->m_rates + m_supportedRatesStore->m_nRates, + length); + m_supportedRatesStore->m_nRates += length; return length; } diff -r 827246e3bc4c src/wifi/model/supported-rates.h --- a/src/wifi/model/supported-rates.h Sun Jul 03 12:01:29 2011 +0100 +++ b/src/wifi/model/supported-rates.h Mon Jul 04 12:36:56 2011 +1200 @@ -22,7 +22,6 @@ #include #include -#include "ns3/buffer.h" #include "ns3/wifi-information-element.h" namespace ns3 { @@ -35,7 +34,92 @@ */ #define MAX_SUPPORTED_RATES (12) -class SupportedRates; +/** + * \brief A storage class for supported rates + * \ingroup wifi + */ +class SupportedRates +{ +public: + SupportedRates (); + + void AddSupportedRate (uint32_t bs); + void SetBasicRate (uint32_t bs); + + bool IsSupportedRate (uint32_t bs) const; + bool IsBasicRate (uint32_t bs) const; + + uint8_t GetNRates (void) const; + uint32_t GetRate (uint8_t i) const; + + /* + * The classes which serialise and deserialise Supported Rates and + * Extended Supported Rates Information Elements need access to our + * internals and thus need to be our friends + */ + friend class SupportedRatesIE; + friend class ExtendedSupportedRatesIE; +private: + uint8_t m_nRates; + uint8_t m_rates[MAX_SUPPORTED_RATES]; +}; + +std::ostream &operator << (std::ostream &os, const SupportedRates &rates); + +/** + * \brief The Supported Rates Information Element + * \ingroup wifi + * + * This class knows how to serialise and deserialise the Supported + * Rates Element that holds the first 8 (non-HT) supported rates. + * + * The \c ExtendedSupportedRatesIE class deals with rates beyond the + * first 8. + */ +class SupportedRatesIE : public WifiInformationElement +{ +public: + /** + * This constructor is used when non-const access is available to + * the SupportedRates object that stores the list of supported + * rates. This is a requirement if a non-const method of this class + * (e.g., Deserialize ()) is to be called. + */ + SupportedRatesIE (SupportedRates *rates); + /** + * This constructor is used when the SupportedRates object that + * stores the list of supported rates must be treated as const - + * perhaps because the method that creates an instance of this class + * only has const access to the SupportedRates object. This level of + * access is sufficient (and appropriate) for determining the size + * of the IE, and serialising it. + */ + SupportedRatesIE (const SupportedRates *rates); + + WifiInformationElementId ElementId () const; + uint8_t GetInformationFieldSize () const; + void SerializeInformationField (Buffer::Iterator start) const; + uint8_t DeserializeInformationField (Buffer::Iterator start, + uint8_t length); + +private: + /** + * Pointer to a supported rates store which this instance of this + * class is allowed to modify (e.g., deserialise to). It is NULL if + * no such privileges have been granted during object construction, + * and if not NULL will point to the same object as \c + * m_supportedRatesStoreReadOnly. + */ + SupportedRates *m_supportedRatesStore; + /** + * Pointer to a supported rates store which this class is to treat + * as read only (perhaps because the method that creates an instance + * of this class is a const member of the class in which the + * SupportedRates object is a member). + */ + const SupportedRates *m_supportedRatesStoreReadOnly; +}; + /** * \brief The Extended Supported Rates Information Element @@ -44,16 +128,26 @@ * This class knows how to serialise and deserialise the Extended * Supported Rates Element that holds (non-HT) rates beyond the 8 that * the original Supported Rates element can carry. - * - * The \c SupportedRates class still records all the rates, and an - * instance of \c ExtendedSupportedRatesIE lies within \c - * SupportedRates. */ class ExtendedSupportedRatesIE : public WifiInformationElement { public: - ExtendedSupportedRatesIE (); + /** + * This constructor is used when non-const access is available to + * the SupportedRates object that stores the list of supported + * rates. This is a requirement if a non-const method of this class + * (e.g., Deserialize ()) is to be called. + */ ExtendedSupportedRatesIE (SupportedRates *rates); + /** + * This constructor is used when the SupportedRates object that + * stores the list of supported rates must be treated as const - + * perhaps because the method that creates an instance of this class + * only has const access to the SupportedRates object. This level of + * access is sufficient (and appropriate) for determining the size + * of the IE, and serialising it. + */ + ExtendedSupportedRatesIE (const SupportedRates *rates); WifiInformationElementId ElementId () const; uint8_t GetInformationFieldSize () const; @@ -69,62 +163,25 @@ */ Buffer::Iterator Serialize (Buffer::Iterator start) const; uint16_t GetSerializedSize () const; + private: /** - * This member points to the SupportedRates object that contains the - * actual rate details. This class is a friend of that, so we have - * access to all the private data we need. + * Pointer to a supported rates store which this instance of this + * class is allowed to modify (e.g., deserialise to). It is NULL if + * no such privileges have been granted during object construction, + * and if not NULL will point to the same object as \c + * m_supportedRatesStoreReadOnly. */ - SupportedRates *m_supportedRates; + SupportedRates *m_supportedRatesStore; + /** + * Pointer to a supported rates store which this class is to treat + * as read only (perhaps because the method that creates an instance + * of this class is a const member of the class in which the + * SupportedRates object is a member). + */ + const SupportedRates *m_supportedRatesStoreReadOnly; }; - -/** - * \brief The Supported Rates Information Element - * \ingroup wifi - * - * This class knows how to serialise and deserialise the Supported - * Rates Element that holds the first 8 (non-HT) supported rates. - * - * The \c ExtendedSupportedRatesIE class (of which an instance exists - * in objects of this class) deals with rates beyond the first 8. - */ -class SupportedRates : public WifiInformationElement -{ -public: - SupportedRates (); - - void AddSupportedRate (uint32_t bs); - void SetBasicRate (uint32_t bs); - - bool IsSupportedRate (uint32_t bs) const; - bool IsBasicRate (uint32_t bs) const; - - uint8_t GetNRates (void) const; - uint32_t GetRate (uint8_t i) const; - - WifiInformationElementId ElementId () const; - uint8_t GetInformationFieldSize () const; - void SerializeInformationField (Buffer::Iterator start) const; - uint8_t DeserializeInformationField (Buffer::Iterator start, - uint8_t length); - - /* - * We support the Extended Supported Rates Information Element - * through the ExtendedSupportedRatesIE object which is declared - * above. We allow this class to be a friend so that it can access - * our private data detailing the rates, and create an instance as - * extended. - */ - friend class ExtendedSupportedRatesIE; - ExtendedSupportedRatesIE extended; -private: - uint8_t m_nRates; - uint8_t m_rates[MAX_SUPPORTED_RATES]; -}; - -std::ostream &operator << (std::ostream &os, const SupportedRates &rates); - } // namespace ns3 #endif /* SUPPORTED_RATES_H */