From 8282f5dc8379deaf6f33a4b622bfd675fd59cc3f Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Fri, 12 Apr 2024 14:29:52 -0400 Subject: [PATCH] wifi: WifiPhyRxTraceHelper documentation --- doc/models/Makefile | 2 + src/wifi/doc/Makefile | 4 +- .../figures/wifi-phy-rx-trace-helper.dia | Bin 0 -> 2540 bytes src/wifi/doc/source/wifi-user.rst | 234 ++++++++++++++++++ 4 files changed, 239 insertions(+), 1 deletion(-) create mode 100644 src/wifi/doc/source/figures/wifi-phy-rx-trace-helper.dia diff --git a/doc/models/Makefile b/doc/models/Makefile index 110b625b6..e3a8a2dbe 100644 --- a/doc/models/Makefile +++ b/doc/models/Makefile @@ -142,6 +142,7 @@ SOURCEFIGS = \ $(SRC)/wifi/doc/source/figures/PhyEntityHierarchy.dia \ $(SRC)/wifi/doc/source/figures/WifiPpduHierarchy.dia \ $(SRC)/wifi/doc/source/figures/FemHierarchy.dia \ + $(SRC)/wifi/doc/source/figures/wifi-phy-rx-trace-helper.dia \ $(SRC)/wifi/doc/source/figures/snir.dia \ $(SRC)/wifi/doc/source/figures/ack-su-format.pdf \ $(SRC)/wifi/doc/source/figures/ack-su-format.png \ @@ -389,6 +390,7 @@ IMAGES_EPS = \ $(FIGURES)/PhyEntityHierarchy.eps \ $(FIGURES)/WifiPpduHierarchy.eps \ $(FIGURES)/FemHierarchy.eps \ + $(FIGURES)/wifi-phy-rx-trace-helper.eps \ $(FIGURES)/snir.eps \ $(FIGURES)/WimaxArchitecture.eps \ $(FIGURES)/epc-ctrl-arch.eps \ diff --git a/src/wifi/doc/Makefile b/src/wifi/doc/Makefile index 5ffe4de16..e08484b5c 100644 --- a/src/wifi/doc/Makefile +++ b/src/wifi/doc/Makefile @@ -13,7 +13,8 @@ IMAGES_DIA = \ $(FIGURES)/WifiArchitecture.dia \ $(FIGURES)/PhyEntityHierarchy.dia \ $(FIGURES)/WifiPpduHierarchy.dia \ - $(FIGURES)/FemHierarchy.dia + $(FIGURES)/FemHierarchy.dia \ + $(FIGURES)/wifi-phy-rx-trace-helper.dia # specify eps figures from which .png and .pdf figures need to be built @@ -23,6 +24,7 @@ IMAGES_EPS = \ $(FIGURES)/PhyEntityHierarchy.eps \ $(FIGURES)/WifiPpduHierarchy.eps \ $(FIGURES)/FemHierarchy.eps \ + $(FIGURES)/wifi-phy-rx-trace-helper.eps \ $(FIGURES)/assoc-manager.eps \ $(FIGURES)/clear-channel.eps \ $(FIGURES)/emlsr-dl-txop.eps \ diff --git a/src/wifi/doc/source/figures/wifi-phy-rx-trace-helper.dia b/src/wifi/doc/source/figures/wifi-phy-rx-trace-helper.dia new file mode 100644 index 0000000000000000000000000000000000000000..080879077081811dc943ab8c65e9cfdd053600e3 GIT binary patch literal 2540 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 CljsWo literal 0 HcmV?d00001 diff --git a/src/wifi/doc/source/wifi-user.rst b/src/wifi/doc/source/wifi-user.rst index bc681f52a..9401903e1 100644 --- a/src/wifi/doc/source/wifi-user.rst +++ b/src/wifi/doc/source/wifi-user.rst @@ -804,6 +804,240 @@ There are many other |ns3| attributes that can be set on the above helpers to deviate from the default behavior; the example scripts show how to do some of this reconfiguration. +WifiPhyRxTraceHelper +==================== +The ``WifiPhyRxTraceHelper`` can be used to collect statistics and records of Wi-Fi +reception events at the physical layer, such as whether a PPDU was received or was dropped for +some reason, and whether a PPDU overlapped in time (collided) with one or more other PPDUs on the +channel. Two possible types of studies that may be helped by this feature are: + +1) Wi-Fi PPDU and MPDU reception outcomes to assess the performance of spatial reuse mechanisms + +2) Calculation of airtime fairness between contending stations on a network + +The trace helper works by hooking PHY-level traces on the applicable nodes, devices, and +links and maintaining per-receiver records of all of the Wi-Fi PPDUs that are received, +from each receiver's vantage point. These records include a listing of all other PPDUs +that may have overlapped in time and/or frequency for a given PPDU, and the received +signal power of each PPDU involved, and the outcome of the attempt at reception (whether +the PPDU was dropped entirely, or whether the PPDU was partially or fully decoded). + +This trace helper collects records of all Wi-Fi PPDus received on every PHY that is enabled +for the helper. As an example, consider the scenario in Figure :ref:`wifi-phy-rx-trace-helper`, +depicting the arrival of three PPDUs that overlap in time. The trace helper keeps a record +of each PPDU arrival, on each enabled PHY, and also keeps track of the PPDUs that collided +with it, if any. In the figure, the first PPDU overlaps in time with both the second and +third PPDU. Likewise, the second PPDU overlaps in time with the first and third PPDUs, and +the third PPDU overlaps in time with the first and second. All of these relationships (each +frame arrival, the frames that overlapped in time with it), from the perspective of each +PHY, are stored in internal data structures. Additionally, the reception outcome of each +PPDU, and its constituent MPDUs, is tracked. This database of reception events can be +exported by the trace helper for fine-grained tabulation of spatial reuse events of interest, +or can be summarized by some built-in statistics printing methods. + +.. _wifi-phy-rx-trace-helper: + +.. figure:: figures/wifi-phy-rx-trace-helper.* + + *WifiPhyRxTraceHelper scenario of interest* + +The output of this trace helper is provided in three formats: + +1) Built-in print methods to allow printing of key statistics with a single C++ statement, + +2) Export of a trace statistics object allowing the user to post-process or format the + data according to the user's formatting choice, and + +3) Export of the complete reception records, allowing the user to perform their own + custom processing of the data. + +A sample usage of this trace helper is as follows, as demonstrated in the example program +``src/wifi/examples/wifi-phy-rx-trace-helper-example.cc``. First, declare an instance +of it as one might do with other Wi-Fi helpers: + +.. sourcecode:: cpp + + WifiPhyRxTraceHelper rxTraceHelper; + +You may need to include the trace helper's header if it is not otherwise included by the +wifi module header: + +.. sourcecode:: cpp + + #include "ns3/wifi-phy-rx-trace-helper.h" + +Next, enable the trace helper on some subset of the Wi-Fi nodes in the simulation. This step +will hook traces on all of the nodes enabled. It is important to include all of the nodes +within reception range of the nodes of interest, because PPDUs need to be traced at +both transmission and reception times. If you are only interested in statistics or records +on a given receiver, you can later (as explained below) request for only the statistics +of interest. For example, if you are interested in a particular AP, in a particular BSS, +and there is an interfering BSS nearby, you will want to enable all of the nodes within +interference range of the AP of interest (even if not in the same BSS). So, in general, +you will want to ``Enable()`` the trace helper on all Wi-Fi nodes in the simulation, +unless you want to explore pruning this set for runtime scaling reasons. + +In this example, we will enable on all of the Wi-Fi nodes: + +.. sourcecode:: cpp + + NodeContainer c; + c.Create(2); + + ... + + NetDeviceContainer apDevice = wifi.Install(wifiPhy, wifiMac, c.Get(1)); + NetDeviceContainer staDevice = wifi.Install(wifiPhy, wifiMac, c.Get(0)); + + ... + + rxTraceHelper.Enable(c); + +The important thing to note in the above is that ``Enable()`` must be called after +Wi-Fi devices are installed, because it will hook traces on what has been installed +up to that point. + +The next configuration aspect is to establish a start and stop time for PPDU reception +collection. In the example program, application data is not sent before 1 second, +and we want to capture all data PPDUs, so the ``Start()`` and ``Stop()`` times are set +as follows: + +.. sourcecode:: cpp + + rxTraceHelper.Start(Seconds(1)); + // The last packet will be sent at time 1 sec. + (numPackets - 1) * interval + // Configure the stop time to be 1 sec. later than this. + Time stopTime = Seconds(1) + (numPackets - 1) * interval + Seconds(1); + rxTraceHelper.Stop(stopTime); + +The start and stop times can be tuned to whatever collection window is desired. Furthermore, +there is a ``Reset()`` method that will clear all of the PPDU records and restart collection; +this can be used if one wants to periodically sample the statistics in different time +intervals. + +Next, run the simulation, and either during the run or after the simulation has completed, +harvest the statistics. As noted above, there are three main ways to output data. +Furthermore, there are C++ method overloads that allow users to narrow the scope of +output data. + +The first option is to use ``PrintStatistics()``, which will dump some statistics with +built-in formatting, such as follows: + +.. sourcecode:: cpp + + traceHelper.PrintStatistics(); + +This will result in a number of statistics being printed out. The statistics will +be aggregated for all nodes that are enabled. The following is some of the default +output of the sample program: + +.. sourcecode:: text + + *** Print statistics for all nodes using built-in print method: + Total PPDUs Received: 1 + Total Non-Overlapping PPDUs Received: 1 + Total Overlapping PPDUs Received: 0 + + Successful PPDUs: 1 + Failed PPDUs: 0 + + Total MPDUs: 1 + Total Successful MPDUs: 1 + Total Failed MPDUs: 0 + + +In the above simple case, there is one PPDU successfully received, and within this PPDU, +there was one MPDU which was successfully decoded. No other PPDUs overlapped in time +with this PPDU. + +Although this is a PHY trace helper, there is one important aspect from the MAC layer +that is used to classify PPDUs. When reporting statistics for a given node, a PPDU +is counted only if there was at least one MPDU intended for the node. If the MPDU +has a MAC address that is either broadcast or belongs to the device (unicast), that +PPDU will be counted. If, instead, a receiver locks onto and overhears a PPDU +that ultimately will be discarded because the receiver was not an intended receiver, that +PPDU reception or failure will be excluded from the statistics. + +The sample program next shows how ``PrintStatistics`` can take an argument: + +.. sourcecode:: cpp + + rxTraceHelper.PrintStatistics(c.Get(0)->GetId()); + rxTraceHelper.PrintStatistics(c.Get(1)); + +In the above, the statistics can be limited to a particular node (either passed in +by Node ID or by Node pointer). Furthermore, although not shown in the example, +the method can be further downscoped to also take a device index argument and +(in the case of multi-link operation (MLO)) a specific link ID. In the above example, +all devices and all MLO links will be included in the output. + +Users can write their own printing methods or further process the statistics by +calling ``GetStatistics()`` as the following example demonstrates: + +.. sourcecode:: cpp + + auto stats = rxTraceHelper.GetStatistics(); + std::cout << " numOverlapppingPpdu: " << stats.m_numOverlappingPpdu << std::endl; + std::cout << " numNonOverlapppingPpdu: " << stats.m_numNonOverlappingPpdu << std::endl; + std::cout << " numPpduFailed: " << stats.m_numPpduFailed << std::endl; + std::cout << " numPpduSuccess: " << stats.m_numPpduSuccess << std::endl; + std::cout << " numMpduSuccess: " << stats.m_numMpduSuccess << std::endl; + std::cout << " numMpduFailed: " << stats.m_numMpduFailed << std::endl; + +Similar to ``PrintStatistics()``, ``GetStatistics()`` with no arguments will collect +a statistics output structure covering all nodes, while additional arguments of +Node ID, device index, and link ID can be used to constrain the statistics report. + +Finally, the output of the internal data structure that tracks PPDU receptions can +be exported, with the ``GetPpduRecords()`` method, which can be called +without any arguments, and with arguments of nodeId, deviceId, and linkId: + +.. sourcecode:: cpp + + auto optionalRecords = rxTraceHelper.GetPpduRecords(1); + +The above statements asks for records from receiving node 1 (the AP). The example +iterates the returned vector, printing out the size of this structure, as well +as some data fields: + +.. sourcecode:: text + + *** Records vector has size of 3 + First record: + first PPDU's RSSI (dBm): -30.6633 + first PPDU's receiver ID: 1 + first PPDU's sender ID: 0 + first PPDU's start time: 1 + first PPDU's end time: 1.00008 + first PPDU's number of MPDUs: 1 + first PPDU's sender device ID: 0 + Second record: + second PPDU's RSSI (dBm): -30.6633 + second PPDU's receiver ID: 1 + second PPDU's sender ID: 0 + second PPDU's start time: 1.00027 + second PPDU's end time: 1.00032 + second PPDU's number of MPDUs: 1 + second PPDU's sender device ID: 0 + Third record: + third PPDU's RSSI (dBm): -30.6633 + third PPDU's receiver ID: 1 + third PPDU's sender ID: 0 + third PPDU's start time: 1.00039 + third PPDU's end time: 1.00072 + third PPDU's number of MPDUs: 1 + third PPDU's sender device ID: 0 + +That the size of the vector is 3 may be surprising, considering that we have observed +above in this example that only one PPDU is being counted in the statistics. However, +in this example, there is only one data PPDU but also additional management and control +frames. Specifically, the first PPDU is a Block ACK ADDBA_REQUEST frame, the second PPDU +is an ACK of the AP's ADDBA_RESPONSE frame, and the third PPDU record corresponds to the +actual data PPDU, starting at time 1.00039 and ending at 1.00072. +The management and control frames (which also include beacons) are filtered out above by +the ``GetStatistics()`` methods, but when the raw PPDU records are retrieved, all PPDUs +received are available and the user is responsible for further filtering as they see fit. + HT configuration ================