From 2987ad26faedef1cec529d57adf45d15c69acf3c Mon Sep 17 00:00:00 2001 From: luozheng <1732036298@qq.com> Date: Mon, 29 Sep 2025 11:16:41 +0800 Subject: [PATCH] =?utf8?q?=E6=B7=BB=E5=8A=A0=E5=B1=8F=E4=BF=9D=E5=88=87?= =?utf8?q?=E6=8D=A2at=E6=8C=87=E4=BB=A4=E5=BE=85ui=E9=AA=8C=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- .../zhihui/leiniao/imsl_ln/leiniao_api_at.c | 13 ++ code/sdk/zhihui/leiniao/imsl_ln/ln_api.h | 1 + .../leiniao/imsl_ln/ln_api_device_info.c | 192 +++++++++++++++++- 3 files changed, 197 insertions(+), 9 deletions(-) diff --git a/code/sdk/zhihui/leiniao/imsl_ln/leiniao_api_at.c b/code/sdk/zhihui/leiniao/imsl_ln/leiniao_api_at.c index dfa8798a6..3cbb8da4c 100644 --- a/code/sdk/zhihui/leiniao/imsl_ln/leiniao_api_at.c +++ b/code/sdk/zhihui/leiniao/imsl_ln/leiniao_api_at.c @@ -1770,6 +1770,17 @@ static uint32_t ln_api_error_at(uint8_t *para, uint32_t paraLen, char *strCommon return ERRCODE_SUCC; } +static uint32_t ln_notify_screen_image_at(uint8_t *para, uint32_t paraLen, char *strCommonCmd) +{ + VAD_UNUSED(para); + VAD_UNUSED(paraLen); + VAD_UNUSED(strCommonCmd); + push_screen_image_download_success_notification(); + printf("+LN_NOTIFY_SCREEN_IMAGE: OK\n"); + printf("[LN][NOTIFY_SCREEN_IMAGE] ok\n"); + return ERRCODE_SUCC; +} + static const at_cmd_table_t g_ln_api_cmd[] = { /* ----------------------------------- VAD ---------------------------------- */ {(char *)"AT^VAD_INIT", vad_init, (char *)"初始化 VAD"}, @@ -1833,6 +1844,8 @@ static const at_cmd_table_t g_ln_api_cmd[] = { {(char *)"AT^LN_SWITCH_EXPRESSION", ln_switch_expression_at, (char *)"切换表情视频: AT^LN_SWITCH_EXPRESSION="}, {(char *)"AT^LN_API_ERROR", ln_api_error_at, (char *)"推送协议错误: AT^LN_API_ERROR[=message]"}, {(char *)"AT^LN_NOTIFY_BIND_AND_UNBIND", ln_notify_bind_and_unbind_at, (char *)"通知用户绑定或解绑: AT^LN_NOTIFY_BIND_AND_UNBIND=1/0"}, + {(char *)"AT^LN_NOTIFY_SCREEN_IMAGE", ln_notify_screen_image_at, (char *)"通知切换屏保: AT^LN_NOTIFY_SCREEN_IMAGE"}, + /* 内存查看相关AT命令 */ {(char *)"AT^LN_MEMORY_INFO", ln_memory_info_at, (char *)"查看系统内存信息: AT^LN_MEMORY_INFO"}, diff --git a/code/sdk/zhihui/leiniao/imsl_ln/ln_api.h b/code/sdk/zhihui/leiniao/imsl_ln/ln_api.h index d3756df3c..d229e281d 100644 --- a/code/sdk/zhihui/leiniao/imsl_ln/ln_api.h +++ b/code/sdk/zhihui/leiniao/imsl_ln/ln_api.h @@ -230,6 +230,7 @@ void ln_read_character_config(void); // 解析设备角色配置 void ln_parse_character_config(const char *json_buf, int json_len); +void ln_parse_character_config_local(const char *json_buf, int json_len); /* 解析哄睡模式开始 */ void ln_parse_sleep_mode_start(const char *json_str, int json_len); /* 解析哄睡模式结束 */ diff --git a/code/sdk/zhihui/leiniao/imsl_ln/ln_api_device_info.c b/code/sdk/zhihui/leiniao/imsl_ln/ln_api_device_info.c index fd0589749..38e13609a 100644 --- a/code/sdk/zhihui/leiniao/imsl_ln/ln_api_device_info.c +++ b/code/sdk/zhihui/leiniao/imsl_ln/ln_api_device_info.c @@ -145,8 +145,8 @@ void ln_parse_character_config(const char *json_buf, int json_len) cJSON *message = cJSON_GetObjectItem(root, "message"); if (errorCode && !cJSON_IsNull(errorCode)) { - printf("[DEVICE_CHARACTER] server error: %s\n",cJSON_IsString(errorCode) ? errorCode->valuestring : "unknown"); - printf("[DEVICE_CHARACTER] server message: %s\n",cJSON_IsString(message) ? message->valuestring : "unknown"); + printf("[DEVICE_CHARACTER] server error: %s\n", cJSON_IsString(errorCode) ? errorCode->valuestring : "unknown"); + printf("[DEVICE_CHARACTER] server message: %s\n", cJSON_IsString(message) ? message->valuestring : "unknown"); // 推送协议错误通知到UI push_api_error_notification(cJSON_IsString(message) ? message->valuestring : "unknown"); cJSON_Delete(root); @@ -172,7 +172,6 @@ void ln_parse_character_config(const char *json_buf, int json_len) ln_assign_dup(&g_ln_character_config.character_name, (cname && cJSON_IsString(cname)) ? cname->valuestring : ""); - // "data": { // "characterId": "char_001", // "characterName": "小艾", @@ -242,18 +241,19 @@ void ln_parse_character_config(const char *json_buf, int json_len) printf(" avatar_screen_image_as_emoji: %d\n", g_ln_character_config.avatar_screen_image_as_emoji); // 如果屏保图片不为空,则保存到本地 - if (g_ln_character_config.avatar_screen_image && strlen(g_ln_character_config.avatar_screen_image) > 0 - && g_ln_character_config.avatar_screen_image_as_emoji == 1) + if (g_ln_character_config.avatar_screen_image && strlen(g_ln_character_config.avatar_screen_image) > 0 && g_ln_character_config.avatar_screen_image_as_emoji == 1) { WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[DEVICE_CHARACTER] 屏保图片不为空,下载屏保图片"); // 下载屏保图片,eg:"https://example.com/new_avatar.bin" ln_download_file_req_t req; memset(&req, 0, sizeof(req)); /* 分配与拷贝,发送方分配,接收方负责释放 */ - if (g_ln_character_config.avatar_screen_image) { + if (g_ln_character_config.avatar_screen_image) + { size_t ulen = strlen(g_ln_character_config.avatar_screen_image); req.url = (char *)malloc(ulen + 1); - if (req.url) { + if (req.url) + { memcpy(req.url, g_ln_character_config.avatar_screen_image, ulen + 1); } } @@ -261,12 +261,12 @@ void ln_parse_character_config(const char *json_buf, int json_len) const char *save = LN_DEVICE_SCREEN_IMAGE_FILE; size_t slen = strlen(save); req.save_path = (char *)malloc(slen + 1); - if (req.save_path) { + if (req.save_path) + { memcpy(req.save_path, save, slen + 1); } } do_ln_http_server_send_data(LN_HTTP_SERVICE_CMD_DOWNLOAD_SCREEN_IMAGE, (char *)&req, sizeof(req)); - } /* 推送角色配置更改通知 */ @@ -283,6 +283,180 @@ void ln_parse_character_config(const char *json_buf, int json_len) ln_clear_character_config(); } +// 本地解析 +void ln_parse_character_config_local(const char *json_buf, int json_len) +{ + if (!json_buf || json_len <= 0) + { + printf("[DEVICE_CHARACTER] invalid json input\n"); + return; + } + + char *text = (char *)malloc((size_t)json_len + 1); + if (!text) + return; + memcpy(text, json_buf, (size_t)json_len); + text[json_len] = '\0'; + + cJSON *root = cJSON_Parse(text); + if (!root) + { + printf("[DEVICE_CHARACTER] json parse failed\n"); + free(text); + return; + } + + cJSON *errorCode = cJSON_GetObjectItem(root, "errorCode"); + cJSON *message = cJSON_GetObjectItem(root, "message"); + if (errorCode && !cJSON_IsNull(errorCode)) + { + printf("[DEVICE_CHARACTER] server error: %s\n", cJSON_IsString(errorCode) ? errorCode->valuestring : "unknown"); + printf("[DEVICE_CHARACTER] server message: %s\n", cJSON_IsString(message) ? message->valuestring : "unknown"); + // 推送协议错误通知到UI + push_api_error_notification(cJSON_IsString(message) ? message->valuestring : "unknown"); + cJSON_Delete(root); + free(text); + return; + } + + cJSON *data = cJSON_GetObjectItem(root, "data"); + if (!data || !cJSON_IsObject(data)) + { + printf("[DEVICE_CHARACTER] no data object\n"); + cJSON_Delete(root); + free(text); + return; + } + + /* 基础字段 */ + cJSON *cid = cJSON_GetObjectItem(data, "characterId"); + cJSON *cname = cJSON_GetObjectItem(data, "characterName"); + ln_assign_dup(&g_ln_character_config.character_id, + (cid && cJSON_IsString(cid)) ? cid->valuestring : ""); + + ln_assign_dup(&g_ln_character_config.character_name, + (cname && cJSON_IsString(cname)) ? cname->valuestring : ""); + + // "data": { + // "characterId": "char_001", + // "characterName": "小艾", + // "characterAvatar": { + // "eyesShape": "upturned-eyes", + // "hairColor": "blue", + // "eyesColor": "green", + // "hairStyle": "side-parted-comma", + // "deviceScreen": "https://example.com/new_avatar.bin", + // "screenImageAsEmoji": true + // } + + /* 头像配置 */ + cJSON *avatar = cJSON_GetObjectItem(data, "characterAvatar"); + if (avatar && cJSON_IsObject(avatar)) + { + cJSON *hairColor = cJSON_GetObjectItem(avatar, "hairColor"); + cJSON *eyesColor = cJSON_GetObjectItem(avatar, "eyesColor"); + cJSON *hairStyle = cJSON_GetObjectItem(avatar, "hairStyle"); + cJSON *eyesShape = cJSON_GetObjectItem(avatar, "eyesShape"); + cJSON *deviceScreen = cJSON_GetObjectItem(avatar, "deviceScreen"); + cJSON *deviceScreenAsEmoji = cJSON_GetObjectItem(avatar, "screenImageAsEmoji"); + + ln_assign_dup(&g_ln_character_config.avatar_hair_color, + (hairColor && cJSON_IsString(hairColor)) ? hairColor->valuestring : ""); + + ln_assign_dup(&g_ln_character_config.avatar_eyes_color, + (eyesColor && cJSON_IsString(eyesColor)) ? eyesColor->valuestring : ""); + + ln_assign_dup(&g_ln_character_config.avatar_hair_style, + (hairStyle && cJSON_IsString(hairStyle)) ? hairStyle->valuestring : ""); + + ln_assign_dup(&g_ln_character_config.avatar_eyes_shape, + (eyesShape && cJSON_IsString(eyesShape)) ? eyesShape->valuestring : ""); + + ln_assign_dup(&g_ln_character_config.avatar_screen_image, + (deviceScreen && cJSON_IsString(deviceScreen)) ? deviceScreen->valuestring : ""); + + g_ln_character_config.avatar_screen_image_as_emoji = + (deviceScreenAsEmoji && cJSON_IsBool(deviceScreenAsEmoji)) ? (cJSON_IsTrue(deviceScreenAsEmoji) ? 1 : 0) : 0; + } + else + { + /* 缺省时清空结构体字段 */ + ln_assign_dup(&g_ln_character_config.avatar_hair_color, ""); + ln_assign_dup(&g_ln_character_config.avatar_eyes_color, ""); + ln_assign_dup(&g_ln_character_config.avatar_hair_style, ""); + ln_assign_dup(&g_ln_character_config.avatar_eyes_shape, ""); + ln_assign_dup(&g_ln_character_config.avatar_screen_image, ""); + g_ln_character_config.avatar_screen_image_as_emoji = 0; + } + + // 将json体落库 + ln_save_character_config(text); + + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[DEVICE_CHARACTER] push character config change notification"); + + /* 打印解析结果 */ + printf("[DEVICE_CHARACTER] parsed:\n"); + printf(" character_id: %s\n", g_ln_character_config.character_id ? g_ln_character_config.character_id : ""); + printf(" character_name: %s\n", g_ln_character_config.character_name ? g_ln_character_config.character_name : ""); + printf(" avatar_hair_color: %s\n", g_ln_character_config.avatar_hair_color ? g_ln_character_config.avatar_hair_color : ""); + printf(" avatar_eyes_color: %s\n", g_ln_character_config.avatar_eyes_color ? g_ln_character_config.avatar_eyes_color : ""); + printf(" avatar_hair_style: %s\n", g_ln_character_config.avatar_hair_style ? g_ln_character_config.avatar_hair_style : ""); + printf(" avatar_eyes_shape: %s\n", g_ln_character_config.avatar_eyes_shape ? g_ln_character_config.avatar_eyes_shape : ""); + printf(" avatar_screen_image: %s\n", g_ln_character_config.avatar_screen_image ? g_ln_character_config.avatar_screen_image : ""); + printf(" avatar_screen_image_as_emoji: %d\n", g_ln_character_config.avatar_screen_image_as_emoji); + + // 如果LN_DEVICE_SCREEN_IMAGE_FILE存在直接发送切换屏保通知 + if (access(LN_DEVICE_SCREEN_IMAGE_FILE, F_OK) != -1) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[DEVICE_CHARACTER] 屏保图片存在,直接发送切换屏保通知"); + push_screen_image_download_success_notification(); + } + else + { + // 如果屏保图片不为空,则保存到本地 + if (g_ln_character_config.avatar_screen_image && strlen(g_ln_character_config.avatar_screen_image) > 0 && g_ln_character_config.avatar_screen_image_as_emoji == 1) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[DEVICE_CHARACTER] 屏保图片不为空,下载屏保图片"); + // 下载屏保图片,eg:"https://example.com/new_avatar.bin" + ln_download_file_req_t req; + memset(&req, 0, sizeof(req)); + /* 分配与拷贝,发送方分配,接收方负责释放 */ + if (g_ln_character_config.avatar_screen_image) + { + size_t ulen = strlen(g_ln_character_config.avatar_screen_image); + req.url = (char *)malloc(ulen + 1); + if (req.url) + { + memcpy(req.url, g_ln_character_config.avatar_screen_image, ulen + 1); + } + } + { + const char *save = LN_DEVICE_SCREEN_IMAGE_FILE; + size_t slen = strlen(save); + req.save_path = (char *)malloc(slen + 1); + if (req.save_path) + { + memcpy(req.save_path, save, slen + 1); + } + } + do_ln_http_server_send_data(LN_HTTP_SERVICE_CMD_DOWNLOAD_SCREEN_IMAGE, (char *)&req, sizeof(req)); + } + + /* 推送角色配置更改通知 */ + push_character_config_change_notification(g_ln_character_config.character_id, + g_ln_character_config.character_name, + g_ln_character_config.avatar_eyes_shape, + g_ln_character_config.avatar_hair_color, + g_ln_character_config.avatar_eyes_color, + g_ln_character_config.avatar_hair_style, + g_ln_character_config.avatar_screen_image_as_emoji); + + cJSON_Delete(root); + free(text); + ln_clear_character_config(); + } +} + // 获取设备角色信息 uint32_t ln_device_get_character_http(const char *device_id, const char *device_token) -- 2.17.1