From 8cdb9a6132e1c108b9d2c0898a1600d31204fc67 Mon Sep 17 00:00:00 2001 From: xue <2144439972@qq.com> Date: Thu, 18 Dec 2025 18:08:24 +0800 Subject: [PATCH] =?utf8?q?=E5=A2=9E=E5=8A=A0=E4=B8=8B=E8=BD=BD=E7=8A=B6?= =?utf8?q?=E6=80=81=E4=B8=8A=E6=8A=A5=E4=B8=8E=E5=8F=96=E6=B6=88=E4=B8=8B?= =?utf8?q?=E8=BD=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- code/sdk/zhihui/leiniao/imsl_ln/ln_api.c | 18 ++ code/sdk/zhihui/leiniao/imsl_ln/ln_api.h | 14 ++ .../sdk/zhihui/leiniao/imsl_ln/ln_api_emoji.c | 236 +++++++++++++++++- .../zhihui/leiniao/imsl_ln/ln_api_web_ack.c | 114 +++++++++ .../zhihui/leiniao/imsl_ln/ln_api_websocket.c | 8 + 5 files changed, 388 insertions(+), 2 deletions(-) diff --git a/code/sdk/zhihui/leiniao/imsl_ln/ln_api.c b/code/sdk/zhihui/leiniao/imsl_ln/ln_api.c index e1c87d7bf..5ddc9ee0a 100644 --- a/code/sdk/zhihui/leiniao/imsl_ln/ln_api.c +++ b/code/sdk/zhihui/leiniao/imsl_ln/ln_api.c @@ -928,6 +928,24 @@ void ln_ws_process_message(const ws_data_msg_t *data_msg, ws_command_t type) } break; } + case WS_CMD_EMOJI_DOWNLOAD_STATUS_REPORT_ACK: + { + printf("[WS] EmojiDownloadStatusReportAck:表情包下载状态上报应答\n"); + if (json_str) + { + ln_parse_emoji_download_status_report_ack(json_str, (int)strlen(json_str)); + } + break; + } + case WS_CMD_CANCEL_DOWNLOAD_EMOJI: + { + printf("[WS] CancelDownloadEmoji:取消下载表情\n"); + if (json_str) + { + ln_parse_cancel_download_emoji(json_str, (int)strlen(json_str)); + } + break; + } case WS_CMD_DEVICE_UPGRADE: { printf("[WS] DeviceUpgrade:设备升级\n"); diff --git a/code/sdk/zhihui/leiniao/imsl_ln/ln_api.h b/code/sdk/zhihui/leiniao/imsl_ln/ln_api.h index 7d18a0bea..89ed82a02 100644 --- a/code/sdk/zhihui/leiniao/imsl_ln/ln_api.h +++ b/code/sdk/zhihui/leiniao/imsl_ln/ln_api.h @@ -400,6 +400,16 @@ int ln_ws_send_schedule_reminder_ack(int schedule_id, bool success, const char * int ln_ws_send_schedule_reminder_config_ack(int schedule_id, bool success, const char *msg); int ln_ws_send_delete_emoji_ack(const char *character_id, const char *eyesColor, const char *eyesShape, bool success, const char *msg); int ln_ws_send_download_emoji_ack(const char *character_id, const char *eyesColor, const char *eyesShape, bool success, const char *msg); +/* 发送表情包下载状态上报 */ +int ln_ws_send_emoji_download_status_report(const char *character_id, const char *eyesColor, const char *eyesShape, + const char *status, int progress, const char *message); +/* 解析表情包下载状态上报应答 */ +void ln_parse_emoji_download_status_report_ack(const char *json_str, int json_len); +/* 解析取消下载表情命令 */ +void ln_parse_cancel_download_emoji(const char *json_str, int json_len); +/* 发送取消下载表情应答 */ +int ln_ws_send_cancel_download_emoji_ack(const char *character_id, const char *eyesColor, const char *eyesShape, + bool success, const char *message); int ln_ws_send_device_upgrade_ack(const char *update_id, const char *target_version, bool success, const char *msg); int ln_ws_send_bluetooth_connect_ack(bool success, const char *msg); int ln_ws_send_bluetooth_unbind_ack(const char *bluetooth_address, const char *bluetooth_name, bool success, const char *msg); @@ -492,6 +502,10 @@ typedef enum { WS_CMD_BLUETOOTH_CONNECT, /* 蓝牙连接(BluetoothConnect) */ WS_CMD_BLUETOOTH_UNBIND, /* 蓝牙解绑(BluetoothUnbind) */ WS_CMD_BLUETOOTH_STATUS_REPORT_ACK, /* 蓝牙状态上报应答(BluetoothStatusReportAck) */ + WS_CMD_EMOJI_DOWNLOAD_STATUS_REPORT, /* 表情包下载状态上报(EmojiDownloadStatusReport) - 发送 */ + WS_CMD_EMOJI_DOWNLOAD_STATUS_REPORT_ACK, /* 表情包下载状态上报应答(EmojiDownloadStatusReportAck) - 接收 */ + WS_CMD_CANCEL_DOWNLOAD_EMOJI, /* 取消下载表情(CancelDownloadEmoji) */ + WS_CMD_CANCEL_DOWNLOAD_EMOJI_ACK, /* 取消下载表情应答(CancelDownloadEmojiAck) - 发送 */ WS_CMD_MAX /* 最大命令 */ } ws_command_t; diff --git a/code/sdk/zhihui/leiniao/imsl_ln/ln_api_emoji.c b/code/sdk/zhihui/leiniao/imsl_ln/ln_api_emoji.c index 686efb91f..2db8b57fe 100644 --- a/code/sdk/zhihui/leiniao/imsl_ln/ln_api_emoji.c +++ b/code/sdk/zhihui/leiniao/imsl_ln/ln_api_emoji.c @@ -35,6 +35,7 @@ typedef struct /* 全局变量 */ EmojiPackage g_emoji_package = {0}; +static volatile int g_emoji_download_cancelled = 0; /* 取消下载标志 */ /* ========== ETA 粗略版辅助函数 ========== */ /* 前置声明,便于在本节工具函数中调用 */ static int ln_emoji_is_cached(const EmojiPackage *pkg, const EmotionEmoji *emoji); @@ -432,6 +433,13 @@ static void ln_emoji_download(void *arg) return; } + // 重置取消标志 + g_emoji_download_cancelled = 0; + + // 上报下载开始状态 + ln_ws_send_emoji_download_status_report(pkg->characterId, pkg->eyesColor, pkg->eyesShape, + "downloading", 0, "开始下载表情包"); + int all_success = 1; int downloaded_count = 0; /* 包含已缓存与成功下载的 */ int failed_count = 0; @@ -460,6 +468,9 @@ static void ln_emoji_download(void *arg) ln_safe_strcpy(mail.status, sizeof(mail.status), "download_fail"); ln_safe_strcpy(mail.description, sizeof(mail.description), "没有足够的空间,跳过下载"); do_ln_http_server_send_data(LN_HTTP_SERVICE_CMD_EMOJI_REPORT, (char *)&mail, (uint32_t)sizeof(mail)); + // 上报下载失败状态 + ln_ws_send_emoji_download_status_report(g_emoji_package.characterId, g_emoji_package.eyesColor, g_emoji_package.eyesShape, + "download_fail", -1, "没有足够的空间,跳过下载"); push_download_fail_notification(DOWNLOAD_FILE_TYPE_EMOJI); ln_free_emoji_list(); return; @@ -496,6 +507,14 @@ static void ln_emoji_download(void *arg) // 遍历下载所有表情 for (int i = 0; i < pkg->emojiCount; i++) { + // 检查是否取消下载 + if (g_emoji_download_cancelled) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[DOWNLOAD] 检测到取消下载标志,停止下载"); + all_success = 0; + break; + } + // 跳过已缓存的文件 if (ln_emoji_is_cached(pkg, &pkg->emojis[i])) { @@ -522,11 +541,32 @@ static void ln_emoji_download(void *arg) uapi_create_folder(dir_buf); } } + // 再次检查是否取消下载(在下载前) + if (g_emoji_download_cancelled) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[DOWNLOAD] 检测到取消下载标志,停止下载"); + all_success = 0; + break; + } + if (uapi_ln_download_file_resume_with_retry(pkg->emojis[i].emojiUrl, save_path, 10) != ERRCODE_SUCC) { + // 检查是否因为取消而失败 + if (g_emoji_download_cancelled) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[DOWNLOAD] 下载被取消"); + all_success = 0; + break; + } + all_success = 0; failed_count++; WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[DOWNLOAD] emoji %s 下载失败", pkg->emojis[i].emotion); + // 上报下载失败状态 + char fail_msg[128]; + snprintf(fail_msg, sizeof(fail_msg), "表情 %s 下载失败", pkg->emojis[i].emotion); + ln_ws_send_emoji_download_status_report(pkg->characterId, pkg->eyesColor, pkg->eyesShape, + "download_fail", -1, fail_msg); /* 单个文件三次重试仍失败,终止后续下载并尽快上报失败 */ break; } @@ -537,6 +577,12 @@ static void ln_emoji_download(void *arg) int progress = (int)(((double)downloaded_count / pkg->emojiCount) * 100); push_download_progress_notification(progress); WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[DOWNLOAD] emoji %s 下载完成", pkg->emojis[i].emotion); + + // 每次进度更新都同步发送协议给服务器更新进度 + char progress_msg[64]; + snprintf(progress_msg, sizeof(progress_msg), "下载进度%d%%", progress); + ln_ws_send_emoji_download_status_report(pkg->characterId, pkg->eyesColor, pkg->eyesShape, + "downloading", progress, progress_msg); /* 粗略版 ETA(平滑版):在单个文件完成后估算一次 */ if (total_bytes_all > 0) @@ -643,17 +689,35 @@ static void ln_emoji_download(void *arg) /* 下载完释放本次表情包占用的内存 */ ln_free_emoji_list(); + /* 检查是否因为取消而结束 */ + if (g_emoji_download_cancelled) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[DOWNLOAD] 下载已取消"); + /* 通知ui下载失败 */ + push_download_fail_notification(DOWNLOAD_FILE_TYPE_EMOJI); + // 上报取消状态 + ln_ws_send_emoji_download_status_report(mail.characterId, mail.eyesColor, mail.eyesShape, + "cancelled", -1, "表情包下载已取消"); + // 清理已下载的部分文件(可选) + // 这里可以选择清理部分下载的文件,或者保留以便断点续传 + } /* 持久化:仅在整个表情组下载成功时记录该表情组 */ - if (all_success) + else if (all_success) { /* 通知ui下载成功 */ push_download_success_notification(DOWNLOAD_FILE_TYPE_EMOJI); ln_persist_add_emoji_group(mail.characterId, mail.eyesColor, mail.eyesShape); + // 上报下载成功状态 + ln_ws_send_emoji_download_status_report(mail.characterId, mail.eyesColor, mail.eyesShape, + "download_success", 100, "表情包下载成功"); } else { /* 通知ui下载失败 */ push_download_fail_notification(DOWNLOAD_FILE_TYPE_EMOJI); + // 上报下载失败状态(如果之前没有上报过) + ln_ws_send_emoji_download_status_report(mail.characterId, mail.eyesColor, mail.eyesShape, + "download_fail", -1, "表情包下载失败"); } } @@ -661,6 +725,8 @@ static void ln_emoji_download(void *arg) void ln_start_emoji_download(void) { WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[DOWNLOAD] 启动表情下载任务"); + // 重置取消标志 + g_emoji_download_cancelled = 0; uapi_ln_set_file_download_type(LN_FILE_DOWNLOAD_TYPE_EMOJI); if (g_emoji_package.emojiCount <= 0 || !g_emoji_package.emojis) { @@ -842,7 +908,7 @@ void ln_parse_download_emoji(const char *json_buf, int json_len) if(uapi_ln_get_file_download_type() == LN_FILE_DOWNLOAD_TYPE_NONE && uapi_ln_is_file_downloading() == 0) { push_download_file_notification(DOWNLOAD_FILE_TYPE_EMOJI); - ln_ws_send_download_emoji_ack(g_emoji_package.characterId, g_emoji_package.eyesColor, g_emoji_package.eyesShape, true, "下载表情"); + ln_ws_send_download_emoji_ack(g_emoji_package.characterId, g_emoji_package.eyesColor, g_emoji_package.eyesShape, true, "开始下载表情包"); } else { @@ -988,10 +1054,16 @@ void ln_parse_delete_emoji(const char *json_buf, int json_len) if (ret == 0) { WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[DELETE_EMOJI] cached files in %s deleted", del_dir); + // 删除成功,发送 delete_success 状态上报 + ln_ws_send_emoji_download_status_report(del_characterId, del_eyesColor, del_eyesShape, + "delete_success", -1, "表情包删除成功"); } else { WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[DELETE_EMOJI] failed to delete cached files in %s", del_dir); + // 删除失败,发送 delete_fail 状态上报 + ln_ws_send_emoji_download_status_report(del_characterId, del_eyesColor, del_eyesShape, + "delete_fail", -1, "表情包删除失败"); } // [WEARABLE E/] [DELETE_EMOJI] parsed successfully: @@ -1404,4 +1476,164 @@ void ln_emoji_report_all(void) if (groups) free(groups); cJSON_Delete(root); +} + +/* 解析表情包下载状态上报应答 EmojiDownloadStatusReportAck */ +void ln_parse_emoji_download_status_report_ack(const char *json_str, int json_len) +{ + if (!json_str || json_len <= 0) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[EMOJI_STATUS_ACK] Invalid JSON string or length\n"); + return; + } + + cJSON *root = cJSON_Parse(json_str); + if (!root) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[EMOJI_STATUS_ACK] Failed to parse JSON\n"); + return; + } + + cJSON *data_obj = cJSON_GetObjectItem(root, "data"); + if (!data_obj || !cJSON_IsObject(data_obj)) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[EMOJI_STATUS_ACK] Missing or invalid data object\n"); + cJSON_Delete(root); + return; + } + + // 解析data字段 + cJSON *characterId = cJSON_GetObjectItem(data_obj, "characterId"); + cJSON *eyesColor = cJSON_GetObjectItem(data_obj, "eyesColor"); + cJSON *eyesShape = cJSON_GetObjectItem(data_obj, "eyesShape"); + cJSON *success = cJSON_GetObjectItem(data_obj, "success"); + cJSON *message = cJSON_GetObjectItem(data_obj, "message"); + + const char *char_id = characterId && cJSON_IsString(characterId) ? characterId->valuestring : ""; + const char *ec = eyesColor && cJSON_IsString(eyesColor) ? eyesColor->valuestring : ""; + const char *es = eyesShape && cJSON_IsString(eyesShape) ? eyesShape->valuestring : ""; + bool success_flag = success && cJSON_IsBool(success) ? cJSON_IsTrue(success) : false; + const char *msg = message && cJSON_IsString(message) ? message->valuestring : ""; + + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[EMOJI_STATUS_ACK] Received EmojiDownloadStatusReportAck: characterId=%s, eyesColor=%s, eyesShape=%s, success=%d, message=%s\n", + char_id, ec, es, success_flag, msg); + + // 如果处理失败,可以在这里添加重试逻辑 + if (!success_flag) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[EMOJI_STATUS_ACK] Server failed to process status report: %s\n", msg); + } + + cJSON_Delete(root); +} + +/* 解析取消下载表情命令 CancelDownloadEmoji */ +void ln_parse_cancel_download_emoji(const char *json_str, int json_len) +{ + if (!json_str || json_len <= 0) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[CANCEL_DOWNLOAD_EMOJI] Invalid JSON string or length\n"); + return; + } + + // 复制并终止字符串 + char *text = (char *)malloc((size_t)json_len + 1); + if (!text) + return; + memcpy(text, json_str, (size_t)json_len); + text[json_len] = '\0'; + + // 解析JSON根对象 + cJSON *root = cJSON_Parse(text); + if (!root) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[CANCEL_DOWNLOAD_EMOJI] json parse failed"); + free(text); + return; + } + + // 检查错误码 + cJSON *errorCode = cJSON_GetObjectItem(root, "errorCode"); + if (errorCode && !cJSON_IsNull(errorCode)) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[CANCEL_DOWNLOAD_EMOJI] server error: %s", + cJSON_IsString(errorCode) ? errorCode->valuestring : "unknown"); + cJSON_Delete(root); + free(text); + return; + } + + // 获取data对象 + cJSON *data = cJSON_GetObjectItem(root, "data"); + if (!data || !cJSON_IsObject(data)) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[CANCEL_DOWNLOAD_EMOJI] no data object"); + cJSON_Delete(root); + free(text); + return; + } + + // 解析字段 + cJSON *characterId = cJSON_GetObjectItem(data, "characterId"); + cJSON *eyesColor = cJSON_GetObjectItem(data, "eyesColor"); + cJSON *eyesShape = cJSON_GetObjectItem(data, "eyesShape"); + + char cancel_characterId[64] = {0}; + char cancel_eyesColor[32] = {0}; + char cancel_eyesShape[32] = {0}; + + ln_safe_strcpy(cancel_characterId, sizeof(cancel_characterId), + (characterId && cJSON_IsString(characterId)) ? characterId->valuestring : ""); + + ln_safe_strcpy(cancel_eyesColor, sizeof(cancel_eyesColor), + (eyesColor && cJSON_IsString(eyesColor)) ? eyesColor->valuestring : ""); + + ln_safe_strcpy(cancel_eyesShape, sizeof(cancel_eyesShape), + (eyesShape && cJSON_IsString(eyesShape)) ? eyesShape->valuestring : ""); + + // 打印解析结果 + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[CANCEL_DOWNLOAD_EMOJI] parsed successfully:"); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, " characterId: %s", cancel_characterId); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, " eyesColor: %s", cancel_eyesColor); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, " eyesShape: %s", cancel_eyesShape); + + // 检查是否正在下载表情 + if (uapi_ln_get_file_download_type() == LN_FILE_DOWNLOAD_TYPE_EMOJI && uapi_ln_is_file_downloading() == 1) + { + // 检查是否匹配当前下载的表情包 + if (g_emoji_package.characterId && g_emoji_package.eyesColor && g_emoji_package.eyesShape && + strcmp(cancel_characterId, g_emoji_package.characterId) == 0 && + strcmp(cancel_eyesColor, g_emoji_package.eyesColor) == 0 && + strcmp(cancel_eyesShape, g_emoji_package.eyesShape) == 0) + { + // 设置取消标志 + g_emoji_download_cancelled = 1; + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[CANCEL_DOWNLOAD_EMOJI] 设置取消下载标志,停止下载"); + + // 发送取消下载应答 + ln_ws_send_cancel_download_emoji_ack(cancel_characterId, cancel_eyesColor, cancel_eyesShape, + true, "取消下载成功"); + + // 发送取消状态上报 + ln_ws_send_emoji_download_status_report(cancel_characterId, cancel_eyesColor, cancel_eyesShape, + "cancelled", -1, "表情包下载已取消"); + } + else + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[CANCEL_DOWNLOAD_EMOJI] 当前下载的表情包不匹配,无法取消"); + // 发送取消下载应答(失败) + ln_ws_send_cancel_download_emoji_ack(cancel_characterId, cancel_eyesColor, cancel_eyesShape, + false, "当前下载的表情包不匹配"); + } + } + else + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[CANCEL_DOWNLOAD_EMOJI] 当前没有正在下载的表情包"); + // 发送取消下载应答(失败) + ln_ws_send_cancel_download_emoji_ack(cancel_characterId, cancel_eyesColor, cancel_eyesShape, + false, "当前没有正在下载的表情包"); + } + + cJSON_Delete(root); + free(text); } \ No newline at end of file diff --git a/code/sdk/zhihui/leiniao/imsl_ln/ln_api_web_ack.c b/code/sdk/zhihui/leiniao/imsl_ln/ln_api_web_ack.c index 4b88ff4c0..2a8e0daa3 100644 --- a/code/sdk/zhihui/leiniao/imsl_ln/ln_api_web_ack.c +++ b/code/sdk/zhihui/leiniao/imsl_ln/ln_api_web_ack.c @@ -666,4 +666,118 @@ int ln_ws_send_bluetooth_unbind_ack(const char *bluetooth_address, const char *b cJSON_free(json_string); cJSON_Delete(json); return ret; +} + +/* 发送表情包下载状态上报 EmojiDownloadStatusReport */ +int ln_ws_send_emoji_download_status_report(const char *character_id, const char *eyesColor, const char *eyesShape, + const char *status, int progress, const char *message) +{ + if (ln_ws_get_connection_state() != 2) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Cannot send EmojiDownloadStatusReport, connection state: %d\n", ln_ws_get_connection_state()); + return -1; + } + + uint32_t timestamp; + uapi_get_timestampe_ss(×tamp); + + cJSON *json = cJSON_CreateObject(); + if (!json) + return -1; + + cJSON_AddStringToObject(json, "deviceId", uapi_ln_get_device_id()); + cJSON_AddNumberToObject(json, "timestamp", (double)timestamp); + + char message_id[128]; + // 使用时间戳和计数器生成唯一消息ID + static uint32_t emoji_status_counter = 0; + emoji_status_counter++; + snprintf(message_id, sizeof(message_id), "emoji_status_%u_%u", timestamp, emoji_status_counter); + cJSON_AddStringToObject(json, "messageId", message_id); + cJSON_AddStringToObject(json, "command", "EmojiDownloadStatusReport"); + + cJSON *data = cJSON_CreateObject(); + if (!data) + { + cJSON_Delete(json); + return -1; + } + cJSON_AddStringToObject(data, "characterId", character_id ? character_id : ""); + cJSON_AddStringToObject(data, "eyesColor", eyesColor ? eyesColor : ""); + cJSON_AddStringToObject(data, "eyesShape", eyesShape ? eyesShape : ""); + cJSON_AddStringToObject(data, "status", status ? status : ""); + if (progress >= 0 && progress <= 100) + { + cJSON_AddNumberToObject(data, "progress", progress); + } + cJSON_AddStringToObject(data, "message", message ? message : ""); + cJSON_AddItemToObject(json, "data", data); + + char *json_string = cJSON_Print(json); + if (!json_string) + { + cJSON_Delete(json); + return -1; + } + + int ret = uapi_ws_send_text(json_string); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Sent EmojiDownloadStatusReport: %s\n", json_string); + cJSON_free(json_string); + cJSON_Delete(json); + return ret; +} + +/* 发送取消下载表情应答 CancelDownloadEmojiAck */ +int ln_ws_send_cancel_download_emoji_ack(const char *character_id, const char *eyesColor, const char *eyesShape, + bool success, const char *message) +{ + if (ln_ws_get_connection_state() != 2) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Cannot send CancelDownloadEmojiAck, connection state: %d\n", ln_ws_get_connection_state()); + return -1; + } + + uint32_t timestamp; + uapi_get_timestampe_ss(×tamp); + + cJSON *json = cJSON_CreateObject(); + if (!json) + return -1; + + cJSON_AddStringToObject(json, "deviceId", uapi_ln_get_device_id()); + cJSON_AddNumberToObject(json, "timestamp", (double)timestamp); + + char message_id[128]; + // 使用时间戳和计数器生成唯一消息ID + static uint32_t cancel_emoji_ack_counter = 0; + cancel_emoji_ack_counter++; + snprintf(message_id, sizeof(message_id), "ack_cancel_download_emoji_%u_%u", timestamp, cancel_emoji_ack_counter); + cJSON_AddStringToObject(json, "messageId", message_id); + cJSON_AddStringToObject(json, "command", "CancelDownloadEmojiAck"); + + cJSON *data = cJSON_CreateObject(); + if (!data) + { + cJSON_Delete(json); + return -1; + } + cJSON_AddStringToObject(data, "characterId", character_id ? character_id : ""); + cJSON_AddStringToObject(data, "eyesColor", eyesColor ? eyesColor : ""); + cJSON_AddStringToObject(data, "eyesShape", eyesShape ? eyesShape : ""); + cJSON_AddBoolToObject(data, "success", success); + cJSON_AddStringToObject(data, "message", message ? message : (success ? "取消下载成功" : "取消下载失败")); + cJSON_AddItemToObject(json, "data", data); + + char *json_string = cJSON_Print(json); + if (!json_string) + { + cJSON_Delete(json); + return -1; + } + + int ret = uapi_ws_send_text(json_string); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Sent CancelDownloadEmojiAck: %s\n", json_string); + cJSON_free(json_string); + cJSON_Delete(json); + return ret; } \ No newline at end of file diff --git a/code/sdk/zhihui/leiniao/imsl_ln/ln_api_websocket.c b/code/sdk/zhihui/leiniao/imsl_ln/ln_api_websocket.c index c727b94aa..10cbb7518 100644 --- a/code/sdk/zhihui/leiniao/imsl_ln/ln_api_websocket.c +++ b/code/sdk/zhihui/leiniao/imsl_ln/ln_api_websocket.c @@ -1909,6 +1909,14 @@ static ws_command_t ln_ws_parse_command_string(const char *command_str) return WS_CMD_BLUETOOTH_UNBIND; } else if (strcmp(command_str, "BluetoothStatusReportAck") == 0) { return WS_CMD_BLUETOOTH_STATUS_REPORT_ACK; + } else if (strcmp(command_str, "EmojiDownloadStatusReport") == 0) { + return WS_CMD_EMOJI_DOWNLOAD_STATUS_REPORT; + } else if (strcmp(command_str, "EmojiDownloadStatusReportAck") == 0) { + return WS_CMD_EMOJI_DOWNLOAD_STATUS_REPORT_ACK; + } else if (strcmp(command_str, "CancelDownloadEmoji") == 0) { + return WS_CMD_CANCEL_DOWNLOAD_EMOJI; + } else if (strcmp(command_str, "CancelDownloadEmojiAck") == 0) { + return WS_CMD_CANCEL_DOWNLOAD_EMOJI_ACK; } else { return WS_CMD_UNKNOWN; } -- 2.17.1