// }
break;
}
+ case WS_CMD_CHAT_SESSION_START_ACK:
+ {
+ printf("[WS] ChatSessionStartAck:对话会话开始应答\n");
+ #if 1
+ if (json_str)
+ {
+ cJSON *root = cJSON_Parse(json_str);
+ if (root)
+ {
+ cJSON *data_obj = cJSON_GetObjectItem(root, "data");
+ if (data_obj && cJSON_IsObject(data_obj))
+ {
+ cJSON *session_id = cJSON_GetObjectItem(data_obj, "sessionId");
+ cJSON *chat_id = cJSON_GetObjectItem(data_obj, "chatId");
+ if (session_id && cJSON_IsString(session_id) && session_id->valuestring)
+ {
+ // 保存sessionId到全局上下文(需要在ln_api_websocket.c中实现保存函数)
+ ln_ws_set_session_id(session_id->valuestring);
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[WS] ChatSessionStartAck: sessionId=%s, chatId=%s",
+ session_id->valuestring,
+ (chat_id && cJSON_IsString(chat_id)) ? chat_id->valuestring : "");
+ }
+ }
+ cJSON_Delete(root);
+ }
+ }
+ #endif
+ break;
+ }
+ case WS_CMD_CHAT_SESSION_END_ACK:
+ {
+ printf("[WS] ChatSessionEndAck:对话会话结束应答\n");
+ #if 1
+ if (json_str)
+ {
+ cJSON *root = cJSON_Parse(json_str);
+ if (root)
+ {
+ cJSON *data_obj = cJSON_GetObjectItem(root, "data");
+ if (data_obj && cJSON_IsObject(data_obj))
+ {
+ cJSON *session_id = cJSON_GetObjectItem(data_obj, "sessionId");
+ cJSON *chat_id = cJSON_GetObjectItem(data_obj, "chatId");
+ // 清空sessionId(需要在ln_api_websocket.c中实现清空函数)
+ ln_ws_clear_session_id();
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[WS] ChatSessionEndAck: sessionId=%s, chatId=%s",
+ (session_id && cJSON_IsString(session_id)) ? session_id->valuestring : "",
+ (chat_id && cJSON_IsString(chat_id)) ? chat_id->valuestring : "");
+ }
+ cJSON_Delete(root);
+ }
+ }
+ #endif
+ break;
+ }
case WS_CMD_PING:
{
printf("[WS] Ping\n");
}
}
}
+ else if (mail.cmd == LN_HTTP_SERVICE_CMD_CHAT_SESSION_START)
+ {
+ printf("LN_HTTP_SERVICE_CMD_CHAT_SESSION_START:语音对话流开始\n");
+ ln_ws_send_chat_session_start();
+ }
+ else if (mail.cmd == LN_HTTP_SERVICE_CMD_CHAT_SESSION_END)
+ {
+ printf("LN_HTTP_SERVICE_CMD_CHAT_SESSION_END:语音对话流结束\n");
+ ln_ws_send_chat_session_end();
+ }
if (mail.data != NULL)
{
printf("free(mail.data)\n");
} ln_http_data_mail_t;
/* ============================== 公共宏与URL路径 ============================== */
+#define LN_VOICE_CHAT_ENABLED 0 //声纹锁开启宏
#define LN_ENV_PRODUCTION 0 //正式环境
/* 接口基础配置 - 如需切换环境/密钥,在此调整 */
#if LN_ENV_PRODUCTION
//蓝牙状态上报相关命令
#define LN_HTTP_SERVICE_CMD_BLUETOOTH_STATUS_REPORT 0x1015 /* 蓝牙状态上报 */
+/* 语音对话流相关命令 */
+#define LN_HTTP_SERVICE_CMD_CHAT_SESSION_START 0x1016 /* 语音对话流开始 */
+#define LN_HTTP_SERVICE_CMD_CHAT_SESSION_END 0x1017 /* 语音对话流结束 */
+
/* 下载文件相关结构体 */
typedef struct
{
WS_CMD_VAD_INITIALIZED, /* VAD 服务器初始化完成 */
WS_CMD_DEVICE_UPGRADE, /* 设备升级(DeviceUpgrade) */
WS_CMD_DEVICE_UPGRADE_STATUS_REPORT_ACK, /* 设备升级状态上报应答(DeviceUpgradeStatusReportAck) */
+ WS_CMD_CHAT_SESSION_START_ACK, /* 对话会话开始应答(ChatSessionStartAck) */
+ WS_CMD_CHAT_SESSION_END_ACK, /* 对话会话结束应答(ChatSessionEndAck) */
WS_CMD_BLUETOOTH_CONNECT, /* 蓝牙连接(BluetoothConnect) */
WS_CMD_BLUETOOTH_UNBIND, /* 蓝牙解绑(BluetoothUnbind) */
WS_CMD_BLUETOOTH_STATUS_REPORT_ACK, /* 蓝牙状态上报应答(BluetoothStatusReportAck) */
int ln_ws_send_voice_chat_interrupt(const char *reason);
int ln_ws_send_sleep_mode_inquire(const char *intention);
const char* ln_ws_get_current_chat_id(void);
+void ln_ws_send_chat_session_start(void);
+void ln_ws_send_chat_session_end(void);
+void ln_ws_set_session_id(const char *session_id);
+void ln_ws_clear_session_id(void);
int ln_ws_stop(void);
// int ln_ws_force_reconnect(void);
int ln_ws_enter_sleep(void);
// 录音上传状态跟踪
static bool g_recording_upload_started = false;
+static char g_session_id[64] = {0}; // 会话ID,由服务端生成
+
// 音频数据缓存结构
typedef struct {
uint8_t *data; // 音频数据
cJSON_AddStringToObject(data_obj, "audioBase64", audio_base64);
cJSON_AddStringToObject(data_obj, "chatId", g_audio_chat_ctx.chat_id);
+ #if LN_VOICE_CHAT_ENABLED
+ cJSON_AddStringToObject(data_obj, "sessionId", g_session_id);
+ #endif
cJSON_AddBoolToObject(data_obj, "finished", finished);
cJSON_AddItemToObject(json, "data", data_obj);
return g_audio_chat_ctx.is_active ? g_audio_chat_ctx.chat_id : NULL;
}
+/**
+ * @brief 设置会话ID(由服务端返回)
+ * @param session_id 会话ID字符串
+ */
+void ln_ws_set_session_id(const char *session_id)
+{
+ if (session_id && strlen(session_id) < sizeof(g_session_id)) {
+ strncpy(g_session_id, session_id, sizeof(g_session_id) - 1);
+ g_session_id[sizeof(g_session_id) - 1] = '\0';
+ LN_WS_DEBUG("Session ID set: %s\n", g_session_id);
+ } else {
+ LN_WS_ERROR("Invalid session ID: %s\n", session_id ? session_id : "NULL");
+ }
+}
+
+/**
+ * @brief 清空会话ID并重置会话状态
+ */
+void ln_ws_clear_session_id(void)
+{
+ memset(g_session_id, 0, sizeof(g_session_id));
+ // 同时重置会话的活跃状态,确保会话完整结束
+ g_audio_chat_ctx.is_active = false;
+ g_audio_chat_ctx.finish_state = LN_CHAT_RECEIVED_END;
+ // 重置对话ID匹配标志
+ reset_chat_id_match();
+ LN_WS_DEBUG("Session ID cleared and chat context reset\n");
+}
+
+void ln_ws_send_chat_session_start(void)
+{
+ // 发送ChatSessionStart请求
+ if (g_ws_connected == WS_STATE_CONNECTED || g_session_id[0] == '\0')
+ {
+ uint32_t timestamp;
+ uapi_get_timestampe_ss(×tamp);
+
+ char message_id[128];
+ generate_chat_id(g_audio_chat_ctx.chat_id, sizeof(g_audio_chat_ctx.chat_id));
+ generate_message_id(message_id, sizeof(message_id), g_audio_chat_ctx.chat_id, 0);
+
+ cJSON *json = cJSON_CreateObject();
+ if (json) {
+ cJSON_AddStringToObject(json, "deviceId", uapi_ln_get_device_id());
+ cJSON_AddNumberToObject(json, "timestamp", (double)timestamp);
+ cJSON_AddStringToObject(json, "messageId", message_id);
+ cJSON_AddStringToObject(json, "command", "ChatSessionStart");
+
+ cJSON *data = cJSON_CreateObject();
+ if (data) {
+ cJSON_AddStringToObject(data, "chatId", g_audio_chat_ctx.chat_id);
+ cJSON_AddItemToObject(json, "data", data);
+ }
+
+ char *json_string = cJSON_Print(json);
+ if (json_string) {
+ uapi_ws_send_text(json_string);
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Sent ChatSessionStart: %s\n", json_string);
+ cJSON_free(json_string);
+ }
+ cJSON_Delete(json);
+ }
+ }
+ return;
+}
+
+void ln_ws_send_chat_session_end(void)
+{
+ // 发送ChatSessionEnd请求
+ if (g_session_id[0] != '\0')
+ {
+ if(g_ws_connected == WS_STATE_CONNECTED)
+ {
+ uint32_t timestamp;
+ uapi_get_timestampe_ss(×tamp);
+
+ char message_id[128];
+ generate_chat_id(g_audio_chat_ctx.chat_id, sizeof(g_audio_chat_ctx.chat_id));
+ generate_message_id(message_id, sizeof(message_id), g_audio_chat_ctx.chat_id, g_audio_chat_ctx.message_counter + 1);
+
+ cJSON *json = cJSON_CreateObject();
+ if (json) {
+ cJSON_AddStringToObject(json, "deviceId", uapi_ln_get_device_id());
+ cJSON_AddNumberToObject(json, "timestamp", (double)timestamp);
+ cJSON_AddStringToObject(json, "messageId", message_id);
+ cJSON_AddStringToObject(json, "command", "ChatSessionEnd");
+
+ cJSON *data = cJSON_CreateObject();
+ if (data) {
+ cJSON_AddStringToObject(data, "sessionId", g_session_id);
+ cJSON_AddStringToObject(data, "chatId", g_audio_chat_ctx.chat_id);
+ cJSON_AddItemToObject(json, "data", data);
+ }
+
+ char *json_string = cJSON_Print(json);
+ if (json_string) {
+ uapi_ws_send_text(json_string);
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Sent ChatSessionEnd: %s\n", json_string);
+ cJSON_free(json_string);
+ }
+ cJSON_Delete(json);
+ }
+ }
+ else
+ {
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ChatSessionEnd: Invalid session ID or chat ID\n");
+ }
+ }
+ return;
+}
+
static void AIVoiceDataCallback_ln(const uint8_t* data, uint32_t size, void* userData)
{
(void)userData;
return WS_CMD_DEVICE_UPGRADE;
} else if (strcmp(command_str, "DeviceUpgradeStatusReportAck") == 0) {
return WS_CMD_DEVICE_UPGRADE_STATUS_REPORT_ACK;
+ } else if (strcmp(command_str, "ChatSessionStartAck") == 0) {
+ return WS_CMD_CHAT_SESSION_START_ACK;
+ } else if (strcmp(command_str, "ChatSessionEndAck") == 0) {
+ return WS_CMD_CHAT_SESSION_END_ACK;
} else if (strcmp(command_str, "BluetoothConnect") == 0) {
return WS_CMD_BLUETOOTH_CONNECT;
} else if (strcmp(command_str, "BluetoothUnbind") == 0) {