#include "signal_analysis.h" #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" #include "esp_timer.h" #include #include #define MAX_CHANNELS 165 #define MAX_HISTORY 100 // Channel utilization tracking static channel_data_t channel_stats[MAX_CHANNELS]; static SemaphoreHandle_t signal_mutex = NULL; // RSSI history tracking (per BSSID) typedef struct { uint8_t bssid[6]; int8_t rssi_history[MAX_HISTORY]; uint32_t timestamps[MAX_HISTORY]; int head; int count; } rssi_tracker_t; static rssi_tracker_t rssi_trackers[10]; static int tracker_count = 0; void signal_update_packet(uint8_t channel, int8_t rssi) { if (channel == 0 || channel > MAX_CHANNELS) { return; } if (signal_mutex == NULL) { signal_mutex = xSemaphoreCreateMutex(); if (signal_mutex == NULL) { return; } } if (xSemaphoreTake(signal_mutex, portMAX_DELAY) != pdTRUE) { return; } channel_data_t *ch = &channel_stats[channel - 1]; ch->channel = channel; ch->packet_count++; ch->rssi = (ch->rssi + rssi) / 2; // Average RSSI ch->timestamp = (uint32_t)(esp_timer_get_time() / 1000000ULL); xSemaphoreGive(signal_mutex); } int signal_get_channel_utilization(channel_data_t *data, int max_channels) { if (signal_mutex == NULL || data == NULL) { return 0; } if (xSemaphoreTake(signal_mutex, portMAX_DELAY) != pdTRUE) { return 0; } int count = 0; for (int i = 0; i < MAX_CHANNELS && count < max_channels; i++) { if (channel_stats[i].packet_count > 0) { data[count++] = channel_stats[i]; } } xSemaphoreGive(signal_mutex); return count; } int signal_get_rssi_history(uint8_t *bssid, int8_t *rssi_history, uint32_t *timestamps, int max_samples) { if (signal_mutex == NULL || bssid == NULL || rssi_history == NULL || timestamps == NULL) { return 0; } if (xSemaphoreTake(signal_mutex, portMAX_DELAY) != pdTRUE) { return 0; } // Find tracker for this BSSID rssi_tracker_t *tracker = NULL; for (int i = 0; i < tracker_count; i++) { if (memcmp(rssi_trackers[i].bssid, bssid, 6) == 0) { tracker = &rssi_trackers[i]; break; } } if (!tracker) { xSemaphoreGive(signal_mutex); return 0; } int samples = (tracker->count < max_samples) ? tracker->count : max_samples; for (int i = 0; i < samples; i++) { int idx = (tracker->head - tracker->count + i + MAX_HISTORY) % MAX_HISTORY; rssi_history[i] = tracker->rssi_history[idx]; timestamps[i] = tracker->timestamps[idx]; } xSemaphoreGive(signal_mutex); return samples; }