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 <algorithm>
12#include <cstdint>
13
14namespace ns3
15{
16
19{
20 return IE_TIM;
21}
22
23uint16_t
25{
26 // When the TIM is carried in a non-S1G PPDU, in the event that all bits other than bit 0 in
27 // the traffic indication virtual bitmap are 0, the Partial Virtual Bitmap field is encoded as
28 // a single octet equal to 0, the Bitmap Offset subfield is 0, and the Length field is 4.
29 // (Sec. 9.4.2.5.1 of 802.11-2020)
30 // The size of the information field is the size of the Partial Virtual Bitmap field,
31 // plus one octet each for the DTIM Count, DTIM Period, and Bitmap Control fields
32 uint16_t partialVirtualBitmapSize =
34 return partialVirtualBitmapSize + 3;
35}
36
37void
38Tim::AddAid(uint16_t aid)
39{
40 NS_ABORT_IF(aid > 2007);
41
42 m_aidValues.insert(aid);
43}
44
45bool
46Tim::HasAid(uint16_t aid) const
47{
48 return m_aidValues.find(aid) != m_aidValues.end();
49}
50
51std::set<uint16_t>
52Tim::GetAidSet(uint16_t aid) const
53{
54 auto start = m_aidValues.upper_bound(aid);
55 return std::set<uint16_t>(start, m_aidValues.cend());
56}
57
58void
60{
61 start.WriteU8(m_dtimCount);
62 start.WriteU8(m_dtimPeriod);
63
64 // the Bitmap Control field is optional if the TIM is carried in an S1G PPDU, while
65 // it is always present when the TIM is carried in a non-S1G PPDU
66 start.WriteU8(GetBitmapControl());
67 auto partialVirtualBitmap = GetPartialVirtualBitmap();
68 for (auto byte : partialVirtualBitmap)
69 {
70 start.WriteU8(byte);
71 }
72}
73
74uint16_t
76{
77 NS_ABORT_MSG_IF(length < 2, "Invalid length: " << length);
78
79 m_dtimCount = start.ReadU8();
80 m_dtimPeriod = start.ReadU8();
81
82 if (length == 2)
83 {
84 // no Bitmap Control field nor Partial Virtual Bitmap field
85 return 2;
86 }
87
88 // Bitmap control field: here we determine the presence of multicast traffic and the offset
89 auto bitmapControl = start.ReadU8();
90 // Least significant bit is the Traffic Indication field
91 m_hasMulticastPending = bitmapControl & 0x01;
92 // Other bits are the Bitmap Offset
93 uint8_t partialVirtualBitmapOffset = bitmapControl & 0xFE;
94 // Next, deserialize the partial virtual bitmap
95 uint16_t octetIndex;
96 // length is the length of the information fields, so we need to
97 // subtract 3 to get the length of the Partial Virtual Bitmap
98 for (octetIndex = partialVirtualBitmapOffset;
99 octetIndex < static_cast<uint16_t>(partialVirtualBitmapOffset + length - 3);
100 ++octetIndex)
101 {
102 if (auto octet = start.ReadU8(); octet > 0)
103 {
104 // Look for bits set to 1
105 for (uint8_t position = 0; position < 8; position++)
106 {
107 if ((octet >> position) & 0x1)
108 {
109 m_aidValues.insert(GetAidFromOctetIndexAndBitPosition(octetIndex, position));
110 }
111 }
112 }
113 }
114 return 3 + octetIndex - partialVirtualBitmapOffset;
115}
116
117uint8_t
118Tim::GetAidOctetIndex(uint16_t aid) const
119{
120 // bit number N (0 <= N <= 2007) in the bitmap corresponds to bit number (N mod 8) in octet
121 // number |_N / 8_| where the low order bit of each octet is bit number 0, and the high order
122 // bit is bit number 7 (Sec. 9.4.2.5.1 of 802.11-2020)
123 return (aid >> 3) & 0xff;
124}
125
126uint8_t
127Tim::GetAidBit(uint16_t aid) const
128{
129 // bit number N (0 <= N <= 2007) in the bitmap corresponds to bit number (N mod 8) in octet
130 // number |_N / 8_| where the low order bit of each octet is bit number 0, and the high order
131 // bit is bit number 7 (Sec. 9.4.2.5.1 of 802.11-2020)
132 return 0x01 << (aid & 0x07);
133}
134
135uint16_t
136Tim::GetAidFromOctetIndexAndBitPosition(uint16_t octet, uint8_t position) const
137{
138 return (octet << 3) + position;
139}
140
141uint8_t
143{
144 if (m_aidValues.empty())
145 {
146 return 0;
147 }
148 // N1 is the largest even number such that bits numbered 1 to (N1 * 8) – 1 in the traffic
149 // indication virtual bitmap are all 0 (Sec. 9.4.2.5.1 of 802.11-2020).
150 // Examples:
151 // first bit set = 53, which belongs to octet 53 / 8 = 6 -> N1 = 6 (all bits 1 - 47 are zero)
152 // first bit set = 61, which belongs to octet 61 / 8 = 7 -> N1 = 6 (all bits 1 - 47 are zero)
153 return GetAidOctetIndex(*m_aidValues.cbegin()) & 0xFE;
154}
155
156uint8_t
158{
159 if (m_aidValues.empty())
160 {
161 return 0;
162 }
163 // N2 is the smallest number such that bits numbered (N2 + 1) * 8 to 2007 in the traffic
164 // indication virtual bitmap are all 0 (Sec. 9.4.2.5.1 of 802.11-2020).
165 // Examples:
166 // last bit set = 53, which belongs to octet 53 / 8 = 6 -> N2 = 6 (all bits 56 - 2007 are zero)
167 // last bit set = 61, which belongs to octet 61 / 8 = 7 -> N2 = 7 (all bits 64 - 2007 are zero)
168 return GetAidOctetIndex(*m_aidValues.rbegin());
169}
170
171uint8_t
173{
174 // Note that setting the bitmapControl directly as the offset can be done because the least
175 // significant bit of the output of GetPartialVirtualBitmapOffset will always be zero, so we
176 // are already putting the relevant information in the appropriate part of the byte.
177 auto bitmapControl = GetPartialVirtualBitmapOffset();
178
179 // Set the multicast indication bit, if this is a DTIM
181 {
182 bitmapControl |= 0x01;
183 }
184
185 return bitmapControl;
186}
187
188std::vector<uint8_t>
190{
191 auto offset = GetPartialVirtualBitmapOffset(); // N1
192
193 // the Partial Virtual Bitmap field consists of octets numbered N1 to N2 of the traffic
194 // indication virtual bitmap (Sec. 9.4.2.5.1 of 802.11-2020)
195 std::vector<uint8_t> partialVirtualBitmap(GetLastNonZeroOctetIndex() - offset + 1, 0);
196
197 for (auto aid : m_aidValues)
198 {
199 partialVirtualBitmap.at(GetAidOctetIndex(aid) - offset) |= GetAidBit(aid);
200 }
201
202 return partialVirtualBitmap;
203}
204
205void
206Tim::Print(std::ostream& os) const
207{
208 os << "DTIM Count: " << +m_dtimCount << ", "
209 << "DTIM Period: " << +m_dtimPeriod << ", "
210 << "Has Multicast Pending: " << m_hasMulticastPending << ", AID values:";
211 for (uint16_t aid = 0; aid < 2008; ++aid)
212 {
213 if (HasAid(aid))
214 {
215 os << aid << " ";
216 }
217 }
218}
219
220} // 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:127
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:75
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:142
std::vector< uint8_t > GetPartialVirtualBitmap() const
Definition tim.cc:189
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:136
void AddAid(uint16_t aid)
Add the provided AID value to the list contained in the Virtual Bitmap.
Definition tim.cc:38
void Print(std::ostream &os) const override
Generate human-readable form of IE.
Definition tim.cc:206
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:118
uint8_t GetLastNonZeroOctetIndex() const
Definition tim.cc:157
WifiInformationElementId ElementId() const override
Get the wifi information element ID.
Definition tim.cc:18
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:52
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:59
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:46
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:172
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:24
#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.
uint8_t WifiInformationElementId
This type is used to represent an Information Element ID.
#define IE_TIM