A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
wifi-information-element.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2010 Dean Armstrong
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Dean Armstrong <deanarm@gmail.com>
7 */
8
10
11namespace ns3
12{
13
17
18void
19WifiInformationElement::Print(std::ostream& os) const
20{
21}
22
23uint16_t
25{
26 uint16_t size = GetInformationFieldSize();
27
28 if (size <= 255) // size includes the Element ID Extension field
29 {
30 return (2 + size);
31 }
32
33 // the element needs to be fragmented (Sec. 10.28.11 of 802.11-2020)
34 // Let M be the number of IEs of maximum size
35 uint16_t m = size / 255;
36 // N equals 1 if an IE not of maximum size is present at the end, 0 otherwise
37 uint8_t remainder = size % 255;
38 uint8_t n = (remainder > 0) ? 1 : 0;
39
40 return m * (2 + 255) + n * (2 + remainder);
41}
42
45{
46 return 0;
47}
48
51{
52 auto size = GetInformationFieldSize();
53
54 if (size > 255)
55 {
56 return SerializeFragments(i, size);
57 }
58
59 i.WriteU8(ElementId());
60 i.WriteU8(size);
61 if (ElementId() == IE_EXTENSION)
62 {
65 i.Next(size - 1);
66 }
67 else
68 {
70 i.Next(size);
71 }
72 return i;
73}
74
77{
78 NS_ASSERT(size > 255);
79 // let the subclass serialize the IE in a temporary buffer
80 Buffer buffer;
81 buffer.AddAtStart(size);
82 Buffer::Iterator source = buffer.Begin();
84
85 // Let M be the number of IEs of maximum size
86 uint16_t m = size / 255;
87
88 for (uint16_t index = 0; index < m; index++)
89 {
90 i.WriteU8((index == 0) ? ElementId() : IE_FRAGMENT);
91 i.WriteU8(255);
92 uint8_t length = 255;
93 if (index == 0 && ElementId() == IE_EXTENSION)
94 {
96 length = 254;
97 }
98 for (uint8_t count = 0; count < length; count++)
99 {
100 i.WriteU8(source.ReadU8());
101 }
102 }
103
104 // last fragment
105 uint8_t remainder = size % 255;
106
107 if (remainder > 0)
108 {
110 i.WriteU8(remainder);
111 for (uint8_t count = 0; count < remainder; count++)
112 {
113 i.WriteU8(source.ReadU8());
114 }
115 }
116
117 return i;
118}
119
122{
123 Buffer::Iterator start = i;
125 // This IE was not optional, so confirm that we did actually
126 // deserialise something.
127 NS_ASSERT(i.GetDistanceFrom(start) != 0);
128 return i;
129}
130
133{
134 if (i.IsEnd())
135 {
136 return i;
137 }
138 Buffer::Iterator start = i;
139 uint8_t elementId = i.ReadU8();
140
141 // If the element here isn't the one we're after then we immediately
142 // return the iterator we were passed indicating that we haven't
143 // taken anything from the buffer.
144 if (elementId != ElementId())
145 {
146 return start;
147 }
148
149 uint16_t length = i.ReadU8();
150 if (ElementId() == IE_EXTENSION)
151 {
152 uint8_t elementIdExt = i.ReadU8();
153 // If the element here isn't the one we're after then we immediately
154 // return the iterator we were passed indicating that we haven't
155 // taken anything from the buffer.
156 if (elementIdExt != ElementIdExt())
157 {
158 return start;
159 }
160 length--;
161 }
162
163 return DoDeserialize(i, length);
164}
165
168{
169 uint16_t limit = (ElementId() == IE_EXTENSION) ? 254 : 255;
170
171 auto tmp = i;
172 tmp.Next(length); // tmp points to past the last byte of the IE/first fragment
173
174 if (length < limit || tmp.IsEnd() || (tmp.PeekU8() != IE_FRAGMENT))
175 {
176 // no fragments
178 return tmp;
179 }
180
181 NS_ASSERT(length == limit);
182
183 // the IE is fragmented, create a new buffer for the subclass to deserialize from.
184 // Such a destination buffer will not contain the Element ID and Length fields
185 Buffer buffer; // destination buffer
186 buffer.AddAtStart(length); // size of the first fragment
187 Buffer::Iterator bufferIt = buffer.Begin();
188
189 uint16_t count = length;
190 length = 0; // reset length
191
192 // Loop invariant:
193 // - i points to the first byte of the fragment to copy (current fragment)
194 // - bufferIt points to the first location of the destination buffer to write
195 // - there is room in the destination buffer to write the current fragment
196 // - count is the size in bytes of the current fragment
197 // - length is the number of bytes written into the destination buffer
198 while (true)
199 {
200 for (uint16_t index = 0; index < count; index++)
201 {
202 bufferIt.WriteU8(i.ReadU8());
203 }
204 length += count;
205
206 if (i.IsEnd() || (i.PeekU8() != IE_FRAGMENT))
207 {
208 break;
209 }
210 i.Next(1); // skip the Element ID byte
211 count = i.ReadU8(); // length of the next fragment
212
213 buffer.AddAtEnd(count);
214 bufferIt = buffer.Begin();
215 bufferIt.Next(length);
216 }
217
218 DeserializeInformationField(buffer.Begin(), length);
219 return i;
220}
221
222bool
224{
225 if (ElementId() != a.ElementId())
226 {
227 return false;
228 }
229
230 if (ElementIdExt() != a.ElementIdExt())
231 {
232 return false;
233 }
234
235 uint32_t ieSize = GetSerializedSize();
236
237 if (ieSize != a.GetSerializedSize())
238 {
239 return false;
240 }
241
242 Buffer myIe;
243 Buffer hisIe;
244 myIe.AddAtEnd(ieSize);
245 hisIe.AddAtEnd(ieSize);
246
247 Serialize(myIe.Begin());
248 a.Serialize(hisIe.Begin());
249
250 return (memcmp(myIe.PeekData(), hisIe.PeekData(), ieSize) == 0);
251}
252
253std::ostream&
254operator<<(std::ostream& os, const WifiInformationElement& element)
255{
256 element.Print(os);
257 return os;
258}
259
260} // namespace ns3
iterator in a Buffer instance
Definition buffer.h:89
void WriteU8(uint8_t data)
Definition buffer.h:870
bool IsEnd() const
Definition buffer.cc:785
uint32_t GetDistanceFrom(const Iterator &o) const
Definition buffer.cc:769
void Next()
go forward by one byte
Definition buffer.h:842
automatically resized byte buffer
Definition buffer.h:83
void AddAtStart(uint32_t start)
Definition buffer.cc:303
Buffer::Iterator Begin() const
Definition buffer.h:1063
void AddAtEnd(uint32_t end)
Definition buffer.cc:349
const uint8_t * PeekData() const
Definition buffer.cc:692
Information element, as defined in 802.11-2007 standard.
virtual WifiInformationElementId ElementId() const =0
Get the wifi information element ID.
uint16_t GetSerializedSize() const
Get the size of the serialized IE including Element ID and length fields (for every element this IE i...
Buffer::Iterator Deserialize(Buffer::Iterator i)
Deserialize entire IE (which may possibly be fragmented into multiple elements), which must be presen...
Buffer::Iterator Serialize(Buffer::Iterator i) const
Serialize entire IE including Element ID and length fields.
virtual uint16_t DeserializeInformationField(Buffer::Iterator start, uint16_t length)=0
Deserialize information (i.e., the body of the IE, not including the Element ID and length octets)
Buffer::Iterator DeserializeIfPresent(Buffer::Iterator i)
Deserialize entire IE (which may possibly be fragmented into multiple elements) if it is present.
Buffer::Iterator SerializeFragments(Buffer::Iterator i, uint16_t size) const
Serialize an IE that needs to be fragmented.
virtual void Print(std::ostream &os) const
Generate human-readable form of IE.
virtual void SerializeInformationField(Buffer::Iterator start) const =0
Serialize information (i.e., the body of the IE, not including the Element ID and length octets)
virtual uint16_t GetInformationFieldSize() const =0
Length of serialized information (i.e., the length of the body of the IE, not including the Element I...
virtual WifiInformationElementId ElementIdExt() const
Get the wifi information element ID extension.
Buffer::Iterator DoDeserialize(Buffer::Iterator i, uint16_t length)
Deserialize the Information field of an IE.
virtual bool operator==(const WifiInformationElement &a) const
Compare two IEs for equality by ID & Length, and then through memcmp of serialised version.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
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:148
uint8_t WifiInformationElementId
This type is used to represent an Information Element ID.
#define IE_FRAGMENT
#define IE_EXTENSION