A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
tim.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2022 Universita' degli Studi di Napoli Federico II
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Davide Magrin <davide@magr.in>
7 */
8
9#include "tim.h"
10
11#include "wifi-constants.h"
12
13#include <algorithm>
14#include <cstdint>
15
16namespace ns3
17{
18
21{
22 return IE_TIM;
23}
24
25uint16_t
27{
28 // When the TIM is carried in a non-S1G PPDU, in the event that all bits other than bit 0 in
29 // the traffic indication virtual bitmap are 0, the Partial Virtual Bitmap field is encoded as
30 // a single octet equal to 0, the Bitmap Offset subfield is 0, and the Length field is 4.
31 // (Sec. 9.4.2.5.1 of 802.11-2020)
32 // The size of the information field is the size of the Partial Virtual Bitmap field,
33 // plus one octet each for the DTIM Count, DTIM Period, and Bitmap Control fields
34 uint16_t partialVirtualBitmapSize =
36 return partialVirtualBitmapSize + 3;
37}
38
39void
40Tim::AddAid(uint16_t aid)
41{
42 NS_ABORT_IF(aid > MAX_AID);
43
44 m_aidValues.insert(aid);
45}
46
47bool
48Tim::HasAid(uint16_t aid) const
49{
50 return m_aidValues.find(aid) != m_aidValues.end();
51}
52
53std::set<uint16_t>
54Tim::GetAidSet(uint16_t aid) const
55{
56 auto start = m_aidValues.upper_bound(aid);
57 return std::set<uint16_t>(start, m_aidValues.cend());
58}
59
60void
62{
63 start.WriteU8(m_dtimCount);
64 start.WriteU8(m_dtimPeriod);
65
66 // the Bitmap Control field is optional if the TIM is carried in an S1G PPDU, while
67 // it is always present when the TIM is carried in a non-S1G PPDU
68 start.WriteU8(GetBitmapControl());
69 auto partialVirtualBitmap = GetPartialVirtualBitmap();
70 for (auto byte : partialVirtualBitmap)
71 {
72 start.WriteU8(byte);
73 }
74}
75
76uint16_t
78{
79 NS_ABORT_MSG_IF(length < 2, "Invalid length: " << length);
80
81 m_dtimCount = start.ReadU8();
82 m_dtimPeriod = start.ReadU8();
83
84 if (length == 2)
85 {
86 // no Bitmap Control field nor Partial Virtual Bitmap field
87 return 2;
88 }
89
90 // Bitmap control field: here we determine the presence of multicast traffic and the offset
91 auto bitmapControl = start.ReadU8();
92 // Least significant bit is the Traffic Indication field
93 m_hasMulticastPending = bitmapControl & 0x01;
94 // Other bits are the Bitmap Offset
95 uint8_t partialVirtualBitmapOffset = bitmapControl & 0xFE;
96 // Next, deserialize the partial virtual bitmap
97 uint16_t octetIndex;
98 // length is the length of the information fields, so we need to
99 // subtract 3 to get the length of the Partial Virtual Bitmap
100 for (octetIndex = partialVirtualBitmapOffset;
101 octetIndex < static_cast<uint16_t>(partialVirtualBitmapOffset + length - 3);
102 ++octetIndex)
103 {
104 if (auto octet = start.ReadU8(); octet > 0)
105 {
106 // Look for bits set to 1
107 for (uint8_t position = 0; position < 8; position++)
108 {
109 if ((octet >> position) & 0x1)
110 {
111 m_aidValues.insert(GetAidFromOctetIndexAndBitPosition(octetIndex, position));
112 }
113 }
114 }
115 }
116 return 3 + octetIndex - partialVirtualBitmapOffset;
117}
118
119uint8_t
120Tim::GetAidOctetIndex(uint16_t aid) const
121{
122 // bit number N (0 <= N <= 2007) in the bitmap corresponds to bit number (N mod 8) in octet
123 // number |_N / 8_| where the low order bit of each octet is bit number 0, and the high order
124 // bit is bit number 7 (Sec. 9.4.2.5.1 of 802.11-2020)
125 return (aid >> 3) & 0xff;
126}
127
128uint8_t
129Tim::GetAidBit(uint16_t aid) const
130{
131 // bit number N (0 <= N <= 2007) in the bitmap corresponds to bit number (N mod 8) in octet
132 // number |_N / 8_| where the low order bit of each octet is bit number 0, and the high order
133 // bit is bit number 7 (Sec. 9.4.2.5.1 of 802.11-2020)
134 return 0x01 << (aid & 0x07);
135}
136
137uint16_t
138Tim::GetAidFromOctetIndexAndBitPosition(uint16_t octet, uint8_t position) const
139{
140 return (octet << 3) + position;
141}
142
143uint8_t
145{
146 if (m_aidValues.empty())
147 {
148 return 0;
149 }
150 // N1 is the largest even number such that bits numbered 1 to (N1 * 8) – 1 in the traffic
151 // indication virtual bitmap are all 0 (Sec. 9.4.2.5.1 of 802.11-2020).
152 // Examples:
153 // first bit set = 53, which belongs to octet 53 / 8 = 6 -> N1 = 6 (all bits 1 - 47 are zero)
154 // first bit set = 61, which belongs to octet 61 / 8 = 7 -> N1 = 6 (all bits 1 - 47 are zero)
155 return GetAidOctetIndex(*m_aidValues.cbegin()) & 0xFE;
156}
157
158uint8_t
160{
161 if (m_aidValues.empty())
162 {
163 return 0;
164 }
165 // N2 is the smallest number such that bits numbered (N2 + 1) * 8 to 2007 in the traffic
166 // indication virtual bitmap are all 0 (Sec. 9.4.2.5.1 of 802.11-2020).
167 // Examples:
168 // last bit set = 53, which belongs to octet 53 / 8 = 6 -> N2 = 6 (all bits 56 - 2007 are zero)
169 // last bit set = 61, which belongs to octet 61 / 8 = 7 -> N2 = 7 (all bits 64 - 2007 are zero)
170 return GetAidOctetIndex(*m_aidValues.rbegin());
171}
172
173uint8_t
175{
176 // Note that setting the bitmapControl directly as the offset can be done because the least
177 // significant bit of the output of GetPartialVirtualBitmapOffset will always be zero, so we
178 // are already putting the relevant information in the appropriate part of the byte.
179 auto bitmapControl = GetPartialVirtualBitmapOffset();
180
181 // Set the multicast indication bit, if this is a DTIM
183 {
184 bitmapControl |= 0x01;
185 }
186
187 return bitmapControl;
188}
189
190std::vector<uint8_t>
192{
193 auto offset = GetPartialVirtualBitmapOffset(); // N1
194
195 // the Partial Virtual Bitmap field consists of octets numbered N1 to N2 of the traffic
196 // indication virtual bitmap (Sec. 9.4.2.5.1 of 802.11-2020)
197 std::vector<uint8_t> partialVirtualBitmap(GetLastNonZeroOctetIndex() - offset + 1, 0);
198
199 for (auto aid : m_aidValues)
200 {
201 partialVirtualBitmap.at(GetAidOctetIndex(aid) - offset) |= GetAidBit(aid);
202 }
203
204 return partialVirtualBitmap;
205}
206
207void
208Tim::Print(std::ostream& os) const
209{
210 os << "TIM=[DTIM Count: " << +m_dtimCount << ", DTIM Period: " << +m_dtimPeriod
211 << ", Has Multicast Pending: " << m_hasMulticastPending << ", AID values: ";
212 for (uint16_t aid = 0; aid < 2008; ++aid)
213 {
214 if (HasAid(aid))
215 {
216 os << aid << " ";
217 }
218 }
219 os << "]";
220}
221
222} // namespace ns3
iterator in a Buffer instance
Definition buffer.h:89
std::set< uint16_t > m_aidValues
List of AID values included in this TIM.
Definition tim.h:135
uint8_t GetAidBit(uint16_t aid) const
Obtain an octet with a set bit, corresponding to the provided AID value.
Definition tim.cc:129
uint16_t DeserializeInformationField(Buffer::Iterator start, uint16_t length) override
Deserialize information (i.e., the body of the IE, not including the Element ID and length octets)
Definition tim.cc:77
uint8_t m_dtimPeriod
The DTIM Period field.
Definition tim.h:86
uint8_t GetPartialVirtualBitmapOffset() const
Get the Partial Virtual Bitmap offset, i.e., the number (denoted as N1 by the specs) of the first oct...
Definition tim.cc:144
std::vector< uint8_t > GetPartialVirtualBitmap() const
Definition tim.cc:191
uint8_t m_dtimCount
The DTIM Count field.
Definition tim.h:85
uint16_t GetAidFromOctetIndexAndBitPosition(uint16_t octet, uint8_t position) const
Obtain the AID value represented by a certain octet index and bit position inside the Virtual Bitmap.
Definition tim.cc:138
void AddAid(uint16_t aid)
Add the provided AID value to the list contained in the Virtual Bitmap.
Definition tim.cc:40
void Print(std::ostream &os) const override
Generate human-readable form of IE.
Definition tim.cc:208
uint8_t GetAidOctetIndex(uint16_t aid) const
Obtain the index of the octet where the provided AID value should be set in the Virtual Bitmap.
Definition tim.cc:120
uint8_t GetLastNonZeroOctetIndex() const
Definition tim.cc:159
WifiInformationElementId ElementId() const override
Get the wifi information element ID.
Definition tim.cc:20
std::set< uint16_t > GetAidSet(uint16_t aid=0) const
Return the AID values, greater than the given AID value, whose corresponding bits are set in the virt...
Definition tim.cc:54
bool m_hasMulticastPending
Whether there is Multicast / Broadcast data.
Definition tim.h:87
void SerializeInformationField(Buffer::Iterator start) const override
Serialize information (i.e., the body of the IE, not including the Element ID and length octets)
Definition tim.cc:61
bool HasAid(uint16_t aid) const
Check whether the bit corresponding to the provided AID is set in the Virtual Bitmap included in this...
Definition tim.cc:48
uint8_t GetBitmapControl() const
The Bitmap Control field is optional if the TIM is carried in an S1G PPDU, while it is always present...
Definition tim.cc:174
uint16_t GetInformationFieldSize() const override
Length of serialized information (i.e., the length of the body of the IE, not including the Element I...
Definition tim.cc:26
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition abort.h:97
#define NS_ABORT_IF(cond)
Abnormal program termination if a condition is true.
Definition abort.h:65
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static constexpr uint16_t MAX_AID
The maximum value for the association ID (Sec. 9.4.1.8 of 802.11-2020)
uint8_t WifiInformationElementId
This type is used to represent an Information Element ID.
Declaration of the constants used across wifi module.
#define IE_TIM