DeterministicESPAsyncWebServer v6.28.0
Zero-allocation, bounded-execution async HTTP server for ESP32
Loading...
Searching...
No Matches
wifi_sniffer.cpp
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.cpp
6 * @brief 802.11 frame decode + traffic tally + RSSI roaming decision (see wifi_sniffer.h).
7 */
8
10
11#if DETWS_ENABLE_WIFI_SNIFFER
12
13#include <string.h>
14
15bool detws_wifi_parse(const uint8_t *frame, size_t len, WifiFrame *out)
16{
17 if (!frame || !out || len < 10) // FrameControl(2) + Duration(2) + Address1(6)
18 return false;
19
20 memset(out, 0, sizeof(*out));
21
22 uint8_t fc0 = frame[0];
23 uint8_t fc1 = frame[1];
24 out->version = fc0 & 0x03;
25 out->type = (fc0 >> 2) & 0x03;
26 out->subtype = (fc0 >> 4) & 0x0F;
27 out->to_ds = (fc1 & 0x01) != 0;
28 out->from_ds = (fc1 & 0x02) != 0;
29 out->retry = (fc1 & 0x08) != 0;
30 out->protected_frame = (fc1 & 0x40) != 0;
31
32 // Address1 always present at this length (offset 4).
33 memcpy(out->addr1, frame + 4, 6);
34 out->naddr = 1;
35 if (len >= 16)
36 {
37 memcpy(out->addr2, frame + 10, 6);
38 out->naddr = 2;
39 }
40 if (len >= 24)
41 {
42 memcpy(out->addr3, frame + 16, 6);
43 out->naddr = 3;
44 }
45 return true;
46}
47
48void detws_wifi_stats_reset(WifiStats *s)
49{
50 if (s)
51 memset(s, 0, sizeof(*s));
52}
53
54void detws_wifi_stats_add(WifiStats *s, const WifiFrame *f)
55{
56 if (!s || !f)
57 return;
58 switch (f->type)
59 {
60 case WifiType::WIFI_TYPE_MGMT:
61 s->mgmt++;
62 break;
63 case WifiType::WIFI_TYPE_CTRL:
64 s->ctrl++;
65 break;
66 case WifiType::WIFI_TYPE_DATA:
67 s->data++;
68 break;
69 default:
70 s->other++;
71 break;
72 }
73 s->total++;
74}
75
76bool detws_wifi_should_roam(int8_t cur_rssi, int8_t cand_rssi, uint8_t hysteresis_db)
77{
78 // Both are negative dBm (stronger = closer to 0). Roam only if the candidate clears the current
79 // by more than the hysteresis, computed in a wide signed type to avoid int8 overflow.
80 int32_t margin = (int32_t)cand_rssi - (int32_t)cur_rssi;
81 return margin > (int32_t)hysteresis_db;
82}
83
84#endif // DETWS_ENABLE_WIFI_SNIFFER
802.11 frame decode + traffic tally + RSSI roaming decision (DETWS_ENABLE_WIFI_SNIFFER).