--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/wifi/model/supported-rates.cc Fri Mar 04 01:26:54 2011 +0000
@@ -0,0 +1,237 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006 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 <mathieu.lacage@sophia.inria.fr>
+ */
+
+#include "supported-rates.h"
+#include "ns3/assert.h"
+#include "ns3/log.h"
+
+NS_LOG_COMPONENT_DEFINE ("SupportedRates");
+
+namespace ns3 {
+
+SupportedRates::SupportedRates ()
+ : extended (this), m_nRates (0)
+{}
+
+void
+SupportedRates::AddSupportedRate (uint32_t bs)
+{
+ NS_ASSERT (m_nRates < MAX_SUPPORTED_RATES);
+ if (IsSupportedRate (bs))
+ {
+ return;
+ }
+ m_rates[m_nRates] = bs/500000;
+ m_nRates++;
+ NS_LOG_DEBUG ("add rate="<<bs<<", n rates="<<(uint32_t)m_nRates);
+}
+void
+SupportedRates::SetBasicRate (uint32_t bs)
+{
+ uint8_t rate = bs / 500000;
+ for (uint8_t i = 0; i < m_nRates; i++)
+ {
+ if ((rate | 0x80) == m_rates[i])
+ {
+ return;
+ }
+ if (rate == m_rates[i])
+ {
+ NS_LOG_DEBUG ("set basic rate="<<bs<<", n rates="<<(uint32_t)m_nRates);
+ m_rates[i] |= 0x80;
+ return;
+ }
+ }
+ AddSupportedRate (bs);
+ SetBasicRate (bs);
+}
+bool
+SupportedRates::IsBasicRate (uint32_t bs) const
+{
+ uint8_t rate = (bs / 500000) | 0x80;
+ for (uint8_t i = 0; i < m_nRates; i++)
+ {
+ if (rate == m_rates[i])
+ {
+ return true;
+ }
+ }
+ return false;
+}
+bool
+SupportedRates::IsSupportedRate (uint32_t bs) const
+{
+ uint8_t rate = bs / 500000;
+ for (uint8_t i = 0; i < m_nRates; i++)
+ {
+ if (rate == m_rates[i] ||
+ (rate|0x80) == m_rates[i])
+ {
+ return true;
+ }
+ }
+ return false;
+}
+uint8_t
+SupportedRates::GetNRates (void) const
+{
+ return m_nRates;
+}
+uint32_t
+SupportedRates::GetRate (uint8_t i) const
+{
+ return (m_rates[i]&0x7f) * 500000;
+}
+
+WifiInformationElementId
+SupportedRates::ElementId () const
+{
+ return IE_SUPPORTED_RATES;
+}
+uint8_t
+SupportedRates::GetInformationFieldSize () const
+{
+ // 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;
+}
+void
+SupportedRates::SerializeInformationField (Buffer::Iterator start) const
+{
+ // 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);
+}
+uint8_t
+SupportedRates::DeserializeInformationField (Buffer::Iterator start,
+ uint8_t length)
+{
+ NS_ASSERT (length <= 8);
+ m_nRates = length;
+ start.Read (m_rates, m_nRates);
+ return m_nRates;
+}
+
+ExtendedSupportedRatesIE::ExtendedSupportedRatesIE ()
+{}
+
+ExtendedSupportedRatesIE::ExtendedSupportedRatesIE (SupportedRates *sr)
+{
+ m_supportedRates = sr;
+}
+
+WifiInformationElementId
+ExtendedSupportedRatesIE::ElementId () const
+{
+ return IE_EXTENDED_SUPPORTED_RATES;
+}
+
+uint8_t
+ExtendedSupportedRatesIE::GetInformationFieldSize () const
+{
+ // 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);
+
+ // The number of rates we have beyond the initial 8 is the size of
+ // the information field.
+ return (m_supportedRates->m_nRates - 8);
+}
+
+void
+ExtendedSupportedRatesIE::SerializeInformationField (Buffer::Iterator start) const
+{
+ // 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.
+ //
+ // 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);
+}
+
+Buffer::Iterator
+ExtendedSupportedRatesIE::Serialize (Buffer::Iterator start) const
+{
+ // 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)
+ {
+ return start;
+ }
+
+ // If there are more than 8 rates then we serialise as per normal.
+ return WifiInformationElement::Serialize (start);
+}
+
+uint16_t
+ExtendedSupportedRatesIE::GetSerializedSize () const
+{
+ // 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)
+ {
+ return 0;
+ }
+
+ // Otherwise, the size of it will be the number of supported rates
+ // beyond 8, plus 2 for the Element ID and Length.
+ return WifiInformationElement::GetSerializedSize ();
+}
+
+uint8_t
+ExtendedSupportedRatesIE::DeserializeInformationField (Buffer::Iterator start,
+ uint8_t length)
+{
+ 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;
+ return length;
+}
+
+std::ostream &operator << (std::ostream &os, const SupportedRates &rates)
+{
+ os << "[";
+ for (uint8_t i = 0; i < rates.GetNRates (); i++)
+ {
+ uint32_t rate = rates.GetRate (i);
+ if (rates.IsBasicRate (rate))
+ {
+ os << "*";
+ }
+ os << rate / 1000000 << "mbs";
+ if (i < rates.GetNRates () - 1)
+ {
+ os << " ";
+ }
+ }
+ os << "]";
+ return os;
+}
+
+} // namespace ns3