fix evse_link

This commit is contained in:
2026-01-24 16:56:51 +00:00
parent 023644a887
commit 286028b6a8
54 changed files with 4456 additions and 2632 deletions

View File

@@ -8,16 +8,20 @@
#include "network.h"
#include "mqtt.h"
#include <string.h>
#include <stdlib.h>
static const char *TAG = "network_api";
typedef struct {
typedef struct
{
bool enabled;
char ssid[33];
char password[65];
} wifi_task_data_t;
static void wifi_apply_config_task(void *param) {
static void wifi_apply_config_task(void *param)
{
wifi_task_data_t *data = (wifi_task_data_t *)param;
ESP_LOGD("wifi_task", "Applying Wi-Fi config in background task");
wifi_set_config(data->enabled, data->ssid, data->password);
@@ -25,12 +29,12 @@ static void wifi_apply_config_task(void *param) {
vTaskDelete(NULL);
}
static esp_err_t wifi_get_handler(httpd_req_t *req) {
static esp_err_t wifi_get_handler(httpd_req_t *req)
{
ESP_LOGD(TAG, "Handling GET /api/v1/config/wifi");
httpd_resp_set_type(req, "application/json");
// Obter dados da NVS via wifi.c
bool enabled = wifi_get_enabled();
char ssid[33] = {0};
char password[65] = {0};
@@ -38,78 +42,82 @@ static esp_err_t wifi_get_handler(httpd_req_t *req) {
wifi_get_ssid(ssid);
wifi_get_password(password);
// Criar JSON
cJSON *json = cJSON_CreateObject();
cJSON_AddBoolToObject(json, "enabled", enabled);
cJSON_AddStringToObject(json, "ssid", ssid);
cJSON_AddStringToObject(json, "password", password);
// Enviar resposta
char *response = cJSON_Print(json);
httpd_resp_sendstr(req, response);
// Limpeza
free(response);
cJSON_Delete(json);
return ESP_OK;
}
static esp_err_t wifi_post_handler(httpd_req_t *req) {
static esp_err_t wifi_post_handler(httpd_req_t *req)
{
ESP_LOGD(TAG, "Handling POST /api/v1/config/wifi");
char buf[512];
int len = httpd_req_recv(req, buf, sizeof(buf) - 1);
if (len <= 0) return ESP_FAIL;
if (len <= 0)
return ESP_FAIL;
buf[len] = '\0';
cJSON *json = cJSON_Parse(buf);
if (!json) return ESP_FAIL;
if (!json)
return ESP_FAIL;
// Valores padrão
bool enabled = false;
const char *ssid = NULL;
const char *password = NULL;
cJSON *j_enabled = cJSON_GetObjectItem(json, "enabled");
if (cJSON_IsBool(j_enabled)) enabled = j_enabled->valueint;
if (cJSON_IsBool(j_enabled))
enabled = j_enabled->valueint;
cJSON *j_ssid = cJSON_GetObjectItem(json, "ssid");
if (cJSON_IsString(j_ssid)) ssid = j_ssid->valuestring;
if (cJSON_IsString(j_ssid))
ssid = j_ssid->valuestring;
cJSON *j_password = cJSON_GetObjectItem(json, "password");
if (cJSON_IsString(j_password)) password = j_password->valuestring;
if (cJSON_IsString(j_password))
password = j_password->valuestring;
// Enviar resposta antes de alterar Wi-Fi
// Resposta imediata
httpd_resp_sendstr(req, "Wi-Fi config atualizada com sucesso");
// Alocar struct para passar para a task
wifi_task_data_t *task_data = malloc(sizeof(wifi_task_data_t));
if (!task_data) {
wifi_task_data_t *task_data = (wifi_task_data_t *)malloc(sizeof(wifi_task_data_t));
if (!task_data)
{
cJSON_Delete(json);
ESP_LOGE(TAG, "Memory allocation failed for Wi-Fi task");
return ESP_ERR_NO_MEM;
}
task_data->enabled = enabled;
strncpy(task_data->ssid, ssid ? ssid : "", sizeof(task_data->ssid));
strncpy(task_data->password, password ? password : "", sizeof(task_data->password));
// Criar task normal com função C
// Copias seguras (garante null-termination)
strncpy(task_data->ssid, ssid ? ssid : "", sizeof(task_data->ssid) - 1);
task_data->ssid[sizeof(task_data->ssid) - 1] = '\0';
strncpy(task_data->password, password ? password : "", sizeof(task_data->password) - 1);
task_data->password[sizeof(task_data->password) - 1] = '\0';
xTaskCreate(
wifi_apply_config_task,
"wifi_config_task",
4096,
task_data,
3,
NULL
);
NULL);
cJSON_Delete(json);
return ESP_OK;
}
static esp_err_t config_mqtt_get_handler(httpd_req_t *req)
{
ESP_LOGD(TAG, "Handling GET /api/v1/config/mqtt");
@@ -139,28 +147,28 @@ static esp_err_t config_mqtt_get_handler(httpd_req_t *req)
cJSON *config = cJSON_CreateObject();
cJSON_AddBoolToObject(config, "enabled", enabled);
cJSON_AddStringToObject(config, "host", server);
cJSON_AddNumberToObject(config, "port", 1883);
cJSON_AddNumberToObject(config, "port", 1883); // fixo (se não usas no mqtt_set_config)
cJSON_AddStringToObject(config, "username", username);
cJSON_AddStringToObject(config, "password", password);
cJSON_AddStringToObject(config, "topic", base_topic);
cJSON_AddNumberToObject(config, "periodicity", periodicity);
const char *config_str = cJSON_Print(config);
char *config_str = cJSON_Print(config);
httpd_resp_sendstr(req, config_str);
free((void *)config_str);
free(config_str);
cJSON_Delete(config);
return ESP_OK;
}
static esp_err_t config_mqtt_post_handler(httpd_req_t *req)
{
ESP_LOGD(TAG, "Handling POST /api/v1/config/mqtt");
char buf[512];
int len = httpd_req_recv(req, buf, sizeof(buf) - 1);
if (len <= 0) {
if (len <= 0)
{
ESP_LOGE(TAG, "Failed to read request body");
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Invalid request body");
return ESP_FAIL;
@@ -169,33 +177,75 @@ static esp_err_t config_mqtt_post_handler(httpd_req_t *req)
ESP_LOGD(TAG, "Received JSON: %s", buf);
cJSON *json = cJSON_Parse(buf);
if (!json) {
if (!json)
{
ESP_LOGE(TAG, "Invalid JSON format");
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Invalid JSON");
return ESP_FAIL;
}
bool enabled = false;
const char *host = NULL, *topic = NULL, *username = NULL, *password = NULL;
int periodicity = 30;
// --- Ler config atual (para permitir "partial update" e evitar strings vazias)
bool current_enabled = mqtt_get_enabled();
char current_host[64] = {0};
char current_topic[32] = {0};
char current_user[32] = {0};
char current_pass[64] = {0};
uint16_t current_periodicity = mqtt_get_periodicity();
if (cJSON_IsBool(cJSON_GetObjectItem(json, "enabled")))
enabled = cJSON_GetObjectItem(json, "enabled")->valueint;
mqtt_get_server(current_host);
mqtt_get_base_topic(current_topic);
mqtt_get_user(current_user);
mqtt_get_password(current_pass);
bool enabled = current_enabled;
const char *host_in = NULL, *topic_in = NULL, *user_in = NULL, *pass_in = NULL;
int periodicity = (int)current_periodicity;
cJSON *j_enabled = cJSON_GetObjectItem(json, "enabled");
if (cJSON_IsBool(j_enabled))
enabled = j_enabled->valueint;
cJSON *j_host = cJSON_GetObjectItem(json, "host");
if (cJSON_IsString(j_host)) host = j_host->valuestring;
if (cJSON_IsString(j_host))
host_in = j_host->valuestring;
cJSON *j_topic = cJSON_GetObjectItem(json, "topic");
if (cJSON_IsString(j_topic)) topic = j_topic->valuestring;
if (cJSON_IsString(j_topic))
topic_in = j_topic->valuestring;
cJSON *j_user = cJSON_GetObjectItem(json, "username");
if (cJSON_IsString(j_user)) username = j_user->valuestring;
if (cJSON_IsString(j_user))
user_in = j_user->valuestring;
cJSON *j_pass = cJSON_GetObjectItem(json, "password");
if (cJSON_IsString(j_pass)) password = j_pass->valuestring;
if (cJSON_IsString(j_pass))
pass_in = j_pass->valuestring;
cJSON *j_periodicity = cJSON_GetObjectItem(json, "periodicity");
if (cJSON_IsNumber(j_periodicity)) periodicity = j_periodicity->valueint;
if (cJSON_IsNumber(j_periodicity))
periodicity = j_periodicity->valueint;
// --- Regras: se vier NULL ou "" mantém o atual; se atual também estiver vazio, usa default
const char *host =
(host_in && host_in[0] != '\0') ? host_in : (current_host[0] != '\0') ? current_host
: "mqtt.plixin.com";
const char *topic =
(topic_in && topic_in[0] != '\0') ? topic_in : (current_topic[0] != '\0') ? current_topic
: "";
const char *username =
(user_in && user_in[0] != '\0') ? user_in : (current_user[0] != '\0') ? current_user
: "";
const char *password =
(pass_in && pass_in[0] != '\0') ? pass_in : (current_pass[0] != '\0') ? current_pass
: "";
if (periodicity <= 0)
periodicity = (int)current_periodicity;
if (periodicity <= 0)
periodicity = 30;
ESP_LOGD(TAG, "Applying MQTT config:");
ESP_LOGD(TAG, " Enabled: %s", enabled ? "true" : "false");
@@ -206,7 +256,8 @@ static esp_err_t config_mqtt_post_handler(httpd_req_t *req)
ESP_LOGD(TAG, " Periodicity: %d", periodicity);
esp_err_t err = mqtt_set_config(enabled, host, topic, username, password, periodicity);
if (err != ESP_OK) {
if (err != ESP_OK)
{
ESP_LOGE(TAG, "Failed to apply MQTT config (code %d)", err);
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to apply config");
cJSON_Delete(json);
@@ -218,40 +269,33 @@ static esp_err_t config_mqtt_post_handler(httpd_req_t *req)
return ESP_OK;
}
void register_network_handlers(httpd_handle_t server, void *ctx) {
void register_network_handlers(httpd_handle_t server, void *ctx)
{
httpd_uri_t wifi_get = {
.uri = "/api/v1/config/wifi",
.method = HTTP_GET,
.handler = wifi_get_handler,
.user_ctx = ctx
};
.user_ctx = ctx};
httpd_register_uri_handler(server, &wifi_get);
httpd_uri_t wifi_post = {
.uri = "/api/v1/config/wifi",
.method = HTTP_POST,
.handler = wifi_post_handler,
.user_ctx = ctx
};
.user_ctx = ctx};
httpd_register_uri_handler(server, &wifi_post);
// URI handler for getting MQTT config
httpd_uri_t config_mqtt_get_uri = {
.uri = "/api/v1/config/mqtt",
.method = HTTP_GET,
.handler = config_mqtt_get_handler,
.user_ctx = ctx
};
.user_ctx = ctx};
httpd_register_uri_handler(server, &config_mqtt_get_uri);
// URI handler for posting MQTT config
httpd_uri_t config_mqtt_post_uri = {
.uri = "/api/v1/config/mqtt",
.method = HTTP_POST,
.handler = config_mqtt_post_handler,
.user_ctx = ctx
};
.user_ctx = ctx};
httpd_register_uri_handler(server, &config_mqtt_post_uri);
}