A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
wifi-tx-stats-helper.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2024 Huazhong University of Science and Technology
3 * Copyright (c) 2024 University of Washington
4 *
5 * SPDX-License-Identifier: GPL-2.0-only
6 *
7 * Authors: Muyuan Shen <muyuan@uw.edu>
8 * Hao Yin <haoyin@uw.edu>
9 */
10
11#ifndef WIFI_TX_STATS_HELPER_H
12#define WIFI_TX_STATS_HELPER_H
13
14#include "ns3/nstime.h"
15#include "ns3/object.h"
16#include "ns3/qos-utils.h"
17#include "ns3/type-id.h"
18#include "ns3/wifi-mac.h"
19#include "ns3/wifi-types.h"
20#include "ns3/wifi-utils.h"
21
22#include <cstdint>
23#include <functional>
24#include <map>
25#include <string>
26#include <tuple>
27#include <vector>
28
29namespace ns3
30{
31
33class NodeContainer;
34class Time;
35class Packet;
36class WifiMpdu;
37
38/**
39 * @brief Statistics helper for tracking outcomes of data MPDU transmissions.
40 *
41 * This helper may be used to track statistics of all data MPDU transmissions on a given Node,
42 * WifiNetDevice, or even link granularity (for MLO operation), including counts of the
43 * number of successfully acknowledged MPDUs, the number of retransmissions (if any) of
44 * those successfully acknowledged MPDUs, and the number of failed MPDUs (by drop reason).
45 * The helper can also be used to access timestamped data about how long the MPDU was enqueued
46 * and how long it took to complete acknowledgement (or failure) once the first transmission
47 * of it was attempted. For failed MPDUs, their WifiMacDropReason can be accessed.
48 */
50{
51 public:
52 /**
53 * When Multi-Link Operation (MLO) is used, it is possible for MPDUs to be sent on
54 * multiple links concurrently. When such an MPDU is acked, a question arises as to how
55 * to count the number of successes (only one success, or success on each link). The
56 * ACK does not convey which transmission on which link triggered the event. Therefore,
57 * two policies are defined for how to count a successful event.
58 * 1) FIRST_LINK_IN_SET: Count the success on the first link of the set of in-flight links
59 * 2) ALL_LINKS: Count the success on all links in the in-flight link set
60 */
66
67 /**
68 * Structure for recording information about an individual data MPDU transmission.
69 */
71 {
72 uint32_t m_nodeId{std::numeric_limits<uint32_t>::max()}; //!< The sending node ID
73 uint32_t m_deviceId{std::numeric_limits<uint32_t>::max()}; //!< The sending device ID
74 Time m_enqueueTime; //!< The enqueue time (time that the packet was added to a WifiMacQueue)
75 Time m_txStartTime; //!< The time at which the MPDU was first transmitted
76 std::optional<Time> m_dropTime; //!< The time of removal from the WifiMacQueue, if failed
77 Time m_ackTime; //!< The time at which the MPDU was acknowledged
78 uint64_t m_mpduSeqNum{0}; //!< The MPDU sequence number
79 uint32_t m_retransmissions{0}; //!< A count of the number of retransmissions of the MPDU
80 uint8_t m_tid{WIFI_TID_UNDEFINED}; //!< The TID for the MPDU
81 std::set<uint8_t> m_successLinkIdSet; //!< If acked, the set of in-flight link ID(s)
82 std::optional<WifiMacDropReason> m_dropReason; //!< If failed, the drop reason
83 };
84
85 /**
86 * Default constructor; start time initialized to zero and stop time to Time::Max()
87 */
89 /**
90 * Construct a helper with start and stop times. Only those MPDUs
91 * enqueued between the start and stop times will be counted.
92 *
93 * @param startTime The measurement start time
94 * @param stopTime The measurement stop time
95 */
97
98 /**
99 * Enables trace collection for all nodes and WifiNetDevices in the specified NodeContainer.
100 * @param nodes The NodeContainer to which traces are to be connected.
101 */
102 void Enable(const NodeContainer& nodes);
103 /**
104 * Enables trace collection for all WifiNetDevices in the specified NetDeviceContainer.
105 * @param devices The NetDeviceContainer to which traces are to be connected.
106 */
107 void Enable(const NetDeviceContainer& devices);
108 /**
109 * @brief Set the start time for statistics collection
110 *
111 * No MPDUs enqueued before startTime will be included
112 * in the statistics.
113 *
114 * @param startTime The measurement start time
115 */
116 void Start(Time startTime);
117 /**
118 * @brief Set the stop time for statistics collection
119 *
120 * No MPDUs enqueued after stopTime elapses will be included in
121 * statistics. However, MPDUs that were enqueued before stopTime
122 * (and after startTime) will be included in the statistics if
123 * they are dequeued before the statistics are queried by the user.
124 *
125 * @param stopTime The measurement stop time
126 */
127 void Stop(Time stopTime);
128 /**
129 * @brief Clear the data structures for all completed successful and failed MpduRecords
130 */
131 void Reset();
132
133 //
134 // Hash function and unordered maps
135 //
136
137 /**
138 * Hash function for the tuples used in unordered_maps
139 */
141 {
142 /**
143 * Combines two hash values into one (similar to boost::hash_combine)
144 * @param seed the starting hash point
145 * @param value the value to combine to the hash
146 */
147 template <typename T>
148 void hash_combine(size_t& seed, const T& value) const
149 {
150 seed ^= std::hash<T>{}(value) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
151 }
152
153 /**
154 * Hash function for tuples of arbitrary size
155 * @param tuple the input Tuple
156 * @return the hash of the tuple elements
157 */
158 template <typename Tuple, size_t Index = 0>
159 size_t tuple_hash(const Tuple& tuple) const
160 {
161 if constexpr (Index < std::tuple_size_v<Tuple>)
162 {
163 size_t seed = tuple_hash<Tuple, Index + 1>(tuple);
164 hash_combine(seed, std::get<Index>(tuple));
165 return seed;
166 }
167 else
168 {
169 return 0; // Base case
170 }
171 }
172
173 /**
174 * Operator overload for calculating hash of tuple
175 * @param tuple the input Tuple
176 * @return the hash of the tuple elements
177 */
178 template <typename... Args>
179 size_t operator()(const std::tuple<Args...>& tuple) const
180 {
181 return tuple_hash(tuple);
182 }
183 };
184
186 std::unordered_map<std::tuple<uint32_t, uint32_t, uint8_t>,
187 uint64_t,
188 TupleHash>; //!< std::unordered_map of {nodeId, deviceId, linkId} tuple
189 //!< to counter value
191 std::unordered_map<std::tuple<uint32_t, uint32_t>,
192 uint64_t,
193 TupleHash>; //!< std::unordered_map of {nodeId, deviceId} tuple to
194 //!< counter value
196 std::unordered_map<std::tuple<uint32_t, uint32_t, uint8_t>,
197 std::list<MpduRecord>,
198 TupleHash>; //!< std::unordered_map of {nodeId, deviceId, linkId} tuple
199 //!< to a list of MPDU records
201 std::unordered_map<std::tuple<uint32_t, uint32_t>,
202 std::list<MpduRecord>,
203 TupleHash>; //!< std::unordered_map of {nodeId, deviceId} tuple to a list
204 //!< of MPDU records
205
206 //
207 // Methods to retrieve the counts tabulated by this helper
208 //
209
210 /**
211 * @brief Return the counts of successful MPDU transmissions in a hash map
212 *
213 * The return type is an std::unordered_map, and the keys are tuples of {node ID,
214 * device ID}. The value returned by indexing the tuple is the count of
215 * successful MPDU transmissions.
216 *
217 * If Multi-Link Operation (MLO) is configured, a variant of this method is available
218 * that returns an unordered_map indexed by a tuple that includes the Link ID, for
219 * more granular statistics reporting.
220 * @see GetSuccessesByNodeDeviceLink
221 *
222 * If Multi-Link Operation (MLO) is configured, and MPDUs are sent on multiple
223 * links in parallel, this method will count one success for any such acknowledged
224 * MPDU (even if it was successfully received on more than one link).
225 *
226 * @return A hash map with counts of MPDU successful transmissions
227 */
229 /**
230 * @brief Return the counts of successful MPDU transmissions in a hash map
231 * @param type how the statistics handle a successful MPDU transmitted on multiple links
232 *
233 * The return type is an std::unordered_map, and the keys are tuples of {node ID,
234 * device ID, link ID}. The value returned by indexing the tuple is the count of
235 * successful MPDU transmissions.
236 *
237 * The link ID corresponds to the link for which the MPDU was successfully
238 * acknowledged, regardless of the links that may have been used in
239 * earlier transmissions of the MPDU.
240 *
241 * For a similar method that does not use Link IDs in the key,
242 * @see GetSuccessesByNodeDevice
243 *
244 * @return A hash map with counts of MPDU successful transmissions
245 */
248 /**
249 * @brief Return the counts of failed MPDU transmissions in a hash map
250 *
251 * The return type is an std::unordered_map, and the keys are tuples of {node ID,
252 * device ID}. The value returned by indexing the tuple is the count of
253 * failed MPDU transmissions.
254 *
255 * The number of failures are only stored with the granularity
256 * of per-device, since in a multi-link scenario, some retransmissions
257 * (that lead to eventual failure) may occur on different links.
258 *
259 * @return A hash map with counts of MPDU failed transmissions
260 */
262 /**
263 * @brief Return the counts of failed MPDU transmissions due to given drop reason in a hash map
264 * @param reason Reason for dropping the MPDU
265 *
266 * The return type is an std::unordered_map, and the keys are tuples of {node ID,
267 * device ID}. The value returned by indexing the tuple is the count of
268 * failed MPDU transmissions due to the reason given.
269 *
270 * The number of failures are only stored with the granularity
271 * of per-device, since in a multi-link scenario, some retransmissions
272 * (that lead to eventual failure) may occur on different links.
273 *
274 * @return A hash map with counts of MPDU failed transmissions
275 */
277 /**
278 * @brief Return the counts of MPDU retransmissions in a hash map
279 *
280 * The return type is an std::unordered_map, and the keys are tuples of {node ID,
281 * device ID}. The value returned by indexing the tuple is the count of
282 * MPDU retransmissions of those MPDUs that were successfully acked.
283 *
284 * The number of retransmissions are only stored with the granularity
285 * of per-device, since in a multi-link scenario, some retransmissions
286 * may be sent on different links.
287 *
288 * @return A hash map with counts of MPDU retransmissions for successful MPDUs
289 */
291 /**
292 * @brief Return the count of successful MPDU transmissions across all enabled devices
293 *
294 * @return The count of all successful MPDU transmissions
295 */
296 uint64_t GetSuccesses() const;
297 /**
298 * @brief Return the count of failed MPDU transmissions across all enabled devices
299 *
300 * @return The count of all failed MPDU transmissions
301 */
302 uint64_t GetFailures() const;
303 /**
304 * @brief Return the count of failed MPDU transmissions due to given drop reason across
305 * all enabled devices
306 * @param reason Reason for dropping the MPDU
307 *
308 * @return The count of all failed MPDU transmissions for the specified reason
309 */
310 uint64_t GetFailures(WifiMacDropReason reason) const;
311 /**
312 * @brief Return the count of MPDU retransmissions across all enabled devices
313 *
314 * @return The count of all MPDU retransmissions for acked MPDUs
315 */
316 uint64_t GetRetransmissions() const;
317 /**
318 * @brief Return the duration since the helper was started or reset
319 *
320 * @return The duration since the helper was started or reset
321 */
322 Time GetDuration() const;
323 /**
324 * @brief Return a hash map of successful MPDU records
325 * @param type how the statistics handle a successful MPDU transmitted on multiple links
326 *
327 * The return type is an std::unordered_map, and the keys are tuples of {node ID,
328 * device ID, link ID}. The value returned by indexing the tuple is the list of MPDU
329 * records of the MPDUs that were successfully acked.
330 *
331 * @return A const reference to the hash map of successful MPDU records
332 */
335 /**
336 * @brief Return a hash map of MPDU records for failed transmissions
337 *
338 * The return type is an std::unordered_map, and the keys are tuples of {node ID,
339 * device ID}. The value returned by indexing the tuple is the list of MPDU
340 * records of the MPDUs that failed.
341 *
342 * @return A const reference to the hash map of MPDU records corresponding to failure
343 */
345
346 private:
347 /**
348 * @brief Callback for the WifiMacQueue::Enqueue trace
349 * @param nodeId the Node ID triggering the trace
350 * @param deviceId the Node ID triggering the trace
351 * @param mpdu The MPDU enqueued
352 */
353 void NotifyMacEnqueue(uint32_t nodeId, uint32_t deviceId, Ptr<const WifiMpdu> mpdu);
354 /**
355 * @brief Callback for the WifiPhy::PhyTxBegin trace
356 * @param nodeId the Node ID triggering the trace
357 * @param deviceId the Node ID triggering the trace
358 * @param pkt The frame being sent
359 */
360 void NotifyTxStart(uint32_t nodeId, uint32_t deviceId, Ptr<const Packet> pkt, Watt_u);
361 /**
362 * @brief Callback for the WifiMac::AckedMpdu trace
363 * @param nodeId the Node ID triggering the trace
364 * @param deviceId the Node ID triggering the trace
365 * @param mpdu The MPDU acked
366 */
367 void NotifyAcked(uint32_t nodeId, uint32_t deviceId, Ptr<const WifiMpdu> mpdu);
368 /**
369 * @brief Callback for the WifiMac::DroppedMpdu trace
370 * @param nodeId the Node ID triggering the trace
371 * @param deviceId the Node ID triggering the trace
372 * @param reason Reason for dropping the MPDU
373 * @param mpdu The MPDU dropped
374 */
375 void NotifyMacDropped(uint32_t nodeId,
376 uint32_t deviceId,
377 WifiMacDropReason reason,
379
380 MpduRecordsPerNodeDevice_t m_successMap; //!< The nested map of successful MPDUs
381 MpduRecordsPerNodeDevice_t m_failureMap; //!< The nested map of failed MPDUs
382 std::map<uint64_t, MpduRecord> m_inflightMap; //!< In-flight MPDUs; key is a Packet UID
383 Time m_startTime; //!< The start time for recording statistics
384 Time m_stopTime{Time::Max()}; //!< The stop time for recording statistics
385};
386
387} // namespace ns3
388
389#endif // WIFI_TX_STATS_HELPER_H
holds a vector of ns3::NetDevice pointers
keep track of a set of node pointers.
network packets
Definition packet.h:228
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:70
Simulation virtual time values and global simulation resolution.
Definition nstime.h:95
static Time Max()
Maximum representable Time Not to be confused with Max(Time,Time).
Definition nstime.h:287
WifiMpdu stores a (const) packet along with a MAC header.
Definition wifi-mpdu.h:51
Time m_stopTime
The stop time for recording statistics.
MpduRecordsPerNodeDevice_t m_successMap
The nested map of successful MPDUs.
void Reset()
Clear the data structures for all completed successful and failed MpduRecords.
std::unordered_map< std::tuple< uint32_t, uint32_t >, std::list< MpduRecord >, TupleHash > MpduRecordsPerNodeDevice_t
std::unordered_map of {nodeId, deviceId} tuple to a list of MPDU records
std::unordered_map< std::tuple< uint32_t, uint32_t, uint8_t >, std::list< MpduRecord >, TupleHash > MpduRecordsPerNodeDeviceLink_t
std::unordered_map of {nodeId, deviceId, linkId} tuple to a list of MPDU records
std::map< uint64_t, MpduRecord > m_inflightMap
In-flight MPDUs; key is a Packet UID.
void NotifyAcked(uint32_t nodeId, uint32_t deviceId, Ptr< const WifiMpdu > mpdu)
Callback for the WifiMac::AckedMpdu trace.
CountPerNodeDeviceLink_t GetSuccessesByNodeDeviceLink(WifiTxStatsHelper::MultiLinkSuccessType type=FIRST_LINK_IN_SET) const
Return the counts of successful MPDU transmissions in a hash map.
MultiLinkSuccessType
When Multi-Link Operation (MLO) is used, it is possible for MPDUs to be sent on multiple links concur...
void Stop(Time stopTime)
Set the stop time for statistics collection.
void NotifyTxStart(uint32_t nodeId, uint32_t deviceId, Ptr< const Packet > pkt, Watt_u)
Callback for the WifiPhy::PhyTxBegin trace.
uint64_t GetFailures() const
Return the count of failed MPDU transmissions across all enabled devices.
WifiTxStatsHelper()
Default constructor; start time initialized to zero and stop time to Time::Max().
Time m_startTime
The start time for recording statistics.
void NotifyMacEnqueue(uint32_t nodeId, uint32_t deviceId, Ptr< const WifiMpdu > mpdu)
Callback for the WifiMacQueue::Enqueue trace.
CountPerNodeDevice_t GetFailuresByNodeDevice() const
Return the counts of failed MPDU transmissions in a hash map.
std::unordered_map< std::tuple< uint32_t, uint32_t >, uint64_t, TupleHash > CountPerNodeDevice_t
std::unordered_map of {nodeId, deviceId} tuple to counter value
const MpduRecordsPerNodeDeviceLink_t GetSuccessRecords(WifiTxStatsHelper::MultiLinkSuccessType type=FIRST_LINK_IN_SET) const
Return a hash map of successful MPDU records.
const MpduRecordsPerNodeDevice_t & GetFailureRecords() const
Return a hash map of MPDU records for failed transmissions.
CountPerNodeDevice_t GetSuccessesByNodeDevice() const
Return the counts of successful MPDU transmissions in a hash map.
MpduRecordsPerNodeDevice_t m_failureMap
The nested map of failed MPDUs.
uint64_t GetSuccesses() const
Return the count of successful MPDU transmissions across all enabled devices.
void NotifyMacDropped(uint32_t nodeId, uint32_t deviceId, WifiMacDropReason reason, Ptr< const WifiMpdu > mpdu)
Callback for the WifiMac::DroppedMpdu trace.
void Enable(const NodeContainer &nodes)
Enables trace collection for all nodes and WifiNetDevices in the specified NodeContainer.
CountPerNodeDevice_t GetRetransmissionsByNodeDevice() const
Return the counts of MPDU retransmissions in a hash map.
uint64_t GetRetransmissions() const
Return the count of MPDU retransmissions across all enabled devices.
void Start(Time startTime)
Set the start time for statistics collection.
Time GetDuration() const
Return the duration since the helper was started or reset.
std::unordered_map< std::tuple< uint32_t, uint32_t, uint8_t >, uint64_t, TupleHash > CountPerNodeDeviceLink_t
std::unordered_map of {nodeId, deviceId, linkId} tuple to counter value
Time stopTime
WifiMacDropReason
The reason why an MPDU was dropped.
Definition wifi-mac.h:71
NodeContainer nodes
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static constexpr uint8_t WIFI_TID_UNDEFINED
Invalid TID identifier.
Definition wifi-utils.h:301
double Watt_u
Watt weak type.
Definition wifi-units.h:25
Structure for recording information about an individual data MPDU transmission.
uint32_t m_deviceId
The sending device ID.
uint32_t m_nodeId
The sending node ID.
uint64_t m_mpduSeqNum
The MPDU sequence number.
Time m_ackTime
The time at which the MPDU was acknowledged.
uint32_t m_retransmissions
A count of the number of retransmissions of the MPDU.
Time m_enqueueTime
The enqueue time (time that the packet was added to a WifiMacQueue).
std::set< uint8_t > m_successLinkIdSet
If acked, the set of in-flight link ID(s).
std::optional< WifiMacDropReason > m_dropReason
If failed, the drop reason.
std::optional< Time > m_dropTime
The time of removal from the WifiMacQueue, if failed.
Time m_txStartTime
The time at which the MPDU was first transmitted.
uint8_t m_tid
The TID for the MPDU.
Hash function for the tuples used in unordered_maps.
size_t operator()(const std::tuple< Args... > &tuple) const
Operator overload for calculating hash of tuple.
size_t tuple_hash(const Tuple &tuple) const
Hash function for tuples of arbitrary size.
void hash_combine(size_t &seed, const T &value) const
Combines two hash values into one (similar to boost::hash_combine).