212 lines
6.4 KiB
C
212 lines
6.4 KiB
C
/*
|
|
* 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 <stdbool.h>
|
|
#include <stdint.h>
|
|
|
|
// 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)
|
|
*/
|
|
typedef enum {
|
|
MCS_BW_20MHZ = 0,
|
|
MCS_BW_40MHZ = 1
|
|
} 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
|
|
|