chore: initial commit
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include "control_plane.h"
|
||||
#include "domain.h"
|
||||
#include "esp_err.h"
|
||||
|
||||
control_plane_direction_command_t control_plane_direction_parse_command_internal(
|
||||
const char *input,
|
||||
size_t *out_direction_index);
|
||||
bool control_plane_extract_model_command(const char *text,
|
||||
control_plane_model_command_type_t *out_command_type,
|
||||
char *out_value,
|
||||
size_t out_value_capacity);
|
||||
const char *control_plane_multimodal_resolve_upstream_mode(void);
|
||||
bool control_plane_multimodal_is_push2talk_mode(void);
|
||||
const char *control_plane_multimodal_resolve_voice_id(const char *auth_voice_id);
|
||||
uint32_t control_plane_multimodal_resolve_downstream_transmit_rate_limit(
|
||||
uint32_t configured_limit);
|
||||
uint32_t control_plane_multimodal_resolve_opus_frame_duration_ms(void);
|
||||
void control_plane_multimodal_generate_uuid(char *out, size_t out_len);
|
||||
esp_err_t control_plane_direction_calibrate_internal(
|
||||
const domain_direction_calibration_t *config,
|
||||
int timeout_ms);
|
||||
|
||||
/* Daily fortune fetch/apply policy (control_plane-owned). */
|
||||
esp_err_t control_plane_fortune_fetch(const char *target_date, domain_fortune_result_t *out_result);
|
||||
|
||||
typedef void (*control_plane_multimodal_responding_text_callback_t)(const char *text,
|
||||
bool finished,
|
||||
void *user_data);
|
||||
|
||||
typedef enum {
|
||||
CONTROL_PLANE_MULTIMODAL_EVENT_TRANSPORT_CONNECTED = 0,
|
||||
CONTROL_PLANE_MULTIMODAL_EVENT_TRANSPORT_DISCONNECTED,
|
||||
CONTROL_PLANE_MULTIMODAL_EVENT_TRANSPORT_ERROR,
|
||||
CONTROL_PLANE_MULTIMODAL_EVENT_TASK_STARTED,
|
||||
CONTROL_PLANE_MULTIMODAL_EVENT_TASK_FAILED,
|
||||
CONTROL_PLANE_MULTIMODAL_EVENT_SERVER_LISTENING,
|
||||
CONTROL_PLANE_MULTIMODAL_EVENT_SERVER_NOT_LISTENING,
|
||||
CONTROL_PLANE_MULTIMODAL_EVENT_RESPONDING_STARTED,
|
||||
CONTROL_PLANE_MULTIMODAL_EVENT_RESPONDING_CONTENT,
|
||||
CONTROL_PLANE_MULTIMODAL_EVENT_RESPONDING_ENDED,
|
||||
CONTROL_PLANE_MULTIMODAL_EVENT_SPEECH_STARTED,
|
||||
CONTROL_PLANE_MULTIMODAL_EVENT_SPEECH_CONTENT,
|
||||
CONTROL_PLANE_MULTIMODAL_EVENT_SPEECH_ENDED,
|
||||
CONTROL_PLANE_MULTIMODAL_EVENT_OUTPUT_ERROR,
|
||||
CONTROL_PLANE_MULTIMODAL_EVENT_DOWNSTREAM_AUDIO
|
||||
} control_plane_multimodal_event_t;
|
||||
|
||||
typedef void (*control_plane_multimodal_event_callback_t)(control_plane_multimodal_event_t event,
|
||||
void *user_data);
|
||||
|
||||
typedef void (*control_plane_multimodal_downstream_audio_callback_t)(const uint8_t *data,
|
||||
size_t len,
|
||||
void *user_data);
|
||||
|
||||
typedef struct {
|
||||
bool connected;
|
||||
bool has_active_task;
|
||||
bool server_listening;
|
||||
bool remote_responding;
|
||||
bool request_to_speak_pending;
|
||||
bool client_speech_active;
|
||||
bool ptt_release_required;
|
||||
bool local_responding_started;
|
||||
bool received_downstream_audio;
|
||||
uint32_t last_heartbeat_ms;
|
||||
uint32_t last_downstream_ms;
|
||||
uint32_t last_downstream_audio_ms;
|
||||
} control_plane_multimodal_runtime_state_t;
|
||||
|
||||
esp_err_t control_plane_multimodal_start(void);
|
||||
void control_plane_multimodal_stop(void);
|
||||
bool control_plane_multimodal_is_connected(void);
|
||||
esp_err_t control_plane_multimodal_send_start(void);
|
||||
esp_err_t control_plane_multimodal_send_stop(const char *reason);
|
||||
esp_err_t control_plane_multimodal_send_request_to_speak(void);
|
||||
esp_err_t control_plane_multimodal_send_speech_start(void);
|
||||
esp_err_t control_plane_multimodal_send_speech_stop(void);
|
||||
esp_err_t control_plane_multimodal_send_cancel_speech(void);
|
||||
esp_err_t control_plane_multimodal_send_request_to_respond(
|
||||
const control_plane_multimodal_respond_request_t *request);
|
||||
esp_err_t control_plane_multimodal_send_update_info(
|
||||
const control_plane_multimodal_update_info_request_t *request);
|
||||
esp_err_t control_plane_multimodal_send_local_responding_started(void);
|
||||
esp_err_t control_plane_multimodal_send_local_responding_ended(void);
|
||||
esp_err_t control_plane_multimodal_send_heartbeat(void);
|
||||
esp_err_t control_plane_multimodal_send_audio_realtime(const uint8_t *data, size_t len);
|
||||
esp_err_t control_plane_multimodal_get_runtime_state(
|
||||
control_plane_multimodal_runtime_state_t *out_state);
|
||||
esp_err_t control_plane_multimodal_register_event_callback(
|
||||
control_plane_multimodal_event_callback_t cb,
|
||||
void *user_data);
|
||||
esp_err_t control_plane_multimodal_register_downstream_audio_callback(
|
||||
control_plane_multimodal_downstream_audio_callback_t cb,
|
||||
void *user_data);
|
||||
esp_err_t control_plane_multimodal_register_responding_text_callback(
|
||||
control_plane_multimodal_responding_text_callback_t cb,
|
||||
void *user_data);
|
||||
esp_err_t control_plane_multimodal_start_uplink(void);
|
||||
void control_plane_multimodal_stop_uplink(void);
|
||||
bool control_plane_multimodal_is_uplink_running(void);
|
||||
esp_err_t control_plane_multimodal_play_downstream_audio(const uint8_t *data, size_t len);
|
||||
esp_err_t control_plane_multimodal_handle_ptt_press_step(void);
|
||||
esp_err_t control_plane_multimodal_handle_ptt_release(void);
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define CONTROL_PLANE_MULTIMODAL_AUTH_TOKEN_MAX_LEN 256
|
||||
#define CONTROL_PLANE_MULTIMODAL_AUTH_ID_MAX_LEN 64
|
||||
#define CONTROL_PLANE_MULTIMODAL_AUTH_VOICE_MAX_LEN 64
|
||||
|
||||
typedef struct {
|
||||
char token[CONTROL_PLANE_MULTIMODAL_AUTH_TOKEN_MAX_LEN];
|
||||
char workspace_id[CONTROL_PLANE_MULTIMODAL_AUTH_ID_MAX_LEN];
|
||||
char app_id[CONTROL_PLANE_MULTIMODAL_AUTH_ID_MAX_LEN];
|
||||
char voice_id[CONTROL_PLANE_MULTIMODAL_AUTH_VOICE_MAX_LEN];
|
||||
char device_id[CONTROL_PLANE_MULTIMODAL_AUTH_ID_MAX_LEN];
|
||||
char serial_number[CONTROL_PLANE_MULTIMODAL_AUTH_ID_MAX_LEN];
|
||||
bool valid;
|
||||
} control_plane_multimodal_auth_info_t;
|
||||
|
||||
esp_err_t control_plane_multimodal_auth_fetch(control_plane_multimodal_auth_info_t *out);
|
||||
void control_plane_multimodal_auth_clear(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Device-auth (device-JWT) engine, control-plane internal.
|
||||
*
|
||||
* The device proves possession of an on-board P-256 key via a challenge/response
|
||||
* signature against the registration backend and is issued a short-lived device
|
||||
* JWT. That JWT is used as the Bearer when requesting the per-session multimodal
|
||||
* token. Persistence (key material + JWT state) is delegated to the platform
|
||||
* store through the domain facade; this engine owns the crypto, HTTP, and the
|
||||
* JWT lifecycle/state machine.
|
||||
*/
|
||||
|
||||
#define CONTROL_PLANE_DEVICE_AUTH_SCOPE_VOICE_SESSION (1u << 0)
|
||||
#define CONTROL_PLANE_DEVICE_AUTH_SCOPE_OTA_REPORT (1u << 1)
|
||||
#define CONTROL_PLANE_DEVICE_AUTH_SCOPE_OTA_READ (1u << 2)
|
||||
#define CONTROL_PLANE_DEVICE_AUTH_SCOPE_OTA_CONFIRM (1u << 3)
|
||||
#define CONTROL_PLANE_DEVICE_AUTH_SCOPE_ALL \
|
||||
(CONTROL_PLANE_DEVICE_AUTH_SCOPE_VOICE_SESSION | \
|
||||
CONTROL_PLANE_DEVICE_AUTH_SCOPE_OTA_REPORT | \
|
||||
CONTROL_PLANE_DEVICE_AUTH_SCOPE_OTA_READ | \
|
||||
CONTROL_PLANE_DEVICE_AUTH_SCOPE_OTA_CONFIRM)
|
||||
|
||||
#define CONTROL_PLANE_DEVICE_AUTH_JWT_MAX_LEN 1536
|
||||
|
||||
typedef enum {
|
||||
CONTROL_PLANE_DEVICE_AUTH_OK = 0,
|
||||
CONTROL_PLANE_DEVICE_AUTH_WAIT_FACTORY,
|
||||
CONTROL_PLANE_DEVICE_AUTH_RETRY_LATER,
|
||||
CONTROL_PLANE_DEVICE_AUTH_FATAL,
|
||||
} control_plane_device_auth_result_t;
|
||||
|
||||
/**
|
||||
* @brief Initialize the engine: load persisted key material + JWT state.
|
||||
*
|
||||
* Idempotent and safe to call repeatedly. Returns `ESP_OK` once key material is
|
||||
* available (loaded or freshly generated); returns an error only when the key
|
||||
* store is unusable.
|
||||
*/
|
||||
esp_err_t control_plane_multimodal_device_auth_init(void);
|
||||
|
||||
/**
|
||||
* @brief Ensure a valid device JWT exists for the requested scope.
|
||||
*
|
||||
* Runs challenge/response (and server-driven key rotation) as needed, applying
|
||||
* retry/backoff. `force_refresh` bypasses the cached JWT.
|
||||
*/
|
||||
control_plane_device_auth_result_t control_plane_multimodal_device_auth_ensure(
|
||||
uint32_t required_scope_mask,
|
||||
bool force_refresh);
|
||||
|
||||
/**
|
||||
* @brief Copy the current device JWT into @p out.
|
||||
*
|
||||
* Returns `ESP_ERR_NOT_FOUND` when no valid JWT is cached, `ESP_ERR_INVALID_SIZE`
|
||||
* when the buffer is too small, otherwise `ESP_OK`.
|
||||
*/
|
||||
esp_err_t control_plane_multimodal_device_auth_copy_jwt(char *out, size_t out_len);
|
||||
|
||||
/**
|
||||
* @brief Invalidate the cached JWT (e.g. after the token endpoint returns 401/403),
|
||||
* forcing a fresh challenge/response on the next ensure.
|
||||
*/
|
||||
void control_plane_multimodal_device_auth_invalidate(int reason);
|
||||
|
||||
/*
|
||||
* Factory-provisioning helpers. These expose the device's key material and sign
|
||||
* factory challenges/rotations during manufacturing/registration. They only need
|
||||
* the on-board key (loaded or generated), so they work independently of whether
|
||||
* the AUTH_V2 token flow is enabled at runtime.
|
||||
*/
|
||||
|
||||
/** @brief Return the device public key + JKT thumbprint (base64url) and key version. */
|
||||
esp_err_t control_plane_multimodal_device_auth_get_key_material(char *out_pub_key_b64u,
|
||||
size_t pub_key_b64u_len,
|
||||
char *out_pub_key_jkt_b64u,
|
||||
size_t pub_key_jkt_b64u_len,
|
||||
uint32_t *out_key_version);
|
||||
|
||||
/** @brief Sign a factory challenge with the device key (raw r||s, base64url). */
|
||||
esp_err_t control_plane_multimodal_device_auth_sign_challenge(const char *device_id,
|
||||
const char *challenge_id_b64u,
|
||||
const char *challenge_b64u,
|
||||
char *out_signature_b64u,
|
||||
size_t out_signature_b64u_len);
|
||||
|
||||
/**
|
||||
* @brief Generate and sign a rotation to a new key. When @p apply_local_key is
|
||||
* true the new key is persisted locally (key_version+1) and the cached JWT
|
||||
* is invalidated.
|
||||
*/
|
||||
esp_err_t control_plane_multimodal_device_auth_prepare_rotate(const char *device_id,
|
||||
uint32_t key_version,
|
||||
char *out_new_pub_key_b64u,
|
||||
size_t new_pub_key_b64u_len,
|
||||
char *out_new_pub_key_jkt_b64u,
|
||||
size_t new_pub_key_jkt_b64u_len,
|
||||
char *out_signature_b64u,
|
||||
size_t out_signature_b64u_len,
|
||||
bool apply_local_key);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user