ESP32/main/metrics_wifi.c
2026-06-23 20:38:23 +08:00

149 lines
4.3 KiB
C

#include "metrics_wifi.h"
#include <string.h>
#include "esp_err.h"
#include "esp_event.h"
#include "esp_http_server.h"
#include "esp_log.h"
#include "esp_netif.h"
#include "esp_wifi.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "metrics_protocol.h"
#include "nvs_flash.h"
#include "ui_screen.h"
static const char *TAG = "metrics_ap";
#define METRICS_AP_SSID "RLCD-Metrics"
#define METRICS_AP_PASSWORD "rlcd123456"
#define METRICS_AP_CHANNEL 6
#define METRICS_AP_MAX_CLIENTS 2
static esp_err_t send_text(httpd_req_t *req, const char *text)
{
httpd_resp_set_type(req, "text/plain; charset=utf-8");
return httpd_resp_sendstr(req, text);
}
static esp_err_t health_handler(httpd_req_t *req)
{
return send_text(req, "ok\n");
}
static esp_err_t metrics_post_handler(httpd_req_t *req)
{
char line[512] = {0};
int total = 0;
while (total < (int)sizeof(line) - 1) {
int read = httpd_req_recv(req, line + total, (sizeof(line) - 1) - total);
if (read <= 0) {
if (read == HTTPD_SOCK_ERR_TIMEOUT) {
continue;
}
break;
}
total += read;
if (total >= req->content_len) {
break;
}
}
line[total] = '\0';
ui_metrics_t metrics;
if (!metrics_parse_line(line, &metrics)) {
ui_screen_set_status("BAD WIFI DATA");
httpd_resp_set_status(req, "400 Bad Request");
return send_text(req, "bad data\n");
}
ui_screen_update_metrics_from_source(&metrics, "LIVE FROM AP");
return send_text(req, "ok\n");
}
static esp_err_t start_http_server(void)
{
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
config.server_port = 80;
config.ctrl_port = 32768;
config.stack_size = 6144;
httpd_handle_t server = NULL;
esp_err_t ret = httpd_start(&server, &config);
if (ret != ESP_OK) {
return ret;
}
httpd_uri_t health_uri = {
.uri = "/health",
.method = HTTP_GET,
.handler = health_handler,
.user_ctx = NULL,
};
httpd_register_uri_handler(server, &health_uri);
httpd_uri_t metrics_uri = {
.uri = "/metrics",
.method = HTTP_POST,
.handler = metrics_post_handler,
.user_ctx = NULL,
};
httpd_register_uri_handler(server, &metrics_uri);
return ESP_OK;
}
static void wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
{
(void)arg;
(void)event_data;
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_AP_STACONNECTED) {
ui_screen_set_status("PC CONNECTED");
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_AP_STADISCONNECTED) {
ui_screen_set_status("AP WAITING PC");
}
}
void metrics_wifi_start(void)
{
esp_err_t nvs_ret = nvs_flash_init();
if (nvs_ret == ESP_ERR_NVS_NO_FREE_PAGES || nvs_ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase());
nvs_ret = nvs_flash_init();
}
ESP_ERROR_CHECK(nvs_ret);
ESP_ERROR_CHECK(esp_netif_init());
esp_err_t loop_ret = esp_event_loop_create_default();
if (loop_ret != ESP_OK && loop_ret != ESP_ERR_INVALID_STATE) {
ESP_ERROR_CHECK(loop_ret);
}
esp_netif_create_default_wifi_ap();
wifi_init_config_t init_config = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&init_config));
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL));
wifi_config_t ap_config = {0};
strlcpy((char *)ap_config.ap.ssid, METRICS_AP_SSID, sizeof(ap_config.ap.ssid));
strlcpy((char *)ap_config.ap.password, METRICS_AP_PASSWORD, sizeof(ap_config.ap.password));
ap_config.ap.ssid_len = strlen(METRICS_AP_SSID);
ap_config.ap.channel = METRICS_AP_CHANNEL;
ap_config.ap.max_connection = METRICS_AP_MAX_CLIENTS;
ap_config.ap.authmode = WIFI_AUTH_WPA2_PSK;
ap_config.ap.pmf_cfg.required = false;
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &ap_config));
ESP_ERROR_CHECK(esp_wifi_start());
ESP_ERROR_CHECK(start_http_server());
ESP_LOGI(TAG, "AP started: SSID=%s password=%s url=http://192.168.4.1/metrics", METRICS_AP_SSID, METRICS_AP_PASSWORD);
ui_screen_set_status("AP RLCD-Metrics");
}