550 lines
18 KiB
C
550 lines
18 KiB
C
/**
|
|
* Web API - REST-Endpoints für Konfiguration
|
|
*/
|
|
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include "web_api.h"
|
|
#include "config/config_manager.h"
|
|
#include "wifi/wifi_manager.h"
|
|
#include "bluetooth/bt_manager.h"
|
|
#include "sip/sip_client.h"
|
|
#include "audio/audio_router.h"
|
|
#include "esp_log.h"
|
|
#include "esp_wifi.h"
|
|
#include "cJSON.h"
|
|
|
|
static const char* TAG = "WEB_API";
|
|
|
|
// Hilfsfunktion: JSON-Body aus Request lesen
|
|
static cJSON* read_json_body(httpd_req_t* req)
|
|
{
|
|
int content_len = req->content_len;
|
|
if (content_len <= 0 || content_len > 4096) {
|
|
return NULL;
|
|
}
|
|
|
|
char* buf = malloc(content_len + 1);
|
|
if (!buf) return NULL;
|
|
|
|
int received = httpd_req_recv(req, buf, content_len);
|
|
if (received <= 0) {
|
|
free(buf);
|
|
return NULL;
|
|
}
|
|
buf[received] = '\0';
|
|
|
|
cJSON* json = cJSON_Parse(buf);
|
|
free(buf);
|
|
return json;
|
|
}
|
|
|
|
// Hilfsfunktion: JSON-Antwort senden
|
|
static esp_err_t send_json_response(httpd_req_t* req, cJSON* json)
|
|
{
|
|
char* str = cJSON_PrintUnformatted(json);
|
|
if (!str) {
|
|
httpd_resp_send_500(req);
|
|
return ESP_FAIL;
|
|
}
|
|
|
|
httpd_resp_set_type(req, "application/json");
|
|
httpd_resp_send(req, str, strlen(str));
|
|
free(str);
|
|
return ESP_OK;
|
|
}
|
|
|
|
static esp_err_t send_json_error(httpd_req_t* req, int status, const char* message)
|
|
{
|
|
cJSON* json = cJSON_CreateObject();
|
|
cJSON_AddBoolToObject(json, "success", false);
|
|
cJSON_AddStringToObject(json, "error", message);
|
|
|
|
httpd_resp_set_status(req, status == 400 ? "400 Bad Request" :
|
|
status == 404 ? "404 Not Found" : "500 Internal Server Error");
|
|
esp_err_t ret = send_json_response(req, json);
|
|
cJSON_Delete(json);
|
|
return ret;
|
|
}
|
|
|
|
static esp_err_t send_json_success(httpd_req_t* req, const char* message)
|
|
{
|
|
cJSON* json = cJSON_CreateObject();
|
|
cJSON_AddBoolToObject(json, "success", true);
|
|
if (message) cJSON_AddStringToObject(json, "message", message);
|
|
|
|
esp_err_t ret = send_json_response(req, json);
|
|
cJSON_Delete(json);
|
|
return ret;
|
|
}
|
|
|
|
// ============ Status API ============
|
|
|
|
static esp_err_t api_status_get(httpd_req_t* req)
|
|
{
|
|
const device_config_t* config = config_get();
|
|
|
|
cJSON* json = cJSON_CreateObject();
|
|
|
|
// WiFi Status
|
|
cJSON* wifi = cJSON_CreateObject();
|
|
cJSON_AddStringToObject(wifi, "state",
|
|
wifi_manager_get_state() == WIFI_STATE_STA_CONNECTED ? "connected" :
|
|
wifi_manager_get_state() == WIFI_STATE_AP_STARTED ? "hotspot" : "disconnected");
|
|
|
|
char ip[16] = {0};
|
|
wifi_manager_get_ip(ip, sizeof(ip));
|
|
cJSON_AddStringToObject(wifi, "ip", ip);
|
|
cJSON_AddStringToObject(wifi, "ssid", config->wifi.ssid);
|
|
cJSON_AddItemToObject(json, "wifi", wifi);
|
|
|
|
// SIP Status
|
|
cJSON* sip = cJSON_CreateObject();
|
|
sip_reg_state_t reg_state = sip_client_get_reg_state();
|
|
cJSON_AddStringToObject(sip, "state",
|
|
reg_state == SIP_REG_STATE_REGISTERED ? "registered" :
|
|
reg_state == SIP_REG_STATE_REGISTERING ? "registering" : "unregistered");
|
|
cJSON_AddStringToObject(sip, "server", config->sip.server);
|
|
cJSON_AddStringToObject(sip, "user", config->sip.username);
|
|
cJSON_AddItemToObject(json, "sip", sip);
|
|
|
|
// Audio Status
|
|
cJSON* audio = cJSON_CreateObject();
|
|
audio_source_t source = audio_router_get_active_source();
|
|
cJSON_AddStringToObject(audio, "source",
|
|
source == AUDIO_SOURCE_USB ? "usb" :
|
|
source == AUDIO_SOURCE_BLUETOOTH ? "bluetooth" : "none");
|
|
cJSON_AddBoolToObject(audio, "usb_connected", audio_router_is_source_available(AUDIO_SOURCE_USB));
|
|
cJSON_AddBoolToObject(audio, "bt_connected", audio_router_is_source_available(AUDIO_SOURCE_BLUETOOTH));
|
|
cJSON_AddNumberToObject(audio, "volume", audio_router_get_volume());
|
|
cJSON_AddBoolToObject(audio, "muted", audio_router_is_muted());
|
|
cJSON_AddItemToObject(json, "audio", audio);
|
|
|
|
// Call Status
|
|
cJSON* call = cJSON_CreateObject();
|
|
sip_call_state_t call_state = sip_client_get_call_state();
|
|
cJSON_AddStringToObject(call, "state",
|
|
call_state == SIP_CALL_STATE_IDLE ? "idle" :
|
|
call_state == SIP_CALL_STATE_INCOMING ? "incoming" :
|
|
call_state == SIP_CALL_STATE_OUTGOING ? "outgoing" :
|
|
call_state == SIP_CALL_STATE_RINGING ? "ringing" :
|
|
call_state == SIP_CALL_STATE_CONNECTED ? "connected" : "unknown");
|
|
|
|
sip_call_info_t call_info;
|
|
if (sip_client_get_call_info(&call_info) == ESP_OK && call_state != SIP_CALL_STATE_IDLE) {
|
|
cJSON_AddStringToObject(call, "remote", call_info.remote_number);
|
|
cJSON_AddStringToObject(call, "name", call_info.remote_name);
|
|
cJSON_AddNumberToObject(call, "duration", call_info.duration_sec);
|
|
}
|
|
cJSON_AddItemToObject(json, "call", call);
|
|
|
|
esp_err_t ret = send_json_response(req, json);
|
|
cJSON_Delete(json);
|
|
return ret;
|
|
}
|
|
|
|
// ============ WiFi API ============
|
|
|
|
static esp_err_t api_wifi_config_get(httpd_req_t* req)
|
|
{
|
|
const device_config_t* config = config_get();
|
|
|
|
cJSON* json = cJSON_CreateObject();
|
|
cJSON_AddStringToObject(json, "ssid", config->wifi.ssid);
|
|
cJSON_AddStringToObject(json, "ip_mode", config->wifi.ip_mode == IP_MODE_DHCP ? "dhcp" : "static");
|
|
cJSON_AddStringToObject(json, "static_ip", config->wifi.static_ip);
|
|
cJSON_AddStringToObject(json, "gateway", config->wifi.gateway);
|
|
cJSON_AddStringToObject(json, "netmask", config->wifi.netmask);
|
|
cJSON_AddStringToObject(json, "dns", config->wifi.dns);
|
|
cJSON_AddBoolToObject(json, "configured", config->wifi.configured);
|
|
|
|
esp_err_t ret = send_json_response(req, json);
|
|
cJSON_Delete(json);
|
|
return ret;
|
|
}
|
|
|
|
static esp_err_t api_wifi_config_post(httpd_req_t* req)
|
|
{
|
|
cJSON* json = read_json_body(req);
|
|
if (!json) {
|
|
return send_json_error(req, 400, "Invalid JSON");
|
|
}
|
|
|
|
wifi_config_data_t wifi_cfg = {0};
|
|
|
|
cJSON* ssid = cJSON_GetObjectItem(json, "ssid");
|
|
cJSON* password = cJSON_GetObjectItem(json, "password");
|
|
cJSON* ip_mode = cJSON_GetObjectItem(json, "ip_mode");
|
|
|
|
if (!ssid || !cJSON_IsString(ssid) || strlen(ssid->valuestring) == 0) {
|
|
cJSON_Delete(json);
|
|
return send_json_error(req, 400, "SSID required");
|
|
}
|
|
|
|
strncpy(wifi_cfg.ssid, ssid->valuestring, CONFIG_MAX_SSID_LEN);
|
|
if (password && cJSON_IsString(password)) {
|
|
strncpy(wifi_cfg.password, password->valuestring, CONFIG_MAX_PASSWORD_LEN);
|
|
}
|
|
|
|
wifi_cfg.ip_mode = IP_MODE_DHCP;
|
|
if (ip_mode && cJSON_IsString(ip_mode) && strcmp(ip_mode->valuestring, "static") == 0) {
|
|
wifi_cfg.ip_mode = IP_MODE_STATIC;
|
|
|
|
cJSON* static_ip = cJSON_GetObjectItem(json, "static_ip");
|
|
cJSON* gateway = cJSON_GetObjectItem(json, "gateway");
|
|
cJSON* netmask = cJSON_GetObjectItem(json, "netmask");
|
|
cJSON* dns = cJSON_GetObjectItem(json, "dns");
|
|
|
|
if (static_ip && cJSON_IsString(static_ip))
|
|
strncpy(wifi_cfg.static_ip, static_ip->valuestring, CONFIG_MAX_IP_LEN);
|
|
if (gateway && cJSON_IsString(gateway))
|
|
strncpy(wifi_cfg.gateway, gateway->valuestring, CONFIG_MAX_IP_LEN);
|
|
if (netmask && cJSON_IsString(netmask))
|
|
strncpy(wifi_cfg.netmask, netmask->valuestring, CONFIG_MAX_IP_LEN);
|
|
if (dns && cJSON_IsString(dns))
|
|
strncpy(wifi_cfg.dns, dns->valuestring, CONFIG_MAX_IP_LEN);
|
|
}
|
|
|
|
cJSON_Delete(json);
|
|
|
|
esp_err_t err = config_save_wifi(&wifi_cfg);
|
|
if (err != ESP_OK) {
|
|
return send_json_error(req, 500, "Save failed");
|
|
}
|
|
|
|
// Neu verbinden
|
|
wifi_manager_connect(&wifi_cfg);
|
|
|
|
return send_json_success(req, "WiFi configuration saved. Connecting...");
|
|
}
|
|
|
|
static esp_err_t api_wifi_scan_get(httpd_req_t* req)
|
|
{
|
|
wifi_manager_scan();
|
|
|
|
// Warten auf Scan-Ergebnis
|
|
vTaskDelay(pdMS_TO_TICKS(3000));
|
|
|
|
uint16_t num_networks = 0;
|
|
esp_wifi_scan_get_ap_num(&num_networks);
|
|
|
|
if (num_networks > 20) num_networks = 20;
|
|
|
|
wifi_ap_record_t* records = malloc(sizeof(wifi_ap_record_t) * num_networks);
|
|
if (!records) {
|
|
return send_json_error(req, 500, "Memory error");
|
|
}
|
|
|
|
esp_wifi_scan_get_ap_records(&num_networks, records);
|
|
|
|
cJSON* json = cJSON_CreateArray();
|
|
for (int i = 0; i < num_networks; i++) {
|
|
cJSON* ap = cJSON_CreateObject();
|
|
cJSON_AddStringToObject(ap, "ssid", (char*)records[i].ssid);
|
|
cJSON_AddNumberToObject(ap, "rssi", records[i].rssi);
|
|
cJSON_AddNumberToObject(ap, "channel", records[i].primary);
|
|
cJSON_AddBoolToObject(ap, "secure", records[i].authmode != WIFI_AUTH_OPEN);
|
|
cJSON_AddItemToArray(json, ap);
|
|
}
|
|
|
|
free(records);
|
|
|
|
esp_err_t ret = send_json_response(req, json);
|
|
cJSON_Delete(json);
|
|
return ret;
|
|
}
|
|
|
|
// ============ SIP API ============
|
|
|
|
static esp_err_t api_sip_config_get(httpd_req_t* req)
|
|
{
|
|
const device_config_t* config = config_get();
|
|
|
|
cJSON* json = cJSON_CreateObject();
|
|
cJSON_AddStringToObject(json, "server", config->sip.server);
|
|
cJSON_AddNumberToObject(json, "port", config->sip.port);
|
|
cJSON_AddStringToObject(json, "username", config->sip.username);
|
|
cJSON_AddStringToObject(json, "display_name", config->sip.display_name);
|
|
cJSON_AddBoolToObject(json, "configured", config->sip.configured);
|
|
// Passwort wird nicht zurückgegeben
|
|
|
|
esp_err_t ret = send_json_response(req, json);
|
|
cJSON_Delete(json);
|
|
return ret;
|
|
}
|
|
|
|
static esp_err_t api_sip_config_post(httpd_req_t* req)
|
|
{
|
|
cJSON* json = read_json_body(req);
|
|
if (!json) {
|
|
return send_json_error(req, 400, "Invalid JSON");
|
|
}
|
|
|
|
sip_config_data_t sip_cfg = {0};
|
|
sip_cfg.port = CONFIG_BSC_SIP_DEFAULT_PORT;
|
|
|
|
cJSON* server = cJSON_GetObjectItem(json, "server");
|
|
cJSON* port = cJSON_GetObjectItem(json, "port");
|
|
cJSON* username = cJSON_GetObjectItem(json, "username");
|
|
cJSON* password = cJSON_GetObjectItem(json, "password");
|
|
cJSON* display_name = cJSON_GetObjectItem(json, "display_name");
|
|
|
|
if (!server || !cJSON_IsString(server) || strlen(server->valuestring) == 0) {
|
|
cJSON_Delete(json);
|
|
return send_json_error(req, 400, "Server required");
|
|
}
|
|
if (!username || !cJSON_IsString(username) || strlen(username->valuestring) == 0) {
|
|
cJSON_Delete(json);
|
|
return send_json_error(req, 400, "Username required");
|
|
}
|
|
|
|
strncpy(sip_cfg.server, server->valuestring, CONFIG_MAX_SIP_SERVER_LEN);
|
|
strncpy(sip_cfg.username, username->valuestring, CONFIG_MAX_SIP_USER_LEN);
|
|
|
|
if (port && cJSON_IsNumber(port)) {
|
|
sip_cfg.port = (uint16_t)port->valueint;
|
|
}
|
|
if (password && cJSON_IsString(password)) {
|
|
strncpy(sip_cfg.password, password->valuestring, CONFIG_MAX_PASSWORD_LEN);
|
|
}
|
|
if (display_name && cJSON_IsString(display_name)) {
|
|
strncpy(sip_cfg.display_name, display_name->valuestring, CONFIG_MAX_SIP_USER_LEN);
|
|
}
|
|
|
|
cJSON_Delete(json);
|
|
|
|
esp_err_t err = config_save_sip(&sip_cfg);
|
|
if (err != ESP_OK) {
|
|
return send_json_error(req, 500, "Save failed");
|
|
}
|
|
|
|
// Neu registrieren
|
|
sip_client_unregister();
|
|
sip_client_register();
|
|
|
|
return send_json_success(req, "SIP configuration saved. Registering...");
|
|
}
|
|
|
|
// ============ Bluetooth API ============
|
|
|
|
static esp_err_t api_bluetooth_devices_get(httpd_req_t* req)
|
|
{
|
|
const device_config_t* config = config_get();
|
|
|
|
cJSON* json = cJSON_CreateArray();
|
|
|
|
for (int i = 0; i < config->bluetooth.device_count; i++) {
|
|
const bt_device_config_t* dev = &config->bluetooth.devices[i];
|
|
cJSON* device = cJSON_CreateObject();
|
|
cJSON_AddStringToObject(device, "address", dev->address);
|
|
cJSON_AddStringToObject(device, "name", dev->name);
|
|
cJSON_AddBoolToObject(device, "paired", dev->paired);
|
|
cJSON_AddBoolToObject(device, "auto_connect", dev->auto_connect);
|
|
cJSON_AddNumberToObject(device, "priority", dev->priority);
|
|
// TODO: Check if currently connected
|
|
cJSON_AddItemToArray(json, device);
|
|
}
|
|
|
|
esp_err_t ret = send_json_response(req, json);
|
|
cJSON_Delete(json);
|
|
return ret;
|
|
}
|
|
|
|
static esp_err_t api_bluetooth_scan_post(httpd_req_t* req)
|
|
{
|
|
ESP_LOGI(TAG, "Starte Bluetooth-Scan");
|
|
bt_manager_start_discovery();
|
|
return send_json_success(req, "Scan started");
|
|
}
|
|
|
|
static esp_err_t api_bluetooth_pair_post(httpd_req_t* req)
|
|
{
|
|
cJSON* json = read_json_body(req);
|
|
if (!json) {
|
|
return send_json_error(req, 400, "Invalid JSON");
|
|
}
|
|
|
|
cJSON* address = cJSON_GetObjectItem(json, "address");
|
|
if (!address || !cJSON_IsString(address)) {
|
|
cJSON_Delete(json);
|
|
return send_json_error(req, 400, "Address required");
|
|
}
|
|
|
|
esp_bd_addr_t addr;
|
|
esp_err_t err = bt_str_to_addr(address->valuestring, addr);
|
|
if (err != ESP_OK) {
|
|
cJSON_Delete(json);
|
|
return send_json_error(req, 400, "Invalid address format");
|
|
}
|
|
|
|
cJSON_Delete(json);
|
|
|
|
err = bt_manager_pair(addr);
|
|
if (err != ESP_OK) {
|
|
return send_json_error(req, 500, "Pairing failed");
|
|
}
|
|
|
|
return send_json_success(req, "Pairing initiated");
|
|
}
|
|
|
|
static esp_err_t api_bluetooth_unpair_post(httpd_req_t* req)
|
|
{
|
|
cJSON* json = read_json_body(req);
|
|
if (!json) {
|
|
return send_json_error(req, 400, "Invalid JSON");
|
|
}
|
|
|
|
cJSON* address = cJSON_GetObjectItem(json, "address");
|
|
if (!address || !cJSON_IsString(address)) {
|
|
cJSON_Delete(json);
|
|
return send_json_error(req, 400, "Address required");
|
|
}
|
|
|
|
esp_bd_addr_t addr;
|
|
esp_err_t err = bt_str_to_addr(address->valuestring, addr);
|
|
if (err != ESP_OK) {
|
|
cJSON_Delete(json);
|
|
return send_json_error(req, 400, "Invalid address format");
|
|
}
|
|
|
|
cJSON_Delete(json);
|
|
|
|
bt_manager_unpair(addr);
|
|
config_remove_bt_device(address->valuestring);
|
|
|
|
return send_json_success(req, "Device removed");
|
|
}
|
|
|
|
static esp_err_t api_bluetooth_connect_post(httpd_req_t* req)
|
|
{
|
|
cJSON* json = read_json_body(req);
|
|
if (!json) {
|
|
return send_json_error(req, 400, "Invalid JSON");
|
|
}
|
|
|
|
cJSON* address = cJSON_GetObjectItem(json, "address");
|
|
if (!address || !cJSON_IsString(address)) {
|
|
cJSON_Delete(json);
|
|
return send_json_error(req, 400, "Address required");
|
|
}
|
|
|
|
esp_bd_addr_t addr;
|
|
esp_err_t err = bt_str_to_addr(address->valuestring, addr);
|
|
cJSON_Delete(json);
|
|
|
|
if (err != ESP_OK) {
|
|
return send_json_error(req, 400, "Invalid address format");
|
|
}
|
|
|
|
err = bt_manager_connect(addr);
|
|
if (err != ESP_OK) {
|
|
return send_json_error(req, 500, "Connection failed");
|
|
}
|
|
|
|
return send_json_success(req, "Connecting...");
|
|
}
|
|
|
|
// ============ Call API ============
|
|
|
|
static esp_err_t api_call_answer_post(httpd_req_t* req)
|
|
{
|
|
esp_err_t err = sip_client_answer();
|
|
if (err != ESP_OK) {
|
|
return send_json_error(req, 500, "Answer failed");
|
|
}
|
|
return send_json_success(req, "Call answered");
|
|
}
|
|
|
|
static esp_err_t api_call_hangup_post(httpd_req_t* req)
|
|
{
|
|
esp_err_t err = sip_client_hangup();
|
|
if (err != ESP_OK) {
|
|
return send_json_error(req, 500, "Hangup failed");
|
|
}
|
|
return send_json_success(req, "Call ended");
|
|
}
|
|
|
|
static esp_err_t api_call_reject_post(httpd_req_t* req)
|
|
{
|
|
esp_err_t err = sip_client_reject();
|
|
if (err != ESP_OK) {
|
|
return send_json_error(req, 500, "Reject failed");
|
|
}
|
|
return send_json_success(req, "Call rejected");
|
|
}
|
|
|
|
// ============ System API ============
|
|
|
|
static esp_err_t api_system_reboot_post(httpd_req_t* req)
|
|
{
|
|
send_json_success(req, "Rebooting...");
|
|
vTaskDelay(pdMS_TO_TICKS(1000));
|
|
esp_restart();
|
|
return ESP_OK;
|
|
}
|
|
|
|
static esp_err_t api_system_factory_reset_post(httpd_req_t* req)
|
|
{
|
|
esp_err_t err = config_factory_reset();
|
|
if (err != ESP_OK) {
|
|
return send_json_error(req, 500, "Reset failed");
|
|
}
|
|
send_json_success(req, "Factory reset complete. Rebooting...");
|
|
vTaskDelay(pdMS_TO_TICKS(1000));
|
|
esp_restart();
|
|
return ESP_OK;
|
|
}
|
|
|
|
// ============ Route Registration ============
|
|
|
|
void web_api_register_handlers(httpd_handle_t server)
|
|
{
|
|
ESP_LOGI(TAG, "Registriere API-Handler");
|
|
|
|
// Status
|
|
httpd_uri_t uri;
|
|
|
|
uri = (httpd_uri_t){.uri = "/api/status", .method = HTTP_GET, .handler = api_status_get};
|
|
httpd_register_uri_handler(server, &uri);
|
|
|
|
// WiFi
|
|
uri = (httpd_uri_t){.uri = "/api/wifi/config", .method = HTTP_GET, .handler = api_wifi_config_get};
|
|
httpd_register_uri_handler(server, &uri);
|
|
uri = (httpd_uri_t){.uri = "/api/wifi/config", .method = HTTP_POST, .handler = api_wifi_config_post};
|
|
httpd_register_uri_handler(server, &uri);
|
|
uri = (httpd_uri_t){.uri = "/api/wifi/scan", .method = HTTP_GET, .handler = api_wifi_scan_get};
|
|
httpd_register_uri_handler(server, &uri);
|
|
|
|
// SIP
|
|
uri = (httpd_uri_t){.uri = "/api/sip/config", .method = HTTP_GET, .handler = api_sip_config_get};
|
|
httpd_register_uri_handler(server, &uri);
|
|
uri = (httpd_uri_t){.uri = "/api/sip/config", .method = HTTP_POST, .handler = api_sip_config_post};
|
|
httpd_register_uri_handler(server, &uri);
|
|
|
|
// Bluetooth
|
|
uri = (httpd_uri_t){.uri = "/api/bluetooth/devices", .method = HTTP_GET, .handler = api_bluetooth_devices_get};
|
|
httpd_register_uri_handler(server, &uri);
|
|
uri = (httpd_uri_t){.uri = "/api/bluetooth/scan", .method = HTTP_POST, .handler = api_bluetooth_scan_post};
|
|
httpd_register_uri_handler(server, &uri);
|
|
uri = (httpd_uri_t){.uri = "/api/bluetooth/pair", .method = HTTP_POST, .handler = api_bluetooth_pair_post};
|
|
httpd_register_uri_handler(server, &uri);
|
|
uri = (httpd_uri_t){.uri = "/api/bluetooth/unpair", .method = HTTP_POST, .handler = api_bluetooth_unpair_post};
|
|
httpd_register_uri_handler(server, &uri);
|
|
uri = (httpd_uri_t){.uri = "/api/bluetooth/connect", .method = HTTP_POST, .handler = api_bluetooth_connect_post};
|
|
httpd_register_uri_handler(server, &uri);
|
|
|
|
// Call
|
|
uri = (httpd_uri_t){.uri = "/api/call/answer", .method = HTTP_POST, .handler = api_call_answer_post};
|
|
httpd_register_uri_handler(server, &uri);
|
|
uri = (httpd_uri_t){.uri = "/api/call/hangup", .method = HTTP_POST, .handler = api_call_hangup_post};
|
|
httpd_register_uri_handler(server, &uri);
|
|
uri = (httpd_uri_t){.uri = "/api/call/reject", .method = HTTP_POST, .handler = api_call_reject_post};
|
|
httpd_register_uri_handler(server, &uri);
|
|
|
|
// System
|
|
uri = (httpd_uri_t){.uri = "/api/system/reboot", .method = HTTP_POST, .handler = api_system_reboot_post};
|
|
httpd_register_uri_handler(server, &uri);
|
|
uri = (httpd_uri_t){.uri = "/api/system/factory-reset", .method = HTTP_POST, .handler = api_system_factory_reset_post};
|
|
httpd_register_uri_handler(server, &uri);
|
|
}
|