A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
tid-to-link-mapping-element.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2022
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Author: Sharan Naribole <sharan.naribole@gmail.com>
18 */
19
21
22#include "ns3/assert.h"
23#include "ns3/simulator.h"
24
25namespace ns3
26{
27
28/// Bitmask with all bits from 63 to 26 set to 1, all the others set to 0
29static constexpr uint64_t BIT_63_TO_26_MASK = 0xfffffffffc000000;
30
31uint16_t
33{
34 // IEEE 802.11be D3.1 Figure 9-1002ap
36 "Presence bitmap not expected if default mapping is set");
38 if (!presenceBitmap.has_value())
39 {
40 return size;
41 }
43}
44
45void
47{
48 auto val = static_cast<uint8_t>(direction) | ((defaultMapping ? 1 : 0) << 2) |
49 ((mappingSwitchTimePresent ? 1 : 0) << 3) |
50 ((expectedDurationPresent ? 1 : 0) << 4) | ((linkMappingSize == 1 ? 1 : 0) << 5);
51
52 start.WriteU8(val);
53 NS_ASSERT_MSG(!defaultMapping || !presenceBitmap.has_value(),
54 "Presence bitmap not expected if default mapping is set");
55 if (presenceBitmap.has_value())
56 {
57 start.WriteU8(presenceBitmap.value());
58 }
59}
60
61uint16_t
63{
64 auto i = start;
65 uint8_t count = 0;
66 auto val = i.ReadU8();
67 count++;
68
69 direction = static_cast<WifiDirection>(val & 0x03);
70 defaultMapping = (((val >> 2) & 0x01) == 1);
71 mappingSwitchTimePresent = (((val >> 3) & 0x01) == 1);
72 expectedDurationPresent = (((val >> 4) & 0x01) == 1);
73 linkMappingSize = (((val >> 5) & 0x01) == 1 ? 1 : 2);
74 if (defaultMapping)
75 {
76 presenceBitmap.reset();
77 return count;
78 }
79 presenceBitmap = i.ReadU8();
80 return ++count;
81}
82
85{
86 return IE_EXTENSION;
87}
88
91{
93}
94
95void
97{
98 // The 2 octet Mapping Switch Time field has units of TUs and is set to the time at which
99 // the new mapping is established using as a time-base the value of the TSF corresponding
100 // to the BSS identified by the BSSID of the frame containing the TID-To-Link Mapping
101 // element: i.e., bits 10 to 25 of the TSF. (Sec. 9.4.2.314 of 802.11be D3.1)
102 NS_ABORT_IF(mappingSwitchTime < Simulator::Now());
103 auto switchTimeUsec = static_cast<uint64_t>(mappingSwitchTime.GetMicroSeconds());
104 // set the Mapping Switch Time field to bits 10 to 25 of the given time
105 m_mappingSwitchTime = (switchTimeUsec & ~BIT_63_TO_26_MASK) >> 10;
107}
108
109std::optional<Time>
111{
113 {
114 return std::nullopt;
115 }
116
117 auto nowUsec = static_cast<uint64_t>(Simulator::Now().GetMicroSeconds());
118 uint64_t switchTimeUsec = (*m_mappingSwitchTime << 10) + (nowUsec & BIT_63_TO_26_MASK);
119 if (switchTimeUsec < nowUsec)
120 {
121 // The switch time derived from the value in the corresponding field may be less than the
122 // current time in case the bits 10 to 25 of TSF have been reset since the transmission
123 // of the frame carrying this field. In such a case we have to increase bits 63 to 26 by 1
124 switchTimeUsec += (1 << 26);
125 }
126 return MicroSeconds(switchTimeUsec);
127}
128
129void
131{
132 auto durationTu = static_cast<uint64_t>(expectedDuration.GetMicroSeconds()) >> 10;
133 m_expectedDuration = (durationTu & 0x0000000000ffffff); // Expected Duration size is 3 bytes
135}
136
137std::optional<Time>
139{
141 {
142 return std::nullopt;
143 }
144
145 return MicroSeconds(*m_expectedDuration << 10);
146}
147
148void
149TidToLinkMapping::SetLinkMappingOfTid(uint8_t tid, std::set<uint8_t> linkIds)
150{
151 NS_ABORT_MSG_IF(tid > 7, "Invalid tid: " << +tid);
153 "Per-TID link mapping not expected if default mapping is set");
154
155 // derive link mapping for the given TID
156 uint16_t linkMapping = 0;
157
158 for (const auto& linkId : linkIds)
159 {
160 linkMapping |= (1 << linkId);
161 if (linkId > 7)
162 {
164 }
165 }
166
167 m_linkMapping[tid] = linkMapping;
168 m_control.presenceBitmap = m_control.presenceBitmap.value_or(0) | (1 << tid);
169}
170
171std::set<uint8_t>
173{
174 auto it = m_linkMapping.find(tid);
175
176 if (it == m_linkMapping.cend())
177 {
178 return {};
179 }
180
181 std::set<uint8_t> linkIds;
182 for (uint8_t linkId = 0; linkId < 15; linkId++)
183 {
184 if (((it->second >> linkId) & 0x0001) == 1)
185 {
186 linkIds.insert(linkId);
187 }
188 }
189 NS_ABORT_MSG_IF(linkIds.empty(), "TID " << +tid << " cannot be mapped to an empty link set");
190
191 return linkIds;
192}
193
194uint16_t
196{
197 // IEEE 802.11be D3.1 9.4.2.314 TID-To-Link Mapping element
198 uint16_t ret = WIFI_IE_ELEMENT_ID_EXT_SIZE; // Element ID Extension
199 ret += m_control.GetSubfieldSize();
201 {
202 ret += 2; // Mapping Switch Time
203 }
205 {
206 ret += 3; // Expected Duration
207 }
208
210 "Per-TID link mapping not expected if default mapping is set");
211 ret += m_control.linkMappingSize * (m_linkMapping.size());
212 return ret;
213}
214
215void
217{
218 // IEEE 802.11be D3.1 9.4.2.314 TID-To-Link Mapping element
219 m_control.Serialize(start);
221 {
222 start.WriteHtolsbU16(*m_mappingSwitchTime);
223 }
225 {
226 start.WriteU8((*m_expectedDuration >> 0) & 0xff);
227 start.WriteU8((*m_expectedDuration >> 8) & 0xff);
228 start.WriteU8((*m_expectedDuration >> 16) & 0xff);
229 }
230
232 "Per-TID link mapping not expected if default mapping is set");
233
234 for (const auto& [tid, linkMapping] : m_linkMapping)
235 {
236 if (m_control.linkMappingSize == 1)
237 {
238 start.WriteU8(linkMapping);
239 }
240 else
241 {
242 start.WriteHtolsbU16(linkMapping);
243 }
244 }
245}
246
247uint16_t
249{
250 auto i = start;
251 uint16_t count = 0;
252 auto nCtrlOctets = m_control.Deserialize(i);
253 NS_ASSERT_MSG(nCtrlOctets <= length, "Tid-to-Link Mapping deserialize error");
254 i.Next(nCtrlOctets);
255 count += nCtrlOctets;
257 {
258 m_mappingSwitchTime = i.ReadLsbtohU16();
259 count += 2;
260 }
262 {
263 uint8_t byte0 = i.ReadU8();
264 uint8_t byte1 = i.ReadU8();
265 uint8_t byte2 = i.ReadU8();
266 m_expectedDuration = byte2;
267 m_expectedDuration.value() <<= 8;
268 m_expectedDuration.value() |= byte1;
269 m_expectedDuration.value() <<= 8;
270 m_expectedDuration.value() |= byte0;
271 count += 3;
272 }
273 m_linkMapping.clear();
274 if (m_control.presenceBitmap.has_value())
275 {
277 "Default mapping should not be set when presence bitmap is present");
278 const auto presenceBitmap = m_control.presenceBitmap.value();
279 for (uint8_t tid = 0; tid < 8; tid++)
280 {
281 if (((presenceBitmap >> tid) & 0x01) == 1)
282 {
283 if (m_control.linkMappingSize == 1)
284 {
285 m_linkMapping[tid] = i.ReadU8();
286 count++;
287 }
288 else
289 {
290 m_linkMapping[tid] = i.ReadLsbtohU16();
291 count += 2;
292 }
293 }
294 }
295 }
296
297 NS_ABORT_MSG_IF(count != length,
298 "TID-to-Link Mapping Length (" << +length
299 << ") differs "
300 "from actual number of bytes read ("
301 << +count << ")");
302 return count;
303}
304
305} // namespace ns3
iterator in a Buffer instance
Definition: buffer.h:100
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
int64_t GetMicroSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:413
#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:86
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
#define NS_ABORT_IF(cond)
Abnormal program termination if a condition is true.
Definition: abort.h:76
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1343
Every class exported by the ns3 library is enclosed in the ns3 namespace.
constexpr uint16_t WIFI_TID_TO_LINK_MAPPING_CONTROL_BASIC_SIZE_B
size in bytes of the TID-To-Link Control field with default link mapping
static constexpr uint64_t BIT_63_TO_26_MASK
Bitmask with all bits from 63 to 26 set to 1, all the others set to 0.
constexpr uint8_t WIFI_IE_ELEMENT_ID_EXT_SIZE
Size in bytes of the Element ID Extension field (IEEE 802.11-2020 9.4.2.1 General)
WifiDirection
Wifi direction.
Definition: wifi-utils.h:43
constexpr uint16_t WIFI_LINK_MAPPING_PRESENCE_IND_SIZE_B
size in bytes of the Link Mapping Presence Indicator field (IEEE 802.11be D2.0 9.4....
uint8_t WifiInformationElementId
This type is used to represent an Information Element ID.
#define IE_EXTENSION
#define IE_EXT_TID_TO_LINK_MAPPING_ELEMENT