new meter
This commit is contained in:
141
components/rest_api/src/auth_api.c
Executable file
141
components/rest_api/src/auth_api.c
Executable file
@@ -0,0 +1,141 @@
|
||||
// =========================
|
||||
// auth_api.c
|
||||
// =========================
|
||||
#include "auth_api.h"
|
||||
#include "auth.h"
|
||||
#include "esp_log.h"
|
||||
#include "cJSON.h"
|
||||
|
||||
static const char *TAG = "auth_api";
|
||||
|
||||
static struct {
|
||||
char username[128];
|
||||
} users[10] = { /*{"admin"}, {"user1"}*/ };
|
||||
static int num_users = 2;
|
||||
|
||||
static esp_err_t auth_methods_get_handler(httpd_req_t *req) {
|
||||
httpd_resp_set_type(req, "application/json");
|
||||
cJSON *json = cJSON_CreateObject();
|
||||
cJSON_AddBoolToObject(json, "RFID", auth_is_enabled() );
|
||||
char *str = cJSON_PrintUnformatted(json);
|
||||
httpd_resp_sendstr(req, str);
|
||||
free(str);
|
||||
cJSON_Delete(json);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t auth_methods_post_handler(httpd_req_t *req) {
|
||||
char buf[256];
|
||||
int len = httpd_req_recv(req, buf, sizeof(buf) - 1);
|
||||
if (len <= 0) {
|
||||
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Erro ao receber dados");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
buf[len] = '\0';
|
||||
cJSON *json = cJSON_Parse(buf);
|
||||
if (!json) {
|
||||
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "JSON inválido");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
cJSON *rfid = cJSON_GetObjectItem(json, "RFID");
|
||||
if (rfid && cJSON_IsBool(rfid)) {
|
||||
auth_set_enabled(cJSON_IsTrue(rfid));
|
||||
} else {
|
||||
cJSON_Delete(json);
|
||||
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Campo 'RFID' inválido ou ausente");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
cJSON_Delete(json);
|
||||
httpd_resp_sendstr(req, "Métodos de autenticação atualizados");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
static esp_err_t users_get_handler(httpd_req_t *req) {
|
||||
httpd_resp_set_type(req, "application/json");
|
||||
cJSON *root = cJSON_CreateObject();
|
||||
cJSON *list = cJSON_CreateArray();
|
||||
for (int i = 0; i < num_users; ++i) {
|
||||
cJSON *u = cJSON_CreateObject();
|
||||
cJSON_AddStringToObject(u, "username", users[i].username);
|
||||
cJSON_AddItemToArray(list, u);
|
||||
}
|
||||
cJSON_AddItemToObject(root, "users", list);
|
||||
char *str = cJSON_Print(root);
|
||||
httpd_resp_sendstr(req, str);
|
||||
free(str);
|
||||
cJSON_Delete(root);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t users_post_handler(httpd_req_t *req) {
|
||||
char buf[128];
|
||||
int len = httpd_req_recv(req, buf, sizeof(buf) - 1);
|
||||
if (len <= 0) return ESP_FAIL;
|
||||
buf[len] = '\0';
|
||||
if (num_users < 10) {
|
||||
strlcpy(users[num_users].username, buf, sizeof(users[num_users].username));
|
||||
num_users++;
|
||||
httpd_resp_sendstr(req, "Usuário adicionado com sucesso");
|
||||
} else {
|
||||
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Limite de usuários atingido");
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t users_delete_handler(httpd_req_t *req) {
|
||||
char query[128];
|
||||
if (httpd_req_get_url_query_str(req, query, sizeof(query)) == ESP_OK) {
|
||||
char username[128];
|
||||
if (httpd_query_key_value(query, "username", username, sizeof(username)) == ESP_OK) {
|
||||
for (int i = 0; i < num_users; i++) {
|
||||
if (strcmp(users[i].username, username) == 0) {
|
||||
for (int j = i; j < num_users - 1; j++) {
|
||||
users[j] = users[j + 1];
|
||||
}
|
||||
num_users--;
|
||||
httpd_resp_sendstr(req, "Usuário removido com sucesso");
|
||||
return ESP_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Usuário não encontrado");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
void register_auth_handlers(httpd_handle_t server, void *ctx) {
|
||||
httpd_register_uri_handler(server, &(httpd_uri_t){
|
||||
.uri = "/api/v1/config/auth-methods",
|
||||
.method = HTTP_GET,
|
||||
.handler = auth_methods_get_handler,
|
||||
.user_ctx = ctx
|
||||
});
|
||||
httpd_register_uri_handler(server, &(httpd_uri_t){
|
||||
.uri = "/api/v1/config/auth-methods",
|
||||
.method = HTTP_POST,
|
||||
.handler = auth_methods_post_handler,
|
||||
.user_ctx = ctx
|
||||
});
|
||||
httpd_register_uri_handler(server, &(httpd_uri_t){
|
||||
.uri = "/api/v1/config/users",
|
||||
.method = HTTP_GET,
|
||||
.handler = users_get_handler,
|
||||
.user_ctx = ctx
|
||||
});
|
||||
httpd_register_uri_handler(server, &(httpd_uri_t){
|
||||
.uri = "/api/v1/config/users",
|
||||
.method = HTTP_POST,
|
||||
.handler = users_post_handler,
|
||||
.user_ctx = ctx
|
||||
});
|
||||
httpd_register_uri_handler(server, &(httpd_uri_t){
|
||||
.uri = "/api/v1/config/users",
|
||||
.method = HTTP_DELETE,
|
||||
.handler = users_delete_handler,
|
||||
.user_ctx = ctx
|
||||
});
|
||||
}
|
||||
83
components/rest_api/src/dashboard_api.c
Normal file
83
components/rest_api/src/dashboard_api.c
Normal file
@@ -0,0 +1,83 @@
|
||||
#include "dashboard_api.h"
|
||||
#include "esp_log.h"
|
||||
#include "cJSON.h"
|
||||
#include "evse_api.h"
|
||||
#include "evse_error.h"
|
||||
|
||||
static const char *TAG = "dashboard_api";
|
||||
|
||||
static esp_err_t dashboard_get_handler(httpd_req_t *req) {
|
||||
httpd_resp_set_type(req, "application/json");
|
||||
|
||||
// Cria o objeto JSON principal do dashboard
|
||||
cJSON *dashboard = cJSON_CreateObject();
|
||||
|
||||
// Status do sistema
|
||||
evse_state_t state = evse_get_state();
|
||||
cJSON_AddStringToObject(dashboard, "status", evse_state_to_str(state));
|
||||
|
||||
// Carregador - informação do carregador 1 (adapte conforme necessário)
|
||||
cJSON *chargers = cJSON_CreateArray();
|
||||
cJSON *charger1 = cJSON_CreateObject();
|
||||
cJSON_AddNumberToObject(charger1, "id", 1);
|
||||
cJSON_AddStringToObject(charger1, "status", evse_state_to_str(state));
|
||||
cJSON_AddNumberToObject(charger1, "current", evse_get_charging_current() / 10);
|
||||
cJSON_AddNumberToObject(charger1, "maxCurrent", evse_get_max_charging_current());
|
||||
|
||||
// Calcular a potência com base na corrente (considerando 230V)
|
||||
int power = (evse_get_charging_current() / 10) * 230;
|
||||
cJSON_AddNumberToObject(charger1, "power", power);
|
||||
|
||||
cJSON_AddItemToArray(chargers, charger1);
|
||||
cJSON_AddItemToObject(dashboard, "chargers", chargers);
|
||||
|
||||
// Consumo e tempo de carregamento
|
||||
cJSON_AddNumberToObject(dashboard, "energyConsumed", evse_get_consumption_limit());
|
||||
cJSON_AddNumberToObject(dashboard, "chargingTime", evse_get_charging_time_limit());
|
||||
|
||||
// Alertas
|
||||
cJSON *alerts = cJSON_CreateArray();
|
||||
if (evse_is_limit_reached()) {
|
||||
cJSON_AddItemToArray(alerts, cJSON_CreateString("Limite de consumo atingido."));
|
||||
}
|
||||
if (!evse_is_available()) {
|
||||
cJSON_AddItemToArray(alerts, cJSON_CreateString("Estação indisponível."));
|
||||
}
|
||||
if (!evse_is_enabled()) {
|
||||
cJSON_AddItemToArray(alerts, cJSON_CreateString("EVSE desativado."));
|
||||
}
|
||||
cJSON_AddItemToObject(dashboard, "alerts", alerts);
|
||||
|
||||
// Erros
|
||||
uint32_t error_bits = evse_get_error();
|
||||
cJSON *errors = cJSON_CreateArray();
|
||||
if (error_bits & EVSE_ERR_DIODE_SHORT_BIT) cJSON_AddItemToArray(errors, cJSON_CreateString("Diodo curto-circuitado"));
|
||||
if (error_bits & EVSE_ERR_LOCK_FAULT_BIT) cJSON_AddItemToArray(errors, cJSON_CreateString("Falha no travamento"));
|
||||
if (error_bits & EVSE_ERR_UNLOCK_FAULT_BIT) cJSON_AddItemToArray(errors, cJSON_CreateString("Falha no destravamento"));
|
||||
if (error_bits & EVSE_ERR_RCM_SELFTEST_FAULT_BIT) cJSON_AddItemToArray(errors, cJSON_CreateString("Falha no autoteste do RCM"));
|
||||
if (error_bits & EVSE_ERR_RCM_TRIGGERED_BIT) cJSON_AddItemToArray(errors, cJSON_CreateString("RCM disparado"));
|
||||
if (error_bits & EVSE_ERR_TEMPERATURE_HIGH_BIT) cJSON_AddItemToArray(errors, cJSON_CreateString("Temperatura elevada"));
|
||||
if (error_bits & EVSE_ERR_PILOT_FAULT_BIT) cJSON_AddItemToArray(errors, cJSON_CreateString("Erro no sinal piloto"));
|
||||
if (error_bits & EVSE_ERR_TEMPERATURE_FAULT_BIT) cJSON_AddItemToArray(errors, cJSON_CreateString("Falha no sensor de temperatura"));
|
||||
cJSON_AddItemToObject(dashboard, "errors", errors);
|
||||
|
||||
// Enviar resposta JSON
|
||||
const char *json_str = cJSON_Print(dashboard);
|
||||
httpd_resp_sendstr(req, json_str);
|
||||
|
||||
// Liberar memória
|
||||
free((void *)json_str);
|
||||
cJSON_Delete(dashboard);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void register_dashboard_handlers(httpd_handle_t server, void *ctx) {
|
||||
httpd_uri_t uri = {
|
||||
.uri = "/api/v1/dashboard",
|
||||
.method = HTTP_GET,
|
||||
.handler = dashboard_get_handler,
|
||||
.user_ctx = ctx
|
||||
};
|
||||
httpd_register_uri_handler(server, &uri);
|
||||
}
|
||||
63
components/rest_api/src/evse_settings_api.c
Executable file
63
components/rest_api/src/evse_settings_api.c
Executable file
@@ -0,0 +1,63 @@
|
||||
// =========================
|
||||
// evse_settings_api.c
|
||||
// =========================
|
||||
#include "evse_settings_api.h"
|
||||
#include "evse_api.h"
|
||||
#include "esp_log.h"
|
||||
#include "cJSON.h"
|
||||
|
||||
static const char *TAG = "evse_settings_api";
|
||||
|
||||
static esp_err_t config_settings_get_handler(httpd_req_t *req) {
|
||||
httpd_resp_set_type(req, "application/json");
|
||||
cJSON *config = cJSON_CreateObject();
|
||||
cJSON_AddNumberToObject(config, "currentLimit", evse_get_max_charging_current());
|
||||
cJSON_AddNumberToObject(config, "temperatureLimit", evse_get_temp_threshold());
|
||||
const char *json_str = cJSON_Print(config);
|
||||
httpd_resp_sendstr(req, json_str);
|
||||
free((void *)json_str);
|
||||
cJSON_Delete(config);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t config_settings_post_handler(httpd_req_t *req) {
|
||||
char buf[512];
|
||||
int len = httpd_req_recv(req, buf, sizeof(buf) - 1);
|
||||
if (len <= 0) {
|
||||
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Empty body");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
buf[len] = '\0';
|
||||
cJSON *json = cJSON_Parse(buf);
|
||||
if (!json) {
|
||||
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Invalid JSON");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
cJSON *current = cJSON_GetObjectItem(json, "currentLimit");
|
||||
if (current) evse_set_max_charging_current(current->valueint);
|
||||
cJSON *temp = cJSON_GetObjectItem(json, "temperatureLimit");
|
||||
if (temp) evse_set_temp_threshold(temp->valueint);
|
||||
|
||||
cJSON_Delete(json);
|
||||
httpd_resp_sendstr(req, "Configurações atualizadas com sucesso");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void register_evse_settings_handlers(httpd_handle_t server, void *ctx) {
|
||||
httpd_uri_t get_uri = {
|
||||
.uri = "/api/v1/config/settings",
|
||||
.method = HTTP_GET,
|
||||
.handler = config_settings_get_handler,
|
||||
.user_ctx = ctx
|
||||
};
|
||||
httpd_register_uri_handler(server, &get_uri);
|
||||
|
||||
httpd_uri_t post_uri = {
|
||||
.uri = "/api/v1/config/settings",
|
||||
.method = HTTP_POST,
|
||||
.handler = config_settings_post_handler,
|
||||
.user_ctx = ctx
|
||||
};
|
||||
httpd_register_uri_handler(server, &post_uri);
|
||||
}
|
||||
108
components/rest_api/src/loadbalancing_settings_api.c
Normal file
108
components/rest_api/src/loadbalancing_settings_api.c
Normal file
@@ -0,0 +1,108 @@
|
||||
#include "loadbalancing_settings_api.h"
|
||||
#include "loadbalancer.h"
|
||||
#include "esp_log.h"
|
||||
#include "cJSON.h"
|
||||
|
||||
static const char *TAG = "loadbalancing_settings_api";
|
||||
|
||||
// GET Handler: Retorna configurações atuais de load balancing
|
||||
static esp_err_t loadbalancing_config_get_handler(httpd_req_t *req) {
|
||||
bool enabled = loadbalancer_is_enabled();
|
||||
uint8_t currentLimit = load_balancing_get_max_grid_current();
|
||||
|
||||
ESP_LOGI(TAG, "Fetching load balancing settings: enabled = %d, currentLimit = %u", enabled, currentLimit);
|
||||
|
||||
httpd_resp_set_type(req, "application/json");
|
||||
|
||||
cJSON *config = cJSON_CreateObject();
|
||||
cJSON_AddBoolToObject(config, "loadBalancingEnabled", enabled);
|
||||
cJSON_AddNumberToObject(config, "loadBalancingCurrentLimit", currentLimit);
|
||||
|
||||
const char *json_str = cJSON_Print(config);
|
||||
httpd_resp_sendstr(req, json_str);
|
||||
|
||||
ESP_LOGI(TAG, "Returned config: %s", json_str);
|
||||
|
||||
free((void *)json_str);
|
||||
cJSON_Delete(config);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
// POST Handler: Atualiza configurações de load balancing
|
||||
static esp_err_t loadbalancing_config_post_handler(httpd_req_t *req) {
|
||||
char buf[512];
|
||||
int len = httpd_req_recv(req, buf, sizeof(buf) - 1);
|
||||
|
||||
if (len <= 0) {
|
||||
ESP_LOGE(TAG, "Received empty POST body");
|
||||
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Empty body");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
buf[len] = '\0';
|
||||
ESP_LOGI(TAG, "Received POST data: %s", buf);
|
||||
|
||||
cJSON *json = cJSON_Parse(buf);
|
||||
if (!json) {
|
||||
ESP_LOGE(TAG, "Invalid JSON");
|
||||
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Invalid JSON");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
// Atualizar estado habilitado
|
||||
cJSON *enabled_item = cJSON_GetObjectItem(json, "loadBalancingEnabled");
|
||||
if (enabled_item && cJSON_IsBool(enabled_item)) {
|
||||
bool isEnabled = cJSON_IsTrue(enabled_item);
|
||||
loadbalancer_set_enabled(isEnabled);
|
||||
ESP_LOGI(TAG, "Updated loadBalancingEnabled to: %d", isEnabled);
|
||||
}
|
||||
|
||||
// Atualizar limite de corrente
|
||||
cJSON *limit_item = cJSON_GetObjectItem(json, "loadBalancingCurrentLimit");
|
||||
if (limit_item && cJSON_IsNumber(limit_item)) {
|
||||
uint8_t currentLimit = (uint8_t)limit_item->valuedouble;
|
||||
|
||||
// Validar intervalo
|
||||
if (currentLimit < 6 || currentLimit > 100) {
|
||||
ESP_LOGW(TAG, "Rejected invalid currentLimit: %d", currentLimit);
|
||||
cJSON_Delete(json);
|
||||
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Invalid currentLimit (must be 6-100)");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t err = load_balancing_set_max_grid_current(currentLimit);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to save currentLimit: %s", esp_err_to_name(err));
|
||||
cJSON_Delete(json);
|
||||
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to save setting");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Updated loadBalancingCurrentLimit to: %d", currentLimit);
|
||||
}
|
||||
|
||||
cJSON_Delete(json);
|
||||
httpd_resp_sendstr(req, "Load balancing settings updated successfully");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
// Registro dos handlers na API HTTP
|
||||
void register_loadbalancing_settings_handlers(httpd_handle_t server, void *ctx) {
|
||||
// GET
|
||||
httpd_uri_t get_uri = {
|
||||
.uri = "/api/v1/config/loadbalancing",
|
||||
.method = HTTP_GET,
|
||||
.handler = loadbalancing_config_get_handler,
|
||||
.user_ctx = ctx
|
||||
};
|
||||
httpd_register_uri_handler(server, &get_uri);
|
||||
|
||||
// POST
|
||||
httpd_uri_t post_uri = {
|
||||
.uri = "/api/v1/config/loadbalancing",
|
||||
.method = HTTP_POST,
|
||||
.handler = loadbalancing_config_post_handler,
|
||||
.user_ctx = ctx
|
||||
};
|
||||
httpd_register_uri_handler(server, &post_uri);
|
||||
}
|
||||
111
components/rest_api/src/meters_settings_api.c
Normal file
111
components/rest_api/src/meters_settings_api.c
Normal file
@@ -0,0 +1,111 @@
|
||||
#include "meters_settings_api.h"
|
||||
#include "meter_manager.h" // Atualizado para usar o novo manager
|
||||
#include "esp_log.h"
|
||||
#include "cJSON.h"
|
||||
|
||||
static const char *TAG = "meters_settings_api";
|
||||
|
||||
// Função para recuperar as configurações dos contadores
|
||||
static esp_err_t meters_config_get_handler(httpd_req_t *req) {
|
||||
ESP_LOGI(TAG, "Received GET request for /api/v1/config/meters");
|
||||
|
||||
httpd_resp_set_type(req, "application/json");
|
||||
|
||||
cJSON *config = cJSON_CreateObject();
|
||||
|
||||
// Recuperando as configurações dos contadores
|
||||
meter_type_t gridmeterType = meter_manager_grid_get_model();
|
||||
meter_type_t evsemeterType = meter_manager_evse_get_model();
|
||||
|
||||
ESP_LOGI(TAG, "Grid meter type: %s", meter_type_to_str(gridmeterType));
|
||||
ESP_LOGI(TAG, "EVSE meter type: %s", meter_type_to_str(evsemeterType));
|
||||
|
||||
// Adicionando os tipos de contadores ao objeto JSON
|
||||
cJSON_AddStringToObject(config, "gridmeter", meter_type_to_str(gridmeterType));
|
||||
cJSON_AddStringToObject(config, "evsemeter", meter_type_to_str(evsemeterType));
|
||||
|
||||
// Convertendo o objeto JSON para uma string
|
||||
const char *json_str = cJSON_Print(config);
|
||||
ESP_LOGI(TAG, "Returning meters config: %s", json_str);
|
||||
|
||||
httpd_resp_sendstr(req, json_str);
|
||||
|
||||
// Liberação da memória
|
||||
free((void *)json_str);
|
||||
cJSON_Delete(config);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
// Função para atualizar as configurações dos contadores
|
||||
static esp_err_t meters_config_post_handler(httpd_req_t *req) {
|
||||
ESP_LOGI(TAG, "Received POST request for /api/v1/config/meters");
|
||||
|
||||
char buf[512];
|
||||
int len = httpd_req_recv(req, buf, sizeof(buf) - 1);
|
||||
|
||||
if (len <= 0) {
|
||||
ESP_LOGE(TAG, "Received empty body in POST request");
|
||||
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Empty body");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
buf[len] = '\0'; // Garantir que a string está terminada
|
||||
|
||||
ESP_LOGI(TAG, "Received POST data: %s", buf);
|
||||
|
||||
cJSON *json = cJSON_Parse(buf);
|
||||
if (!json) {
|
||||
ESP_LOGE(TAG, "Failed to parse JSON data");
|
||||
// Resposta detalhada de erro
|
||||
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Invalid JSON format");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
// Atualizando os contadores
|
||||
cJSON *gridmeter = cJSON_GetObjectItem(json, "gridmeter");
|
||||
if (gridmeter) {
|
||||
meter_type_t gridType = string_to_meter_type(gridmeter->valuestring); // Usando a função string_to_meter_type
|
||||
ESP_LOGI(TAG, "Updating grid meter type to: %s", gridmeter->valuestring);
|
||||
meter_manager_grid_set_model(gridType);
|
||||
}
|
||||
|
||||
cJSON *evsemeter = cJSON_GetObjectItem(json, "evsemeter");
|
||||
if (evsemeter) {
|
||||
meter_type_t evseType = string_to_meter_type(evsemeter->valuestring); // Usando a função string_to_meter_type
|
||||
ESP_LOGI(TAG, "Updating EVSE meter type to: %s", evsemeter->valuestring);
|
||||
meter_manager_evse_set_model(evseType);
|
||||
}
|
||||
|
||||
cJSON_Delete(json);
|
||||
httpd_resp_sendstr(req, "Meters updated successfully");
|
||||
|
||||
ESP_LOGI(TAG, "Meters configuration updated successfully");
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
// Registrando os manipuladores de URI para os contadores
|
||||
void register_meters_settings_handlers(httpd_handle_t server, void *ctx) {
|
||||
ESP_LOGI(TAG, "Registering URI handlers for meters settings");
|
||||
|
||||
// URI para o método GET
|
||||
httpd_uri_t meters_get_uri = {
|
||||
.uri = "/api/v1/config/meters",
|
||||
.method = HTTP_GET,
|
||||
.handler = meters_config_get_handler,
|
||||
.user_ctx = ctx
|
||||
};
|
||||
ESP_LOGI(TAG, "Registering GET handler for /api/v1/config/meters");
|
||||
httpd_register_uri_handler(server, &meters_get_uri);
|
||||
|
||||
// URI para o método POST
|
||||
httpd_uri_t meters_post_uri = {
|
||||
.uri = "/api/v1/config/meters",
|
||||
.method = HTTP_POST,
|
||||
.handler = meters_config_post_handler,
|
||||
.user_ctx = ctx
|
||||
};
|
||||
ESP_LOGI(TAG, "Registering POST handler for /api/v1/config/meters");
|
||||
httpd_register_uri_handler(server, &meters_post_uri);
|
||||
}
|
||||
257
components/rest_api/src/network_api.c
Executable file
257
components/rest_api/src/network_api.c
Executable file
@@ -0,0 +1,257 @@
|
||||
// =========================
|
||||
// network_api.c
|
||||
// =========================
|
||||
|
||||
#include "network_api.h"
|
||||
#include "esp_log.h"
|
||||
#include "cJSON.h"
|
||||
#include "wifi.h"
|
||||
#include "mqtt.h"
|
||||
|
||||
static const char *TAG = "network_api";
|
||||
|
||||
typedef struct {
|
||||
bool enabled;
|
||||
char ssid[33];
|
||||
char password[65];
|
||||
} wifi_task_data_t;
|
||||
|
||||
|
||||
static void wifi_apply_config_task(void *param) {
|
||||
wifi_task_data_t *data = (wifi_task_data_t *)param;
|
||||
ESP_LOGI("wifi_task", "Applying Wi-Fi config in background task");
|
||||
wifi_set_config(data->enabled, data->ssid, data->password);
|
||||
free(data);
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
static esp_err_t wifi_get_handler(httpd_req_t *req) {
|
||||
ESP_LOGI(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};
|
||||
|
||||
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) {
|
||||
ESP_LOGI(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;
|
||||
buf[len] = '\0';
|
||||
|
||||
cJSON *json = cJSON_Parse(buf);
|
||||
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;
|
||||
|
||||
cJSON *j_ssid = cJSON_GetObjectItem(json, "ssid");
|
||||
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;
|
||||
|
||||
// Enviar resposta antes de alterar Wi-Fi
|
||||
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) {
|
||||
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
|
||||
xTaskCreate(
|
||||
wifi_apply_config_task,
|
||||
"wifi_config_task",
|
||||
4096,
|
||||
task_data,
|
||||
3,
|
||||
NULL
|
||||
);
|
||||
|
||||
cJSON_Delete(json);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
static esp_err_t config_mqtt_get_handler(httpd_req_t *req)
|
||||
{
|
||||
ESP_LOGI(TAG, "Handling GET /api/v1/config/mqtt");
|
||||
|
||||
httpd_resp_set_type(req, "application/json");
|
||||
|
||||
bool enabled = mqtt_get_enabled();
|
||||
char server[64] = {0};
|
||||
char base_topic[32] = {0};
|
||||
char username[32] = {0};
|
||||
char password[64] = {0};
|
||||
uint16_t periodicity = mqtt_get_periodicity();
|
||||
|
||||
mqtt_get_server(server);
|
||||
mqtt_get_base_topic(base_topic);
|
||||
mqtt_get_user(username);
|
||||
mqtt_get_password(password);
|
||||
|
||||
ESP_LOGI(TAG, "MQTT Config:");
|
||||
ESP_LOGI(TAG, " Enabled: %s", enabled ? "true" : "false");
|
||||
ESP_LOGI(TAG, " Server: %s", server);
|
||||
ESP_LOGI(TAG, " Topic: %s", base_topic);
|
||||
ESP_LOGI(TAG, " Username: %s", username);
|
||||
ESP_LOGI(TAG, " Password: %s", password);
|
||||
ESP_LOGI(TAG, " Periodicity: %d", periodicity);
|
||||
|
||||
cJSON *config = cJSON_CreateObject();
|
||||
cJSON_AddBoolToObject(config, "enabled", enabled);
|
||||
cJSON_AddStringToObject(config, "host", server);
|
||||
cJSON_AddNumberToObject(config, "port", 1883);
|
||||
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);
|
||||
httpd_resp_sendstr(req, config_str);
|
||||
|
||||
free((void *)config_str);
|
||||
cJSON_Delete(config);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
static esp_err_t config_mqtt_post_handler(httpd_req_t *req)
|
||||
{
|
||||
ESP_LOGI(TAG, "Handling POST /api/v1/config/mqtt");
|
||||
|
||||
char buf[512];
|
||||
int len = httpd_req_recv(req, buf, sizeof(buf) - 1);
|
||||
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;
|
||||
}
|
||||
buf[len] = '\0';
|
||||
ESP_LOGI(TAG, "Received JSON: %s", buf);
|
||||
|
||||
cJSON *json = cJSON_Parse(buf);
|
||||
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;
|
||||
|
||||
if (cJSON_IsBool(cJSON_GetObjectItem(json, "enabled")))
|
||||
enabled = cJSON_GetObjectItem(json, "enabled")->valueint;
|
||||
|
||||
cJSON *j_host = cJSON_GetObjectItem(json, "host");
|
||||
if (cJSON_IsString(j_host)) host = j_host->valuestring;
|
||||
|
||||
cJSON *j_topic = cJSON_GetObjectItem(json, "topic");
|
||||
if (cJSON_IsString(j_topic)) topic = j_topic->valuestring;
|
||||
|
||||
cJSON *j_user = cJSON_GetObjectItem(json, "username");
|
||||
if (cJSON_IsString(j_user)) username = j_user->valuestring;
|
||||
|
||||
cJSON *j_pass = cJSON_GetObjectItem(json, "password");
|
||||
if (cJSON_IsString(j_pass)) password = j_pass->valuestring;
|
||||
|
||||
cJSON *j_periodicity = cJSON_GetObjectItem(json, "periodicity");
|
||||
if (cJSON_IsNumber(j_periodicity)) periodicity = j_periodicity->valueint;
|
||||
|
||||
ESP_LOGI(TAG, "Applying MQTT config:");
|
||||
ESP_LOGI(TAG, " Enabled: %s", enabled ? "true" : "false");
|
||||
ESP_LOGI(TAG, " Host: %s", host);
|
||||
ESP_LOGI(TAG, " Topic: %s", topic);
|
||||
ESP_LOGI(TAG, " Username: %s", username);
|
||||
ESP_LOGI(TAG, " Password: %s", password);
|
||||
ESP_LOGI(TAG, " Periodicity: %d", periodicity);
|
||||
|
||||
esp_err_t err = mqtt_set_config(enabled, host, topic, username, password, periodicity);
|
||||
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);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
httpd_resp_sendstr(req, "Configuração MQTT atualizada com sucesso");
|
||||
cJSON_Delete(json);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
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
|
||||
};
|
||||
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
|
||||
};
|
||||
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
|
||||
};
|
||||
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
|
||||
};
|
||||
httpd_register_uri_handler(server, &config_mqtt_post_uri);
|
||||
}
|
||||
92
components/rest_api/src/ocpp_api.c
Executable file
92
components/rest_api/src/ocpp_api.c
Executable file
@@ -0,0 +1,92 @@
|
||||
// =========================
|
||||
// ocpp_api.c
|
||||
// =========================
|
||||
#include "ocpp_api.h"
|
||||
#include "esp_log.h"
|
||||
#include "cJSON.h"
|
||||
|
||||
static const char *TAG = "ocpp_api";
|
||||
|
||||
static struct {
|
||||
char url[256];
|
||||
char chargeBoxId[128];
|
||||
char certificate[256];
|
||||
char privateKey[256];
|
||||
} ocpp_config = {"", "", "", ""};
|
||||
|
||||
static esp_err_t ocpp_get_status_handler(httpd_req_t *req) {
|
||||
httpd_resp_set_type(req, "application/json");
|
||||
cJSON *status = cJSON_CreateObject();
|
||||
cJSON_AddStringToObject(status, "status", "connected");
|
||||
char *str = cJSON_Print(status);
|
||||
httpd_resp_sendstr(req, str);
|
||||
free(str);
|
||||
cJSON_Delete(status);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t ocpp_get_config_handler(httpd_req_t *req) {
|
||||
httpd_resp_set_type(req, "application/json");
|
||||
cJSON *json = cJSON_CreateObject();
|
||||
cJSON_AddStringToObject(json, "url", ocpp_config.url);
|
||||
cJSON_AddStringToObject(json, "chargeBoxId", ocpp_config.chargeBoxId);
|
||||
cJSON_AddStringToObject(json, "certificate", ocpp_config.certificate);
|
||||
cJSON_AddStringToObject(json, "privateKey", ocpp_config.privateKey);
|
||||
char *str = cJSON_Print(json);
|
||||
httpd_resp_sendstr(req, str);
|
||||
free(str);
|
||||
cJSON_Delete(json);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t ocpp_post_config_handler(httpd_req_t *req) {
|
||||
char buf[512];
|
||||
int len = httpd_req_recv(req, buf, sizeof(buf) - 1);
|
||||
if (len <= 0) {
|
||||
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Empty body");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
buf[len] = '\0';
|
||||
cJSON *json = cJSON_Parse(buf);
|
||||
if (!json) {
|
||||
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Invalid JSON");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
cJSON *url = cJSON_GetObjectItem(json, "url");
|
||||
if (url) strlcpy(ocpp_config.url, url->valuestring, sizeof(ocpp_config.url));
|
||||
cJSON *id = cJSON_GetObjectItem(json, "chargeBoxId");
|
||||
if (id) strlcpy(ocpp_config.chargeBoxId, id->valuestring, sizeof(ocpp_config.chargeBoxId));
|
||||
cJSON *cert = cJSON_GetObjectItem(json, "certificate");
|
||||
if (cert) strlcpy(ocpp_config.certificate, cert->valuestring, sizeof(ocpp_config.certificate));
|
||||
cJSON *key = cJSON_GetObjectItem(json, "privateKey");
|
||||
if (key) strlcpy(ocpp_config.privateKey, key->valuestring, sizeof(ocpp_config.privateKey));
|
||||
cJSON_Delete(json);
|
||||
httpd_resp_sendstr(req, "OCPP config atualizada com sucesso");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void register_ocpp_handlers(httpd_handle_t server, void *ctx) {
|
||||
httpd_uri_t status_uri = {
|
||||
.uri = "/api/v1/ocpp",
|
||||
.method = HTTP_GET,
|
||||
.handler = ocpp_get_status_handler,
|
||||
.user_ctx = ctx
|
||||
};
|
||||
httpd_register_uri_handler(server, &status_uri);
|
||||
|
||||
httpd_uri_t get_uri = {
|
||||
.uri = "/api/v1/config/ocpp",
|
||||
.method = HTTP_GET,
|
||||
.handler = ocpp_get_config_handler,
|
||||
.user_ctx = ctx
|
||||
};
|
||||
httpd_register_uri_handler(server, &get_uri);
|
||||
|
||||
httpd_uri_t post_uri = {
|
||||
.uri = "/api/v1/config/ocpp",
|
||||
.method = HTTP_POST,
|
||||
.handler = ocpp_post_config_handler,
|
||||
.user_ctx = ctx
|
||||
};
|
||||
httpd_register_uri_handler(server, &post_uri);
|
||||
}
|
||||
53
components/rest_api/src/rest_main.c
Executable file
53
components/rest_api/src/rest_main.c
Executable file
@@ -0,0 +1,53 @@
|
||||
#include "rest_main.h"
|
||||
#include "evse_settings_api.h"
|
||||
#include "meters_settings_api.h"
|
||||
#include "loadbalancing_settings_api.h"
|
||||
#include "network_api.h"
|
||||
#include "ocpp_api.h"
|
||||
#include "auth_api.h"
|
||||
#include "dashboard_api.h"
|
||||
#include "static_file_api.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
|
||||
static const char *TAG = "rest_main";
|
||||
|
||||
esp_err_t rest_server_init(const char *base_path) {
|
||||
ESP_LOGI(TAG, "Initializing REST API with base path: %s", base_path);
|
||||
|
||||
rest_server_context_t *ctx = calloc(1, sizeof(rest_server_context_t));
|
||||
if (!ctx) {
|
||||
ESP_LOGE(TAG, "Failed to allocate memory for REST context");
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
strlcpy(ctx->base_path, base_path, sizeof(ctx->base_path));
|
||||
|
||||
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
|
||||
config.uri_match_fn = httpd_uri_match_wildcard;
|
||||
config.max_uri_handlers = 32;
|
||||
|
||||
httpd_handle_t server = NULL;
|
||||
esp_err_t err = httpd_start(&server, &config);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to start HTTP server: %s", esp_err_to_name(err));
|
||||
free(ctx);
|
||||
return err;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "HTTP server started successfully");
|
||||
|
||||
// Register endpoint groups
|
||||
register_evse_settings_handlers(server, ctx); // Apenas chamando a função sem comparação
|
||||
register_network_handlers(server, ctx); // Apenas chamando a função sem comparação
|
||||
register_ocpp_handlers(server, ctx); // Apenas chamando a função sem comparação
|
||||
register_auth_handlers(server, ctx); // Apenas chamando a função sem comparação
|
||||
register_dashboard_handlers(server, ctx); // Apenas chamando a função sem comparação
|
||||
register_meters_settings_handlers(server, ctx); // Apenas chamando a função sem comparação
|
||||
register_loadbalancing_settings_handlers(server, ctx); // Apenas chamando a função sem comparação
|
||||
register_static_file_handlers(server, ctx); // Apenas chamando a função sem comparação
|
||||
|
||||
ESP_LOGI(TAG, "All REST API endpoint groups registered successfully");
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
89
components/rest_api/src/static_file_api.c
Normal file
89
components/rest_api/src/static_file_api.c
Normal file
@@ -0,0 +1,89 @@
|
||||
#include "static_file_api.h"
|
||||
#include "esp_log.h"
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include "esp_vfs.h"
|
||||
|
||||
static const char *TAG = "static_file_api";
|
||||
|
||||
#define FILE_PATH_MAX (ESP_VFS_PATH_MAX + 128)
|
||||
#define SCRATCH_BUFSIZE (10240)
|
||||
|
||||
typedef struct rest_server_context {
|
||||
char base_path[ESP_VFS_PATH_MAX + 1];
|
||||
char scratch[SCRATCH_BUFSIZE];
|
||||
} rest_server_context_t;
|
||||
|
||||
#define CHECK_FILE_EXTENSION(filename, ext) \
|
||||
(strcasecmp(&filename[strlen(filename) - strlen(ext)], ext) == 0)
|
||||
|
||||
static esp_err_t set_content_type_from_file(httpd_req_t *req, const char *filepath) {
|
||||
const char *type = "text/plain";
|
||||
if (CHECK_FILE_EXTENSION(filepath, ".html")) type = "text/html";
|
||||
else if (CHECK_FILE_EXTENSION(filepath, ".js")) type = "application/javascript";
|
||||
else if (CHECK_FILE_EXTENSION(filepath, ".css")) type = "text/css";
|
||||
else if (CHECK_FILE_EXTENSION(filepath, ".png")) type = "image/png";
|
||||
else if (CHECK_FILE_EXTENSION(filepath, ".ico")) type = "image/x-icon";
|
||||
else if (CHECK_FILE_EXTENSION(filepath, ".svg")) type = "image/svg+xml";
|
||||
return httpd_resp_set_type(req, type);
|
||||
}
|
||||
|
||||
static esp_err_t static_get_handler(httpd_req_t *req) {
|
||||
char filepath[FILE_PATH_MAX];
|
||||
rest_server_context_t *ctx = (rest_server_context_t *) req->user_ctx;
|
||||
|
||||
strlcpy(filepath, ctx->base_path, sizeof(filepath));
|
||||
if (req->uri[strlen(req->uri) - 1] == '/') {
|
||||
strlcat(filepath, "/index.html", sizeof(filepath));
|
||||
} else {
|
||||
strlcat(filepath, req->uri, sizeof(filepath));
|
||||
}
|
||||
|
||||
int fd = open(filepath, O_RDONLY, 0);
|
||||
if (fd == -1) {
|
||||
// fallback para /index.html (SPA)
|
||||
ESP_LOGW(TAG, "Arquivo não encontrado: %s. Tentando index.html", filepath);
|
||||
strlcpy(filepath, ctx->base_path, sizeof(filepath));
|
||||
strlcat(filepath, "/index.html", sizeof(filepath));
|
||||
fd = open(filepath, O_RDONLY, 0);
|
||||
if (fd == -1) {
|
||||
httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "Arquivo não encontrado");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
set_content_type_from_file(req, filepath);
|
||||
|
||||
char *chunk = ctx->scratch;
|
||||
ssize_t read_bytes;
|
||||
do {
|
||||
read_bytes = read(fd, chunk, SCRATCH_BUFSIZE);
|
||||
if (read_bytes == -1) {
|
||||
ESP_LOGE(TAG, "Erro lendo arquivo: %s", filepath);
|
||||
close(fd);
|
||||
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Erro ao ler arquivo");
|
||||
return ESP_FAIL;
|
||||
} else if (read_bytes > 0) {
|
||||
if (httpd_resp_send_chunk(req, chunk, read_bytes) != ESP_OK) {
|
||||
close(fd);
|
||||
httpd_resp_sendstr_chunk(req, NULL);
|
||||
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Erro ao enviar arquivo");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
}
|
||||
} while (read_bytes > 0);
|
||||
|
||||
close(fd);
|
||||
httpd_resp_send_chunk(req, NULL, 0);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void register_static_file_handlers(httpd_handle_t server, void *ctx) {
|
||||
httpd_uri_t uri = {
|
||||
.uri = "/*",
|
||||
.method = HTTP_GET,
|
||||
.handler = static_get_handler,
|
||||
.user_ctx = ctx
|
||||
};
|
||||
httpd_register_uri_handler(server, &uri);
|
||||
}
|
||||
Reference in New Issue
Block a user