A Discrete-Event Network Simulator
API
supported-rates.cc
Go to the documentation of this file.
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 namespace ns3 {
26 
27 NS_LOG_COMPONENT_DEFINE ("SupportedRates");
28 
29 #define BSS_MEMBERSHIP_SELECTOR_HT_PHY 127
30 #define BSS_MEMBERSHIP_SELECTOR_VHT_PHY 126
31 
33  : extended (this),
34  m_nRates (0)
35 {
36  NS_LOG_FUNCTION (this);
37 }
38 
40 {
41  NS_LOG_FUNCTION (this);
42  m_nRates = rates.m_nRates;
43  memcpy (m_rates, rates.m_rates, MAX_SUPPORTED_RATES);
44  //reset the back pointer to this object
46 }
47 
50 {
51  this->m_nRates = rates.m_nRates;
52  memcpy (this->m_rates, rates.m_rates, MAX_SUPPORTED_RATES);
53  //reset the back pointer to this object
54  this->extended.SetSupportedRates (this);
55  return (*this);
56 }
57 
58 void
60 {
61  NS_LOG_FUNCTION (this << bs);
62  NS_ASSERT_MSG (IsBssMembershipSelectorRate (bs) == false, "Invalid rate");
65  {
66  // Encoding defined in Sec. 8.4.2.3, IEEE 802.11-2012
68  m_nRates++;
69  NS_LOG_DEBUG ("add HT_PHY membership selector");
70  }
71  else if (bs == BSS_MEMBERSHIP_SELECTOR_VHT_PHY)
72  {
73  // Encoding defined in Sec. 8.4.2.3, IEEE 802.11-2012
75  m_nRates++;
76  NS_LOG_DEBUG ("add VHT_PHY membership selector");
77  }
78  else
79  {
80  if (IsSupportedRate (bs))
81  {
82  return;
83  }
84  m_rates[m_nRates] = bs / 500000;
85  m_nRates++;
86  NS_LOG_DEBUG ("add rate=" << bs << ", n rates=" << (uint32_t)m_nRates);
87  }
88 }
89 
90 void
92 {
93  NS_LOG_FUNCTION (this << bs);
94  NS_ASSERT_MSG (IsBssMembershipSelectorRate (bs) == false, "Invalid rate");
95  uint8_t rate = bs / 500000;
96  for (uint8_t i = 0; i < m_nRates; i++)
97  {
98  if ((rate | 0x80) == m_rates[i])
99  {
100  return;
101  }
102  if (rate == m_rates[i])
103  {
104  NS_LOG_DEBUG ("set basic rate=" << bs << ", n rates=" << (uint32_t)m_nRates);
105  m_rates[i] |= 0x80;
106  return;
107  }
108  }
109  AddSupportedRate (bs);
110  SetBasicRate (bs);
111 }
112 
113 void
115 {
116  NS_LOG_FUNCTION (this << bs);
118  {
119  NS_ASSERT_MSG (false, "Value " << bs << " not a BSS Membership Selector");
120  }
121  uint32_t rate = (bs | 0x80);
122  for (uint8_t i = 0; i < m_nRates; i++)
123  {
124  if (rate == m_rates[i])
125  {
126  return;
127  }
128  }
129  m_rates[m_nRates] = rate;
130  NS_LOG_DEBUG ("add BSS membership selector rate " << bs << " as rate " << m_nRates);
131  m_nRates++;
132 }
133 
134 bool
135 SupportedRates::IsBasicRate (uint32_t bs) const
136 {
137  NS_LOG_FUNCTION (this << bs);
138  uint8_t rate = (bs / 500000) | 0x80;
139  for (uint8_t i = 0; i < m_nRates; i++)
140  {
141  if (rate == m_rates[i])
142  {
143  return true;
144  }
145  }
146  return false;
147 }
148 
149 bool
151 {
152  NS_LOG_FUNCTION (this << bs);
153  uint8_t rate = bs / 500000;
154  for (uint8_t i = 0; i < m_nRates; i++)
155  {
156  if (rate == m_rates[i]
157  || (rate | 0x80) == m_rates[i])
158  {
159  return true;
160  }
161  }
162  return false;
163 }
164 
165 bool
167 {
168  NS_LOG_FUNCTION (this << bs);
169  if ( (bs & 0x7f) == BSS_MEMBERSHIP_SELECTOR_HT_PHY || (bs & 0x7f) == BSS_MEMBERSHIP_SELECTOR_VHT_PHY)
170  {
171  return true;
172  }
173  return false;
174 }
175 
176 uint8_t
178 {
179  return m_nRates;
180 }
181 
182 uint32_t
183 SupportedRates::GetRate (uint8_t i) const
184 {
185  return (m_rates[i] & 0x7f) * 500000;
186 }
187 
190 {
191  return IE_SUPPORTED_RATES;
192 }
193 
194 uint8_t
196 {
197  //The Supported Rates Information Element contains only the first 8
198  //supported rates - the remainder appear in the Extended Supported
199  //Rates Information Element.
200  return m_nRates > 8 ? 8 : m_nRates;
201 }
202 
203 void
205 {
206  //The Supported Rates Information Element contains only the first 8
207  //supported rates - the remainder appear in the Extended Supported
208  //Rates Information Element.
209  start.Write (m_rates, m_nRates > 8 ? 8 : m_nRates);
210 }
211 
212 uint8_t
214  uint8_t length)
215 {
216  NS_ASSERT (length <= 8);
217  m_nRates = length;
218  start.Read (m_rates, m_nRates);
219  return m_nRates;
220 }
221 
223 {
224 }
225 
227 {
228  m_supportedRates = sr;
229 }
230 
233 {
235 }
236 
237 void
239 {
240  m_supportedRates = sr;
241 }
242 
243 uint8_t
245 {
246  //If there are 8 or fewer rates then we don't need an Extended
247  //Supported Rates IE and so could return zero here, but we're
248  //overriding the GetSerializedSize() method, so if this function is
249  //invoked in that case then it indicates a programming error. Hence
250  //we have an assertion on that condition.
252 
253  //The number of rates we have beyond the initial 8 is the size of
254  //the information field.
255  return (m_supportedRates->m_nRates - 8);
256 }
257 
258 void
260 {
261  //If there are 8 or fewer rates then there should be no Extended
262  //Supported Rates Information Element at all so being here would
263  //seemingly indicate a programming error.
264  //
265  //Our overridden version of the Serialize() method should ensure
266  //that this routine is never invoked in that case (by ensuring that
267  //WifiInformationElement::Serialize() is not invoked).
270 }
271 
274 {
275  //If there are 8 or fewer rates then we don't need an Extended
276  //Supported Rates IE, so we don't serialise anything.
277  if (m_supportedRates->m_nRates <= 8)
278  {
279  return start;
280  }
281 
282  //If there are more than 8 rates then we serialise as per normal.
283  return WifiInformationElement::Serialize (start);
284 }
285 
286 uint16_t
288 {
289  //If there are 8 or fewer rates then we don't need an Extended
290  //Supported Rates IE, so it's serialised length will be zero.
291  if (m_supportedRates->m_nRates <= 8)
292  {
293  return 0;
294  }
295 
296  //Otherwise, the size of it will be the number of supported rates
297  //beyond 8, plus 2 for the Element ID and Length.
299 }
300 
301 uint8_t
303  uint8_t length)
304 {
305  NS_ASSERT (length > 0);
308  m_supportedRates->m_nRates += length;
309  return length;
310 }
311 
320 std::ostream &operator << (std::ostream &os, const SupportedRates &rates)
321 {
322  os << "[";
323  for (uint8_t i = 0; i < rates.GetNRates (); i++)
324  {
325  uint32_t rate = rates.GetRate (i);
326  if (rates.IsBasicRate (rate))
327  {
328  os << "*";
329  }
330  os << rate / 1000000 << "mbs";
331  if (i < rates.GetNRates () - 1)
332  {
333  os << " ";
334  }
335  }
336  os << "]";
337  return os;
338 }
339 
340 } //namespace ns3
uint32_t GetRate(uint8_t i) const
Return the rate at the given index.
void AddSupportedRate(uint32_t bs)
Add the given rate to the supported rates.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
uint8_t DeserializeInformationField(Buffer::Iterator start, uint8_t length)
Deserialize information (i.e., the body of the IE, not including the Element ID and length octets) ...
def start()
Definition: core.py:1482
uint16_t GetSerializedSize() const
Return the serialized size of this supported rates information element.
#define BSS_MEMBERSHIP_SELECTOR_HT_PHY
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
uint8_t GetNRates(void) const
Return the number of supported rates.
void SerializeInformationField(Buffer::Iterator start) const
Serialize information (i.e., the body of the IE, not including the Element ID and length octets) ...
The Supported Rates Information ElementThis class knows how to serialise and deserialise the Supporte...
uint16_t GetSerializedSize() const
Get the size of the serialized IE including Element ID and length fields.
iterator in a Buffer instance
Definition: buffer.h:98
ExtendedSupportedRatesIE extended
Buffer::Iterator Serialize(Buffer::Iterator start) const
This information element is a bit special in that it is only included if there are more than 8 rates...
WifiInformationElementId ElementId() const
Own unique Element ID.
uint8_t GetInformationFieldSize() const
Length of serialized information (i.e., the length of the body of the IE, not including the Element I...
#define IE_SUPPORTED_RATES
void SetSupportedRates(SupportedRates *rates)
void SetBasicRate(uint32_t bs)
Set the given rate to basic rates.
std::ostream & operator<<(std::ostream &os, const Angles &a)
print a struct Angles to output
Definition: angles.cc:42
bool IsBasicRate(uint32_t bs) const
Check if the given rate is a basic rate.
uint8_t m_nRates
Number of supported rates.
void AddBssMembershipSelectorRate(uint32_t bs)
Add a special value to the supported rate set, corresponding to a BSS membership selector.
#define IE_EXTENDED_SUPPORTED_RATES
Every class exported by the ns3 library is enclosed in the ns3 namespace.
uint8_t m_rates[MAX_SUPPORTED_RATES]
List of supported bitrate (divided by 500000)
void Read(uint8_t *buffer, uint32_t size)
Definition: buffer.cc:1123
uint8_t DeserializeInformationField(Buffer::Iterator start, uint8_t length)
Deserialize information (i.e., the body of the IE, not including the Element ID and length octets) ...
#define BSS_MEMBERSHIP_SELECTOR_VHT_PHY
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:90
SupportedRates * m_supportedRates
This member points to the SupportedRates object that contains the actual rate details.
WifiInformationElementId ElementId() const
Own unique Element ID.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:236
void Write(uint8_t const *buffer, uint32_t size)
Definition: buffer.cc:953
bool IsSupportedRate(uint32_t bs) const
Check if the given rate is supported.
uint8_t WifiInformationElementId
This type is used to represent an Information Element ID.
uint8_t GetInformationFieldSize() const
Length of serialized information (i.e., the length of the body of the IE, not including the Element I...
SupportedRates & operator=(const SupportedRates &)
void SerializeInformationField(Buffer::Iterator start) const
Serialize information (i.e., the body of the IE, not including the Element ID and length octets) ...
static const uint8_t MAX_SUPPORTED_RATES
This defines the maximum number of supported rates that a STA is allowed to have. ...
Buffer::Iterator Serialize(Buffer::Iterator i) const
Serialize entire IE including Element ID and length fields.
bool IsBssMembershipSelectorRate(uint32_t bs) const
Check if the given rate is a BSS membership selector value.