/* * mcs_telemetry.h * * Copyright (c) 2026 Umber Networks & Robert McMahon * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of its * contributors may be used to endorse or promote products derived from * this software without prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #ifndef MCS_TELEMETRY_H #define MCS_TELEMETRY_H #include "esp_wifi.h" #include "esp_wifi_types.h" #include #include // Include wifi_monitor.h to get wifi_frame_info_t definition #include "wifi_monitor.h" #ifdef __cplusplus extern "C" { #endif /** * @brief Maximum MCS index for 802.11ax (0-11) */ #define MCS_TELEMETRY_MAX_MCS 11 /** * @brief Maximum Spatial Streams (1-4 for ESP32-C5) */ #define MCS_TELEMETRY_MAX_SS 4 /** * @brief Maximum device entries to track */ #define MCS_TELEMETRY_MAX_DEVICES 16 /** * @brief Telemetry aggregation window in milliseconds */ #define MCS_TELEMETRY_WINDOW_MS 1000 /** * @brief 802.11ax Bandwidth types (ESP32-C5 supports 20MHz and 40MHz, but we track 80MHz for compatibility) */ typedef enum { MCS_BW_20MHZ = 0, MCS_BW_40MHZ = 1, MCS_BW_80MHZ = 2 } mcs_bandwidth_t; /** * @brief Single telemetry sample */ typedef struct { uint32_t timestamp_ms; // Timestamp in milliseconds uint8_t mcs; // MCS index (0-11) uint8_t ss; // Spatial Streams (1-4) int8_t rssi; // RSSI in dBm uint8_t channel; // WiFi channel mcs_bandwidth_t bandwidth; // Bandwidth (20MHz or 40MHz) uint32_t phy_rate_kbps; // PHY rate in Kbps uint16_t frame_len; // Frame length in bytes bool is_retry; // Retry flag uint8_t sig_mode; // Signal mode (0=legacy, 1=HT, 3=VHT, 4=HE) } mcs_sample_t; /** * @brief Aggregated telemetry per device (MAC address) */ typedef struct { uint8_t mac[6]; // MAC address of the device uint32_t sample_count; // Number of samples in this window uint32_t last_update_ms; // Last update timestamp // Aggregated statistics uint8_t current_mcs; // Current/dominant MCS uint8_t current_ss; // Current/dominant SS int8_t avg_rssi; // Average RSSI int8_t min_rssi; // Minimum RSSI int8_t max_rssi; // Maximum RSSI uint32_t total_bytes; // Total bytes transmitted uint32_t total_frames; // Total frame count uint32_t retry_frames; // Retry frame count uint32_t avg_phy_rate_kbps; // Average PHY rate uint32_t max_phy_rate_kbps; // Maximum PHY rate // MCS distribution (how many frames per MCS) uint32_t mcs_count[MCS_TELEMETRY_MAX_MCS + 1]; // SS distribution (how many frames per SS) uint32_t ss_count[MCS_TELEMETRY_MAX_SS + 1]; // Time series for recent samples (sliding window) mcs_sample_t samples[16]; // Last 16 samples uint8_t sample_idx; // Current sample index } mcs_device_telemetry_t; /** * @brief Global telemetry statistics */ typedef struct { uint32_t total_frames_captured; uint32_t total_devices; uint32_t window_start_ms; uint32_t window_end_ms; mcs_device_telemetry_t devices[MCS_TELEMETRY_MAX_DEVICES]; } mcs_telemetry_stats_t; /** * @brief Callback function type for telemetry updates * * @param stats Telemetry statistics */ typedef void (*mcs_telemetry_cb_t)(const mcs_telemetry_stats_t *stats); /** * @brief Initialize MCS telemetry capture * * @param callback Optional callback for telemetry updates (can be NULL) * @return esp_err_t ESP_OK on success */ esp_err_t mcs_telemetry_init(mcs_telemetry_cb_t callback); /** * @brief Start MCS telemetry capture * * @return esp_err_t ESP_OK on success */ esp_err_t mcs_telemetry_start(void); /** * @brief Stop MCS telemetry capture * * @return esp_err_t ESP_OK on success */ esp_err_t mcs_telemetry_stop(void); /** * @brief Process a captured 802.11 frame * * @param frame_info Parsed frame information (from wifi_monitor) * @param rx_ctrl RX control information * @return esp_err_t ESP_OK on success */ esp_err_t mcs_telemetry_process_frame(const wifi_frame_info_t *frame_info, const wifi_pkt_rx_ctrl_t *rx_ctrl); /** * @brief Get current telemetry statistics * * @param stats Output: telemetry statistics * @return esp_err_t ESP_OK on success */ esp_err_t mcs_telemetry_get_stats(mcs_telemetry_stats_t *stats); /** * @brief Reset telemetry statistics */ void mcs_telemetry_reset(void); /** * @brief Get telemetry as JSON string (for HTTP POST) * * @param json_buffer Output buffer for JSON string * @param buffer_len Buffer length * @param device_id Device identifier string * @return esp_err_t ESP_OK on success */ esp_err_t mcs_telemetry_to_json(char *json_buffer, size_t buffer_len, const char *device_id); /** * @brief Calculate PHY rate from MCS, SS, and bandwidth (802.11ax) * * @param mcs MCS index (0-11) * @param ss Spatial Streams (1-4) * @param bandwidth Bandwidth (20MHz or 40MHz) * @param sgi Short Guard Interval (true = 400ns, false = 800ns) * @return uint32_t PHY rate in Kbps, 0 if invalid */ uint32_t mcs_calculate_phy_rate_ax(uint8_t mcs, uint8_t ss, mcs_bandwidth_t bandwidth, bool sgi); #ifdef __cplusplus } #endif #endif // MCS_TELEMETRY_H