214 lines
7.6 KiB
C
214 lines
7.6 KiB
C
#include "rest_server_internal.h"
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include "domain.h"
|
|
|
|
#define VOICE_CONTROL_TIMEOUT_MIN_MS 500
|
|
#define VOICE_CONTROL_TIMEOUT_MAX_MS 30000
|
|
|
|
static esp_err_t rest_server_parse_voice_timeout(httpd_req_t *req, uint32_t *out_timeout_ms) {
|
|
if (out_timeout_ms == NULL) {
|
|
return ESP_ERR_INVALID_ARG;
|
|
}
|
|
*out_timeout_ms = 0;
|
|
if (req->content_len <= 0) {
|
|
return ESP_OK;
|
|
}
|
|
|
|
char *body = NULL;
|
|
esp_err_t body_err = rest_server_read_body(req, &body);
|
|
if (body_err != ESP_OK) {
|
|
return body_err;
|
|
}
|
|
|
|
cJSON *json = cJSON_Parse(body);
|
|
free(body);
|
|
if (json == NULL) {
|
|
return ESP_ERR_INVALID_ARG;
|
|
}
|
|
|
|
cJSON *jtimeout = cJSON_GetObjectItemCaseSensitive(json, "timeout_ms");
|
|
if (jtimeout != NULL) {
|
|
if (!cJSON_IsNumber(jtimeout) ||
|
|
jtimeout->valuedouble < VOICE_CONTROL_TIMEOUT_MIN_MS ||
|
|
jtimeout->valuedouble > VOICE_CONTROL_TIMEOUT_MAX_MS) {
|
|
cJSON_Delete(json);
|
|
return ESP_ERR_INVALID_ARG;
|
|
}
|
|
*out_timeout_ms = (uint32_t)jtimeout->valuedouble;
|
|
}
|
|
|
|
cJSON_Delete(json);
|
|
return ESP_OK;
|
|
}
|
|
|
|
static void rest_server_add_voice_status(cJSON *root) {
|
|
voice_interaction_status_t st = {0};
|
|
voice_interaction_get_status(&st);
|
|
printer_runtime_status_t printer = {0};
|
|
printer_protocol_get_runtime_status(&printer);
|
|
|
|
cJSON_AddBoolToObject(root, "voice_ready", st.ready);
|
|
cJSON_AddBoolToObject(root, "voice_session_active", st.session_active);
|
|
cJSON_AddBoolToObject(root, "voice_ws_connected", st.ws_connected);
|
|
cJSON_AddBoolToObject(root, "voice_started", st.started);
|
|
cJSON_AddBoolToObject(root, "voice_tap_active", st.tap_active);
|
|
cJSON_AddBoolToObject(root, "voice_marker_image_gen_running", st.marker_image_gen_running);
|
|
cJSON_AddStringToObject(root,
|
|
"voice_dialog_state",
|
|
voice_interaction_dialog_state_str(st.dialog_state));
|
|
cJSON_AddStringToObject(root, "voice_task_id", st.task_id);
|
|
cJSON_AddStringToObject(root, "voice_dialog_id", st.dialog_id);
|
|
cJSON_AddStringToObject(root, "voice_last_error", st.last_error);
|
|
cJSON_AddNumberToObject(root, "voice_last_event_ms", (double)st.last_event_ms);
|
|
cJSON_AddNumberToObject(root, "voice_upstream_packets", (double)st.upstream_packets);
|
|
cJSON_AddNumberToObject(root, "voice_downstream_packets", (double)st.downstream_packets);
|
|
cJSON_AddBoolToObject(root, "printer_busy", printer.busy);
|
|
cJSON_AddNumberToObject(root, "queue_depth", (double)printer.queue_depth);
|
|
}
|
|
|
|
esp_err_t rest_server_voice_status_get(httpd_req_t *req) {
|
|
if (!rest_server_auth_ok(req)) {
|
|
return rest_server_send_error(req, "401 Unauthorized", "unauthorized");
|
|
}
|
|
|
|
cJSON *root = cJSON_CreateObject();
|
|
cJSON_AddBoolToObject(root, "ok", true);
|
|
rest_server_add_voice_status(root);
|
|
|
|
esp_err_t err = rest_server_send_json(req, "200 OK", root);
|
|
cJSON_Delete(root);
|
|
return err;
|
|
}
|
|
|
|
esp_err_t rest_server_voice_session_start_post(httpd_req_t *req) {
|
|
if (!rest_server_auth_ok(req)) {
|
|
return rest_server_send_error(req, "401 Unauthorized", "unauthorized");
|
|
}
|
|
|
|
uint32_t timeout_ms = 0;
|
|
if (rest_server_parse_voice_timeout(req, &timeout_ms) != ESP_OK) {
|
|
return rest_server_send_error(req, "400 Bad Request", "invalid request body");
|
|
}
|
|
|
|
char start_err[128] = {0};
|
|
esp_err_t rc = voice_interaction_start_with_timeout(timeout_ms, start_err, sizeof(start_err));
|
|
if (rc != ESP_OK) {
|
|
if (rc == ESP_ERR_TIMEOUT) {
|
|
return rest_server_send_error(req,
|
|
"504 Gateway Timeout",
|
|
start_err[0] != '\0' ? start_err : "voice session start timeout");
|
|
}
|
|
return rest_server_send_error(req,
|
|
"409 Conflict",
|
|
start_err[0] != '\0' ? start_err : "voice session start failed");
|
|
}
|
|
|
|
cJSON *root = cJSON_CreateObject();
|
|
cJSON_AddBoolToObject(root, "ok", true);
|
|
cJSON_AddStringToObject(root, "message", "voice session started");
|
|
rest_server_add_voice_status(root);
|
|
|
|
esp_err_t err = rest_server_send_json(req, "200 OK", root);
|
|
cJSON_Delete(root);
|
|
return err;
|
|
}
|
|
|
|
esp_err_t rest_server_voice_session_stop_post(httpd_req_t *req) {
|
|
if (!rest_server_auth_ok(req)) {
|
|
return rest_server_send_error(req, "401 Unauthorized", "unauthorized");
|
|
}
|
|
|
|
uint32_t timeout_ms = 0;
|
|
if (rest_server_parse_voice_timeout(req, &timeout_ms) != ESP_OK) {
|
|
return rest_server_send_error(req, "400 Bad Request", "invalid request body");
|
|
}
|
|
|
|
char stop_err[128] = {0};
|
|
esp_err_t rc = voice_interaction_stop_with_timeout(timeout_ms, stop_err, sizeof(stop_err));
|
|
if (rc != ESP_OK) {
|
|
if (rc == ESP_ERR_TIMEOUT) {
|
|
return rest_server_send_error(req,
|
|
"504 Gateway Timeout",
|
|
stop_err[0] != '\0' ? stop_err : "voice session stop timeout");
|
|
}
|
|
return rest_server_send_error(req,
|
|
"409 Conflict",
|
|
stop_err[0] != '\0' ? stop_err : "voice session stop failed");
|
|
}
|
|
|
|
cJSON *root = cJSON_CreateObject();
|
|
cJSON_AddBoolToObject(root, "ok", true);
|
|
cJSON_AddStringToObject(root, "message", "voice session stopped");
|
|
rest_server_add_voice_status(root);
|
|
|
|
esp_err_t err = rest_server_send_json(req, "200 OK", root);
|
|
cJSON_Delete(root);
|
|
return err;
|
|
}
|
|
|
|
esp_err_t rest_server_voice_tap_start_post(httpd_req_t *req) {
|
|
if (!rest_server_auth_ok(req)) {
|
|
return rest_server_send_error(req, "401 Unauthorized", "unauthorized");
|
|
}
|
|
|
|
if (req->content_len > 0) {
|
|
char *body = NULL;
|
|
esp_err_t body_err = rest_server_read_body(req, &body);
|
|
if (body_err != ESP_OK) {
|
|
return rest_server_send_error(req, "400 Bad Request", "invalid request body");
|
|
}
|
|
free(body);
|
|
}
|
|
|
|
char tap_err[128] = {0};
|
|
esp_err_t rc = voice_interaction_tap_start(tap_err, sizeof(tap_err));
|
|
if (rc != ESP_OK) {
|
|
return rest_server_send_error(req,
|
|
"409 Conflict",
|
|
tap_err[0] != '\0' ? tap_err : "tap start failed");
|
|
}
|
|
|
|
cJSON *root = cJSON_CreateObject();
|
|
cJSON_AddBoolToObject(root, "ok", true);
|
|
cJSON_AddStringToObject(root, "message", "tap started");
|
|
rest_server_add_voice_status(root);
|
|
|
|
esp_err_t err = rest_server_send_json(req, "200 OK", root);
|
|
cJSON_Delete(root);
|
|
return err;
|
|
}
|
|
|
|
esp_err_t rest_server_voice_tap_cancel_post(httpd_req_t *req) {
|
|
if (!rest_server_auth_ok(req)) {
|
|
return rest_server_send_error(req, "401 Unauthorized", "unauthorized");
|
|
}
|
|
|
|
if (req->content_len > 0) {
|
|
char *body = NULL;
|
|
esp_err_t body_err = rest_server_read_body(req, &body);
|
|
if (body_err != ESP_OK) {
|
|
return rest_server_send_error(req, "400 Bad Request", "invalid request body");
|
|
}
|
|
free(body);
|
|
}
|
|
|
|
char tap_err[128] = {0};
|
|
esp_err_t rc = voice_interaction_tap_cancel(tap_err, sizeof(tap_err));
|
|
if (rc != ESP_OK) {
|
|
return rest_server_send_error(req,
|
|
"409 Conflict",
|
|
tap_err[0] != '\0' ? tap_err : "tap cancel failed");
|
|
}
|
|
|
|
cJSON *root = cJSON_CreateObject();
|
|
cJSON_AddBoolToObject(root, "ok", true);
|
|
cJSON_AddStringToObject(root, "message", "tap stopped");
|
|
rest_server_add_voice_status(root);
|
|
|
|
esp_err_t err = rest_server_send_json(req, "200 OK", root);
|
|
cJSON_Delete(root);
|
|
return err;
|
|
}
|