添加时间线相关协议的接口,包含at测试,ui通知,数据获取
authorluozheng <1732036298@qq.com>
Tue, 14 Oct 2025 09:11:02 +0000 (17:11 +0800)
committerluozheng <1732036298@qq.com>
Tue, 14 Oct 2025 09:11:02 +0000 (17:11 +0800)
code/sdk/application/wearable/ln/nativeapp/nativeui/include/uiservice/ui_service.h
code/sdk/application/wearable/ln/nativeapp/nativeui/uiservice/src/ui_service.cpp
code/sdk/zhihui/leiniao/imsl_ln/CMakeLists.txt
code/sdk/zhihui/leiniao/imsl_ln/leiniao_api_at.c
code/sdk/zhihui/leiniao/imsl_ln/ln_api.c
code/sdk/zhihui/leiniao/imsl_ln/ln_api.h
code/sdk/zhihui/leiniao/imsl_ln/ln_api_timeline_activities.c [new file with mode: 0644]
code/sdk/zhihui/leiniao/ln_api_cpp/ln_api_interface.cpp
code/sdk/zhihui/leiniao/ln_api_cpp/ln_api_interface.h

index c6c8540..f346a47 100644 (file)
@@ -67,6 +67,7 @@ typedef enum {
     HAND_DOWNLOAD_PROGRESS_NOTIFY, // 下载进度通知
     HAND_AUDIO_PLAYBACK_END_NOTIFY, // 音频播放结束通知
     HAND_NPC_EMOTION_CHANGE_NOTIFY, // npc表情变化通知
+    HAND_TIMELINE_STATUS_CHANGE_NOTIFY, // 时间线状态变化通知
     MAX_NUM_HANDLER, 
 } UiServiceMsgId;
 
index 4051721..6454491 100644 (file)
@@ -103,6 +103,7 @@ static void HandDownloadFailNotify(Request *request);
 static void HandDownloadProgressNotify(Request *request);
 static void HandAudioPlaybackEndNotify(Request *request);
 static void HandNpcEmotionChangeNotify(Request *request);
+static void HandTimelineStatusChangeNotify(Request *request);
 // 消息处理程序项数组(每个消息类型对应一个处理函数,函数名以 Handle 开头)
 MsgHandlerEntry msgHandlers[] = {
     {HANDLE_JUMP_OTA_VIEW, HandleJumpOtaView},
@@ -122,6 +123,7 @@ MsgHandlerEntry msgHandlers[] = {
     {HAND_DOWNLOAD_PROGRESS_NOTIFY,HandDownloadProgressNotify},
     {HAND_AUDIO_PLAYBACK_END_NOTIFY,HandAudioPlaybackEndNotify},
     {HAND_NPC_EMOTION_CHANGE_NOTIFY,HandNpcEmotionChangeNotify},
+    {HAND_TIMELINE_STATUS_CHANGE_NOTIFY,HandTimelineStatusChangeNotify},
 };
 /* -------------------------------------------------------------------------- */
 void ScreenTurnOn(int32_t timeout)
@@ -623,6 +625,13 @@ void HandNpcEmotionChangeNotify(Request *request)
     std::string emotion(static_cast<char*>(request->data), request->len);
     WEARABLE_LOGE(WEARABLE_LOG_MODULE_UI_SERVICE, "HandNpcEmotionChangeNotify emotion = %s", emotion.c_str());
 }
+// 通知时间线状态变化
+void HandTimelineStatusChangeNotify(Request *request)
+{
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_UI_SERVICE, "HandTimelineStatusChangeNotify msg_id = %d", request->msgId);
+    std::string payload(static_cast<char*>(request->data), request->len);
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_UI_SERVICE, "HandTimelineStatusChangeNotify payload = %s", payload.c_str());
+}
 /* -------------------------------------------------------------------------- */
 #ifdef __cplusplus
 }
index 9863e37..6ce3f05 100644 (file)
@@ -20,6 +20,7 @@ set(SOURCES
     ${CMAKE_CURRENT_SOURCE_DIR}/ln_api_websocket.c
     ${CMAKE_CURRENT_SOURCE_DIR}/ln_api_schedule.c
     ${CMAKE_CURRENT_SOURCE_DIR}/ln_api_emoji.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/ln_api_timeline_activities.c
 )
 
 # 公共头文件路径(供其他模块引用)
index 16deb0e..2aa15c8 100644 (file)
@@ -1892,6 +1892,14 @@ static uint32_t ln_download_success_notification_at(uint8_t *para, uint32_t para
     return ERRCODE_SUCC;
 }
 
+/* AT^LN_TIMELINE_GET_STATUS - 获取时间线状态 */
+static uint32_t ln_timeline_get_status_at(uint8_t *para, uint32_t paraLen, char *strCommonCmd)
+{
+    VAD_UNUSED(strCommonCmd);
+    do_ln_http_server_send_data(LN_HTTP_SERVICE_CMD_TIMELINE_GET_STATUS, NULL, 0);
+    return ERRCODE_SUCC;
+}
+
 static const at_cmd_table_t g_ln_api_cmd[] = {
     /* ----------------------------------- VAD ---------------------------------- */
     {(char *)"AT^VAD_INIT", vad_init, (char *)"初始化 VAD"},
@@ -1916,6 +1924,7 @@ static const at_cmd_table_t g_ln_api_cmd[] = {
     {(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"},
+    {(char *)"AT^LN_TIMELINE_GET_STATUS", ln_timeline_get_status_at, (char *)"获取时间线状态: AT^LN_TIMELINE_GET_STATUS"},
     
 
      /* -------------------------------- WebSocket -------------------------------- */
index de709aa..dbb8458 100644 (file)
@@ -1315,6 +1315,11 @@ static void ln_http_server_send_task(void const *arg)
             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[LN_HTTP_SERVICE_CMD_SCHEDULE_REMINDER] 日程提醒");
             ln_parse_schedule_reminder(mail.data, mail.len);
         }
+        else if(mail.cmd == LN_HTTP_SERVICE_CMD_TIMELINE_GET_STATUS)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[LN_HTTP_SERVICE_CMD_TIMELINE_GET_STATUS] 查询时间线状态");
+            ln_timeline_get_status_http(uapi_ln_get_device_id(), uapi_ln_get_device_token());
+        }
         if (mail.data != NULL)
         {
             printf("free(mail.data)\n");
index 7e2cf53..c7c3b9e 100644 (file)
@@ -42,6 +42,7 @@ typedef struct
 #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"
+#define LN_TIMELINE_GET_STATUS_PATH "/v1/timeline/getStatus"
 #define LN_STORY_CHOOSE_URL LN_BASE_URL LN_STORY_CHOOSE_PATH
 #define LN_STORY_RANDOM_URL LN_BASE_URL LN_STORY_RANDOM_PATH
 #define LN_STORY_EXIT_INQUIRY_URL LN_BASE_URL LN_STORY_EXIT_INQUIRY_PATH
@@ -53,6 +54,7 @@ typedef struct
 // #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
 #define LN_EMOJI_REPORT_ALL_URL LN_BASE_URL LN_EMOJI_REPORT_ALL_PATH
+#define LN_TIMELINE_GET_STATUS_URL LN_BASE_URL LN_TIMELINE_GET_STATUS_PATH
 #define LN_SIGN_SECRET "vDdXVXgPUEUM6_piUjz5AEhMvYTSFzQdPaN-ogKnSus="
 /* 用户数据保存目录 */
 #define LN_DATA_PATH "/user/userdata/leiniao"
@@ -119,6 +121,9 @@ typedef struct
 // 表情下载相关命令
 #define LN_HTTP_SERVICE_CMD_DOWNLOAD_EMOJI 0x1011 /* 下载表情 */
 
+// 时间线状态相关命令
+#define LN_HTTP_SERVICE_CMD_TIMELINE_GET_STATUS 0x1012 /* 查询时间线状态 */
+
 /* 下载文件相关结构体 */
 typedef struct
 {
@@ -270,6 +275,11 @@ void ln_parse_delete_emoji(const char *json_str, int json_len);
 /* 上报角色表情组下载状态(从队列数据解析)*/
 void ln_emoji_report_status(char *data);
 
+/* =================== 时间线状态(Timeline getStatus) =================== */
+/* 查询时间线状态(GET /v1/timeline/getStatus)*/
+uint32_t ln_timeline_get_status_http(const char *device_id,
+                                     const char *device_token);
+
 /* ============================== 各接口函数声明 ============================== */
 uint32_t ln_get_device_token_http(const char *device_id,
                                     const char *device_iccid,
diff --git a/code/sdk/zhihui/leiniao/imsl_ln/ln_api_timeline_activities.c b/code/sdk/zhihui/leiniao/imsl_ln/ln_api_timeline_activities.c
new file mode 100644 (file)
index 0000000..11780f5
--- /dev/null
@@ -0,0 +1,120 @@
+#include "ln_api.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "cJSON.h"
+
+/*
+GET /v1/timeline/getStatus
+Headers: deviceId, deviceToken
+Response success:
+{
+  "errorCode": null,
+  "message": null,
+  "data": { "description": "...", "emotion": "happy" }
+}
+*/
+
+/* 解析并通知:时间线状态 */
+static void ln_parse_timeline_status_and_notify(const char *json_buf, int json_len)
+{
+       if (!json_buf || json_len <= 0)
+               return;
+       cJSON *root = cJSON_Parse(json_buf);
+       if (!root)
+               return;
+       cJSON *errorCode = cJSON_GetObjectItem(root, "errorCode");
+       cJSON *message = cJSON_GetObjectItem(root, "message");
+       if (errorCode && !cJSON_IsNull(errorCode))
+       {
+               const char *err = cJSON_IsString(errorCode) ? errorCode->valuestring : "unknown";
+               WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[TIMELINE] getStatus error: %s", err);
+               const char *msg = cJSON_IsString(message) ? message->valuestring : "unknown";
+               WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[TIMELINE] getStatus message: %s", msg);
+               push_api_error_notification(msg);
+               cJSON_Delete(root);
+               return;
+       }
+       cJSON *data = cJSON_GetObjectItem(root, "data");
+       const char *desc = NULL;
+       const char *emotion = NULL;
+       if (data && cJSON_IsObject(data))
+       {
+               cJSON *d = cJSON_GetObjectItem(data, "description");
+               cJSON *e = cJSON_GetObjectItem(data, "emotion");
+               if (d && cJSON_IsString(d) && d->valuestring)
+                       desc = d->valuestring;
+               if (e && cJSON_IsString(e) && e->valuestring)
+                       emotion = e->valuestring;
+       }
+       //通知时间线状态变化
+       push_timeline_status_change_notification(desc, emotion);
+       cJSON_Delete(root);
+}
+
+/* 时间线状态查询(GET)*/
+uint32_t ln_timeline_get_status_http(const char *device_id,
+                                                                                const char *device_token)
+{
+       if (!device_id || !device_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)
+               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);
+
+       HTTPC_RESULT prep = ln_http_prepare_auto(&clientData, 2048, LN_CLIENT_PREPARE_SIZE*2);
+       if (prep != HTTP_SUCCESS)
+       {
+               free(header_buf);
+               return ERRCODE_FAIL;
+       }
+
+       HTTPC_RESULT res = HttpClientGetRequest(&client, LN_TIMELINE_GET_STATUS_URL, &clientData);
+       if (res != HTTP_SUCCESS)
+       {
+               goto end;
+       }
+       int code = HttpClientGetResponseCode(&client);
+       if (code != 200)
+       {
+               goto end;
+       }
+       if (clientData.responseBuf && clientData.responseBufLen > 0)
+       {
+               int real_len = clientData.responseContentLen > 0 ? clientData.responseContentLen : clientData.responseBufLen;
+               ln_parse_timeline_status_and_notify(clientData.responseBuf, real_len);
+       }
+
+end:
+       HttpClientUnprepare(&clientData);
+       HttpClientClse(&client);
+       free(header_buf);
+       return ERRCODE_SUCC;
+}
+
+
index 1adf043..22228e0 100644 (file)
@@ -265,6 +265,16 @@ void push_npc_emotion_change_notification(const char *emotion)
     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[NPC_EMOTION_CHANGE] emotion=%s", emotion);
     SendMsgToUIService(HAND_NPC_EMOTION_CHANGE_NOTIFY, 0, (void *)emotion, (int32_t)strlen(emotion));
 }
+//通知时间线状态变化
+void push_timeline_status_change_notification(const char *description, const char *emotion)
+{
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[TIMELINE_STATUS_CHANGE] description=%s, emotion=%s", description, emotion);
+    char payload[512] = {0};
+    const char *d = description ? description : "";
+    const char *e = emotion ? emotion : "";
+    (void)snprintf(payload, sizeof(payload) - 1, "%s|%s", d, e);
+    SendMsgToUIService(HAND_TIMELINE_STATUS_CHANGE_NOTIFY, 0, (void *)payload, (int32_t)strlen(payload));
+}
 #ifdef __cplusplus
 };
 #endif
\ No newline at end of file
index 7675e2d..bbcaa8c 100644 (file)
@@ -102,6 +102,8 @@ void push_download_progress_notification(int progress);
 void push_audio_playback_end_notification(void);
 //通知npc表情变化
 void push_npc_emotion_change_notification(const char *emotion);
+//通知时间线状态变化
+void push_timeline_status_change_notification(const char *description, const char *emotion);
 #ifdef __cplusplus
 }
 #endif