src/wifi/model/supported-rates.cc
changeset 6852 8f1a53d3f6ca
parent 6848 1f453ad50ef3
child 7141 072fb225b714
equal deleted inserted replaced
6851:7fdad61b88f1 6852:8f1a53d3f6ca
       
     1 /* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
       
     2 /*
       
     3  * Copyright (c) 2006 INRIA
       
     4  *
       
     5  * This program is free software; you can redistribute it and/or modify
       
     6  * it under the terms of the GNU General Public License version 2 as 
       
     7  * published by the Free Software Foundation;
       
     8  *
       
     9  * This program is distributed in the hope that it will be useful,
       
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    12  * GNU General Public License for more details.
       
    13  *
       
    14  * You should have received a copy of the GNU General Public License
       
    15  * along with this program; if not, write to the Free Software
       
    16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
    17  *
       
    18  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
       
    19  */
       
    20 
       
    21 #include "supported-rates.h"
       
    22 #include "ns3/assert.h"
       
    23 #include "ns3/log.h"
       
    24 
       
    25 NS_LOG_COMPONENT_DEFINE ("SupportedRates");
       
    26 
       
    27 namespace ns3 {
       
    28 
       
    29 SupportedRates::SupportedRates ()
       
    30   : extended (this), m_nRates (0)
       
    31 {}
       
    32 
       
    33 void 
       
    34 SupportedRates::AddSupportedRate (uint32_t bs)
       
    35 {
       
    36   NS_ASSERT (m_nRates < MAX_SUPPORTED_RATES);
       
    37   if (IsSupportedRate (bs))
       
    38     {
       
    39       return;
       
    40     }
       
    41   m_rates[m_nRates] = bs/500000;
       
    42   m_nRates++;
       
    43   NS_LOG_DEBUG ("add rate="<<bs<<", n rates="<<(uint32_t)m_nRates);
       
    44 }
       
    45 void 
       
    46 SupportedRates::SetBasicRate (uint32_t bs)
       
    47 {
       
    48   uint8_t rate = bs / 500000;
       
    49   for (uint8_t i = 0; i < m_nRates; i++)
       
    50     {
       
    51       if ((rate | 0x80) == m_rates[i])
       
    52         {
       
    53           return;
       
    54         }
       
    55       if (rate == m_rates[i])
       
    56         {
       
    57           NS_LOG_DEBUG ("set basic rate="<<bs<<", n rates="<<(uint32_t)m_nRates);
       
    58           m_rates[i] |= 0x80;
       
    59           return;
       
    60         }
       
    61     }
       
    62   AddSupportedRate (bs);
       
    63   SetBasicRate (bs);
       
    64 }
       
    65 bool 
       
    66 SupportedRates::IsBasicRate (uint32_t bs) const
       
    67 {
       
    68   uint8_t rate = (bs / 500000) | 0x80;
       
    69   for (uint8_t i = 0; i < m_nRates; i++)
       
    70     {
       
    71       if (rate == m_rates[i])
       
    72         {
       
    73           return true;
       
    74         }
       
    75     }
       
    76   return false;
       
    77 }
       
    78 bool 
       
    79 SupportedRates::IsSupportedRate (uint32_t bs) const
       
    80 {
       
    81   uint8_t rate = bs / 500000;
       
    82   for (uint8_t i = 0; i < m_nRates; i++) 
       
    83     {
       
    84       if (rate == m_rates[i] ||
       
    85           (rate|0x80) == m_rates[i]) 
       
    86         {
       
    87           return true;
       
    88         }
       
    89     }
       
    90   return false;
       
    91 }
       
    92 uint8_t 
       
    93 SupportedRates::GetNRates (void) const
       
    94 {
       
    95   return m_nRates;
       
    96 }
       
    97 uint32_t 
       
    98 SupportedRates::GetRate (uint8_t i) const
       
    99 {
       
   100   return (m_rates[i]&0x7f) * 500000;
       
   101 }
       
   102 
       
   103 WifiInformationElementId
       
   104 SupportedRates::ElementId () const
       
   105 {
       
   106   return IE_SUPPORTED_RATES;
       
   107 }
       
   108 uint8_t
       
   109 SupportedRates::GetInformationFieldSize () const
       
   110 {
       
   111   // The Supported Rates Information Element contains only the first 8
       
   112   // supported rates - the remainder appear in the Extended Supported
       
   113   // Rates Information Element.
       
   114   return m_nRates > 8 ? 8 : m_nRates;
       
   115 }
       
   116 void
       
   117 SupportedRates::SerializeInformationField (Buffer::Iterator start) const
       
   118 {
       
   119   // The Supported Rates Information Element contains only the first 8
       
   120   // supported rates - the remainder appear in the Extended Supported
       
   121   // Rates Information Element.
       
   122   start.Write (m_rates, m_nRates > 8 ? 8 : m_nRates);
       
   123 }
       
   124 uint8_t
       
   125 SupportedRates::DeserializeInformationField (Buffer::Iterator start,
       
   126                                         uint8_t length)
       
   127 {
       
   128   NS_ASSERT (length <= 8);
       
   129   m_nRates = length;
       
   130   start.Read (m_rates, m_nRates);
       
   131   return m_nRates;
       
   132 }
       
   133 
       
   134 ExtendedSupportedRatesIE::ExtendedSupportedRatesIE ()
       
   135 {}
       
   136 
       
   137 ExtendedSupportedRatesIE::ExtendedSupportedRatesIE (SupportedRates *sr)
       
   138 {
       
   139   m_supportedRates = sr;
       
   140 }
       
   141 
       
   142 WifiInformationElementId
       
   143 ExtendedSupportedRatesIE::ElementId () const
       
   144 {
       
   145   return IE_EXTENDED_SUPPORTED_RATES;
       
   146 }
       
   147 
       
   148 uint8_t
       
   149 ExtendedSupportedRatesIE::GetInformationFieldSize () const
       
   150 {
       
   151   // If there are 8 or fewer rates then we don't need an Extended
       
   152   // Supported Rates IE and so could return zero here, but we're
       
   153   // overriding the GetSerializedSize() method, so if this function is
       
   154   // invoked in that case then it indicates a programming error. Hence
       
   155   // we have an assertion on that condition.
       
   156   NS_ASSERT(m_supportedRates->m_nRates > 8);
       
   157 
       
   158   // The number of rates we have beyond the initial 8 is the size of
       
   159   // the information field.
       
   160   return (m_supportedRates->m_nRates - 8);
       
   161 }
       
   162 
       
   163 void
       
   164 ExtendedSupportedRatesIE::SerializeInformationField (Buffer::Iterator start) const
       
   165 {
       
   166   // If there are 8 or fewer rates then there should be no Extended
       
   167   // Supported Rates Information Element at all so being here would
       
   168   // seemingly indicate a programming error.
       
   169   //
       
   170   // Our overridden version of the Serialize() method should ensure
       
   171   // that this routine is never invoked in that case (by ensuring that
       
   172   // WifiInformationElement::Serialize() is not invoked).
       
   173   NS_ASSERT(m_supportedRates->m_nRates > 8);
       
   174   start.Write (m_supportedRates->m_rates + 8, m_supportedRates->m_nRates - 8);
       
   175 }
       
   176 
       
   177 Buffer::Iterator
       
   178 ExtendedSupportedRatesIE::Serialize (Buffer::Iterator start) const
       
   179 {
       
   180   // If there are 8 or fewer rates then we don't need an Extended
       
   181   // Supported Rates IE, so we don't serialise anything.
       
   182   if (m_supportedRates->m_nRates <= 8)
       
   183     {
       
   184       return start;
       
   185     }
       
   186 
       
   187   // If there are more than 8 rates then we serialise as per normal.
       
   188   return WifiInformationElement::Serialize (start);
       
   189 }
       
   190 
       
   191 uint16_t
       
   192 ExtendedSupportedRatesIE::GetSerializedSize () const
       
   193 {
       
   194   // If there are 8 or fewer rates then we don't need an Extended
       
   195   // Supported Rates IE, so it's serialised length will be zero.
       
   196   if (m_supportedRates->m_nRates <= 8)
       
   197     {
       
   198       return 0;
       
   199     }
       
   200 
       
   201   // Otherwise, the size of it will be the number of supported rates
       
   202   // beyond 8, plus 2 for the Element ID and Length.
       
   203   return WifiInformationElement::GetSerializedSize ();
       
   204 }
       
   205 
       
   206 uint8_t
       
   207 ExtendedSupportedRatesIE::DeserializeInformationField (Buffer::Iterator start,
       
   208                                                        uint8_t length)
       
   209 {
       
   210   NS_ASSERT (length > 0);
       
   211   NS_ASSERT (m_supportedRates->m_nRates + length <= MAX_SUPPORTED_RATES);
       
   212   start.Read (m_supportedRates->m_rates + m_supportedRates->m_nRates, length);
       
   213   m_supportedRates->m_nRates += length;
       
   214   return length;
       
   215 }
       
   216 
       
   217 std::ostream &operator << (std::ostream &os, const SupportedRates &rates)
       
   218 {
       
   219   os << "[";
       
   220   for (uint8_t i = 0; i < rates.GetNRates (); i++)
       
   221     {
       
   222       uint32_t rate = rates.GetRate (i);
       
   223       if (rates.IsBasicRate (rate))
       
   224         {
       
   225           os << "*";
       
   226         }
       
   227       os << rate / 1000000 << "mbs";
       
   228       if (i < rates.GetNRates () - 1)
       
   229         {
       
   230           os << " ";
       
   231         }
       
   232     }
       
   233   os << "]";
       
   234   return os;
       
   235 }
       
   236 
       
   237 } // namespace ns3