From b777ed3231ee57fea220761e07e83702c0da008f Mon Sep 17 00:00:00 2001 From: luozheng <1732036298@qq.com> Date: Thu, 25 Sep 2025 21:37:48 +0800 Subject: [PATCH] =?utf8?q?=E6=B7=BB=E5=8A=A0=E5=AF=B9=E8=AF=9D=E4=BD=93?= =?utf8?q?=E5=8A=9B=E4=B8=8E=E6=B5=81=E9=87=8F=E9=80=9A=E7=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- .../nativeui/include/uiservice/ui_service.h | 1 + .../nativeui/uiservice/src/ui_service.cpp | 18 ++ .../zhihui/leiniao/imsl_ln/leiniao_api_at.c | 74 ++++++- code/sdk/zhihui/leiniao/imsl_ln/ln_api.h | 2 + .../leiniao/imsl_ln/ln_api_device_info.c | 204 ++++++++++++++++-- .../sdk/zhihui/leiniao/imsl_ln/ln_api_emoji.c | 62 +++--- .../leiniao/ln_api_cpp/ln_api_interface.cpp | 17 ++ .../leiniao/ln_api_cpp/ln_api_interface.h | 6 + 8 files changed, 344 insertions(+), 40 deletions(-) diff --git a/code/sdk/application/wearable/ln/nativeapp/nativeui/include/uiservice/ui_service.h b/code/sdk/application/wearable/ln/nativeapp/nativeui/include/uiservice/ui_service.h index 19176de1c..4b4bd868c 100644 --- a/code/sdk/application/wearable/ln/nativeapp/nativeui/include/uiservice/ui_service.h +++ b/code/sdk/application/wearable/ln/nativeapp/nativeui/include/uiservice/ui_service.h @@ -57,6 +57,7 @@ typedef enum { HAND_SLEEP_MODE_START_NOTIFY, // 哄睡模式开始通知 HAND_SLEEP_MODE_END_NOTIFY, // 哄睡模式结束通知 HAND_DOWNLOAD_EMOJI_NOTIFY, // 下载表情通知 + HAND_CHAT_STAMINA_NOTIFY, // 对话体力与流量通知 MAX_NUM_HANDLER, } UiServiceMsgId; diff --git a/code/sdk/application/wearable/ln/nativeapp/nativeui/uiservice/src/ui_service.cpp b/code/sdk/application/wearable/ln/nativeapp/nativeui/uiservice/src/ui_service.cpp index e2d413656..db5c6f1ea 100644 --- a/code/sdk/application/wearable/ln/nativeapp/nativeui/uiservice/src/ui_service.cpp +++ b/code/sdk/application/wearable/ln/nativeapp/nativeui/uiservice/src/ui_service.cpp @@ -90,6 +90,7 @@ static void HandTaskReminderNotify(Request *request); static void HandTaskCharacterConfigNotify(Request *request); static void HandSleepModeStartNotify(Request *request); static void HandSleepModeEndNotify(Request *request); +static void HandChatStaminaNotify(Request *request); static void HandDownloadEmojiNotify(Request *request); // 消息处理程序项数组(每个消息类型对应一个处理函数,函数名以 Handle 开头) MsgHandlerEntry msgHandlers[] = { @@ -99,6 +100,7 @@ MsgHandlerEntry msgHandlers[] = { {HAND_CHARACTER_CONFIG_CHANGE_NOTIFY,HandTaskCharacterConfigNotify}, {HAND_SLEEP_MODE_START_NOTIFY,HandSleepModeStartNotify}, {HAND_SLEEP_MODE_END_NOTIFY,HandSleepModeEndNotify}, + {HAND_CHAT_STAMINA_NOTIFY,HandChatStaminaNotify}, {HAND_DOWNLOAD_EMOJI_NOTIFY,HandDownloadEmojiNotify}, }; /* -------------------------------------------------------------------------- */ @@ -385,6 +387,7 @@ void HandSleepModeEndNotify(Request *request) { WEARABLE_LOGE(WEARABLE_LOG_MODULE_UI_SERVICE, "HandSleepModeEndNotify msg_id = %d",request->msgId); } + // 下载表情通知 void HandDownloadEmojiNotify(Request *request) { @@ -398,6 +401,21 @@ void HandDownloadEmojiNotify(Request *request) WEARABLE_LOGE(WEARABLE_LOG_MODULE_UI_SERVICE, "HandDownloadEmojiNotify eyesColor = %s", eyesColor.c_str()); WEARABLE_LOGE(WEARABLE_LOG_MODULE_UI_SERVICE, "HandDownloadEmojiNotify eyesShape = %s", eyesShape.c_str()); } + +// 对话体力与流量通知 +// 负载格式: "chatLeft|chatDesc|flowLeft|flowDesc|qrcodeUrl",其中可能有空字段 +static void HandChatStaminaNotify(Request *request) +{ + WEARABLE_LOGE(WEARABLE_LOG_MODULE_UI_SERVICE, "HandChatStaminaNotify msg_id = %d", request->msgId); + if (request->data == nullptr || request->len <= 0) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_UI_SERVICE, "HandChatStaminaNotify: invalid data"); + return; + } + std::string payload(static_cast(request->data), request->len); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_UI_SERVICE, "HandChatStaminaNotify payload = %s", payload.c_str()); + // TODO: UI 可在此解析并展示(或直接将payload转交ThunderBirdModel) +} + /* -------------------------------------------------------------------------- */ #ifdef __cplusplus } 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 682adc2da..d3448af49 100644 --- a/code/sdk/zhihui/leiniao/imsl_ln/leiniao_api_at.c +++ b/code/sdk/zhihui/leiniao/imsl_ln/leiniao_api_at.c @@ -651,7 +651,7 @@ static uint32_t ln_ota_get_task_at(uint8_t *para, uint32_t paraLen, char *strCom } /* - * 职责单一:仅触发“根据最近一次getTask结果下载并校验MD5”的动作 + * 职责单一:仅触发"根据最近一次getTask结果下载并校验MD5"的动作 * 不负责:查询任务/升级/重启/重取token */ static uint32_t ln_ota_download_at(uint8_t *para, uint32_t paraLen, char *strCommonCmd) @@ -1470,6 +1470,73 @@ static uint32_t ln_download_emoji_at(uint8_t *para, uint32_t paraLen, char *strC free(json); return ERRCODE_SUCC; } +/* AT^LN_GET_CHAT_STAMINA - 获取对话体力与流量信息 */ +static uint32_t ln_get_chat_stamina_at(uint8_t *para, uint32_t paraLen, char *strCommonCmd) +{ + VAD_UNUSED(para); + VAD_UNUSED(paraLen); + VAD_UNUSED(strCommonCmd); + const char *id = uapi_ln_get_device_id(); + const char *token = uapi_ln_get_device_token(); + if (!id || !id[0] || !token || !token[0]) { + printf("[LN][CHAT_STAMINA] deviceId/token missing\n"); + return ERRCODE_FAIL; + } + uint32_t ret = ln_device_get_chat_stamina_http(id, token); + return ret; +} + +/* AT^LN_CHAT_STAMINA_DEMO[=profile|chatLeft,flowLeft[,chatDesc,flowDesc,qrcodeUrl]] + * profile: member/enough/low/empty + 预置场景: + AT^LN_CHAT_STAMINA_DEMO=member + AT^LN_CHAT_STAMINA_DEMO=enough + AT^LN_CHAT_STAMINA_DEMO=low + AT^LN_CHAT_STAMINA_DEMO=empty + 自定义场景: + AT^LN_CHAT_STAMINA_DEMO=chatLeft,flowLeft[,chatDesc,flowDesc,qrcodeUrl] + 例: AT^LN_CHAT_STAMINA_DEMO=10,80,"对话额度不足20轮,可扫码续充","流量不足100M了哦,扫码可充值流量","https://example.com/qrcode/recharge=860132063148589" + */ +static uint32_t ln_chat_stamina_demo_at(uint8_t *para, uint32_t paraLen, char *strCommonCmd) +{ + VAD_UNUSED(strCommonCmd); + int chatLeft = 0; + int flowLeft = 0; + const char *chatDesc = NULL; + const char *flowDesc = NULL; + const char *qrcode = "https://example.com/qrcode/recharge"; + + if (para == NULL || paraLen == 0) { + printf("Usage: AT^LN_CHAT_STAMINA_DEMO=member|enough|low|empty or AT^LN_CHAT_STAMINA_DEMO=chatLeft,flowLeft[,chatDesc,flowDesc,qrcode]\n"); + return ERRCODE_FAIL; + } + + uint8_t argv[LN_MAX_ARGC][LN_MAX_ARGV_LEN] = {0}; + uint32_t argc = 0; + (void)ConvertCmdToParam(para, paraLen, argv, &argc); + if (argc >= 1) { + if (strcmp((char*)argv[0], "member") == 0) { + chatLeft = -1; chatDesc = NULL; flowLeft = 500; flowDesc = NULL; + } else if (strcmp((char*)argv[0], "enough") == 0) { + chatLeft = 25; chatDesc = NULL; flowLeft = 200; flowDesc = NULL; + } else if (strcmp((char*)argv[0], "low") == 0) { + chatLeft = 10; chatDesc = "对话额度不足20轮,可扫码续充"; flowLeft = 80; flowDesc = "流量不足100M了哦,扫码可充值流量"; + } else if (strcmp((char*)argv[0], "empty") == 0) { + chatLeft = 0; chatDesc = "啊哦,对话轮数已用完,扫码续上吧"; flowLeft = 0; flowDesc = "流量用完了哦"; + } else { + chatLeft = atoi((char*)argv[0]); + if (argc >= 2) flowLeft = atoi((char*)argv[1]); else flowLeft = 0; + if (argc >= 3) chatDesc = (char*)argv[2]; + if (argc >= 4) flowDesc = (char*)argv[3]; + if (argc >= 5) qrcode = (char*)argv[4]; + } + } + + push_chat_stamina_notification(chatLeft, chatDesc, flowLeft, flowDesc, qrcode); + printf("[LN][CHAT_STAMINA_DEMO] chatLeft=%d, flowLeft=%d\n", chatLeft, flowLeft); + return ERRCODE_SUCC; +} + static const at_cmd_table_t g_ln_api_cmd[] = { /* ----------------------------------- VAD ---------------------------------- */ {(char *)"AT^VAD_INIT", vad_init, (char *)"初始化 VAD"}, @@ -1494,7 +1561,9 @@ static const at_cmd_table_t g_ln_api_cmd[] = { {(char *)"AT^LN_SET_DEV_USERID", ln_device_set_userid_at, (char *)"获取设备绑定用户ID(JSON,SET): AT^LN_SET_DEV_USERID"}, {(char *)"AT^LN_OTA_GET_TASK", ln_ota_get_task_at, (char *)"获取OTA升级任务(JSON,GET): AT^LN_OTA_GET_TASK"}, {(char *)"AT^LN_OTA_DOWNLOAD", ln_ota_download_at, (char *)"下载OTA升级包(JSON,GET->下载): AT^LN_OTA_DOWNLOAD"}, - + {(char *)"AT^LN_GET_CHAT_STAMINA", ln_get_chat_stamina_at, (char *)"获取对话体力与流量: AT^LN_GET_CHAT_STAMINA"}, + + /* -------------------------------- WebSocket -------------------------------- */ {(char *)"AT^LN_WS_START", ln_ws_start_at, (char *)"启动WebSocket连接: AT^LN_WS_START"}, {(char *)"AT^LN_WS_STOP", ln_ws_stop_at, (char *)"停止WebSocket连接: AT^LN_WS_STOP"}, @@ -1526,6 +1595,7 @@ static const at_cmd_table_t g_ln_api_cmd[] = { {(char *)"AT^LN_SLEEP_MODE_START", ln_sleep_mode_start_at, (char *)"哄睡模式开始: AT^LN_SLEEP_MODE_START[=storyTheme]"}, {(char *)"AT^LN_SLEEP_MODE_END", ln_sleep_mode_end_at, (char *)"哄睡模式结束: AT^LN_SLEEP_MODE_END"}, {(char *)"AT^LN_DOWNLOAD_EMOJI", ln_download_emoji_at, (char *)"下载表情: AT^LN_DOWNLOAD_EMOJI[=characterId,eyesColor,eyesShape]"}, + {(char *)"AT^LN_CHAT_STAMINA_DEMO", ln_chat_stamina_demo_at, (char *)"演示对话体力/流量UI: AT^LN_CHAT_STAMINA_DEMO=member|enough|low|empty 或自定义"}, /* 内存查看相关AT命令 */ {(char *)"AT^LN_MEMORY_INFO", ln_memory_info_at, (char *)"查看系统内存信息: AT^LN_MEMORY_INFO"}, {(char *)"AT^LN_FOLDER_SIZE", ln_folder_size_at, (char *)"查看文件夹大小: AT^LN_FOLDER_SIZE[=/path/to/folder]"}, diff --git a/code/sdk/zhihui/leiniao/imsl_ln/ln_api.h b/code/sdk/zhihui/leiniao/imsl_ln/ln_api.h index 0667ca1cb..e86d0b552 100644 --- a/code/sdk/zhihui/leiniao/imsl_ln/ln_api.h +++ b/code/sdk/zhihui/leiniao/imsl_ln/ln_api.h @@ -38,6 +38,7 @@ typedef struct #define LN_STORY_FINISH_PATH "/v1/story/finishSleepMode" #define LN_DEVICE_GET_CHARACTER_PATH "/v1/device/getCharacter" #define LN_DEVICE_GET_USER_ID_PATH "/v1/device/getUserId" +#define LN_DEVICE_GET_CHAT_STAMINA_PATH "/v1/device/getChatStamina" #define LN_OTA_GET_TASK_PATH "/v1/upgrade/getTask" #define LN_EMOJI_REPORT_PATH "/v1/emoji/reportEmoji" #define LN_EMOJI_REPORT_ALL_PATH "/v1/emoji/reportAllEmoji" @@ -47,6 +48,7 @@ typedef struct #define LN_STORY_FINISH_URL LN_BASE_URL LN_STORY_FINISH_PATH #define LN_DEVICE_GET_CHARACTER_URL LN_BASE_URL LN_DEVICE_GET_CHARACTER_PATH #define LN_DEVICE_GET_USER_ID_URL LN_BASE_URL LN_DEVICE_GET_USER_ID_PATH +#define LN_DEVICE_GET_CHAT_STAMINA_URL LN_BASE_URL LN_DEVICE_GET_CHAT_STAMINA_PATH #define LN_OTA_GET_TASK_URL LN_BASE_URL LN_OTA_GET_TASK_PATH // #define LN_OTA_GET_TASK_URL "http://110.42.224.129:8089/leiniaoota.jsp" #define LN_EMOJI_REPORT_URL LN_BASE_URL LN_EMOJI_REPORT_PATH 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 0b71a786b..a75892f83 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 @@ -9,20 +9,25 @@ LnCharacterConfig g_ln_character_config = {0}; /* 动态字符串工具 */ static inline char *ln_strdup_s(const char *src) { - if (src == NULL) src = ""; + if (src == NULL) + src = ""; size_t len = strlen(src); char *p = (char *)malloc(len + 1); - if (!p) return NULL; + if (!p) + return NULL; memcpy(p, src, len + 1); return p; } static inline void ln_assign_dup(char **dst, const char *src) { - if (!dst) return; + if (!dst) + return; char *newp = ln_strdup_s(src); - if (!newp) return; - if (*dst) free(*dst); + if (!newp) + return; + if (*dst) + free(*dst); *dst = newp; } @@ -54,12 +59,12 @@ void ln_read_character_config(void) static void ln_save_character_config(const char *json_buf) { WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[DEVICE_CHARACTER] save character config"); - if (!json_buf) + if (!json_buf) { printf("[DEVICE_CHARACTER] json_buf is NULL\n"); return; } - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "LN_CHARACTER_CONFIG_FILE:%s",LN_CHARACTER_CONFIG_FILE); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "LN_CHARACTER_CONFIG_FILE:%s", LN_CHARACTER_CONFIG_FILE); FILE *file = fopen(LN_CHARACTER_CONFIG_FILE, "wb+"); if (!file) { @@ -204,7 +209,7 @@ void ln_parse_character_config(const char *json_buf, int json_len) g_ln_character_config.avatar_screen_image_as_emoji = 0; } - //将json体落库 + // 将json体落库 ln_save_character_config(text); WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[DEVICE_CHARACTER] push character config change notification"); @@ -222,12 +227,12 @@ void ln_parse_character_config(const char *json_buf, int json_len) /* 推送角色配置更改通知 */ push_character_config_change_notification(g_ln_character_config.character_id, - g_ln_character_config.character_name, - 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_eyes_shape, - g_ln_character_config.avatar_screen_image_as_emoji); + g_ln_character_config.character_name, + 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_eyes_shape, + g_ln_character_config.avatar_screen_image_as_emoji); cJSON_Delete(root); free(text); @@ -510,3 +515,174 @@ uint32_t uapi_ln_device_get_user_id(LnDeviceBindStatus *out_status, char *out_us free(header_buf3); return ERRCODE_SUCC; } + +// 获取对话体力与流量信息 +uint32_t ln_device_get_chat_stamina_http(const char *device_id, const char *device_token) +{ + if (!device_id || !device_token) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[CHAT_STAMINA] missing deviceId/token"); + return ERRCODE_FAIL; + } + +#ifdef SUPPORT_CAT1_SERVICE + cat1_api_add_cat1_vote(); + cat1_api_wakeup_cat1(1); + cat1_api_keep_wakeup(1); + cat1_api_disable_cat1_cmd(0); + LOS_Msleep(200); +#endif + + HttpClient client = (HttpClient){0}; + HttpClientData clientData = (HttpClientData){0}; + client.isHttp = false; + client.remotePort = 443; + + char *header_buf = (char *)malloc(512); + if (!header_buf) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[CHAT_STAMINA] malloc failed for header_buf"); + return ERRCODE_FAIL; + } + int hdr = snprintf(header_buf, 512, + "deviceId: %s\r\n" + "deviceToken: %s\r\n" + "Content-Type: application/json\r\n", + device_id, device_token); + if (hdr <= 0) + { + free(header_buf); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[CHAT_STAMINA] snprintf failed for header_buf"); + return ERRCODE_FAIL; + } + HttpClientSetCustomHeader(&client, header_buf); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[CHAT_STAMINA] header_buf: %s", header_buf); + + HTTPC_RESULT prep = ln_http_prepare_auto(&clientData, 2048, LN_CLIENT_PREPARE_SIZE * 2); + if (prep != HTTP_SUCCESS) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[CHAT_STAMINA] prepare failed: %d", prep); + free(header_buf); + return ERRCODE_FAIL; + } + + HTTPC_RESULT res = HttpClientGetRequest(&client, LN_DEVICE_GET_CHAT_STAMINA_URL, &clientData); + if (res != HTTP_SUCCESS) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[CHAT_STAMINA] request failed: %d", res); + HttpClientUnprepare(&clientData); + HttpClientClse(&client); + free(header_buf); + return ERRCODE_FAIL; + } + + int code = HttpClientGetResponseCode(&client); + int body_len = clientData.responseContentLen > 0 ? clientData.responseContentLen : clientData.responseBufLen; + if (body_len <= 0 || !clientData.responseBuf) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[CHAT_STAMINA] empty body, code=%d", code); + HttpClientUnprepare(&clientData); + HttpClientClse(&client); + free(header_buf); + return ERRCODE_FAIL; + } + if (clientData.responseBuf && clientData.responseBufLen > 0) + { + int real_len = clientData.responseContentLen > 0 ? clientData.responseContentLen : clientData.responseBufLen; + char *response_buf = (char *)malloc(real_len + 1); + if (!response_buf) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[EMOJI_REPORT_STATUS] malloc failed for response_buf"); + free(header_buf); + return ERRCODE_FAIL; + } + memcpy(response_buf, clientData.responseBuf, real_len); + response_buf[real_len] = '\0'; + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[EMOJI_REPORT_STATUS] response body: %s", response_buf); + free(response_buf); + } + + char *json_text = (char *)malloc((size_t)body_len + 1); + if (!json_text) + { + HttpClientUnprepare(&clientData); + HttpClientClse(&client); + free(header_buf); + return ERRCODE_FAIL; + } + memcpy(json_text, clientData.responseBuf, (size_t)body_len); + json_text[body_len] = '\0'; + + /* 若非200,打印原始响应体便于排查 */ + if (code != 200) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[CHAT_STAMINA] HTTP code=%d", code); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[CHAT_STAMINA] body=%s", json_text); + } + + cJSON *root = cJSON_Parse(json_text); + if (!root) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[CHAT_STAMINA] json parse failed"); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[CHAT_STAMINA] raw body: %s", json_text); + free(json_text); + HttpClientUnprepare(&clientData); + HttpClientClse(&client); + free(header_buf); + return ERRCODE_FAIL; + } + + cJSON *errorCode = cJSON_GetObjectItem(root, "errorCode"); + if (errorCode && !cJSON_IsNull(errorCode)) + { + cJSON *message = cJSON_GetObjectItem(root, "message"); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[CHAT_STAMINA] server error: %s, msg=%s", + cJSON_IsString(errorCode) ? errorCode->valuestring : "", + (message && cJSON_IsString(message)) ? message->valuestring : ""); + cJSON_Delete(root); + free(json_text); + HttpClientUnprepare(&clientData); + HttpClientClse(&client); + free(header_buf); + return ERRCODE_FAIL; + } + + cJSON *data = cJSON_GetObjectItem(root, "data"); + if (!data || !cJSON_IsObject(data)) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[CHAT_STAMINA] no data"); + cJSON_Delete(root); + free(json_text); + HttpClientUnprepare(&clientData); + HttpClientClse(&client); + free(header_buf); + return ERRCODE_FAIL; + } + + cJSON *chatLeft = cJSON_GetObjectItem(data, "chatStaminaLeft"); + cJSON *chatDesc = cJSON_GetObjectItem(data, "chatStaminaDesc"); + cJSON *flowLeft = cJSON_GetObjectItem(data, "cardFlowLeft"); + cJSON *flowDesc = cJSON_GetObjectItem(data, "cardFlowDesc"); + cJSON *qrcode = cJSON_GetObjectItem(data, "qrcodeUrl"); + + int chat_left = chatLeft && cJSON_IsNumber(chatLeft) ? (int)chatLeft->valuedouble : 0; + const char *chat_desc = (chatDesc && cJSON_IsString(chatDesc)) ? chatDesc->valuestring : NULL; + int flow_left = flowLeft && cJSON_IsNumber(flowLeft) ? (int)flowLeft->valuedouble : 0; + const char *flow_desc = (flowDesc && cJSON_IsString(flowDesc)) ? flowDesc->valuestring : NULL; + const char *qr = (qrcode && cJSON_IsString(qrcode)) ? qrcode->valuestring : NULL; + + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[CHAT_STAMINA] chatStaminaLeft=%d, chatStaminaDesc=%s", + chat_left, chat_desc ? chat_desc : ""); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[CHAT_STAMINA] cardFlowLeft=%d, cardFlowDesc=%s", + flow_left, flow_desc ? flow_desc : ""); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[CHAT_STAMINA] qrcodeUrl=%s", qr ? qr : ""); + + /* 推送到UI */ + push_chat_stamina_notification(chat_left, chat_desc, flow_left, flow_desc, qr); + + cJSON_Delete(root); + free(json_text); + HttpClientUnprepare(&clientData); + HttpClientClse(&client); + free(header_buf); + return ERRCODE_SUCC; +} \ No newline at end of file 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 4277f7a14..20224903a 100644 --- a/code/sdk/zhihui/leiniao/imsl_ln/ln_api_emoji.c +++ b/code/sdk/zhihui/leiniao/imsl_ln/ln_api_emoji.c @@ -447,27 +447,6 @@ void ln_parse_delete_emoji(const char *json_buf, int json_len) free(text); } -static inline int ln_fill_auth_header(HttpClient *client, - const char *device_id, - const char *device_token) -{ - if (!client || !device_id || !device_token) - return -1; - char *header_buf = (char *)malloc(512); - if (!header_buf) - return -1; - int hdr = snprintf(header_buf, 512, - "deviceId: %s\r\n" - "deviceToken: %s\r\n" - "Content-Type: application/json\r\n", - device_id, device_token); - if (hdr <= 0) - return -1; - HttpClientSetCustomHeader(client, header_buf); - free(header_buf); - return 0; -} - /* 7.1 上报角色表情组下载状态 */ uint32_t ln_emoji_report_status_http(const char *device_id, const char *device_token, @@ -495,11 +474,25 @@ uint32_t ln_emoji_report_status_http(const char *device_id, HttpClient client = (HttpClient){0}; HttpClientData clientData = (HttpClientData){0}; - if (ln_fill_auth_header(&client, device_id, device_token) != 0) + /* 直接构造自定义请求头,生命周期贯穿整个请求,结束后再释放 */ + char *header_buf = (char *)malloc(512); + if (!header_buf) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[EMOJI_REPORT_STATUS] fill auth header failed"); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[EMOJI_REPORT_STATUS] malloc header_buf failed"); return ERRCODE_FAIL; } + int hdr = snprintf(header_buf, 512, + "deviceId: %s\r\n" + "deviceToken: %s\r\n" + "Content-Type: application/json\r\n", + device_id, device_token); + if (hdr <= 0) + { + free(header_buf); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[EMOJI_REPORT_STATUS] build header failed"); + return ERRCODE_FAIL; + } + HttpClientSetCustomHeader(&client, header_buf); /* 组装 JSON */ cJSON *root = cJSON_CreateObject(); @@ -524,6 +517,7 @@ uint32_t ln_emoji_report_status_http(const char *device_id, if (prep != HTTP_SUCCESS) { free(body); + free(header_buf); WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[EMOJI_REPORT_STATUS] prepare auto failed"); return ERRCODE_FAIL; } @@ -544,6 +538,7 @@ uint32_t ln_emoji_report_status_http(const char *device_id, { free(body); HttpClientUnprepare(&clientData); + free(header_buf); WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[EMOJI_REPORT_STATUS] request failed"); return ERRCODE_FAIL; } @@ -573,12 +568,14 @@ uint32_t ln_emoji_report_status_http(const char *device_id, { free(body); HttpClientUnprepare(&clientData); + free(header_buf); WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[EMOJI_REPORT_STATUS] response code not 200"); return ERRCODE_FAIL; } free(body); HttpClientUnprepare(&clientData); + free(header_buf); return ERRCODE_SUCC; } /* 7.2 上报设备所有表情组状态 */ @@ -603,8 +600,21 @@ uint32_t ln_emoji_report_all_http(const char *device_id, client.isHttp = false; client.remotePort = 443; - if (ln_fill_auth_header(&client, device_id, device_token) != 0) + /* 直接构造自定义请求头,生命周期贯穿整个请求,结束后再释放 */ + char *header_buf = (char *)malloc(512); + if (!header_buf) return ERRCODE_FAIL; + int hdr = snprintf(header_buf, 512, + "deviceId: %s\r\n" + "deviceToken: %s\r\n" + "Content-Type: application/json\r\n", + device_id, device_token); + if (hdr <= 0) + { + free(header_buf); + return ERRCODE_FAIL; + } + HttpClientSetCustomHeader(&client, header_buf); /* 组装 JSON 数组 */ cJSON *root = cJSON_CreateObject(); @@ -639,6 +649,7 @@ uint32_t ln_emoji_report_all_http(const char *device_id, if (prep != HTTP_SUCCESS) { free(body); + free(header_buf); return ERRCODE_FAIL; } clientData.postBuf = body; @@ -650,6 +661,7 @@ uint32_t ln_emoji_report_all_http(const char *device_id, { free(body); HttpClientUnprepare(&clientData); + free(header_buf); return ERRCODE_FAIL; } @@ -672,11 +684,13 @@ uint32_t ln_emoji_report_all_http(const char *device_id, { free(body); HttpClientUnprepare(&clientData); + free(header_buf); return ERRCODE_FAIL; } free(body); HttpClientUnprepare(&clientData); + free(header_buf); return ERRCODE_SUCC; } diff --git a/code/sdk/zhihui/leiniao/ln_api_cpp/ln_api_interface.cpp b/code/sdk/zhihui/leiniao/ln_api_cpp/ln_api_interface.cpp index cd9755244..aea9993a4 100644 --- a/code/sdk/zhihui/leiniao/ln_api_cpp/ln_api_interface.cpp +++ b/code/sdk/zhihui/leiniao/ln_api_cpp/ln_api_interface.cpp @@ -149,6 +149,23 @@ void push_download_emoji_notification(char *characterId, char *eyesColor, char * //切换表情通知ui SendMsgToUIService(HAND_DOWNLOAD_EMOJI_NOTIFY, 0, (void *)payload, (int32_t)strlen(payload)); } +// 推送对话体力与流量信息到UI +// chatLeft:对话体力剩余数量 +// chatDesc:对话体力说明文字 +// flowLeft:流量剩余数量 +// flowDesc:流量说明文字 +// qrcodeUrl:充值二维码链接 +void push_chat_stamina_notification(int chatLeft, const char *chatDesc, + int flowLeft, const char *flowDesc, + const char *qrcodeUrl) +{ + char payload[512] = {0}; + const char *cd = chatDesc ? chatDesc : ""; + const char *fd = flowDesc ? flowDesc : ""; + const char *qr = qrcodeUrl ? qrcodeUrl : ""; + (void)snprintf(payload, sizeof(payload) - 1, "%d|%s|%d|%s|%s", chatLeft, cd, flowLeft, fd, qr); + SendMsgToUIService(HAND_CHAT_STAMINA_NOTIFY, 0, (void *)payload, (int32_t)strlen(payload)); +} #ifdef __cplusplus }; #endif \ No newline at end of file diff --git a/code/sdk/zhihui/leiniao/ln_api_cpp/ln_api_interface.h b/code/sdk/zhihui/leiniao/ln_api_cpp/ln_api_interface.h index b2b090cc3..4ca2875ad 100644 --- a/code/sdk/zhihui/leiniao/ln_api_cpp/ln_api_interface.h +++ b/code/sdk/zhihui/leiniao/ln_api_cpp/ln_api_interface.h @@ -67,6 +67,12 @@ void push_sleep_mode_start_notification(const char *storyTheme); void push_sleep_mode_end_notification(void); //通知ui下载表情 void push_download_emoji_notification(char *characterId, char *eyesColor, char *eyesShape); +// 推送对话体力与流量信息到UI(管道字符串,以'|'分隔) +void push_chat_stamina_notification(int chatLeft, + const char *chatDesc, + int flowLeft, + const char *flowDesc, + const char *qrcodeUrl); #ifdef __cplusplus } #endif -- 2.17.1