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 "ns3/log.h"
22 #include "supported-rates.h"
23 
24 namespace ns3 {
25 
26 NS_LOG_COMPONENT_DEFINE ("SupportedRates");
27 
28 #define BSS_MEMBERSHIP_SELECTOR_HT_PHY 127
29 #define BSS_MEMBERSHIP_SELECTOR_VHT_PHY 126
30 #define BSS_MEMBERSHIP_SELECTOR_HE_PHY 125
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");
64  if (IsSupportedRate (bs))
65  {
66  return;
67  }
68  m_rates[m_nRates] = static_cast<uint8_t> (bs / 500000);
69  m_nRates++;
70  NS_LOG_DEBUG ("add rate=" << bs << ", n rates=" << +m_nRates);
71 }
72 
73 void
75 {
76  NS_LOG_FUNCTION (this << bs);
77  NS_ASSERT_MSG (IsBssMembershipSelectorRate (bs) == false, "Invalid rate");
78  uint8_t rate = static_cast<uint8_t> (bs / 500000);
79  for (uint8_t i = 0; i < m_nRates; i++)
80  {
81  if ((rate | 0x80) == m_rates[i])
82  {
83  return;
84  }
85  if (rate == m_rates[i])
86  {
87  NS_LOG_DEBUG ("set basic rate=" << bs << ", n rates=" << +m_nRates);
88  m_rates[i] |= 0x80;
89  return;
90  }
91  }
92  AddSupportedRate (bs);
93  SetBasicRate (bs);
94 }
95 
96 void
98 {
99  NS_LOG_FUNCTION (this << bs);
103  "Value " << bs << " not a BSS Membership Selector");
104  uint8_t rate = static_cast<uint8_t> (bs / 500000);
105  for (uint8_t i = 0; i < m_nRates; i++)
106  {
107  if (rate == m_rates[i])
108  {
109  return;
110  }
111  }
112  m_rates[m_nRates] = rate;
113  NS_LOG_DEBUG ("add BSS membership selector rate " << bs << " as rate " << +rate);
114  m_nRates++;
115 }
116 
117 bool
118 SupportedRates::IsBasicRate (uint64_t bs) const
119 {
120  NS_LOG_FUNCTION (this << bs);
121  uint8_t rate = static_cast<uint8_t> (bs / 500000) | 0x80;
122  for (uint8_t i = 0; i < m_nRates; i++)
123  {
124  if (rate == m_rates[i])
125  {
126  return true;
127  }
128  }
129  return false;
130 }
131 
132 bool
134 {
135  NS_LOG_FUNCTION (this << bs);
136  uint8_t rate = static_cast<uint8_t> (bs / 500000);
137  for (uint8_t i = 0; i < m_nRates; i++)
138  {
139  if (rate == m_rates[i]
140  || (rate | 0x80) == m_rates[i])
141  {
142  return true;
143  }
144  }
145  return false;
146 }
147 
148 bool
150 {
151  NS_LOG_FUNCTION (this << bs);
152  if ((bs & 0x7f) == BSS_MEMBERSHIP_SELECTOR_HT_PHY
153  || (bs & 0x7f) == BSS_MEMBERSHIP_SELECTOR_VHT_PHY
154  || (bs & 0x7f) == BSS_MEMBERSHIP_SELECTOR_HE_PHY)
155  {
156  return true;
157  }
158  return false;
159 }
160 
161 uint8_t
163 {
164  return m_nRates;
165 }
166 
167 uint32_t
168 SupportedRates::GetRate (uint8_t i) const
169 {
170  return (m_rates[i] & 0x7f) * 500000;
171 }
172 
175 {
176  return IE_SUPPORTED_RATES;
177 }
178 
179 uint8_t
181 {
182  //The Supported Rates Information Element contains only the first 8
183  //supported rates - the remainder appear in the Extended Supported
184  //Rates Information Element.
185  return m_nRates > 8 ? 8 : m_nRates;
186 }
187 
188 void
190 {
191  //The Supported Rates Information Element contains only the first 8
192  //supported rates - the remainder appear in the Extended Supported
193  //Rates Information Element.
194  start.Write (m_rates, m_nRates > 8 ? 8 : m_nRates);
195 }
196 
197 uint8_t
199  uint8_t length)
200 {
201  NS_ASSERT (length <= 8);
202  m_nRates = length;
203  start.Read (m_rates, m_nRates);
204  return m_nRates;
205 }
206 
208 {
209 }
210 
212 {
213  m_supportedRates = sr;
214 }
215 
218 {
220 }
221 
222 void
224 {
225  m_supportedRates = sr;
226 }
227 
228 uint8_t
230 {
231  //If there are 8 or fewer rates then we don't need an Extended
232  //Supported Rates IE and so could return zero here, but we're
233  //overriding the GetSerializedSize() method, so if this function is
234  //invoked in that case then it indicates a programming error. Hence
235  //we have an assertion on that condition.
237 
238  //The number of rates we have beyond the initial 8 is the size of
239  //the information field.
240  return (m_supportedRates->m_nRates - 8);
241 }
242 
243 void
245 {
246  //If there are 8 or fewer rates then there should be no Extended
247  //Supported Rates Information Element at all so being here would
248  //seemingly indicate a programming error.
249  //
250  //Our overridden version of the Serialize() method should ensure
251  //that this routine is never invoked in that case (by ensuring that
252  //WifiInformationElement::Serialize() is not invoked).
255 }
256 
259 {
260  //If there are 8 or fewer rates then we don't need an Extended
261  //Supported Rates IE, so we don't serialise anything.
262  if (m_supportedRates->m_nRates <= 8)
263  {
264  return start;
265  }
266 
267  //If there are more than 8 rates then we serialise as per normal.
269 }
270 
271 uint16_t
273 {
274  //If there are 8 or fewer rates then we don't need an Extended
275  //Supported Rates IE, so it's serialised length will be zero.
276  if (m_supportedRates->m_nRates <= 8)
277  {
278  return 0;
279  }
280 
281  //Otherwise, the size of it will be the number of supported rates
282  //beyond 8, plus 2 for the Element ID and Length.
284 }
285 
286 uint8_t
288  uint8_t length)
289 {
290  NS_ASSERT (length > 0);
293  m_supportedRates->m_nRates += length;
294  return length;
295 }
296 
297 std::ostream &operator << (std::ostream &os, const SupportedRates &rates)
298 {
299  os << "[";
300  for (uint8_t i = 0; i < rates.GetNRates (); i++)
301  {
302  uint32_t rate = rates.GetRate (i);
303  if (rates.IsBasicRate (rate))
304  {
305  os << "*";
306  }
307  os << rate / 1000000 << "mbs";
308  if (i < rates.GetNRates () - 1)
309  {
310  os << " ";
311  }
312  }
313  os << "]";
314  return os;
315 }
316 
317 } //namespace ns3
iterator in a Buffer instance
Definition: buffer.h:99
uint8_t DeserializeInformationField(Buffer::Iterator start, uint8_t length) override
Deserialize information (i.e., the body of the IE, not including the Element ID and length octets)
WifiInformationElementId ElementId() const override
SupportedRates * m_supportedRates
This member points to the SupportedRates object that contains the actual rate details.
void SetSupportedRates(SupportedRates *rates)
Set supported rates.
void SerializeInformationField(Buffer::Iterator start) const override
Serialize information (i.e., the body of the IE, not including the Element ID and length octets)
uint8_t GetInformationFieldSize() const override
Length of serialized information (i.e., the length of the body of the IE, not including the Element I...
uint16_t GetSerializedSize() const override
Get the size of the serialized IE including Element ID and length fields.
Buffer::Iterator Serialize(Buffer::Iterator start) const override
Serialize entire IE including Element ID and length fields.
The Supported Rates Information Element.
void SetBasicRate(uint64_t bs)
Set the given rate to basic rates.
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)
WifiInformationElementId ElementId() const
ExtendedSupportedRatesIE extended
extended supported rates info element
void AddBssMembershipSelectorRate(uint64_t bs)
Add a special value to the supported rate set, corresponding to a BSS membership selector.
uint8_t m_nRates
Number of supported rates.
uint8_t m_rates[MAX_SUPPORTED_RATES]
List of supported bit rates (divided by 500000)
SupportedRates & operator=(const SupportedRates &rates)
Assignment operator.
uint8_t GetNRates(void) const
Return the number of supported rates.
uint8_t GetInformationFieldSize() const
Length of serialized information (i.e., the length of the body of the IE, not including the Element I...
void SerializeInformationField(Buffer::Iterator start) const
Serialize information (i.e., the body of the IE, not including the Element ID and length octets)
bool IsBasicRate(uint64_t bs) const
Check if the given rate is a basic rate.
bool IsBssMembershipSelectorRate(uint64_t bs) const
Check if the given rate is a BSS membership selector value.
static const uint8_t MAX_SUPPORTED_RATES
This defines the maximum number of supported rates that a STA is allowed to have.
uint32_t GetRate(uint8_t i) const
Return the rate at the given index.
void AddSupportedRate(uint64_t bs)
Add the given rate to the supported rates.
bool IsSupportedRate(uint64_t bs) const
Check if the given rate is supported.
virtual uint16_t GetSerializedSize() const
Get the size of the serialized IE including Element ID and length fields.
virtual Buffer::Iterator Serialize(Buffer::Iterator i) const
Serialize entire IE including Element ID and length fields.
#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_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:88
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:139
@ extended
Definition: ff-mac-common.h:85
uint8_t WifiInformationElementId
This type is used to represent an Information Element ID.
def start()
Definition: core.py:1853
#define BSS_MEMBERSHIP_SELECTOR_HT_PHY
#define BSS_MEMBERSHIP_SELECTOR_HE_PHY
#define BSS_MEMBERSHIP_SELECTOR_VHT_PHY
#define IE_EXTENDED_SUPPORTED_RATES
#define IE_SUPPORTED_RATES