DeterministicESPAsyncWebServer v6.28.0
Zero-allocation, bounded-execution async HTTP server for ESP32
Loading...
Searching...
No Matches
wifi_sniffer.h
Go to the documentation of this file.
1// Copyright (C) 2026 Douglas Quigg (dstroy0) <dquigg123@gmail.com>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4/**
5 * @file wifi_sniffer.h
6 * @brief 802.11 frame decode + traffic tally + RSSI roaming decision (DETWS_ENABLE_WIFI_SNIFFER).
7 *
8 * The ESP32 can run its WiFi MAC in promiscuous mode and hand raw 802.11 frames to a callback. Turning
9 * those into a useful sniffer / traffic analyzer / RF-diagnostics panel means decoding the 802.11 MAC
10 * header (frame control type/subtype + flags, and the three addresses whose roles - receiver /
11 * transmitter / BSSID - depend on the ToDS/FromDS bits), tallying frames by type, and, for
12 * channel-agility roaming, deciding when a candidate AP is enough stronger than the current one to switch.
13 *
14 * This is that pure decode + decision layer; the promiscuous-mode radio callback belongs to the app. No
15 * heap, no stdlib, host-testable against captured frame bytes.
16 */
17
18#ifndef DETERMINISTICESPASYNCWEBSERVER_WIFI_SNIFFER_H
19#define DETERMINISTICESPASYNCWEBSERVER_WIFI_SNIFFER_H
20
21#include "ServerConfig.h"
22#include <stddef.h>
23#include <stdint.h>
24
25#if DETWS_ENABLE_WIFI_SNIFFER
26
27/** @brief 802.11 frame type (Frame Control bits 2-3). */
28struct WifiType
29{
30 static constexpr uint8_t WIFI_TYPE_MGMT = 0; ///< management (beacon, probe, auth, assoc, ...).
31 static constexpr uint8_t WIFI_TYPE_CTRL = 1; ///< control (RTS/CTS/ACK, ...).
32 static constexpr uint8_t WIFI_TYPE_DATA = 2; ///< data.
33 static constexpr uint8_t WIFI_TYPE_EXT = 3; ///< extension.
34};
35
36/** @brief A decoded 802.11 MAC header. Addresses not present for the frame's length are left zeroed. */
37struct WifiFrame
38{
39 uint8_t version; ///< protocol version (FC bits 0-1).
40 uint8_t type; ///< WIFI_TYPE_*.
41 uint8_t subtype; ///< FC bits 4-7.
42 bool to_ds; ///< to the distribution system.
43 bool from_ds; ///< from the distribution system.
44 bool retry; ///< retransmission.
45 bool protected_frame; ///< the Protected Frame (WEP/WPA) flag.
46 uint8_t naddr; ///< number of addresses decoded (1..3).
47 uint8_t addr1[6]; ///< receiver / destination (role varies by DS bits).
48 uint8_t addr2[6]; ///< transmitter / source (present when naddr >= 2).
49 uint8_t addr3[6]; ///< BSSID / source / dest (present when naddr >= 3).
50};
51
52/**
53 * @brief Decode the 802.11 MAC header of a captured frame.
54 *
55 * Requires at least the Frame Control + Duration + Address1 (10 bytes); Address2 is decoded at >= 16
56 * bytes and Address3 at >= 24 bytes, with @p out->naddr reporting how many were present.
57 * @return true if @p len >= 10 and @p frame is non-null; false otherwise.
58 */
59bool detws_wifi_parse(const uint8_t *frame, size_t len, WifiFrame *out);
60
61/** @brief Running per-type frame tally. */
62struct WifiStats
63{
64 uint32_t mgmt;
65 uint32_t ctrl;
66 uint32_t data;
67 uint32_t other;
68 uint32_t total;
69};
70
71/** @brief Zero a tally. */
72void detws_wifi_stats_reset(WifiStats *s);
73
74/** @brief Fold one decoded frame into the tally. */
75void detws_wifi_stats_add(WifiStats *s, const WifiFrame *f);
76
77/**
78 * @brief Channel-agility roaming decision.
79 * @return true if @p cand_rssi exceeds @p cur_rssi by more than @p hysteresis_db (so a switch is worth it).
80 */
81bool detws_wifi_should_roam(int8_t cur_rssi, int8_t cand_rssi, uint8_t hysteresis_db);
82
83#endif // DETWS_ENABLE_WIFI_SNIFFER
84#endif // DETERMINISTICESPASYNCWEBSERVER_WIFI_SNIFFER_H
User-facing configuration for DeterministicESPAsyncWebServer.