A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
supported-rates.cc
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),
31  m_nRates (0)
32 {
33 }
34 
35 void
36 SupportedRates::AddSupportedRate (uint32_t bs)
37 {
38  NS_ASSERT (m_nRates < MAX_SUPPORTED_RATES);
39  if (IsSupportedRate (bs))
40  {
41  return;
42  }
43  m_rates[m_nRates] = bs / 500000;
44  m_nRates++;
45  NS_LOG_DEBUG ("add rate=" << bs << ", n rates=" << (uint32_t)m_nRates);
46 }
47 void
48 SupportedRates::SetBasicRate (uint32_t bs)
49 {
50  uint8_t rate = bs / 500000;
51  for (uint8_t i = 0; i < m_nRates; i++)
52  {
53  if ((rate | 0x80) == m_rates[i])
54  {
55  return;
56  }
57  if (rate == m_rates[i])
58  {
59  NS_LOG_DEBUG ("set basic rate=" << bs << ", n rates=" << (uint32_t)m_nRates);
60  m_rates[i] |= 0x80;
61  return;
62  }
63  }
64  AddSupportedRate (bs);
65  SetBasicRate (bs);
66 }
67 bool
68 SupportedRates::IsBasicRate (uint32_t bs) const
69 {
70  uint8_t rate = (bs / 500000) | 0x80;
71  for (uint8_t i = 0; i < m_nRates; i++)
72  {
73  if (rate == m_rates[i])
74  {
75  return true;
76  }
77  }
78  return false;
79 }
80 bool
81 SupportedRates::IsSupportedRate (uint32_t bs) const
82 {
83  uint8_t rate = bs / 500000;
84  for (uint8_t i = 0; i < m_nRates; i++)
85  {
86  if (rate == m_rates[i]
87  || (rate | 0x80) == m_rates[i])
88  {
89  return true;
90  }
91  }
92  return false;
93 }
94 uint8_t
95 SupportedRates::GetNRates (void) const
96 {
97  return m_nRates;
98 }
99 uint32_t
100 SupportedRates::GetRate (uint8_t i) const
101 {
102  return (m_rates[i] & 0x7f) * 500000;
103 }
104 
107 {
108  return IE_SUPPORTED_RATES;
109 }
110 uint8_t
112 {
113  // The Supported Rates Information Element contains only the first 8
114  // supported rates - the remainder appear in the Extended Supported
115  // Rates Information Element.
116  return m_nRates > 8 ? 8 : m_nRates;
117 }
118 void
120 {
121  // The Supported Rates Information Element contains only the first 8
122  // supported rates - the remainder appear in the Extended Supported
123  // Rates Information Element.
124  start.Write (m_rates, m_nRates > 8 ? 8 : m_nRates);
125 }
126 uint8_t
128  uint8_t length)
129 {
130  NS_ASSERT (length <= 8);
131  m_nRates = length;
132  start.Read (m_rates, m_nRates);
133  return m_nRates;
134 }
135 
136 ExtendedSupportedRatesIE::ExtendedSupportedRatesIE ()
137 {
138 }
139 
140 ExtendedSupportedRatesIE::ExtendedSupportedRatesIE (SupportedRates *sr)
141 {
142  m_supportedRates = sr;
143 }
144 
147 {
148  return IE_EXTENDED_SUPPORTED_RATES;
149 }
150 
151 uint8_t
153 {
154  // If there are 8 or fewer rates then we don't need an Extended
155  // Supported Rates IE and so could return zero here, but we're
156  // overriding the GetSerializedSize() method, so if this function is
157  // invoked in that case then it indicates a programming error. Hence
158  // we have an assertion on that condition.
159  NS_ASSERT (m_supportedRates->m_nRates > 8);
160 
161  // The number of rates we have beyond the initial 8 is the size of
162  // the information field.
163  return (m_supportedRates->m_nRates - 8);
164 }
165 
166 void
168 {
169  // If there are 8 or fewer rates then there should be no Extended
170  // Supported Rates Information Element at all so being here would
171  // seemingly indicate a programming error.
172  //
173  // Our overridden version of the Serialize() method should ensure
174  // that this routine is never invoked in that case (by ensuring that
175  // WifiInformationElement::Serialize() is not invoked).
176  NS_ASSERT (m_supportedRates->m_nRates > 8);
177  start.Write (m_supportedRates->m_rates + 8, m_supportedRates->m_nRates - 8);
178 }
179 
181 ExtendedSupportedRatesIE::Serialize (Buffer::Iterator start) const
182 {
183  // If there are 8 or fewer rates then we don't need an Extended
184  // Supported Rates IE, so we don't serialise anything.
185  if (m_supportedRates->m_nRates <= 8)
186  {
187  return start;
188  }
189 
190  // If there are more than 8 rates then we serialise as per normal.
191  return WifiInformationElement::Serialize (start);
192 }
193 
194 uint16_t
195 ExtendedSupportedRatesIE::GetSerializedSize () const
196 {
197  // If there are 8 or fewer rates then we don't need an Extended
198  // Supported Rates IE, so it's serialised length will be zero.
199  if (m_supportedRates->m_nRates <= 8)
200  {
201  return 0;
202  }
203 
204  // Otherwise, the size of it will be the number of supported rates
205  // beyond 8, plus 2 for the Element ID and Length.
207 }
208 
209 uint8_t
211  uint8_t length)
212 {
213  NS_ASSERT (length > 0);
214  NS_ASSERT (m_supportedRates->m_nRates + length <= MAX_SUPPORTED_RATES);
215  start.Read (m_supportedRates->m_rates + m_supportedRates->m_nRates, length);
216  m_supportedRates->m_nRates += length;
217  return length;
218 }
219 
220 std::ostream &operator << (std::ostream &os, const SupportedRates &rates)
221 {
222  os << "[";
223  for (uint8_t i = 0; i < rates.GetNRates (); i++)
224  {
225  uint32_t rate = rates.GetRate (i);
226  if (rates.IsBasicRate (rate))
227  {
228  os << "*";
229  }
230  os << rate / 1000000 << "mbs";
231  if (i < rates.GetNRates () - 1)
232  {
233  os << " ";
234  }
235  }
236  os << "]";
237  return os;
238 }
239 
240 } // namespace ns3
uint8_t DeserializeInformationField(Buffer::Iterator start, uint8_t length)
#define NS_ASSERT(condition)
Definition: assert.h:64
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
void SerializeInformationField(Buffer::Iterator start) const
The Supported Rates Information ElementThis class knows how to serialise and deserialise the Supporte...
iterator in a Buffer instance
Definition: buffer.h:98
WifiInformationElementId ElementId() const
Own unique Element ID.
uint8_t GetInformationFieldSize() const
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:43
void Read(uint8_t *buffer, uint32_t size)
Definition: buffer.cc:1148
uint8_t DeserializeInformationField(Buffer::Iterator start, uint8_t length)
SupportedRates * m_supportedRates
WifiInformationElementId ElementId() const
Own unique Element ID.
#define NS_LOG_DEBUG(msg)
Definition: log.h:255
void Write(uint8_t const *buffer, uint32_t size)
Definition: buffer.cc:978
uint8_t WifiInformationElementId
uint8_t GetInformationFieldSize() const
void SerializeInformationField(Buffer::Iterator start) const
Buffer::Iterator Serialize(Buffer::Iterator i) const
Serialize entire IE including Element ID and length fields.