修复表冠转动会息屏问题,优化佩戴检测未正常启动bug,优化PGNSS数据注入,增加pgnss的http服务 2167/1 2167/head 2169/target/1
authorpenglei <1624952103@qq.com>
Thu, 28 Aug 2025 10:53:43 +0000 (18:53 +0800)
committerpenglei <1624952103@qq.com>
Thu, 28 Aug 2025 10:53:43 +0000 (18:53 +0800)
20 files changed:
code/sdk/application/brandy/brandy_standard/thread_pri_init.c
code/sdk/application/wearable/fd230/nativeapp/nativeui/traing/src/TraingModel.cpp
code/sdk/application/wearable/fd230/service/power_manager/src/power_display_service.c
code/sdk/application/wearable/service/power_manager/src/power_display_service.c
code/sdk/drivers/boards/brandy_evb/linker/standard/acore.prelds
code/sdk/zhihui/UI/producttest/include/testPresenter.h
code/sdk/zhihui/UI/producttest/src/testView.cpp
code/sdk/zhihui/config/include/ConfigModelC.h
code/sdk/zhihui/config/src/ConfigModel.cpp
code/sdk/zhihui/drivers/mag/service/mag_service.c
code/sdk/zhihui/drivers/ppg/pah8009/sensor/pah800x_main.c
code/sdk/zhihui/services/gnss/CMakeLists.txt
code/sdk/zhihui/services/gnss/inc/gnss_http_server.h [new file with mode: 0644]
code/sdk/zhihui/services/gnss/inc/gnss_tcp_server.h [deleted file]
code/sdk/zhihui/services/gnss/sample/pgnss_sample/pgnss_encode.c
code/sdk/zhihui/services/gnss/sample/pgnss_sample/pgnss_encode.h
code/sdk/zhihui/services/gnss/sample/pgnss_sample/pgnss_sample.c
code/sdk/zhihui/services/gnss/src/gnss_http_server.c [new file with mode: 0644]
code/sdk/zhihui/services/gnss/src/gnss_tcp_server.c [deleted file]
code/sdk/zhihui/utils/custom_utils.c

index c1fd487..47bc99e 100644 (file)
 #include "mixo_service.h"\r
 #endif\r
 \r
+#ifdef SUPPORT_GNSS\r
+#include "gnss_http_server.h"\r
+#endif\r
+\r
 #define EMMC_BASE_ADDR              0x52062000\r
 #define TASK_PRIORITY_APP           (osPriority_t)(17)\r
 #define TICK_TEN_MS                 (10U)\r
@@ -574,8 +578,9 @@ static void thread_main(const void *unused)
     uapi_pin_set_ie(S_MGPIO34, HAL_PIO_IE_ENBALE); //启动期间关闭uart输入中断,启动后开启\r
 #endif\r
 \r
-#ifdef SUPPORT_GNSS_SERVER\r
+#ifdef SUPPORT_GNSS\r
     gnss_uart_init();\r
+    uapi_gnss_http_server_init();\r
 #endif\r
 \r
 #ifdef SUPPORT_OHOSFWK\r
index fa50c4a..cc5d5f3 100644 (file)
 #include "system/include/SystemLogModel.h"
 #include <custom_save_runtime.h>
 
+#include "graphic_service.h"
+
 #if defined(SUPPORT_GNSS)
 #include "NMEA0183.h"
 #include "gnss_ctl.h"
-#include "graphic_service.h"
 #include "pgnss_sample.h"
 #endif
 
index cfbb7f0..5e40905 100644 (file)
@@ -620,6 +620,7 @@ errcode_t uapi_power_display_init(void)
     g_event_filter_map[TIMER_EVENT] = display_get_timer_filter();\r
     g_event_filter_map[SLICE_EVENT] = display_get_slice_filter();\r
     ts_register_power_manager_cb(power_display_touch_event_cb);\r
+    re_register_power_manager_cb(power_display_key_event_cb);\r
     button_register_power_display_cb(power_display_key_event_cb);\r
     return ERRCODE_SUCC;\r
 }\r
index 2a27a66..297dd3a 100644 (file)
@@ -618,6 +618,7 @@ errcode_t uapi_power_display_init(void)
     g_event_filter_map[TIMER_EVENT] = display_get_timer_filter();\r
     g_event_filter_map[SLICE_EVENT] = display_get_slice_filter();\r
     ts_register_power_manager_cb(power_display_touch_event_cb);\r
+    re_register_power_manager_cb(power_display_key_event_cb);\r
     button_register_power_display_cb(power_display_key_event_cb);\r
     return ERRCODE_SUCC;\r
 }\r
index 54f57b5..4d419a0 100644 (file)
@@ -93,12 +93,20 @@ SECTIONS
         SORT(*libbms*.a:*.o*) (.data .data* .sdata .sdata*)
         SORT(*libace.a:*.o*) (.data .data* .sdata .sdata*)
         SORT(*liblwip.a:*.o*) (.data .data* .sdata .sdata*)
-        SORT(*libcat1Service.a:*.o*) (.data .data* .sdata .sdata*)
+        SORT(*libcat1*.a:*.o*) (.data .data* .sdata .sdata*)
         SORT(*libppg*.a:*.o*) (.data .data* .sdata .sdata*)
         SORT(*libmag*.a:*.o*) (.data .data* .sdata .sdata*)
         SORT(*libcywee*.a:*.o*) (.data .data* .sdata .sdata*)
         SORT(*libbatterry*.a:*.o*) (.data .data* .sdata .sdata*)
+#ifdef SUPPORT_GNSS
         SORT(*libgnss*.a:*.o*) (.data .data* .sdata .sdata*)
+        SORT(*libpgnss*.a:*.o*) (.data .data* .sdata .sdata*)
+#endif
+        SORT(*librotary*.a:*.o*) (.data .data* .sdata .sdata*)
+        SORT(*libvibrator*.a:*.o*) (.data .data* .sdata .sdata*)
+#ifdef SUPPORT_GYRO_SERVICE
+        SORT(*libgyro*.a:*.o*) (.data .data* .sdata .sdata*)
+#endif
         SORT(*libace_adapt.a:*.o*) (.data .data* .sdata .sdata*)
         SORT(*libace_http*.a:*.o*) (.data .data* .sdata .sdata*)
         SORT(*libnetstack_http*.a:*.o*) (.data .data* .sdata .sdata*)
@@ -133,7 +141,15 @@ SECTIONS
         SORT(*libmag*.a:*.o*) (.bss .bss* .sbss .sbss* COMMON)
         SORT(*libcywee*.a:*.o*) (.bss .bss* .sbss .sbss* COMMON)
         SORT(*libbatterry*.a:*.o*) (.bss .bss* .sbss .sbss* COMMON)
+#ifdef SUPPORT_GNSS
         SORT(*libgnss*.a:*.o*) (.bss .bss* .sbss .sbss* COMMON)
+        SORT(*libpgnss*.a:*.o*) (.bss .bss* .sbss .sbss* COMMON)
+#endif
+        SORT(*librotary*.a:*.o*) (.bss .bss* .sbss .sbss* COMMON)
+        SORT(*libvibrator*.a:*.o*) (.bss .bss* .sbss .sbss* COMMON)
+#ifdef SUPPORT_GYRO_SERVICE
+        SORT(*libgyro*.a:*.o*) (.bss .bss* .sbss .sbss* COMMON)
+#endif
         SORT(*libace_adapt.a:*.o*) (.bss .bss* .sbss .sbss* COMMON)
         SORT(*libace_http*.a:*.o*) (.bss .bss* .sbss .sbss* COMMON)
         SORT(*libnetstack_http*.a:*.o*) (.bss .bss* .sbss .sbss* COMMON)
index 7930646..1ff73a0 100644 (file)
@@ -53,6 +53,7 @@ namespace OHOS
     typedef enum\r
     {\r
         TESTVIEW = 0,     // 系统视图(slice)\r
+        QRCODE,  // 添加二维码视图\r
         VISON,\r
         LCD,\r
         TP,\r
@@ -78,7 +79,6 @@ namespace OHOS
         // pressuretest,\r
         PRESSURETEST,\r
         OLDTEST,\r
-        QRCODE,  // 添加二维码视图\r
         DEEPSLEEP,\r
         \r
         shutdown,\r
index c227524..9e59004 100644 (file)
@@ -920,6 +920,12 @@ namespace OHOS
         {
             switch (hideView)
             {
+            case QRCODE:
+                group->Remove(SystemScrollView[hideView]);
+                delete test_QRCode_view;
+                test_QRCode_view = nullptr;
+                SystemScrollView[hideView] = nullptr;
+                break;
             case VISON:
                 group->Remove(SystemScrollView[hideView]);
                 delete test_about_view;
index 8e6291b..9f60a01 100644 (file)
@@ -144,6 +144,9 @@ void set_save_runtime_log_switch(int value);
 
 int get_save_runtime_log_switch(void);
 
+/*手表是否绑定*/
+bool cm_getisFirstTimeStart(void);
+
 
 #ifdef __cplusplus
 #if __cplusplus
index 730f171..7370ceb 100644 (file)
@@ -1362,6 +1362,11 @@ int cm_getScreenBrightness(void)
    return OHOS::ConfigModel::GetInstance()->GetBrightness();
 }
 
+bool cm_getisFirstTimeStart(void)
+{
+   return OHOS::ConfigModel::GetInstance()->GetisFirstTimeStart();
+}
+
 void cm_initializeScreenDuration(void)
 {
    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "cm_initializeScreenDuration");
index 817da88..3161de5 100644 (file)
@@ -17,7 +17,7 @@ osTimerId_t g_mag_service_timer = NULL;
 static bool g_mag_sensor_exist = false;
 
 static bool g_bat_timer_is_running = false;
-#define MAG_CHECK_MS 40
+#define MAG_CHECK_MS 20
 static unsigned long g_app_queue= 0xFFFFFFFF;
 
 static bool mag_service_running_stat = false;
index 185c382..da7c969 100644 (file)
@@ -1925,7 +1925,7 @@ void pah8009_control(char *mode,uint8_t enable)
 \r
         time_cnt = 0;\r
 \r
-        if(g_pah8009_timer != NULL && work_mode < 3 && work_mode > 0)\r
+        if(g_pah8009_timer != NULL && work_mode < 4 && work_mode > 0)\r
         {\r
             // printf("time_out : %d\n",time_out);\r
             osTimerStart(g_pah8009_timer,time_out);\r
index 912d56b..3794b39 100644 (file)
@@ -12,7 +12,7 @@ set(SOURCES
     ${CMAKE_CURRENT_SOURCE_DIR}/src/uart_gnss.c
     ${CMAKE_CURRENT_SOURCE_DIR}/src/gnss_ctl.c
     ${CMAKE_CURRENT_SOURCE_DIR}/src/NMEA0183.c
-    # ${CMAKE_CURRENT_SOURCE_DIR}/src/gnss_tcp_server.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/gnss_http_server.c
     ${TIOT_SRC_LIST}
 )
 set(PUBLIC_HEADER
diff --git a/code/sdk/zhihui/services/gnss/inc/gnss_http_server.h b/code/sdk/zhihui/services/gnss/inc/gnss_http_server.h
new file mode 100644 (file)
index 0000000..a0d09f0
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * @Author: penglei 1624952103@qq.com
+ * @Date: 2025-02-14 10:30:32
+ * @LastEditors: penglei 1624952103@qq.com
+ * @LastEditTime: 2025-07-17 12:13:52
+ * @FilePath: /sdk615/code/sdk/zhihui/drivers/gnss/service/gnss_ble_service.h
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
+ */
+
+ #ifndef _GNSS_HTTP_SERVER_H_
+ #define _GNSS_HTTP_SERVER_H_
+ 
+ 
+ #ifdef __cplusplus
+ #if __cplusplus
+ extern "C" {
+ #endif /* __cplusplus */
+ #endif /* __cplusplus */
+ 
+ #include "stdint.h"
+ #include "errcode.h"
+ 
+ typedef struct {
+     int cmd;
+     char *data;
+     uint32_t len;
+ } gnss_http_data_mail_t;
+ 
+ 
+ #define GNSS_HTTP_SERVICE_CMD_DATA_UPLOAD 0x1
+ #define GNSS_HTTP_SERVICE_CMD_SERVER_INIT 0x2
+ #define GNSS_HTTP_SERVICE_CMD_SERVER_DEINIT 0x3
+ #define GNSS_HTTP_SERVICE_CMD_DOWNLOAD_AGNSS 0x4
+ #define GNSS_HTTP_SERVICE_CMD_AGNSS_RECV 0x5
+ 
+ 
+ 
+ // void do_gnss_http_server_send_data(int cmd,int *data,uint32_t len);
+ int gnss_http_init(void);
+ errcode_t uapi_gnss_http_server_init(void);
+ int gnss_agnss_get_ephemeris(void);
+ void do_gnss_http_server_send_data(int cmd,char *data,uint32_t len);
+ 
+ #ifdef __cplusplus
+ #if __cplusplus
+ }
+ #endif /* __cplusplus */
+ #endif /* __cplusplus */
+ 
+ #endif /* _GNSS_HTTP_SERVER_H_ */
\ No newline at end of file
diff --git a/code/sdk/zhihui/services/gnss/inc/gnss_tcp_server.h b/code/sdk/zhihui/services/gnss/inc/gnss_tcp_server.h
deleted file mode 100644 (file)
index e67dfcd..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * @Author: penglei 1624952103@qq.com
- * @Date: 2025-02-14 10:30:32
- * @LastEditors: penglei 1624952103@qq.com
- * @LastEditTime: 2025-07-17 12:13:52
- * @FilePath: /sdk615/code/sdk/zhihui/drivers/gnss/service/gnss_ble_service.h
- * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
- */
-
-#ifndef _GNSS_TCP_SERVER_H_
-#define _GNSS_TCP_SERVER_H_
-
-
-#ifdef __cplusplus
-#if __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-#endif /* __cplusplus */
-
-#include "stdint.h"
-#include "errcode.h"
-
-typedef struct {
-    int cmd;
-    char *data;
-    uint32_t len;
-} gnss_tcp_data_mail_t;
-
-
-#define GNSS_TCP_SERVICE_CMD_DATA_UPLOAD 0x1
-#define GNSS_TCP_SERVICE_CMD_SERVER_INIT 0x2
-#define GNSS_TCP_SERVICE_CMD_SERVER_DEINIT 0x3
-
-// void do_gnss_tcp_server_send_data(int cmd,int *data,uint32_t len);
-int gnss_tcp_init(void);
-errcode_t uapi_gnss_tcp_server_init(void);
-int gnss_tcp_sign_up(void);
-
-#ifdef __cplusplus
-#if __cplusplus
-}
-#endif /* __cplusplus */
-#endif /* __cplusplus */
-
-#endif
\ No newline at end of file
index 5d677d4..efe4eb3 100644 (file)
-/*\r
- * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved.\r
- * Description: pgnss encode\r
- * Author:\r
- * Create:\r
- */\r
-#include "pgnss_encode.h"\r
-#include <stdio.h>\r
-#include <dirent.h>\r
-#include <string.h>\r
-#include "securec.h"\r
-#include "tiot_service_interface.h"\r
-#include "gnss_datatypes.h"\r
-\r
-\r
-#define GNSS_ENCODE_BUFF_MAX_LEN 9300\r
-#define FILE_PATH_LEN            1024\r
-#define GLO_EPH_VALID_TIME       900\r
-#define OTHER_EPH_VALID_TIME     7200\r
-#define ONE_CENTURY_YEARS        100\r
-#define FOUR_CENTURY_YEARS       400\r
-#define LEAP_YEAR_LENGTH         4\r
-#define UNIX_TIME_START_YEAR     1970    // start year of unix time\r
-#define TIME_UNIT                1000\r
-#define SECONDS_PER_MIN          (60)\r
-#define SECONDS_PER_HOUR         (60 * SECONDS_PER_MIN)\r
-#define SECONDS_PER_DAY          (24 * SECONDS_PER_HOUR)\r
-#define SECONDS_PER_NORMAL_YEAR  (365 * SECONDS_PER_DAY)\r
-#define NON_GLO_GNSS_TYPES       4\r
-#define GLO_EPH_NUM_ONE_FILE     8\r
-#define OTHER_ASSIST_TYPES       7\r
-#define INJECT_SLEEP_MS_TIME     500\r
-#define PGNSS_FILE_MAX_SIZE      1024000\r
-\r
-/** days per month on normal and leap year */\r
-int32_t g_normMonthDays[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };\r
-int32_t g_leapMonthDays[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };\r
-// 监听消息\r
-static uint8_t g_ackBuff[REPORT_MAX_BYTES] = { 0 };\r
-\r
-/* 获取begin和end年份之间的闰年数 */\r
-int32_t GetLeapYearNum(uint16_t begin, uint16_t end)\r
-{\r
-    if (end <= begin || end < 1) {\r
-        return 0;\r
-    }\r
-    int32_t numPer400Year = (end - 1) / FOUR_CENTURY_YEARS - begin / FOUR_CENTURY_YEARS;\r
-    int32_t numPer100Year = (end - 1) / ONE_CENTURY_YEARS - begin / ONE_CENTURY_YEARS;\r
-    int32_t numPer4Year = (end - 1) / LEAP_YEAR_LENGTH - begin / LEAP_YEAR_LENGTH;\r
-    return (numPer400Year + numPer4Year - numPer100Year);\r
-}\r
-\r
-/* 闰年判断 */\r
-int32_t CheckIfLeapYear(uint16_t year)\r
-{\r
-    if ((year % ONE_CENTURY_YEARS) == 0) {\r
-        if ((year % FOUR_CENTURY_YEARS) == 0) {\r
-            return 1;\r
-        }\r
-    } else {\r
-        if ((year % LEAP_YEAR_LENGTH) == 0) {\r
-            return 1;\r
-        }\r
-    }\r
-    return 0;\r
-}\r
-\r
-/* 将日历时(年月日时分秒) 转换为 unix时间(1970年1月1日起的时间秒数) */\r
-int32_t Utc2UnixTime(GnssUtcTime utcTime, uint32_t *unixTime)\r
-{\r
-    if (unixTime == NULL) {\r
-        printf("\nerror: [Utc2UnixTime] null pointer!\n");\r
-        return 0;\r
-    }\r
-\r
-    if (utcTime.month > 12 || utcTime.valid == 0) {\r
-        printf("\nerror: [Utc2UnixTime] utcTime invalid!\n");\r
-        return 0;\r
-    }\r
-\r
-    // 判断是否为闰年\r
-    int32_t *monthDays = (CheckIfLeapYear(utcTime.year) == 1) ? g_leapMonthDays : g_normMonthDays;\r
-\r
-    // 计算从1970.01.01开始的unix 秒数\r
-    uint32_t timestamp = 0;\r
-    timestamp += (uint32_t)(utcTime.year - UNIX_TIME_START_YEAR) * SECONDS_PER_NORMAL_YEAR;\r
-    timestamp += (uint32_t)GetLeapYearNum(UNIX_TIME_START_YEAR, utcTime.year) * SECONDS_PER_DAY;\r
-\r
-    for (int32_t i = 1; i < utcTime.month; i++) {\r
-        timestamp += (uint32_t)monthDays[i - 1] * SECONDS_PER_DAY;\r
-    }\r
-\r
-    timestamp += (uint32_t)(utcTime.day - 1) * SECONDS_PER_DAY;\r
-    timestamp += (uint32_t)utcTime.hour * SECONDS_PER_HOUR;\r
-    timestamp += (uint32_t)utcTime.minute * SECONDS_PER_MIN;\r
-    uint32_t timestampSec = (uint32_t)(utcTime.second + utcTime.ms / TIME_UNIT);\r
-\r
-    *unixTime = timestamp + timestampSec;\r
-    return 1;\r
-}\r
-\r
-/* 计算命令内容校准和 */\r
-static uint16_t CalcChecksum(uint8_t *buff, uint16_t len)\r
-{\r
-    uint16_t checksum = 0;\r
-    uint16_t i = 0;\r
-    while (i++ < len) {\r
-        checksum += *buff;\r
-        buff++;\r
-    }\r
-    return checksum;\r
-}\r
-\r
-int32_t PgnssInjectUtcTime(tiot_handle handle, GnssUtcTime *utcTime, uint32_t* ts)\r
-{\r
-    uint8_t *buff = (uint8_t *)malloc(GNSS_ENCODE_BUFF_MAX_LEN);\r
-    if (buff == NULL) {\r
-        printf("\nerror: malloc failed in PgnssINjectUtcTime\r\n");\r
-        return 0;\r
-    }\r
-    memset_s(buff, GNSS_ENCODE_BUFF_MAX_LEN, 0, GNSS_ENCODE_BUFF_MAX_LEN);\r
-\r
-    GnssMsg *hdr = (GnssMsg *)buff;\r
-    hdr->cmd = 0x0404;\r
-    hdr->sequence = 0;\r
-    errno_t copyRet = memcpy_s(hdr->data, (GNSS_ENCODE_BUFF_MAX_LEN - sizeof(GnssMsg)), utcTime, sizeof(GnssUtcTime));\r
-    if (copyRet != EOK) {\r
-        printf("\nmemcpy UtcTime failed! Errno is %d\r\n", copyRet);\r
-        free(buff);\r
-        return 0;\r
-    }\r
-    hdr->dataLength = sizeof(GnssUtcTime);\r
-    hdr->checkSum = CalcChecksum(hdr->data, hdr->dataLength);\r
-    int32_t ret = tiot_service_write(handle, buff, (sizeof(GnssMsg) + hdr->dataLength));\r
-    if (ret < 0) {\r
-        printf("\nerror: PgnssInjectUtcTime error: %d\r\n", ret);\r
-        free(buff);\r
-        return 0;\r
-    }\r
-    if (Utc2UnixTime((*utcTime), ts) == 0) {\r
-        printf("\nerror: Utc2UnixTime error\r\n");\r
-        free(buff);\r
-        return 0;\r
-    }\r
-\r
-    free(buff);\r
-    return 1;\r
-}\r
-\r
-static uint16_t FillGnssMessageData(uint8_t *inBuff, uint32_t inLen, uint8_t *outBuff, uint32_t outLen)\r
-{\r
-    errno_t ret = memcpy_s(outBuff, outLen, inBuff, inLen);\r
-    if (ret != EOK) {\r
-        printf("memcpy XgnssData failed! Errno is %d \r\n", ret);\r
-        return 0;\r
-    }\r
-\r
-    return inLen;\r
-}\r
-\r
-static int32_t EncodeGnssMsg(uint8_t *inBuff, uint32_t inLen, uint8_t *outBuff, uint32_t outLen)\r
-{\r
-    uint16_t len = FillGnssMessageData(inBuff, inLen, outBuff, outLen);\r
-    if (len > 0) {\r
-        return 1;\r
-    }\r
-    return 0;\r
-}\r
-\r
-static void ListenAck(tiot_handle handle)\r
-{\r
-    int32_t i = 0;\r
-    for (;;) {\r
-        // 监听\r
-        int32_t ret = tiot_service_read(handle, g_ackBuff, REPORT_MAX_BYTES, LISTEN_TIME_THR);\r
-        if (ret > 0) {\r
-            uint16_t *type = (uint16_t *)g_ackBuff;\r
-            // 二进制消息类型\r
-            if (type[0] == 0) {\r
-                g_ackBuff[ret] = '\0';\r
-                printf("%s\r\n", (char *)&g_ackBuff[MSG_CONTENT_IDX]);\r
-            }\r
-            i++;\r
-        }\r
-        if (i >= 1) {\r
-            printf("\r\ncnt enough\r\n");\r
-            break;\r
-        }\r
-    }\r
-}\r
-\r
-static int32_t EncodeAndInjectCmd(tiot_handle handle, GnssCmdType cmdType, uint8_t* inBuff, uint32_t inLen)\r
-{\r
-    // 获取GNSS业务消息头\r
-    int32_t len = 0;\r
-    uint8_t *buff = (uint8_t *)malloc(GNSS_ENCODE_BUFF_MAX_LEN);\r
-    if (buff == NULL) {\r
-        printf("\r\nerror: malloc failed in EncodeAndInjectCmd\r\n");\r
-        return 0;\r
-    }\r
-    memset_s(buff, GNSS_ENCODE_BUFF_MAX_LEN, 0, GNSS_ENCODE_BUFF_MAX_LEN);\r
-\r
-    GnssMsg *gnssHdr = (GnssMsg *)buff;\r
-    len += sizeof(GnssMsg);\r
-\r
-    gnssHdr->sequence = 0;\r
-\r
-    int32_t retLen = EncodeGnssMsg(inBuff, inLen, buff + len, (GNSS_ENCODE_BUFF_MAX_LEN - len));\r
-    if (retLen != 1) {\r
-        printf("\nerror: Encode Cmd failed: %d\r\n", cmdType);\r
-        free(buff);\r
-        return retLen;\r
-    }\r
-    gnssHdr->cmd = cmdType;\r
-    gnssHdr->dataLength = inLen;\r
-    gnssHdr->checkSum = CalcChecksum(gnssHdr->data, gnssHdr->dataLength);\r
-    int32_t ret = tiot_service_write(handle, buff, (sizeof(GnssMsg) + gnssHdr->dataLength));\r
-    if (ret < 0) {\r
-        printf("\r\nerror: Inject Cmd failed: %d\r\n", cmdType);\r
-        free(buff);\r
-        return 0;\r
-    }\r
-    ListenAck(handle);\r
-    printf("\r\nInject Cmd SUCCESS: %x\r\n", cmdType);\r
-    free(buff);\r
-    return 1;\r
-}\r
-\r
-void PgnssSendFileContent(tiot_handle handle, const char *fileName, GnssCmdType cmdType)\r
-{\r
-    FILE *fp = fopen(fileName, "rb");\r
-    if (fp == NULL) {\r
-        printf("\r\nerror: open file failed: %s\r\n", fileName);\r
-        return;\r
-    }\r
-    fseek(fp, 0, SEEK_END);\r
-    int32_t len = ftell(fp);\r
-    fseek(fp, 0, SEEK_SET);\r
-    if (len < 0 || len > PGNSS_FILE_MAX_SIZE) {\r
-        fclose(fp);\r
-        printf("\r\nerror: get file len failed: %s\r\n", fileName);\r
-        return;\r
-    }\r
-    uint8_t *buff = (uint8_t *)malloc(len);\r
-    if (buff == NULL) {\r
-        fclose(fp);\r
-        printf("\r\nerror: malloc file len failed: %s\r\n", fileName);\r
-        return;\r
-    }\r
-    int32_t dataSize = fread(buff, len, 1, fp);\r
-    if (dataSize < 0) {\r
-        fclose(fp);\r
-        printf("\r\nerror: read file failed: %s\r\n", fileName);\r
-        free(buff);\r
-        return;\r
-    }\r
-    fclose(fp);\r
-    EncodeAndInjectCmd(handle, cmdType, buff, len);\r
-    free(buff);\r
-}\r
-\r
-int32_t FormatFileName(char *fileName, char *dName)\r
-{\r
-    int32_t ret = snprintf_s(fileName, FILE_PATH_LEN, (FILE_PATH_LEN - 1), "%s%s", "/user/userdata/gnss/", dName);\r
-    if (ret <= 0) {\r
-        return 0;\r
-    }\r
-    return 1;\r
-}\r
-\r
-int32_t GetEphFileName(int32_t ts, const char *prefix, char *fileName)\r
-{\r
-    int32_t interval = (strcmp(prefix, "GLO") == 0) ? GLO_EPH_VALID_TIME : OTHER_EPH_VALID_TIME;\r
-    DIR *dir = opendir("/user/userdata/gnss/");\r
-    if (dir == NULL) {\r
-        printf("Failed to open /user/xgnss directory.\r\n");\r
-        return 0;\r
-    }\r
-    int32_t time, ret;\r
-    struct dirent *entry;\r
-    for (entry = readdir(dir); entry != NULL; entry = readdir(dir)) {\r
-        // 检查文件名\r
-        if (strstr(entry->d_name, ".eph") != NULL) {\r
-            char *p = strrchr(entry->d_name, '_');\r
-            if (p != NULL) {\r
-                char *q = strstr(entry->d_name, prefix);\r
-                if (q != NULL) {\r
-                    time = atoi(p + 1);\r
-                    if (abs(time - ts) <= interval) {\r
-                        ret = FormatFileName(fileName, entry->d_name);\r
-                        closedir(dir);\r
-                        return ret;\r
-                    }\r
-                    else\r
-                    {\r
-                        printf("time:%d,ts:%d,interval:%d\r\n",time,ts,interval);\r
-                    }\r
-                }\r
-            }\r
-        }\r
-    }\r
-    closedir(dir);\r
-    printf("closedir(dir);\r\n");\r
-    return 0;\r
-}\r
-\r
-void PgnssSendEphFile(tiot_handle handle, const char *prefix, GnssCmdType cmdType, uint32_t ts)\r
-{\r
-    char fileName[FILE_PATH_LEN] = {0};\r
-    int32_t ret = GetEphFileName(ts, prefix, fileName);\r
-    if (ret == 0) {\r
-        printf("\r\nerror: GetEphFileName failed\r\n");\r
-        return;\r
-    }\r
-    printf("\nGetEphFileName success\r\n");\r
-    PgnssSendFileContent(handle, fileName, cmdType);\r
-}\r
-\r
-void PgnssInjectAllEph(tiot_handle handle, uint32_t ts)\r
-{\r
-    PgnssSendEphFile(handle, "GPS", CMD_PGNSS_INJECT_EPH_GPS, ts);\r
-    osal_msleep(INJECT_SLEEP_MS_TIME);\r
-    printf("send GPS eph success\r\n");\r
-    PgnssSendEphFile(handle, "GLO", CMD_PGNSS_INJECT_EPH_GANSS, ts);\r
-    osal_msleep(INJECT_SLEEP_MS_TIME);\r
-    printf("send GLO eph success\r\n");\r
-    PgnssSendEphFile(handle, "BDS", CMD_PGNSS_INJECT_EPH_GANSS, ts);\r
-    osal_msleep(INJECT_SLEEP_MS_TIME);\r
-    printf("send BDS eph success\r\n");\r
-    PgnssSendEphFile(handle, "GAL", CMD_PGNSS_INJECT_EPH_GANSS, ts);\r
-    osal_msleep(INJECT_SLEEP_MS_TIME);\r
-    printf("send GAL eph success\r\n");\r
-    PgnssSendEphFile(handle, "QZS", CMD_PGNSS_INJECT_EPH_GANSS, ts);\r
-    osal_msleep(INJECT_SLEEP_MS_TIME);\r
-    printf("send QZS eph success\r\n");\r
-}\r
-\r
-void PgnssInjectOtherAssist(tiot_handle handle)\r
-{\r
-    PgnssSendFileContent(handle, "/user/userdata/gnss/GPS_UTC.dat", CMD_PGNSS_INJECT_UTC_GPS);\r
-    osal_msleep(INJECT_SLEEP_MS_TIME);\r
-    printf("send GPS_UTC success\r\n");\r
-    PgnssSendFileContent(handle, "/user/userdata/gnss/GPS_RTI.dat", CMD_PGNSS_INJECT_RTI_GPS);\r
-    osal_msleep(INJECT_SLEEP_MS_TIME);\r
-    printf("send GPS_RTI success\r\n");\r
-    PgnssSendFileContent(handle, "/user/userdata/gnss/GPS_ION.dat", CMD_PGNSS_INJECT_ION_GPS);\r
-    osal_msleep(INJECT_SLEEP_MS_TIME);\r
-    printf("send GPS_ION success\r\n");\r
-    PgnssSendFileContent(handle, "/user/userdata/gnss/GLO_RTI.dat", CMD_PGNSS_INJECT_RTI_GANSS);\r
-    osal_msleep(INJECT_SLEEP_MS_TIME);\r
-    printf("send GLO_RTI success\r\n");\r
-    PgnssSendFileContent(handle, "/user/userdata/gnss/GLO_AUX.dat", CMD_PGNSS_INJECT_AUX_GANSS);\r
-    osal_msleep(INJECT_SLEEP_MS_TIME);\r
-    printf("send GLO_AUX success\r\n");\r
-    PgnssSendFileContent(handle, "/user/userdata/gnss/BDS_RTI.dat", CMD_PGNSS_INJECT_RTI_GANSS);\r
-    osal_msleep(INJECT_SLEEP_MS_TIME);\r
-    printf("send BDS_RTI success\r\n");\r
-    PgnssSendFileContent(handle, "/user/userdata/gnss/GAL_RTI.dat", CMD_PGNSS_INJECT_RTI_GANSS);\r
-    osal_msleep(INJECT_SLEEP_MS_TIME);\r
-    printf("send GAL_RTI success\r\n");\r
-}\r
-\r
-void PgnssInject(tiot_handle handle, uint32_t ts)\r
-{\r
-    // 注入Pgnss辅助数据\r
-    PgnssInjectAllEph(handle, ts);\r
-    PgnssInjectOtherAssist(handle);\r
-}\r
-\r
-\r
-// 以下为使用PGNSS解析数据合并输出接口生成的星历文件进行注入的代码\r
-int32_t GetNonGloEphFileName(int32_t ts, char *fileName)\r
-{\r
-    const char prefix[] = "NonGlo";\r
-    DIR *dir = opendir("/user/userdata/gnss/");\r
-    if (dir == NULL) {\r
-        printf("Failed to open /user/xgnss directory.\r\n");\r
-        return 0;\r
-    }\r
-    int32_t time, ret;\r
-    int32_t minDist = OTHER_EPH_VALID_TIME;\r
-    int32_t closestTime = 0;\r
-    struct dirent *entry;\r
-    for (entry = readdir(dir); entry != NULL; entry = readdir(dir)) {\r
-        // 检查文件名\r
-        if (strstr(entry->d_name, ".eph") != NULL) {\r
-            char *p = strrchr(entry->d_name, '_');\r
-            if (p != NULL) {\r
-                char *q = strstr(entry->d_name, prefix);\r
-                if (q != NULL) {\r
-                    time = atoi(p + 1);\r
-                    // 查找星历文件时间戳与当前时间相差2小时以内且距离最近的\r
-                    if (abs(time - ts) < minDist) {\r
-                        minDist = abs(time - ts);\r
-                        closestTime = time;\r
-                    }\r
-                    else\r
-                    {\r
-                        printf("time:%d,ts:%d,minDist:%d\r\n",time,ts,minDist);\r
-                    }\r
-                }\r
-            }\r
-        }\r
-    }\r
-    if (closestTime != 0) {\r
-        ret = snprintf_s(fileName, FILE_PATH_LEN, (FILE_PATH_LEN - 1), "%s%d%s", "/user/userdata/gnss/NonGlo_", closestTime,\r
-            ".eph");\r
-        printf("closest eph fileName:%s\r\n", fileName);\r
-        closedir(dir);\r
-        return ((ret <= 0) ? 0 : 1);\r
-    }\r
-    else\r
-    {\r
-        printf("closestTime == 0\r\n");\r
-    }\r
-    closedir(dir);\r
-    return 0;\r
-}\r
-\r
-int32_t GetGloEphFileName(int32_t ts, char *fileName)\r
-{\r
-    const char prefix[] = "GLO";\r
-    DIR *dir = opendir("/user/userdata/gnss/");\r
-    if (dir == NULL) {\r
-        printf("Failed to open /user/xgnss directory.\r\n");\r
-        return 0;\r
-    }\r
-    int32_t ephTime, ret;\r
-    struct dirent *entry;\r
-    for (entry = readdir(dir); entry != NULL; entry = readdir(dir)) {\r
-        // 检查文件名\r
-        if (strstr(entry->d_name, ".eph") != NULL) {\r
-            char *p = strrchr(entry->d_name, '_');\r
-            if (p != NULL) {\r
-                char *q = strstr(entry->d_name, prefix);\r
-                if (q != NULL) {\r
-                    ephTime = atoi(p + 1);\r
-                    printf("ephTime:%ld, ts:%ld\n", ephTime, ts);\r
-                    // 当前时间大于GLO星历文件时间戳,则需要选取相差2小时以内的星历\r
-                    // 当前时间小于GLO星历文件时间戳,则需要选取相差小于15分钟的星历\r
-                    if (((ts - ephTime) >= 0 && abs(ephTime - ts) < OTHER_EPH_VALID_TIME) ||\r
-                        ((ts - ephTime) <= 0 && abs(ephTime - ts) < GLO_EPH_VALID_TIME)) {\r
-                        ret = FormatFileName(fileName, entry->d_name);\r
-                        printf("glo eph fileName:%s\n", fileName);\r
-                        closedir(dir);\r
-                        return ret;\r
-                    }\r
-                }\r
-            }\r
-        }\r
-    }\r
-    closedir(dir);\r
-    return 0;\r
-}\r
-\r
-void PgnssSendNonGloEph(tiot_handle handle, const char *fileName)\r
-{\r
-    FILE *fp = fopen(fileName, "rb");\r
-    if (fp == NULL) {\r
-        printf("\nerror: open file failed: %s\r\n", fileName);\r
-        return;\r
-    }\r
-    fseek(fp, 0, SEEK_END);\r
-    int32_t len = ftell(fp);\r
-    fseek(fp, 0, SEEK_SET);\r
-    if (len < 0 || len > PGNSS_FILE_MAX_SIZE) {\r
-        fclose(fp);\r
-        printf("\nerror: get file len failed: %s\r\n", fileName);\r
-        return;\r
-    }\r
-    uint8_t *buff = (uint8_t *)malloc(len);\r
-    if (buff == NULL) {\r
-        fclose(fp);\r
-        printf("\nerror: malloc file len failed: %s\r\n", fileName);\r
-        return;\r
-    }\r
-    int32_t dataSize = fread(buff, len, 1, fp);\r
-    if (dataSize < 0) {\r
-        fclose(fp);\r
-        printf("\nerror: read file failed: %s\r\n", fileName);\r
-        free(buff);\r
-        return;\r
-    }\r
-    fclose(fp);\r
-    int32_t fileLen = 0;\r
-    for (int32_t i = 0; i < NON_GLO_GNSS_TYPES && fileLen <= len; i++) {\r
-        EphHeadInfo *ephHdr = (EphHeadInfo *)(buff + fileLen);\r
-        EncodeAndInjectCmd(handle, ephHdr->cmd, (buff + fileLen + sizeof(EphHeadInfo)), ephHdr->len);\r
-        fileLen += (ephHdr->len + sizeof(EphHeadInfo));\r
-        osal_msleep(INJECT_SLEEP_MS_TIME);\r
-    }\r
-    free(buff);\r
-}\r
-\r
-void PgnssSendGloEph(tiot_handle handle, const char *fileName, int32_t ts)\r
-{\r
-    FILE *fp = fopen(fileName, "rb");\r
-    if (fp == NULL) {\r
-        printf("\nerror: open file failed: %s\r\n", fileName);\r
-        return;\r
-    }\r
-    fseek(fp, 0, SEEK_END);\r
-    int32_t len = ftell(fp);\r
-    fseek(fp, 0, SEEK_SET);\r
-    if (len < 0 || len > PGNSS_FILE_MAX_SIZE) {\r
-        fclose(fp);\r
-        printf("\nerror: get file len failed: %s\r\n", fileName);\r
-        return;\r
-    }\r
-    uint8_t *buff = (uint8_t *)malloc(len);\r
-    if (buff == NULL) {\r
-        fclose(fp);\r
-        printf("\nerror: malloc file len failed: %s\r\n", fileName);\r
-        return;\r
-    }\r
-    int32_t dataSize = fread(buff, len, 1, fp);\r
-    if (dataSize < 0) {\r
-        fclose(fp);\r
-        printf("\nerror: read file failed: %s\r\n", fileName);\r
-        free(buff);\r
-        return;\r
-    }\r
-    fclose(fp);\r
-    int32_t fileLen = 0;\r
-    for (int32_t i = 0; i < GLO_EPH_NUM_ONE_FILE && fileLen <= len; i++) {\r
-        EphHeadInfo *ephHdr = (EphHeadInfo *)(buff + fileLen);\r
-        printf("glo eph, time:%u, ts:%d\r\n", ephHdr->time, ts);\r
-        if (abs((int32_t)ephHdr->time - ts) < GLO_EPH_VALID_TIME) {\r
-            EncodeAndInjectCmd(handle, ephHdr->cmd, (buff + fileLen + sizeof(EphHeadInfo)), ephHdr->len);\r
-            osal_msleep(INJECT_SLEEP_MS_TIME);\r
-            break;\r
-        }\r
-        fileLen += (ephHdr->len + sizeof(EphHeadInfo));\r
-    }\r
-    free(buff);\r
-}\r
-\r
-void PgnssInjectAllEphLessFiles(tiot_handle handle, uint32_t ts)\r
-{\r
-    char fileName[FILE_PATH_LEN] = {0};\r
-    if (GetNonGloEphFileName(ts, fileName) == 0) {\r
-        printf("\nerror: GetNonGloEphFileName failed\r\n");\r
-        return;\r
-    }\r
-    PgnssSendNonGloEph(handle, fileName);\r
-    if (GetGloEphFileName(ts, fileName) == 0) {\r
-        printf("\nerror: GetGloEphFileName failed\r\n");\r
-        return;\r
-    }\r
-    PgnssSendGloEph(handle, fileName, ts);\r
-}\r
-\r
-void PgnssSendOtherAssistInfo(tiot_handle handle, const char *fileName)\r
-{\r
-    FILE *fp = fopen(fileName, "rb");\r
-    if (fp == NULL) {\r
-        printf("\nerror: open file failed: %s\r\n", fileName);\r
-        return;\r
-    }\r
-    fseek(fp, 0, SEEK_END);\r
-    int32_t len = ftell(fp);\r
-    fseek(fp, 0, SEEK_SET);\r
-    if (len < 0 || len > PGNSS_FILE_MAX_SIZE) {\r
-        fclose(fp);\r
-        printf("\nerror: get file len failed: %s\r\n", fileName);\r
-        return;\r
-    }\r
-    uint8_t *buff = (uint8_t *)malloc(len);\r
-    if (buff == NULL) {\r
-        fclose(fp);\r
-        printf("\nerror: malloc file len failed: %s\r\n", fileName);\r
-        return;\r
-    }\r
-    int32_t dataSize = fread(buff, len, 1, fp);\r
-    if (dataSize < 0) {\r
-        fclose(fp);\r
-        printf("\nerror: read file failed: %s\r\n", fileName);\r
-        free(buff);\r
-        return;\r
-    }\r
-    fclose(fp);\r
-    int32_t fileLen = 0;\r
-    for (int32_t i = 0; i < OTHER_ASSIST_TYPES && fileLen <= len; i++) {\r
-        OtherAssistHeadInfo *otherHdr = (OtherAssistHeadInfo *)(buff + fileLen);\r
-        EncodeAndInjectCmd(handle, otherHdr->cmd, (buff + fileLen + sizeof(OtherAssistHeadInfo)), otherHdr->len);\r
-        fileLen += (otherHdr->len + sizeof(OtherAssistHeadInfo));\r
-        osal_msleep(INJECT_SLEEP_MS_TIME);\r
-    }\r
-    free(buff);\r
-}\r
-\r
-void PgnssInjectOtherAssistLessFiles(tiot_handle handle)\r
-{\r
-    PgnssSendOtherAssistInfo(handle, "/user/userdata/gnss/AssistInfo.dat");\r
-}\r
-\r
-// 注入PGNSS解析数据合并输出接口生成的星历文件\r
-void PgnssInjectLessFiles(tiot_handle handle, uint32_t ts)\r
-{\r
-    // 注入Pgnss辅助数据\r
-    PgnssInjectAllEphLessFiles(handle, ts);\r
-    PgnssInjectOtherAssistLessFiles(handle);\r
+/*
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved.
+ * Description: pgnss encode
+ * Author:
+ * Create:
+ */
+#include "pgnss_encode.h"
+#include <stdio.h>
+#include <dirent.h>
+#include <string.h>
+#include "securec.h"
+#include "tiot_service_interface.h"
+#include "gnss_datatypes.h"
+
+
+#define GNSS_ENCODE_BUFF_MAX_LEN 9300
+#define FILE_PATH_LEN            1024
+#define GLO_EPH_VALID_TIME       900
+#define OTHER_EPH_VALID_TIME     7200
+#define ONE_CENTURY_YEARS        100
+#define FOUR_CENTURY_YEARS       400
+#define LEAP_YEAR_LENGTH         4
+#define UNIX_TIME_START_YEAR     1970    // start year of unix time
+#define TIME_UNIT                1000
+#define SECONDS_PER_MIN          (60)
+#define SECONDS_PER_HOUR         (60 * SECONDS_PER_MIN)
+#define SECONDS_PER_DAY          (24 * SECONDS_PER_HOUR)
+#define SECONDS_PER_NORMAL_YEAR  (365 * SECONDS_PER_DAY)
+#define NON_GLO_GNSS_TYPES       4
+#define GLO_EPH_NUM_ONE_FILE     8
+#define OTHER_ASSIST_TYPES       7
+#define INJECT_SLEEP_MS_TIME     500
+#define PGNSS_FILE_MAX_SIZE      1024000
+
+/** days per month on normal and leap year */
+static int32_t g_normMonthDays[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+static int32_t g_leapMonthDays[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+// 监听消息
+static uint8_t g_ackBuff[REPORT_MAX_BYTES] = { 0 };
+
+/* 获取begin和end年份之间的闰年数 */
+int32_t GetLeapYearNum(uint16_t begin, uint16_t end)
+{
+    if (end <= begin || end < 1) {
+        return 0;
+    }
+    int32_t numPer400Year = (end - 1) / FOUR_CENTURY_YEARS - begin / FOUR_CENTURY_YEARS;
+    int32_t numPer100Year = (end - 1) / ONE_CENTURY_YEARS - begin / ONE_CENTURY_YEARS;
+    int32_t numPer4Year = (end - 1) / LEAP_YEAR_LENGTH - begin / LEAP_YEAR_LENGTH;
+    return (numPer400Year + numPer4Year - numPer100Year);
+}
+
+/* 闰年判断 */
+int32_t CheckIfLeapYear(uint16_t year)
+{
+    if ((year % ONE_CENTURY_YEARS) == 0) {
+        if ((year % FOUR_CENTURY_YEARS) == 0) {
+            return 1;
+        }
+    } else {
+        if ((year % LEAP_YEAR_LENGTH) == 0) {
+            return 1;
+        }
+    }
+    return 0;
+}
+
+/* 将日历时(年月日时分秒) 转换为 unix时间(1970年1月1日起的时间秒数) */
+int32_t Utc2UnixTime(GnssUtcTime utcTime, uint32_t *unixTime)
+{
+    if (unixTime == NULL) {
+        printf("\nerror: [Utc2UnixTime] null pointer!\n");
+        return 0;
+    }
+
+    if (utcTime.month > 12 || utcTime.valid == 0) {
+        printf("\nerror: [Utc2UnixTime] utcTime invalid!\n");
+        return 0;
+    }
+
+    // 判断是否为闰年
+    int32_t *monthDays = (CheckIfLeapYear(utcTime.year) == 1) ? g_leapMonthDays : g_normMonthDays;
+
+    // 计算从1970.01.01开始的unix 秒数
+    uint32_t timestamp = 0;
+    timestamp += (uint32_t)(utcTime.year - UNIX_TIME_START_YEAR) * SECONDS_PER_NORMAL_YEAR;
+    timestamp += (uint32_t)GetLeapYearNum(UNIX_TIME_START_YEAR, utcTime.year) * SECONDS_PER_DAY;
+
+    for (int32_t i = 1; i < utcTime.month; i++) {
+        timestamp += (uint32_t)monthDays[i - 1] * SECONDS_PER_DAY;
+    }
+
+    timestamp += (uint32_t)(utcTime.day - 1) * SECONDS_PER_DAY;
+    timestamp += (uint32_t)utcTime.hour * SECONDS_PER_HOUR;
+    timestamp += (uint32_t)utcTime.minute * SECONDS_PER_MIN;
+    uint32_t timestampSec = (uint32_t)(utcTime.second + utcTime.ms / TIME_UNIT);
+
+    *unixTime = timestamp + timestampSec;
+    return 1;
+}
+
+/* 计算命令内容校准和 */
+static uint16_t CalcChecksum(uint8_t *buff, uint16_t len)
+{
+    uint16_t checksum = 0;
+    uint16_t i = 0;
+    while (i++ < len) {
+        checksum += *buff;
+        buff++;
+    }
+    return checksum;
+}
+
+int32_t PgnssInjectUtcTime(tiot_handle handle, GnssUtcTime *utcTime, uint32_t* ts)
+{
+    uint8_t *buff = (uint8_t *)malloc(GNSS_ENCODE_BUFF_MAX_LEN);
+    if (buff == NULL) {
+        printf("\nerror: malloc failed in PgnssINjectUtcTime\r\n");
+        return 0;
+    }
+    memset_s(buff, GNSS_ENCODE_BUFF_MAX_LEN, 0, GNSS_ENCODE_BUFF_MAX_LEN);
+
+    GnssMsg *hdr = (GnssMsg *)buff;
+    hdr->cmd = 0x0404;
+    hdr->sequence = 0;
+    errno_t copyRet = memcpy_s(hdr->data, (GNSS_ENCODE_BUFF_MAX_LEN - sizeof(GnssMsg)), utcTime, sizeof(GnssUtcTime));
+    if (copyRet != EOK) {
+        printf("\nmemcpy UtcTime failed! Errno is %d\r\n", copyRet);
+        free(buff);
+        return 0;
+    }
+    hdr->dataLength = sizeof(GnssUtcTime);
+    hdr->checkSum = CalcChecksum(hdr->data, hdr->dataLength);
+    int32_t ret = tiot_service_write(handle, buff, (sizeof(GnssMsg) + hdr->dataLength));
+    if (ret < 0) {
+        printf("\nerror: PgnssInjectUtcTime error: %d\r\n", ret);
+        free(buff);
+        return 0;
+    }
+    if (Utc2UnixTime((*utcTime), ts) == 0) {
+        printf("\nerror: Utc2UnixTime error\r\n");
+        free(buff);
+        return 0;
+    }
+
+    free(buff);
+    return 1;
+}
+
+static uint16_t FillGnssMessageData(uint8_t *inBuff, uint32_t inLen, uint8_t *outBuff, uint32_t outLen)
+{
+    errno_t ret = memcpy_s(outBuff, outLen, inBuff, inLen);
+    if (ret != EOK) {
+        printf("memcpy XgnssData failed! Errno is %d \r\n", ret);
+        return 0;
+    }
+
+    return inLen;
+}
+
+static int32_t EncodeGnssMsg(uint8_t *inBuff, uint32_t inLen, uint8_t *outBuff, uint32_t outLen)
+{
+    uint16_t len = FillGnssMessageData(inBuff, inLen, outBuff, outLen);
+    if (len > 0) {
+        return 1;
+    }
+    return 0;
+}
+
+static void ListenAck(tiot_handle handle)
+{
+    int32_t i = 0;
+    for (;;) {
+        // 监听
+        int32_t ret = tiot_service_read(handle, g_ackBuff, REPORT_MAX_BYTES, LISTEN_TIME_THR);
+        if (ret > 0) {
+            uint16_t *type = (uint16_t *)g_ackBuff;
+            // 二进制消息类型
+            if (type[0] == 0) {
+                g_ackBuff[ret] = '\0';
+                printf("%s\r\n", (char *)&g_ackBuff[MSG_CONTENT_IDX]);
+            }
+            i++;
+        }
+        if (i >= 1) {
+            printf("\r\ncnt enough\r\n");
+            break;
+        }
+    }
+}
+
+static int32_t EncodeAndInjectCmd(tiot_handle handle, GnssCmdType cmdType, uint8_t* inBuff, uint32_t inLen)
+{
+    // 获取GNSS业务消息头
+    int32_t len = 0;
+    uint8_t *buff = (uint8_t *)malloc(GNSS_ENCODE_BUFF_MAX_LEN);
+    if (buff == NULL) {
+        printf("\r\nerror: malloc failed in EncodeAndInjectCmd\r\n");
+        return 0;
+    }
+    memset_s(buff, GNSS_ENCODE_BUFF_MAX_LEN, 0, GNSS_ENCODE_BUFF_MAX_LEN);
+
+    GnssMsg *gnssHdr = (GnssMsg *)buff;
+    len += sizeof(GnssMsg);
+
+    gnssHdr->sequence = 0;
+
+    int32_t retLen = EncodeGnssMsg(inBuff, inLen, buff + len, (GNSS_ENCODE_BUFF_MAX_LEN - len));
+    if (retLen != 1) {
+        printf("\nerror: Encode Cmd failed: %d\r\n", cmdType);
+        free(buff);
+        return retLen;
+    }
+    gnssHdr->cmd = cmdType;
+    gnssHdr->dataLength = inLen;
+    gnssHdr->checkSum = CalcChecksum(gnssHdr->data, gnssHdr->dataLength);
+    int32_t ret = tiot_service_write(handle, buff, (sizeof(GnssMsg) + gnssHdr->dataLength));
+    if (ret < 0) {
+        printf("\r\nerror: Inject Cmd failed: %d\r\n", cmdType);
+        free(buff);
+        return 0;
+    }
+    ListenAck(handle);
+    printf("\r\nInject Cmd SUCCESS: %x\r\n", cmdType);
+    free(buff);
+    return 1;
+}
+
+void PgnssSendFileContent(tiot_handle handle, const char *fileName, GnssCmdType cmdType)
+{
+    FILE *fp = fopen(fileName, "rb");
+    if (fp == NULL) {
+        printf("\r\nerror: open file failed: %s\r\n", fileName);
+        return;
+    }
+    fseek(fp, 0, SEEK_END);
+    int32_t len = ftell(fp);
+    fseek(fp, 0, SEEK_SET);
+    if (len < 0 || len > PGNSS_FILE_MAX_SIZE) {
+        fclose(fp);
+        printf("\r\nerror: get file len failed: %s\r\n", fileName);
+        return;
+    }
+    uint8_t *buff = (uint8_t *)malloc(len);
+    if (buff == NULL) {
+        fclose(fp);
+        printf("\r\nerror: malloc file len failed: %s\r\n", fileName);
+        return;
+    }
+    int32_t dataSize = fread(buff, len, 1, fp);
+    if (dataSize < 0) {
+        fclose(fp);
+        printf("\r\nerror: read file failed: %s\r\n", fileName);
+        free(buff);
+        return;
+    }
+    fclose(fp);
+    EncodeAndInjectCmd(handle, cmdType, buff, len);
+    free(buff);
+}
+
+int32_t FormatFileName(char *fileName, char *dName)
+{
+    int32_t ret = snprintf_s(fileName, FILE_PATH_LEN, (FILE_PATH_LEN - 1), "%s%s", "/user/userdata/gnss/", dName);
+    if (ret <= 0) {
+        return 0;
+    }
+    return 1;
+}
+
+int32_t GetEphFileName(int32_t ts, const char *prefix, char *fileName)
+{
+    int32_t interval = (strcmp(prefix, "GLO") == 0) ? GLO_EPH_VALID_TIME : OTHER_EPH_VALID_TIME;
+    DIR *dir = opendir("/user/userdata/gnss/");
+    if (dir == NULL) {
+        printf("Failed to open /user/xgnss directory.\r\n");
+        return 0;
+    }
+    int32_t time, ret;
+    struct dirent *entry;
+    for (entry = readdir(dir); entry != NULL; entry = readdir(dir)) {
+        // 检查文件名
+        if (strstr(entry->d_name, ".eph") != NULL) {
+            char *p = strrchr(entry->d_name, '_');
+            if (p != NULL) {
+                char *q = strstr(entry->d_name, prefix);
+                if (q != NULL) {
+                    time = atoi(p + 1);
+                    if (abs(time - ts) <= interval) {
+                        ret = FormatFileName(fileName, entry->d_name);
+                        closedir(dir);
+                        return ret;
+                    }
+                    else
+                    {
+                        printf("time:%d,ts:%d,interval:%d\r\n",time,ts,interval);
+                    }
+                }
+            }
+        }
+    }
+    closedir(dir);
+    printf("closedir(dir);\r\n");
+    return 0;
+}
+
+void PgnssSendEphFile(tiot_handle handle, const char *prefix, GnssCmdType cmdType, uint32_t ts)
+{
+    char fileName[FILE_PATH_LEN] = {0};
+    int32_t ret = GetEphFileName(ts, prefix, fileName);
+    if (ret == 0) {
+        printf("\r\nerror: GetEphFileName failed\r\n");
+        return;
+    }
+    printf("\nGetEphFileName success\r\n");
+    PgnssSendFileContent(handle, fileName, cmdType);
+}
+
+void PgnssInjectAllEph(tiot_handle handle, uint32_t ts)
+{
+    PgnssSendEphFile(handle, "GPS", CMD_PGNSS_INJECT_EPH_GPS, ts);
+    osal_msleep(INJECT_SLEEP_MS_TIME);
+    printf("send GPS eph success\r\n");
+    PgnssSendEphFile(handle, "GLO", CMD_PGNSS_INJECT_EPH_GANSS, ts);
+    osal_msleep(INJECT_SLEEP_MS_TIME);
+    printf("send GLO eph success\r\n");
+    PgnssSendEphFile(handle, "BDS", CMD_PGNSS_INJECT_EPH_GANSS, ts);
+    osal_msleep(INJECT_SLEEP_MS_TIME);
+    printf("send BDS eph success\r\n");
+    PgnssSendEphFile(handle, "GAL", CMD_PGNSS_INJECT_EPH_GANSS, ts);
+    osal_msleep(INJECT_SLEEP_MS_TIME);
+    printf("send GAL eph success\r\n");
+    PgnssSendEphFile(handle, "QZS", CMD_PGNSS_INJECT_EPH_GANSS, ts);
+    osal_msleep(INJECT_SLEEP_MS_TIME);
+    printf("send QZS eph success\r\n");
+}
+
+void PgnssInjectOtherAssist(tiot_handle handle)
+{
+    PgnssSendFileContent(handle, "/user/userdata/gnss/GPS_UTC.dat", CMD_PGNSS_INJECT_UTC_GPS);
+    osal_msleep(INJECT_SLEEP_MS_TIME);
+    printf("send GPS_UTC success\r\n");
+    PgnssSendFileContent(handle, "/user/userdata/gnss/GPS_RTI.dat", CMD_PGNSS_INJECT_RTI_GPS);
+    osal_msleep(INJECT_SLEEP_MS_TIME);
+    printf("send GPS_RTI success\r\n");
+    PgnssSendFileContent(handle, "/user/userdata/gnss/GPS_ION.dat", CMD_PGNSS_INJECT_ION_GPS);
+    osal_msleep(INJECT_SLEEP_MS_TIME);
+    printf("send GPS_ION success\r\n");
+    PgnssSendFileContent(handle, "/user/userdata/gnss/GLO_RTI.dat", CMD_PGNSS_INJECT_RTI_GANSS);
+    osal_msleep(INJECT_SLEEP_MS_TIME);
+    printf("send GLO_RTI success\r\n");
+    PgnssSendFileContent(handle, "/user/userdata/gnss/GLO_AUX.dat", CMD_PGNSS_INJECT_AUX_GANSS);
+    osal_msleep(INJECT_SLEEP_MS_TIME);
+    printf("send GLO_AUX success\r\n");
+    PgnssSendFileContent(handle, "/user/userdata/gnss/BDS_RTI.dat", CMD_PGNSS_INJECT_RTI_GANSS);
+    osal_msleep(INJECT_SLEEP_MS_TIME);
+    printf("send BDS_RTI success\r\n");
+    PgnssSendFileContent(handle, "/user/userdata/gnss/GAL_RTI.dat", CMD_PGNSS_INJECT_RTI_GANSS);
+    osal_msleep(INJECT_SLEEP_MS_TIME);
+    printf("send GAL_RTI success\r\n");
+}
+
+void PgnssInject(tiot_handle handle, uint32_t ts)
+{
+    // 注入Pgnss辅助数据
+    PgnssInjectAllEph(handle, ts);
+    PgnssInjectOtherAssist(handle);
+}
+
+
+// 以下为使用PGNSS解析数据合并输出接口生成的星历文件进行注入的代码
+// 全局变量,存储AGNSS文件夹路径
+static char *g_agnss_folder_path = NULL;
+
+// 新增接口:设置AGNSS文件夹路径
+void set_agnss_folder_path(const char *path)
+{
+    if (g_agnss_folder_path != NULL) {
+        free(g_agnss_folder_path);
+        g_agnss_folder_path = NULL;
+    }
+    if (path != NULL) {
+        g_agnss_folder_path = strdup(path);
+    }
+}
+
+// 新增接口:获取AGNSS文件夹路径
+const char* get_agnss_folder_path(void)
+{
+    return g_agnss_folder_path != NULL ? g_agnss_folder_path : "/user/userdata/gnss";
+}
+
+// 新增接口:清理AGNSS文件夹路径
+void cleanup_pgnss_encode_agnss_folder_path(void)
+{
+    if (g_agnss_folder_path != NULL) {
+        free(g_agnss_folder_path);
+        g_agnss_folder_path = NULL;
+    }
+}
+
+int32_t GetNonGloEphFileName(int32_t ts, char *fileName)
+{
+    const char prefix[] = "NonGlo";
+    const char *search_path = get_agnss_folder_path();
+    if(search_path == NULL)
+    {
+        printf("search_path == NULL\r\n");
+        return 0;
+    }
+    DIR *dir = opendir(search_path);
+    if (dir == NULL) {
+        printf("Failed to open directory: %s\r\n", search_path);
+        return 0;
+    }
+    int32_t time, ret;
+    int32_t minDist = OTHER_EPH_VALID_TIME;
+    int32_t closestTime = 0;
+    struct dirent *entry;
+    for (entry = readdir(dir); entry != NULL; entry = readdir(dir)) {
+        // 检查文件名
+        if (strstr(entry->d_name, ".eph") != NULL) {
+            char *p = strrchr(entry->d_name, '_');
+            if (p != NULL) {
+                char *q = strstr(entry->d_name, prefix);
+                if (q != NULL) {
+                    time = atoi(p + 1);
+                    // 查找星历文件时间戳与当前时间相差2小时以内且距离最近的
+                    if (abs(time - ts) < minDist) {
+                        minDist = abs(time - ts);
+                        closestTime = time;
+                    }
+                    else
+                    {
+                        printf("time:%d,ts:%d,minDist:%d\r\n",time,ts,minDist);
+                    }
+                }
+            }
+        }
+    }
+    if (closestTime != 0) {
+        ret = snprintf_s(fileName, FILE_PATH_LEN, (FILE_PATH_LEN - 1), "%s/NonGlo_%d.eph", search_path, closestTime);
+        printf("closest eph fileName:%s\r\n", fileName);
+        closedir(dir);
+        return ((ret <= 0) ? 0 : 1);
+    }
+    else
+    {
+        printf("closestTime == 0\r\n");
+    }
+    closedir(dir);
+    return 0;
+}
+
+int32_t GetGloEphFileName(int32_t ts, char *fileName)
+{
+    const char prefix[] = "GLO";
+    const char *search_path = get_agnss_folder_path();
+    if(search_path == NULL)
+    {
+        printf("search_path == NULL\r\n");
+        return 0;
+    }
+    DIR *dir = opendir(search_path);
+    if (dir == NULL) {
+        printf("search_path open failed %s\r\n", search_path);
+        return 0;
+    }
+    int32_t ephTime, ret;
+    struct dirent *entry;
+    for (entry = readdir(dir); entry != NULL; entry = readdir(dir)) {
+        // 检查文件名
+        if (strstr(entry->d_name, ".eph") != NULL) {
+            char *p = strrchr(entry->d_name, '_');
+            if (p != NULL) {
+                char *q = strstr(entry->d_name, prefix);
+                if (q != NULL) {
+                    ephTime = atoi(p + 1);
+                    printf("ephTime:%ld, ts:%ld\n", ephTime, ts);
+                    // 当前时间大于GLO星历文件时间戳,则需要选取相差2小时以内的星历
+                    // 当前时间小于GLO星历文件时间戳,则需要选取相差小于15分钟的星历
+                    if (((ts - ephTime) >= 0 && abs(ephTime - ts) < OTHER_EPH_VALID_TIME) ||
+                        ((ts - ephTime) <= 0 && abs(ephTime - ts) < GLO_EPH_VALID_TIME)) {
+                        ret = FormatFileName(fileName, entry->d_name);
+                        printf("glo eph fileName:%s\n", fileName);
+                        closedir(dir);
+                        return ret;
+                    }
+                }
+            }
+        }
+    }
+    closedir(dir);
+    return 0;
+}
+
+void PgnssSendNonGloEph(tiot_handle handle, const char *fileName)
+{
+    FILE *fp = fopen(fileName, "rb");
+    if (fp == NULL) {
+        printf("\nerror: open file failed: %s\r\n", fileName);
+        return;
+    }
+    fseek(fp, 0, SEEK_END);
+    int32_t len = ftell(fp);
+    fseek(fp, 0, SEEK_SET);
+    if (len < 0 || len > PGNSS_FILE_MAX_SIZE) {
+        fclose(fp);
+        printf("\nerror: get file len failed: %s\r\n", fileName);
+        return;
+    }
+    uint8_t *buff = (uint8_t *)malloc(len);
+    if (buff == NULL) {
+        fclose(fp);
+        printf("\nerror: malloc file len failed: %s\r\n", fileName);
+        return;
+    }
+    int32_t dataSize = fread(buff, len, 1, fp);
+    if (dataSize < 0) {
+        fclose(fp);
+        printf("\nerror: read file failed: %s\r\n", fileName);
+        free(buff);
+        return;
+    }
+    fclose(fp);
+    int32_t fileLen = 0;
+    for (int32_t i = 0; i < NON_GLO_GNSS_TYPES && fileLen <= len; i++) {
+        EphHeadInfo *ephHdr = (EphHeadInfo *)(buff + fileLen);
+        EncodeAndInjectCmd(handle, ephHdr->cmd, (buff + fileLen + sizeof(EphHeadInfo)), ephHdr->len);
+        fileLen += (ephHdr->len + sizeof(EphHeadInfo));
+        osal_msleep(INJECT_SLEEP_MS_TIME);
+    }
+    free(buff);
+}
+
+void PgnssSendGloEph(tiot_handle handle, const char *fileName, int32_t ts)
+{
+    FILE *fp = fopen(fileName, "rb");
+    if (fp == NULL) {
+        printf("\nerror: open file failed: %s\r\n", fileName);
+        return;
+    }
+    fseek(fp, 0, SEEK_END);
+    int32_t len = ftell(fp);
+    fseek(fp, 0, SEEK_SET);
+    if (len < 0 || len > PGNSS_FILE_MAX_SIZE) {
+        fclose(fp);
+        printf("\nerror: get file len failed: %s\r\n", fileName);
+        return;
+    }
+    uint8_t *buff = (uint8_t *)malloc(len);
+    if (buff == NULL) {
+        fclose(fp);
+        printf("\nerror: malloc file len failed: %s\r\n", fileName);
+        return;
+    }
+    int32_t dataSize = fread(buff, len, 1, fp);
+    if (dataSize < 0) {
+        fclose(fp);
+        printf("\nerror: read file failed: %s\r\n", fileName);
+        free(buff);
+        return;
+    }
+    fclose(fp);
+    int32_t fileLen = 0;
+    for (int32_t i = 0; i < GLO_EPH_NUM_ONE_FILE && fileLen <= len; i++) {
+        EphHeadInfo *ephHdr = (EphHeadInfo *)(buff + fileLen);
+        printf("glo eph, time:%u, ts:%d\r\n", ephHdr->time, ts);
+        if (abs((int32_t)ephHdr->time - ts) < GLO_EPH_VALID_TIME) {
+            EncodeAndInjectCmd(handle, ephHdr->cmd, (buff + fileLen + sizeof(EphHeadInfo)), ephHdr->len);
+            osal_msleep(INJECT_SLEEP_MS_TIME);
+            break;
+        }
+        fileLen += (ephHdr->len + sizeof(EphHeadInfo));
+    }
+    free(buff);
+}
+
+int32_t PgnssInjectAllEphLessFiles(tiot_handle handle, uint32_t ts)
+{
+    char fileName[FILE_PATH_LEN] = {0};
+    if (GetNonGloEphFileName(ts, fileName) == 0) {
+        printf("\nerror: GetNonGloEphFileName failed\r\n");
+        return 0;  // 返回失败状态
+    }
+    PgnssSendNonGloEph(handle, fileName);
+    if (GetGloEphFileName(ts, fileName) == 0) {
+        printf("\nerror: GetGloEphFileName failed\r\n");
+        return 0;  // 返回失败状态
+    }
+    PgnssSendGloEph(handle, fileName, ts);
+    return 1;  // 返回成功状态
+}
+
+void PgnssSendOtherAssistInfo(tiot_handle handle, const char *fileName)
+{
+    FILE *fp = fopen(fileName, "rb");
+    if (fp == NULL) {
+        printf("\nerror: open file failed: %s\r\n", fileName);
+        return;
+    }
+    fseek(fp, 0, SEEK_END);
+    int32_t len = ftell(fp);
+    fseek(fp, 0, SEEK_SET);
+    if (len < 0 || len > PGNSS_FILE_MAX_SIZE) {
+        fclose(fp);
+        printf("\nerror: get file len failed: %s\r\n", fileName);
+        return;
+    }
+    uint8_t *buff = (uint8_t *)malloc(len);
+    if (buff == NULL) {
+        fclose(fp);
+        printf("\nerror: malloc file len failed: %s\r\n", fileName);
+        return;
+    }
+    int32_t dataSize = fread(buff, len, 1, fp);
+    if (dataSize < 0) {
+        fclose(fp);
+        printf("\nerror: read file failed: %s\r\n", fileName);
+        free(buff);
+        return;
+    }
+    fclose(fp);
+    int32_t fileLen = 0;
+    for (int32_t i = 0; i < OTHER_ASSIST_TYPES && fileLen <= len; i++) {
+        OtherAssistHeadInfo *otherHdr = (OtherAssistHeadInfo *)(buff + fileLen);
+        EncodeAndInjectCmd(handle, otherHdr->cmd, (buff + fileLen + sizeof(OtherAssistHeadInfo)), otherHdr->len);
+        fileLen += (otherHdr->len + sizeof(OtherAssistHeadInfo));
+        osal_msleep(INJECT_SLEEP_MS_TIME);
+    }
+    free(buff);
+}
+
+int32_t PgnssInjectOtherAssistLessFiles(tiot_handle handle)
+{
+    char *assist_file_path = malloc(256);
+    if (assist_file_path == NULL) {
+        printf("Failed to allocate memory for assist file path\n");
+        return 0;
+    }
+    
+    const char *agnss_folder_path = get_agnss_folder_path();
+    int ret = snprintf(assist_file_path, 256, "%s/AssistInfo.dat", agnss_folder_path);
+    if (ret < 0 || ret >= 256) {
+        printf("ERROR: snprintf failed or buffer overflow for assist_file_path\n");
+        free(assist_file_path);
+        return 0;
+    }
+    PgnssSendOtherAssistInfo(handle, assist_file_path);
+    
+    free(assist_file_path);
+    return 1;  // 返回成功状态
+}
+
+// 注入PGNSS解析数据合并输出接口生成的星历文件
+int32_t PgnssInjectLessFiles(tiot_handle handle, uint32_t ts, const char *agnss_folder_path)
+{
+    // 设置AGNSS文件夹路径
+    set_agnss_folder_path(agnss_folder_path);
+    
+    // 注入Pgnss辅助数据
+    int32_t ephRet = PgnssInjectAllEphLessFiles(handle, ts);
+    int32_t assistRet = PgnssInjectOtherAssistLessFiles(handle);
+    
+    // 如果星历注入失败,返回失败状态
+    if (ephRet == 0) {
+        printf("PGNSS ephemeris injection failed\r\n");
+        return 0;
+    }
+    
+    return 1;  // 返回成功状态
 }
\ No newline at end of file
index a666edc..8456ef0 100644 (file)
@@ -1,16 +1,21 @@
-/*\r
- * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved.\r
- * Description: pgnss encode\r
- * Author:\r
- * Create:\r
- */\r
-#ifndef PGNSS_ENCODE_H\r
-#define PGNSS_ENCODE_H\r
-\r
-#include "gnss_datatypes.h"\r
-#include "tiot_service_interface.h"\r
-\r
-int32_t PgnssInjectUtcTime(tiot_handle handle, GnssUtcTime *utcTime, uint32_t* ts);\r
-void PgnssInject(tiot_handle handle, uint32_t ts);\r
-void PgnssInjectLessFiles(tiot_handle handle, uint32_t ts);\r
+/*
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved.
+ * Description: pgnss encode
+ * Author:
+ * Create:
+ */
+#ifndef PGNSS_ENCODE_H
+#define PGNSS_ENCODE_H
+
+#include "gnss_datatypes.h"
+#include "tiot_service_interface.h"
+
+int32_t PgnssInjectUtcTime(tiot_handle handle, GnssUtcTime *utcTime, uint32_t* ts);
+void PgnssInject(tiot_handle handle, uint32_t ts);
+int32_t PgnssInjectLessFiles(tiot_handle handle, uint32_t ts, const char *agnss_folder_path);
+
+// 新增接口:获取时间戳文件夹路径
+const char* get_agnss_folder_path(void);
+void set_agnss_folder_path(const char *path);
+void cleanup_pgnss_encode_agnss_folder_path(void);
 #endif
\ No newline at end of file
index a97b078..9843b91 100644 (file)
-/*\r
- * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved.\r
- * Description: pgnss sample\r
- * Author:\r
- * Create:\r
- */\r
-#include "pgnss_sample.h"\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <string.h>\r
-#include <stdlib.h>\r
-#include <string.h>\r
-#include "securec.h"\r
-#include "tiot_service_interface.h"\r
-#include "pm_definition.h"\r
-#include "gnss_datatypes.h"\r
-#include "pgnss_encode.h"\r
-#include "NMEA0183.h"\r
-#include "sys/time.h"\r
-#include "time.h"\r
-#include "gnss_ctl.h"\r
-\r
-\r
-#define PGNSS_FIXMODEALL_NMEADEF_SAMPLE            0\r
-#define PGNSS_LESS_FILES_FIXMODEALL_NMEADEF_SAMPLE 0\r
-\r
-#ifndef ARRAY_SIZE\r
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))\r
-#endif\r
-#define MSG_TYPE_BINRY              0\r
-#define MSG_TYPE_ASCII              1\r
-#define LISTEN_DATA_MAX_LINES       1000\r
-\r
-static FILE* g_gnssLogFp = NULL;\r
-static uint8_t g_gnssServiceBuff[REPORT_MAX_BYTES] = { 0 };\r
-\r
-typedef int32_t (*GnssCfgFunc)(tiot_handle handle);\r
-\r
-typedef struct {\r
-    uint16_t    sampleId;\r
-    GnssCfgFunc cfgHandle;\r
-} GnssSamplesCfgTable;\r
-\r
-static NMEA0183 g_nmeadata={0};\r
-static gps_data_t g_global_gpsData={0};\r
-\r
-/**GPS状态位*/\r
-static int g_is_pgnss_poweron=0;\r
-static int g_is_pgnss_logon=0;\r
-static int g_pgnss_stopflag=0;\r
-\r
-static char *pgnss_log = NULL;\r
-\r
-static int32_t QryVersion(tiot_handle handle)\r
-{\r
-    const uint8_t qryVersion[] = {0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00};\r
-    // 查询版本号\r
-    int32_t ret = tiot_service_write(handle, qryVersion, sizeof(qryVersion));\r
-    if (ret < 0) {\r
-        printf("\nerror: QryVersion error: %d\r\n", ret);\r
-        return 0;\r
-    }\r
-    return 1;\r
-}\r
-\r
-static int decode_nmea(char c)\r
-{\r
-    int ret=0;\r
-    ret=0;\r
-    if(nmea_decode(&g_nmeadata,c) ==1 ) ///调用解析函数\r
-    {\r
-        dump_nmea_str(&(g_nmeadata.gpsParse));\r
-        if (g_nmeadata.gpsParse.sentence_type == GPS_SENTENCE_TH002 )\r
-        {\r
-            //一组数据最后一条\r
-            memcpy_s(&g_global_gpsData,sizeof(gps_data_t),&(g_nmeadata.gpsData),sizeof(gps_data_t));\r
-            ret = 1;\r
-            memset(&g_nmeadata,0,sizeof(g_nmeadata));\r
-        }\r
-    } \r
-\r
-    return ret;\r
-}\r
-\r
-gps_data_t * getPGPSGlobaldata(void)\r
-{\r
-    return &g_global_gpsData;\r
-}\r
-\r
-\r
-// 注入PGNSS,使用默认配置启动\r
-int32_t InjectPgnssCfgAutoStartFixModeAndNmeaDefault(tiot_handle handle)\r
-{\r
-    const uint8_t cfgLogLevelInfo[] = {0x03, 0x00, 0x15, 0x00, 0x00, 0x00, 0x05, 0x00, 0x01, 0x10, 0x01, 0x00, 0x03};\r
-\r
-    // 配置log级别:info级别。\r
-    int32_t ret = tiot_service_write(handle, cfgLogLevelInfo, sizeof(cfgLogLevelInfo));\r
-    if (ret < 0) {\r
-        printf("\nerror: cfgLogLevelInfo error: %d\r\n", ret);\r
-        return 0;\r
-    }\r
-\r
-    // 注入UTC时间, 注入Pgnss辅助数据前必须先注入参考时间\r
-    GnssUtcTime utcTime = {2024, 2, 26, 6, 0, 0, 0, 1}; // 需要用当前的UTC时间替换\r
-\r
-    time_t rawtime;\r
-    struct tm* timeinfo;\r
-\r
-    time(&rawtime);          // 获取UTC时间戳\r
-    timeinfo = gmtime(&rawtime);  // 转换为UTC时间(无时区偏移)\r
-\r
-    utcTime.year = timeinfo->tm_year + 1900;\r
-    utcTime.month = timeinfo->tm_mon + 1;\r
-    utcTime.day = timeinfo->tm_mday;\r
-    utcTime.hour = timeinfo->tm_hour;\r
-    utcTime.minute = timeinfo->tm_min;\r
-    utcTime.second = timeinfo->tm_sec;\r
-\r
-    printf("year[%d], mon[%d], day[%d], hour[%d], min[%d], sec[%d] \r\n",\r
-    utcTime.year,utcTime.month,utcTime.day,\r
-    utcTime.hour,utcTime.minute,utcTime.second);\r
-\r
-    uint32_t ts = 0;\r
-    ret = PgnssInjectUtcTime(handle, &utcTime, &ts);\r
-    if (ret == 0) {\r
-        printf("\nerror: PgnssInjectUtcTime failed!\r\n");\r
-        return 0;\r
-    }\r
-    printf("\nPgnssInjectUtcTime success!\r\n");\r
-\r
-    // PGNSS注入\r
-    // 注意,默认PGNSS星历文件存放在/user/xgnss/目录中,如修改目录,请全局搜索替换\r
-    PgnssInject(handle, ts);\r
-\r
-    return 1;\r
-}\r
-\r
-// 注入PGNSS,使用默认配置启动\r
-int32_t InjectPgnssLessFilesCfgAutoStartFixModeAndNmeaDefault(tiot_handle handle)\r
-{\r
-    const uint8_t cfgLogLevelInfo[] = {0x03, 0x00, 0x15, 0x00, 0x00, 0x00, 0x05, 0x00, 0x01, 0x10, 0x01, 0x00, 0x03};\r
-\r
-    // 配置log级别:info级别。\r
-    int32_t ret = tiot_service_write(handle, cfgLogLevelInfo, sizeof(cfgLogLevelInfo));\r
-    if (ret < 0) {\r
-        printf("\nerror: cfgLogLevelInfo error: %d\r\n", ret);\r
-        return 0;\r
-    }\r
-\r
-    // 注入UTC时间, 注入Pgnss辅助数据前必须先注入参考时间\r
-    GnssUtcTime utcTime = {2024, 3, 14, 12, 0, 0, 0, 1}; // 需要用当前的UTC时间替换\r
-\r
-    time_t rawtime;\r
-    struct tm* timeinfo;\r
-\r
-    time(&rawtime);          // 获取UTC时间戳\r
-    timeinfo = gmtime(&rawtime);  // 转换为UTC时间(无时区偏移)\r
-\r
-    utcTime.year = timeinfo->tm_year + 1900;\r
-    utcTime.month = timeinfo->tm_mon + 1;\r
-    utcTime.day = timeinfo->tm_mday;\r
-    utcTime.hour = timeinfo->tm_hour;\r
-    utcTime.minute = timeinfo->tm_min;\r
-    utcTime.second = timeinfo->tm_sec;\r
-\r
-    printf("year[%d], mon[%d], day[%d], hour[%d], min[%d], sec[%d] \r\n",\r
-    utcTime.year,utcTime.month,utcTime.day,\r
-    utcTime.hour,utcTime.minute,utcTime.second);\r
-\r
-\r
-    uint32_t ts = 0;\r
-    ret = PgnssInjectUtcTime(handle, &utcTime, &ts);\r
-    if (ret == 0) {\r
-        printf("\nerror: PgnssInjectUtcTime failed!\r\n");\r
-        return 0;\r
-    }\r
-    printf("\nPgnssInjectUtcTime success!\r\n");\r
-\r
-    // PGNSS注入\r
-    // 注意,默认PGNSS星历文件存放在/user/xgnss/目录中,如修改目录,请全局搜索替换\r
-    PgnssInjectLessFiles(handle, ts);\r
-\r
-    return 1;\r
-}\r
-\r
-static const GnssSamplesCfgTable g_gnssSamplesCfg[] = {\r
-    // {PGNSS_FIXMODEALL_NMEADEF_SAMPLE,            InjectPgnssCfgAutoStartFixModeAndNmeaDefault},\r
-    {PGNSS_LESS_FILES_FIXMODEALL_NMEADEF_SAMPLE, InjectPgnssLessFilesCfgAutoStartFixModeAndNmeaDefault}\r
-};\r
-\r
-static int32_t StartGnss(tiot_handle handle)\r
-{\r
-    const uint8_t startCmd[] = {0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00,\r
-        0x01, 0x00, 0x00, 0x00, 0x00, 0x00};\r
-    // 启动GNSS\r
-    int32_t ret = tiot_service_write(handle, startCmd, sizeof(startCmd));\r
-    if (ret < 0) {\r
-        printf("\nerror: start gnss error: %d\r\n", ret);\r
-        return 0;\r
-    }\r
-    printf("\nstart gnss\r\n");\r
-    return 1;\r
-}\r
-\r
-static int32_t StopGnss(tiot_handle handle)\r
-{\r
-    const uint8_t stopCmd[] = {0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};\r
-    // 停止GNSS\r
-    int32_t ret = tiot_service_write(handle, stopCmd, sizeof(stopCmd));\r
-    if (ret < 0) {\r
-        printf("\nerror: stop gnss error: %d\r\n", ret);\r
-        return 0;\r
-    }\r
-    printf("\nstop gnss\r\n");\r
-    return 1;\r
-}\r
-\r
-\r
-static void ListenGnssData(tiot_handle handle)\r
-{\r
-    int32_t i = 0;\r
-    // 写日志\r
-    for (;;) {  // 写日志条件\r
-\r
-        if (i >= LISTEN_DATA_MAX_LINES) {\r
-            printf("\r\ncnt enough\r\n");\r
-            break;\r
-        }\r
-        if (g_pgnss_stopflag == 1)\r
-        {\r
-            break;\r
-        }\r
-        // 监听\r
-        int32_t ret = tiot_service_read(handle, g_gnssServiceBuff, REPORT_MAX_BYTES, LISTEN_TIME_THR);\r
-        if (ret > 0) {\r
-            uint16_t *type = (uint16_t *)g_gnssServiceBuff;\r
-            if (type[0] == MSG_TYPE_ASCII) {\r
-                g_gnssServiceBuff[ret] = '\0';\r
-                char* pbuf=(char *)&g_gnssServiceBuff[MSG_CONTENT_IDX];\r
-                printf("%s\r\n", pbuf);\r
-                if (g_is_pgnss_logon)\r
-                    fprintf(g_gnssLogFp, "%s\n", pbuf);\r
-                for (int index=0;index < ret ;index++)\r
-                {\r
-                    if (decode_nmea(pbuf[index])==1)\r
-                    {\r
-                        // dump_location_data(&g_global_gpsData);\r
-                        char temp_buf[512];\r
-                        dump_location_data_to_buf(&g_global_gpsData, temp_buf, sizeof(temp_buf));\r
-                        \r
-                        // 追加到pgnss_log中\r
-                        if (pgnss_log != NULL) {\r
-                            int current_len = strlen(pgnss_log);\r
-                            int data_len = strlen(temp_buf);\r
-                            if (current_len + data_len < 2047) {  // 留1字节给字符串结束符\r
-                                snprintf(pgnss_log + current_len, 2048 - current_len, "%s", temp_buf);\r
-                            }\r
-                        }\r
-                        \r
-                        printf("decode_nmea done\r\n");\r
-                    }\r
-                }\r
-            }\r
-            i++;\r
-        }\r
-\r
-    }\r
-}\r
-\r
-void PGnssServerStop(void)\r
-{\r
-    g_pgnss_stopflag=1;\r
-}\r
-\r
-int getPGnssServerStat(void)\r
-{\r
-    return g_is_pgnss_poweron;\r
-}\r
-\r
-int is_PGnssLogEnabled(void)\r
-{\r
-    return g_is_pgnss_logon;\r
-}\r
-\r
-int PGnssLogEnable(bool enable)\r
-{\r
-    if (enable)\r
-        g_is_pgnss_logon = 1;\r
-    else\r
-        g_is_pgnss_logon = 0;\r
-\r
-    return g_is_pgnss_logon;\r
-}\r
-\r
-\r
-void PGnssServerStart(void)\r
-{\r
-    printf("\nenter gnss samples\r\n");\r
-    \r
-    if (pgnss_log == NULL) \r
-    {\r
-        pgnss_log = (char *)malloc(2048);\r
-        if (pgnss_log == NULL) {\r
-            printf("error: malloc pgnss_log failed!\n");\r
-            return;\r
-        }\r
-        memset(pgnss_log, 0, 2048);\r
-    }\r
-\r
-    if(g_is_pgnss_poweron == 1)\r
-    {\r
-        printf("gnss already on\r\n");\r
-        if (pgnss_log != NULL) {\r
-            free(pgnss_log);\r
-            pgnss_log = NULL;\r
-        }\r
-        return ;\r
-    }\r
-    uapi_pm_add_sleep_veto(PM_ID_SYS);\r
-\r
-    #ifdef DOWNLOAD_GNSS_SWITCH\r
-    download_gnss_switch(SWITCH_TO_GNSS);\r
-    #endif\r
-    g_is_pgnss_poweron = 1;\r
-    g_pgnss_stopflag = 0;\r
-    sw_debug_uart_deinit();\r
-    // Step1: init\r
-    int32_t ret = tiot_service_init();\r
-    if (ret != 0) {\r
-        printf("tiot service init fail\r\n");\r
-        g_is_pgnss_poweron = 0;\r
-        g_pgnss_stopflag = 1;\r
-        if (pgnss_log != NULL) {\r
-            free(pgnss_log);\r
-            pgnss_log = NULL;\r
-        }\r
-        return;\r
-    }\r
-\r
-    // 打开日志文件\r
-    if (g_is_pgnss_logon)\r
-    {\r
-        g_gnssLogFp = fopen("/user/log/gnss.log", "w");\r
-        if (g_gnssLogFp == NULL) {\r
-            printf("error: open log file error\n");\r
-            if (pgnss_log != NULL) {\r
-                free(pgnss_log);\r
-                pgnss_log = NULL;\r
-            }\r
-            return;\r
-        }\r
-    }\r
-    printf("before open tiot service\n");\r
-\r
-    // Step2: power on gnss\r
-    tiot_handle handle = tiot_service_open("gn71", NULL);\r
-    if (handle == 0) {\r
-        printf("open tiot service fail\r\n");\r
-        g_is_pgnss_poweron = 0;\r
-        g_pgnss_stopflag = 1;\r
-        if (pgnss_log != NULL) {\r
-            free(pgnss_log);\r
-            pgnss_log = NULL;\r
-        }\r
-        return;\r
-    }\r
-    printf("open tiot service success\r\n");\r
-\r
-    int32_t cfgRet;\r
-    // ---- loop ----------\r
-    for (uint16_t i = 0; i < ARRAY_SIZE(g_gnssSamplesCfg); i++) {\r
-        cfgRet = 0;\r
-        if (g_gnssSamplesCfg[i].sampleId == i) {\r
-            // Step3: config gnss\r
-            if (g_gnssSamplesCfg[i].cfgHandle != NULL) {\r
-                cfgRet = g_gnssSamplesCfg[i].cfgHandle(handle);\r
-            }\r
-            if (cfgRet == 0) {\r
-                continue;\r
-            }\r
-            printf("cfg sample id:%u\r\n", g_gnssSamplesCfg[i].sampleId);\r
-            QryVersion(handle);\r
-\r
-            // Step4: start gnss\r
-            if (StartGnss(handle) == 0) {\r
-                continue;\r
-            }\r
-            // Step5: listening gnss data\r
-            ListenGnssData(handle);\r
-            // Step6: stop gnss\r
-            if (StopGnss(handle) == 0) {\r
-                continue;\r
-            }\r
-        }\r
-    }\r
-    // ---------------------\r
-    // Step7: power off gnss\r
-    tiot_service_close(handle);\r
-    // 关日志文件\r
-    if (g_is_pgnss_logon)\r
-    {\r
-        fclose(g_gnssLogFp);\r
-        g_gnssLogFp = NULL;\r
-    }\r
-    // Step8: deinit\r
-    tiot_service_deinit();\r
-\r
-    #ifdef DOWNLOAD_GNSS_SWITCH\r
-    download_gnss_switch(SWITCH_TO_DOWNLOAD);\r
-    #endif\r
-    uapi_pm_remove_sleep_veto(PM_ID_SYS);\r
-    g_is_pgnss_poweron=0;\r
-    sw_debug_uart_deinit();\r
-    uart_config_init();\r
-    printf("finish gnss samples\r\n");\r
-    \r
-    printf("pgnss_log: %s\r\n", pgnss_log);\r
-    // 释放pgnss_log内存\r
-    if (pgnss_log != NULL) {\r
-        free(pgnss_log);\r
-        pgnss_log = NULL;\r
-    }\r
-}\r
+/*
+* Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved.
+* Description: pgnss sample
+* Author:
+* Create:
+*/
+#include "pgnss_sample.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "securec.h"
+#include "tiot_service_interface.h"
+#include "pm_definition.h"
+#include "gnss_datatypes.h"
+#include "pgnss_encode.h"
+#include "NMEA0183.h"
+#include "sys/time.h"
+#include "time.h"
+#include "gnss_ctl.h"
+#include "custom_runtime.h"
+#include "los_base.h"
+#include "ConfigModelC.h"
+#include "gnss_http_server.h"
+#include "custom_utils.h"
+#include <dirent.h>
+#include <sys/stat.h>
+// #include "gnss_sample.h"
+
+#define PGNSS_DATA_PATH          "/user/userdata/gnss"
+
+#define PGNSS_FIXMODEALL_NMEADEF_SAMPLE            0
+#define PGNSS_LESS_FILES_FIXMODEALL_NMEADEF_SAMPLE 0
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+#endif
+#define MSG_TYPE_BINRY              0
+#define MSG_TYPE_ASCII              1
+#define LISTEN_DATA_MAX_LINES       1000
+
+static FILE* g_gnssLogFp = NULL;
+static uint8_t g_gnssServiceBuff[REPORT_MAX_BYTES] = { 0 };
+
+typedef int32_t (*GnssCfgFunc)(tiot_handle handle);
+
+typedef struct {
+    uint16_t    sampleId;
+    GnssCfgFunc cfgHandle;
+} GnssSamplesCfgTable;
+
+static NMEA0183 g_nmeadata={0};
+static gps_data_t g_global_gpsData={0};
+
+/**GPS状态位*/
+static int g_is_pgnss_poweron=0;
+static int g_is_pgnss_logon=0;
+static int g_pgnss_stopflag=0;
+static int g_cold_start_pgnss_stopflag = 0;
+
+static char *pgnss_log = NULL;
+
+// 全局变量,存储当前有效的时间戳文件夹路径
+static char *g_current_agnss_folder = NULL;
+
+static int32_t QryVersion(tiot_handle handle)
+{
+    const uint8_t qryVersion[] = {0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00};
+    // 查询版本号
+    int32_t ret = tiot_service_write(handle, qryVersion, sizeof(qryVersion));
+    if (ret < 0) {
+        printf("\nerror: QryVersion error: %d\r\n", ret);
+        return 0;
+    }
+    return 1;
+}
+
+static int decode_nmea(char c)
+{
+    int ret=0;
+    ret=0;
+    if(nmea_decode(&g_nmeadata,c) ==1 ) ///调用解析函数
+    {
+        dump_nmea_str(&(g_nmeadata.gpsParse));
+        if (g_nmeadata.gpsParse.sentence_type == GPS_SENTENCE_TH002 )
+        {
+            //一组数据最后一条
+            memcpy_s(&g_global_gpsData,sizeof(gps_data_t),&(g_nmeadata.gpsData),sizeof(gps_data_t));
+            ret = 1;
+            memset(&g_nmeadata,0,sizeof(g_nmeadata));
+        }
+    } 
+
+    return ret;
+}
+
+gps_data_t * getPGPSGlobaldata(void)
+{
+    return &g_global_gpsData;
+}
+
+
+// 添加普通GNSS冷启动配置函数的声明和实现
+// 从gnss_sample.c中复制冷启动相关的命令定义
+
+// 函数声明
+void PGnssServerStartColdStart(void);
+static int pgnss_startup_check(void);
+static int check_agnss_files_exist(void);
+
+// 获取当前有效的时间戳文件夹路径
+const char* get_current_agnss_folder_path(void)
+{
+    if (g_current_agnss_folder != NULL) {
+        return g_current_agnss_folder;
+    }
+    return PGNSS_DATA_PATH;
+}
+
+// 清理AGNSS文件夹路径内存
+void cleanup_agnss_folder_path(void)
+{
+    if (g_current_agnss_folder != NULL) {
+        free(g_current_agnss_folder);
+        g_current_agnss_folder = NULL;
+    }
+}
+static const uint8_t cfgColdStartCmd[] = {0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01};
+static const uint8_t cfgFixModeAllCmd[] = {0x03, 0x00, 0x23, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x1f, 0x00, 0x00, 0x00};
+static const uint8_t cfgNmeaAllCmd[] = {0x03, 0x00, 0x04, 0x01, 0x00, 0x00, 0x06, 0x00, 0x03, 0x00, 0x02, 0x00, 0xff, 0x00};
+static const uint8_t CFG_TRK_LPW_DISABLE[] = {0x03, 0x00, 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00};
+static const uint8_t CFG_ACQ_LPW_DISABLE[] = {0x03, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00};
+static const uint8_t CFG_ANTIJAM_ENABLE[] = {0x03, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x08, 0x00, 0x06, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00};
+
+// 普通GNSS冷启动配置函数实现
+static int32_t CfgColdStartFixModeGpsNmeaAll(tiot_handle handle)
+{
+    // 配置启动模式:冷启动模式
+    int32_t ret = tiot_service_write(handle, cfgColdStartCmd, sizeof(cfgColdStartCmd));
+    if (ret < 0) {
+        printf("\nerror: cfgColdStartCmd error: %d\r\n", ret);
+        return 0;
+    }
+
+    // 配置使能的GNSS星座:GPS
+    ret = tiot_service_write(handle, cfgFixModeAllCmd, sizeof(cfgFixModeAllCmd));
+    if (ret < 0) {
+        printf("\nerror: cfgFixModeAllCmd error: %d\r\n", ret);
+        return 0;
+    }
+
+    // 配置上报NMEA类型:PNT/ZDA/VTG/RMC/GSV/GSA/GLL/GGA
+    ret = tiot_service_write(handle, cfgNmeaAllCmd, sizeof(cfgNmeaAllCmd));
+    if (ret < 0) {
+        printf("\nerror: cfgNmeaAllCmd error: %d\r\n", ret);
+        return 0;
+    }
+
+    ret = tiot_service_write(handle, CFG_TRK_LPW_DISABLE, sizeof(CFG_TRK_LPW_DISABLE));
+    if (ret < 0) {
+        printf("\nerror: CFG_TRK_LPW_DISABLE error: %d\r\n", ret);
+        return 0;
+    }
+
+    ret = tiot_service_write(handle, CFG_ACQ_LPW_DISABLE, sizeof(CFG_ACQ_LPW_DISABLE));
+    if (ret < 0) {
+        printf("\nerror: CFG_ACQ_LPW_DISABLE error: %d\r\n", ret);
+        return 0;
+    }
+
+    ret = tiot_service_write(handle, CFG_ANTIJAM_ENABLE, sizeof(CFG_ANTIJAM_ENABLE));
+    if (ret < 0) {
+        printf("\nerror: CFG_ANTIJAM_ENABLE error: %d\r\n", ret);
+        return 0;
+    }
+    
+    printf("Cold start mode configured successfully\r\n");
+    return 1;
+}
+
+// 修改后的PGNSS配置函数,支持降级到普通GNSS
+int32_t InjectPgnssWithFallbackToColdStart(tiot_handle handle)
+{
+    const uint8_t cfgLogLevelInfo[] = {0x03, 0x00, 0x15, 0x00, 0x00, 0x00, 0x05, 0x00, 0x01, 0x10, 0x01, 0x00, 0x03};
+
+    // 配置log级别:info级别。
+    int32_t ret = tiot_service_write(handle, cfgLogLevelInfo, sizeof(cfgLogLevelInfo));
+    if (ret < 0) {
+        printf("\nerror: cfgLogLevelInfo error: %d\r\n", ret);
+        return 0;
+    }
+
+    // 注入UTC时间, 注入Pgnss辅助数据前必须先注入参考时间
+    GnssUtcTime utcTime = {2024, 2, 26, 6, 0, 0, 0, 1}; // 需要用当前的UTC时间替换
+
+    time_t rawtime;
+    struct tm* timeinfo;
+
+    time(&rawtime);          // 获取UTC时间戳
+    timeinfo = gmtime(&rawtime);  // 转换为UTC时间(无时区偏移)
+
+    utcTime.year = timeinfo->tm_year + 1900;
+    utcTime.month = timeinfo->tm_mon + 1;
+    utcTime.day = timeinfo->tm_mday;
+    utcTime.hour = timeinfo->tm_hour;
+    utcTime.minute = timeinfo->tm_min;
+    utcTime.second = timeinfo->tm_sec;
+
+    printf("year[%d], mon[%d], day[%d], hour[%d], min[%d], sec[%d] \r\n",
+    utcTime.year,utcTime.month,utcTime.day,
+    utcTime.hour,utcTime.minute,utcTime.second);
+
+    uint32_t ts = 0;
+    ret = PgnssInjectUtcTime(handle, &utcTime, &ts);
+    if (ret == 0) {
+        printf("\nerror: PgnssInjectUtcTime failed!\r\n");
+        return 0;
+    }
+    printf("\nPgnssInjectUtcTime success!\r\n");
+
+    // PGNSS注入
+    // 使用当前有效的时间戳文件夹路径
+    // 设置AGNSS文件夹路径到pgnss_encode模块
+    set_agnss_folder_path(get_current_agnss_folder_path());
+    int32_t injectRet = PgnssInjectLessFiles(handle, ts, get_current_agnss_folder_path());
+    if (injectRet == 0) {
+        // PGNSS注入失败,设置停止标志并重新启动
+        printf("PGNSS injection failed, restarting with cold start mode\r\n");
+        // if(uapi_dev_runtime_get_cat1_powerstat())
+        // {
+
+        // }
+        // else
+        // {           
+            // 设置停止标志
+            g_cold_start_pgnss_stopflag = 1;
+        // }
+
+        return 0; // 返回0表示需要重新启动
+    }
+
+    printf("PGNSS injection completed successfully\r\n");
+    return 1;
+}
+
+
+// 注入PGNSS,使用默认配置启动
+int32_t InjectPgnssLessFilesCfgAutoStartFixModeAndNmeaDefault(tiot_handle handle)
+{
+    // 调用新的带降级功能的函数
+    return InjectPgnssWithFallbackToColdStart(handle);
+}
+
+static const GnssSamplesCfgTable g_gnssSamplesCfg[] = {
+    // {PGNSS_FIXMODEALL_NMEADEF_SAMPLE,            InjectPgnssCfgAutoStartFixModeAndNmeaDefault},
+    {PGNSS_LESS_FILES_FIXMODEALL_NMEADEF_SAMPLE, InjectPgnssLessFilesCfgAutoStartFixModeAndNmeaDefault}
+};
+
+static int32_t StartGnss(tiot_handle handle)
+{
+    const uint8_t startCmd[] = {0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00,
+        0x01, 0x00, 0x00, 0x00, 0x00, 0x00};
+    // 启动GNSS
+    int32_t ret = tiot_service_write(handle, startCmd, sizeof(startCmd));
+    if (ret < 0) {
+        printf("\nerror: start gnss error: %d\r\n", ret);
+        return 0;
+    }
+    printf("\nstart gnss\r\n");
+    return 1;
+}
+
+static int32_t StopGnss(tiot_handle handle)
+{
+    const uint8_t stopCmd[] = {0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+    // 停止GNSS
+    int32_t ret = tiot_service_write(handle, stopCmd, sizeof(stopCmd));
+    if (ret < 0) {
+        printf("\nerror: stop gnss error: %d\r\n", ret);
+        return 0;
+    }
+    printf("\nstop gnss\r\n");
+    return 1;
+}
+
+
+static void ListenGnssData(tiot_handle handle)
+{
+    int32_t i = 0;
+    // 写日志
+    for (;;) {  // 写日志条件
+
+        if (i >= LISTEN_DATA_MAX_LINES) {
+            printf("\r\ncnt enough\r\n");
+            break;
+        }
+        if (g_pgnss_stopflag == 1)
+        {
+            break;
+        }
+        // 监听
+        int32_t ret = tiot_service_read(handle, g_gnssServiceBuff, REPORT_MAX_BYTES, LISTEN_TIME_THR);
+        if (ret > 0) {
+            uint16_t *type = (uint16_t *)g_gnssServiceBuff;
+            if (type[0] == MSG_TYPE_ASCII) {
+                g_gnssServiceBuff[ret] = '\0';
+                char* pbuf=(char *)&g_gnssServiceBuff[MSG_CONTENT_IDX];
+                printf("%s\r\n", pbuf);
+                if (g_is_pgnss_logon)
+                    fprintf(g_gnssLogFp, "%s\n", pbuf);
+                for (int index=0;index < ret ;index++)
+                {
+                    if (decode_nmea(pbuf[index])==1)
+                    {
+                        // dump_location_data(&g_global_gpsData);
+                        char temp_buf[512];
+                        dump_location_data_to_buf(&g_global_gpsData, temp_buf, sizeof(temp_buf));
+                        
+                        // 追加到pgnss_log中
+                        if (pgnss_log != NULL) {
+                            int current_len = strlen(pgnss_log);
+                            int data_len = strlen(temp_buf);
+                            if (current_len + data_len < 2047) {  // 留1字节给字符串结束符
+                                snprintf(pgnss_log + current_len, 2048 - current_len, "%s", temp_buf);
+                            }
+                        }
+                        
+                        printf("decode_nmea done\r\n");
+                    }
+                }
+            }
+            i++;
+        }
+
+    }
+}
+
+void PGnssServerStop(void)
+{
+    g_pgnss_stopflag=1;
+    
+    // 清理pgnss_sample模块的内存
+    cleanup_agnss_folder_path();
+    
+    // 清理pgnss_encode模块的内存
+    cleanup_pgnss_encode_agnss_folder_path();
+    
+    if (pgnss_log != NULL) {
+        free(pgnss_log);
+        pgnss_log = NULL;
+    }
+}
+
+int getPGnssServerStat(void)
+{
+    return g_is_pgnss_poweron;
+}
+
+int is_PGnssLogEnabled(void)
+{
+    return g_is_pgnss_logon;
+}
+
+int PGnssLogEnable(bool enable)
+{
+    if (enable)
+        g_is_pgnss_logon = 1;
+    else
+        g_is_pgnss_logon = 0;
+
+    return g_is_pgnss_logon;
+}
+
+// 直接启动冷启动模式的函数
+void PGnssServerStartColdStart(void)
+{
+    printf("\nenter cold start mode\r\n");
+    
+    if (pgnss_log == NULL) 
+    {
+        pgnss_log = (char *)malloc(2048);
+        if (pgnss_log == NULL) {
+            printf("error: malloc pgnss_log failed!\n");
+            return;
+        }
+        memset(pgnss_log, 0, 2048);
+    }
+
+    uapi_pm_add_sleep_veto(PM_ID_SYS);
+
+    #ifdef DOWNLOAD_GNSS_SWITCH
+    download_gnss_switch(SWITCH_TO_GNSS);
+    #endif
+    g_is_pgnss_poweron = 1;
+    g_pgnss_stopflag = 0;
+    g_cold_start_pgnss_stopflag = 0;
+    sw_debug_uart_deinit();
+    
+    // Step1: init
+    int32_t ret = tiot_service_init();
+    if (ret != 0) {
+        printf("tiot service init fail\r\n");
+        g_is_pgnss_poweron = 0;
+        g_pgnss_stopflag = 1;
+        if (pgnss_log != NULL) {
+            free(pgnss_log);
+            pgnss_log = NULL;
+        }
+        return;
+    }
+
+    // 打开日志文件
+    if (g_is_pgnss_logon)
+    {
+        g_gnssLogFp = fopen("/user/log/gnss.log", "w");
+        if (g_gnssLogFp == NULL) {
+            printf("error: open log file error\n");
+            if (pgnss_log != NULL) {
+                free(pgnss_log);
+                pgnss_log = NULL;
+            }
+            return;
+        }
+    }
+    printf("before open tiot service for cold start\n");
+
+    // Step2: power on gnss
+    tiot_handle handle = tiot_service_open("gn71", NULL);
+    if (handle == 0) {
+        printf("open tiot service fail\r\n");
+        g_is_pgnss_poweron = 0;
+        g_pgnss_stopflag = 1;
+        if (pgnss_log != NULL) {
+            free(pgnss_log);
+            pgnss_log = NULL;
+        }
+        return;
+    }
+    printf("open tiot service success for cold start\n");
+
+    // 直接配置为冷启动模式
+    printf("Configuring cold start mode...\r\n");
+    int32_t cfgRet = CfgColdStartFixModeGpsNmeaAll(handle);
+    if (cfgRet == 0) {
+        printf("Cold start configuration failed\r\n");
+        tiot_service_close(handle);
+        return;
+    }
+    printf("Cold start mode configured successfully\r\n");
+    
+    QryVersion(handle);
+
+    // Step4: start gnss
+    if (StartGnss(handle) == 0) {
+        printf("Start GNSS failed\r\n");
+        tiot_service_close(handle);
+        return;
+    }
+    
+    // Step5: listening gnss data
+    ListenGnssData(handle);
+    
+    // Step6: stop gnss
+    if (StopGnss(handle) == 0) {
+        printf("Stop GNSS failed\r\n");
+    }
+    
+    // Step7: power off gnss
+    tiot_service_close(handle);
+    
+    // 关日志文件
+    if (g_is_pgnss_logon)
+    {
+        fclose(g_gnssLogFp);
+        g_gnssLogFp = NULL;
+    }
+    
+    // Step8: deinit
+    tiot_service_deinit();
+
+    #ifdef DOWNLOAD_GNSS_SWITCH
+    download_gnss_switch(SWITCH_TO_DOWNLOAD);
+    #endif
+    uapi_pm_remove_sleep_veto(PM_ID_SYS);
+
+    g_is_pgnss_poweron = 0;
+    sw_debug_uart_deinit();
+    uart_config_init();
+    printf("finish cold start mode\r\n");
+    
+    printf("gnss_log: %s\r\n", pgnss_log);
+    // 释放pgnss_log内存
+    if (pgnss_log != NULL) {
+        free(pgnss_log);
+        pgnss_log = NULL;
+    }
+}
+
+// 检查AGNSS文件夹是否过期的函数
+static int check_agnss_folder_expired(void)
+{
+    DIR *dir = opendir(PGNSS_DATA_PATH);
+    if (dir == NULL) {
+        printf("AGNSS directory does not exist: %s\n", PGNSS_DATA_PATH);
+        return 1; // 目录不存在,认为过期
+    }
+    
+    // 获取当前时间戳
+    uint32_t current_timestamp = 0;
+    uapi_get_timestampe_ss(&current_timestamp);
+    
+    struct dirent *entry;
+    int found_valid_folder = 0;
+    uint32_t min_time_diff = 0xFFFFFFFF;
+    
+    while ((entry = readdir(dir)) != NULL) {
+        // 跳过 . 和 .. 目录
+        if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
+            continue;
+        }
+        
+        // 检查是否是数字文件夹(时间戳文件夹)
+        char *endptr;
+        uint32_t folder_timestamp = strtoul(entry->d_name, &endptr, 10);
+        
+        // 如果转换成功且没有剩余字符,说明是纯数字文件夹
+        if (*endptr == '\0' && folder_timestamp > 0) {
+            // 计算时间差
+            uint32_t time_diff = 0;
+            if (current_timestamp >= folder_timestamp) {
+                time_diff = current_timestamp - folder_timestamp;
+            } else {
+                time_diff = folder_timestamp - current_timestamp;
+            }
+            
+            // 检查是否在24小时内
+            if (time_diff < 86400) { // 24小时 = 86400秒
+                found_valid_folder = 1;
+                if (time_diff < min_time_diff) {
+                    min_time_diff = time_diff;
+                    // 更新全局变量,存储最接近的时间戳文件夹路径
+                    if (g_current_agnss_folder != NULL) {
+                        free(g_current_agnss_folder);
+                        g_current_agnss_folder = NULL;
+                    }
+                    g_current_agnss_folder = malloc(256);
+                    if (g_current_agnss_folder != NULL) {
+                        int ret = snprintf(g_current_agnss_folder, 256, "%s/%s", PGNSS_DATA_PATH, entry->d_name);
+                        if (ret < 0 || ret >= 256) {
+                            printf("ERROR: snprintf failed or buffer overflow for g_current_agnss_folder\n");
+                            free(g_current_agnss_folder);
+                            g_current_agnss_folder = NULL;
+                        }
+                    } else {
+                        printf("ERROR: Failed to allocate memory for g_current_agnss_folder\n");
+                    }
+                }
+                printf("Found valid AGNSS folder: %s (time diff: %u seconds)\n", 
+                       entry->d_name, time_diff);
+            } else {
+                printf("Found expired AGNSS folder: %s (time diff: %u seconds, %.1f days)\n", 
+                       entry->d_name, time_diff, time_diff / 86400.0);
+            }
+        }
+    }
+    
+    closedir(dir);
+    
+    if (!found_valid_folder) {
+        printf("No valid AGNSS folder found within 24 hours\n");
+        return 1; // 过期
+    }
+
+    return 0; // 未过期
+}
+
+// PGNSS启动前检查函数:检查AGNSS文件夹是否过期,过期则尝试下载
+// 返回值:0=检查通过,可以正常启动PGNSS;1=检查失败,需要冷启动
+static int pgnss_startup_check(void)
+{
+    printf("=== PGNSS Startup Check ===\n");
+    
+    // 首先检查AGNSS文件夹是否过期
+    int agnss_expired = check_agnss_folder_expired();
+    if (!agnss_expired) {
+        printf("=== PGNSS Startup Check Passed ===\n");
+        return 0; // 检查通过,可以正常启动PGNSS
+    }
+    
+    printf("AGNSS folder is expired or does not exist. Attempting to download...\n");
+    
+    // 检查4G状态
+    int cat1_status = uapi_dev_runtime_get_cat1_powerstat();
+    printf("CAT1 power status: %d (1=powered on, 0=powered off)\n", cat1_status);
+    
+    if (cat1_status != 1) {
+        printf("ERROR: CAT1 is not powered on! Need cold start mode\n");
+        return 1; // 检查失败,需要冷启动
+    }
+    
+    printf("4G is powered on. Starting AGNSS download process...\n");
+    
+    // 第一次发送下载指令
+    printf("Sending first download command...\n");
+    do_gnss_http_server_send_data(GNSS_HTTP_SERVICE_CMD_DOWNLOAD_AGNSS, NULL, 0);
+    
+    // 每10秒检查一次,最多检查6次(60秒)
+    int check_count = 0;
+    int max_checks = 6; // 60秒 / 10秒 = 6次检查
+    int retry_sent = 0; // 标记是否已发送重试指令
+    
+    while (check_count < max_checks) {
+        // 等待10秒
+        printf("Waiting 10 seconds for download (check %d/%d)...\n", check_count + 1, max_checks);
+        LOS_Msleep(10000);
+        check_count++;
+        
+        // 检查是否有文件
+        if (check_agnss_folder_expired()) {
+            printf("✓ AGNSS files downloaded successfully after %d seconds\n", check_count * 10);
+            printf("=== PGNSS Startup Check Passed ===\n");
+            
+            return 0; // 检查通过,可以正常启动PGNSS
+        }
+        
+        // 在第3次检查后(30秒)发送重试指令
+        if (check_count == 3 && !retry_sent) {
+            printf("No files found after 30s. Sending second download command...\n");
+            do_gnss_http_server_send_data(GNSS_HTTP_SERVICE_CMD_DOWNLOAD_AGNSS, NULL, 0);
+            retry_sent = 1;
+        }
+    }
+    
+    // 60秒后还没有数据,降级为冷启动
+    printf("ERROR: No AGNSS files downloaded after 60 seconds. Need cold start mode\n");
+
+    
+    return 1; // 检查失败,需要冷启动
+}
+
+void PGnssServerStart(void)
+{
+    //未绑定直接冷启动
+    if(cm_getisFirstTimeStart())
+    {
+        printf("PGnssServerStartColdStart \n");
+        PGnssServerStartColdStart();
+        return;
+    }
+
+    // 执行PGNSS启动前检查
+    int check_result = pgnss_startup_check();
+    if (check_result != 0) {
+        printf("PGNSS startup check failed. Starting cold start mode\n");
+        PGnssServerStartColdStart();
+        return;
+    }
+    
+    printf("PGNSS startup check passed. Proceeding with PGNSS mode\n");
+
+    printf("\nenter gnss samples\r\n");
+    
+    if (pgnss_log == NULL) 
+    {
+        pgnss_log = (char *)malloc(2048);
+        if (pgnss_log == NULL) {
+            printf("error: malloc pgnss_log failed!\n");
+            return;
+        }
+        memset(pgnss_log, 0, 2048);
+    }
+
+    if(g_is_pgnss_poweron == 1)
+    {
+        printf("gnss already on\r\n");
+        if (pgnss_log != NULL) {
+            free(pgnss_log);
+            pgnss_log = NULL;
+        }
+        return ;
+    }
+    uapi_pm_add_sleep_veto(PM_ID_SYS);
+
+    #ifdef DOWNLOAD_GNSS_SWITCH
+    download_gnss_switch(SWITCH_TO_GNSS);
+    #endif
+    g_is_pgnss_poweron = 1;
+    g_pgnss_stopflag = 0;
+    g_cold_start_pgnss_stopflag = 0;
+    sw_debug_uart_deinit();
+    // Step1: init
+    int32_t ret = tiot_service_init();
+    if (ret != 0) {
+        printf("tiot service init fail\r\n");
+        g_is_pgnss_poweron = 0;
+        g_pgnss_stopflag = 1;
+        if (pgnss_log != NULL) {
+            free(pgnss_log);
+            pgnss_log = NULL;
+        }
+        return;
+    }
+
+    // 打开日志文件
+    if (g_is_pgnss_logon)
+    {
+        g_gnssLogFp = fopen("/user/log/gnss.log", "w");
+        if (g_gnssLogFp == NULL) {
+            printf("error: open log file error\n");
+            if (pgnss_log != NULL) {
+                free(pgnss_log);
+                pgnss_log = NULL;
+            }
+            return;
+        }
+    }
+    printf("before open tiot service\n");
+
+    // Step2: power on gnss
+    tiot_handle handle = tiot_service_open("gn71", NULL);
+    if (handle == 0) {
+        printf("open tiot service fail\r\n");
+        g_is_pgnss_poweron = 0;
+        g_pgnss_stopflag = 1;
+        g_cold_start_pgnss_stopflag = 1;
+        if (pgnss_log != NULL) {
+            free(pgnss_log);
+            pgnss_log = NULL;
+        }
+        return;
+    }
+    printf("open tiot service success\r\n");
+
+    int32_t cfgRet;
+    // ---- loop ----------
+    for (uint16_t i = 0; i < ARRAY_SIZE(g_gnssSamplesCfg); i++) {
+        cfgRet = 0;
+        if (g_gnssSamplesCfg[i].sampleId == i) {
+            // Step3: config gnss
+            if (g_gnssSamplesCfg[i].cfgHandle != NULL) {
+                cfgRet = g_gnssSamplesCfg[i].cfgHandle(handle);
+            }
+            if (cfgRet == 0) {
+                // continue;
+                break;
+            }
+            printf("cfg sample id:%u\r\n", g_gnssSamplesCfg[i].sampleId);
+            QryVersion(handle);
+
+            // Step4: start gnss
+            if (StartGnss(handle) == 0) {
+                continue;
+            }
+            // Step5: listening gnss data
+            ListenGnssData(handle);
+            // Step6: stop gnss
+            if (StopGnss(handle) == 0) {
+                continue;
+            }
+        }
+    }
+    // ---------------------
+    // Step7: power off gnss
+    tiot_service_close(handle);
+    // 关日志文件
+    if (g_is_pgnss_logon)
+    {
+        fclose(g_gnssLogFp);
+        g_gnssLogFp = NULL;
+    }
+    // Step8: deinit
+    tiot_service_deinit();
+
+    #ifdef DOWNLOAD_GNSS_SWITCH
+    download_gnss_switch(SWITCH_TO_DOWNLOAD);
+    #endif
+    uapi_pm_remove_sleep_veto(PM_ID_SYS);
+    if(!g_cold_start_pgnss_stopflag)
+        g_is_pgnss_poweron = 0;
+    sw_debug_uart_deinit();
+    uart_config_init();
+    printf("finish gnss samples\r\n");
+    
+    printf("pgnss_log: %s\r\n", pgnss_log);
+    // 释放pgnss_log内存
+    if (pgnss_log != NULL) {
+        free(pgnss_log);
+        pgnss_log = NULL;
+    }
+    if(g_cold_start_pgnss_stopflag == 1)
+    {
+        // GnssServerStart();
+        PGnssServerStartColdStart();
+    }
+
+}
diff --git a/code/sdk/zhihui/services/gnss/src/gnss_http_server.c b/code/sdk/zhihui/services/gnss/src/gnss_http_server.c
new file mode 100644 (file)
index 0000000..ef9616a
--- /dev/null
@@ -0,0 +1,1631 @@
+#include "pinctrl.h"
+#include "debug_print.h"
+#include "rtc.h"
+#include "timer.h"
+#include "systick.h"
+
+#include "tcxo.h"
+
+#include "cmsis_os2.h"
+#include "input_app.h"
+#include "gnss_service.h"
+#include "custom_utils.h"
+#include "gnss_http_server.h"
+#include "custom_runtime.h"
+#include <dirent.h>
+#include "pm_definition.h"
+#include "mbedtls/md5.h"
+#include "mbedtls/base64.h"
+#include "cJSON.h"
+#include "mbedtls/hmac_drbg.h"
+#include "gnss_http_server.h"
+#include "mbedtls/md.h"
+#include "mbedtls/base64.h"
+#include "mbedtls/md5.h"
+#include "netinet/in.h"
+#include "arpa/inet.h"
+// 使用新的httpclient.h接口
+#include "netstack/http/include/httpclient.h"
+// code/sdk/open_source/openharmony/foundation/ace/ace_engine_lite/modules/netstack/http/include/httpclient.h
+#include <sys/stat.h>
+
+#define PGNSS_DATA_PATH          "/user/userdata/gnss"
+
+// 全局变量用于存储接收到的数据
+static char *g_agnss_response_buffer = NULL;
+static size_t g_agnss_response_size = 0;
+static size_t g_agnss_response_capacity = 0;
+
+// 全局静态变量用于防止重复处理
+static int g_processing_count = 0;
+
+static unsigned long g_app_recv_queue= 0xFFFFFFFF;
+static unsigned long g_app_send_queue= 0xFFFFFFFF;
+
+static app_task_definition_t send_taskcfg={0};
+static app_task_definition_t recv_taskcfg={0};
+
+
+static void cleanup_agnss_response_buffer(void);
+static void agnss_accumulate_data(const char *data, size_t len);
+static void emergency_cleanup(void);
+static void smart_json_cleanup(void);
+static char* extract_folder_path(const char *download_url);
+
+// URL解析结构体
+typedef struct {
+    char *protocol;
+    char *host;
+    int port;
+    char *path;
+    char *query;
+    char *error;
+} BK_URL;
+
+// URL解析函数
+static BK_URL parse_url(const char *url);
+static void free_url(BK_URL *url);
+int download_agnss_file(const char *filename);
+
+
+void do_gnss_http_server_recv_data(int cmd,char *data,uint32_t len);
+
+// 使用新的httpclient.h接口的下载结果处理函数
+static void agnss_download_result_handler(const char *filename, HTTPC_RESULT result, int response_code, const char *response_data, int data_len)
+{
+    if (filename) {
+        // 单个文件下载的结果处理 - 只保留成功信息
+        if (result == HTTP_SUCCESS && response_code == 200) {
+            // 验证文件是否真的写入成功 - 在时间戳文件夹中查找
+            char filepath[512];
+            int file_found = 0;
+            
+            // 首先尝试在根目录查找
+            snprintf(filepath, sizeof(filepath), "%s/%s", PGNSS_DATA_PATH, filename);
+            FILE *fp = fopen(filepath, "rb");
+            if (fp != NULL) {
+                fseek(fp, 0, SEEK_END);
+                long file_size = ftell(fp);
+                fclose(fp);
+                
+                if (file_size > 0) {
+                    printf("✓ %s: %ld bytes\n", filename, file_size);
+                    file_found = 1;
+                }
+            }
+            
+            // 如果根目录没有找到,在时间戳文件夹中查找
+            if (!file_found) {
+                DIR *dir = opendir(PGNSS_DATA_PATH);
+                if (dir != NULL) {
+                    struct dirent *entry;
+                    while ((entry = readdir(dir)) != NULL) {
+                        // 跳过 . 和 .. 目录
+                        if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
+                            continue;
+                        }
+                        
+                        // 检查是否是数字文件夹(时间戳文件夹)
+                        char *endptr;
+                        uint32_t folder_timestamp = strtoul(entry->d_name, &endptr, 10);
+                        if (*endptr == '\0' && folder_timestamp > 0) {
+                            // 在时间戳文件夹中查找文件
+                            snprintf(filepath, sizeof(filepath), "%s/%s/%s", PGNSS_DATA_PATH, entry->d_name, filename);
+                            fp = fopen(filepath, "rb");
+                            if (fp != NULL) {
+                                fseek(fp, 0, SEEK_END);
+                                long file_size = ftell(fp);
+                                fclose(fp);
+                                
+                                if (file_size > 0) {
+                                    printf("✓ %s: %ld bytes (in %s)\n", filename, file_size, entry->d_name);
+                                    file_found = 1;
+                                    break;
+                                }
+                            }
+                        }
+                    }
+                    closedir(dir);
+                }
+            }
+        }
+    } else {
+        // AGNSS文件列表下载的结果处理
+        if (result == HTTP_SUCCESS && response_code == 200) {
+            // 处理接收到的数据
+            if (data_len > 0 && response_data) {
+                agnss_accumulate_data(response_data, data_len);
+            }
+            
+            // 发送完成信号到接收任务
+            do_gnss_http_server_recv_data(GNSS_HTTP_SERVICE_CMD_AGNSS_RECV, NULL, 0);
+        }
+    }
+}
+
+// 使用简单的socket直接下载文件
+static HTTPC_RESULT download_file_with_httpclient(const char *filename, const char *url)
+{
+
+    // 解析URL
+    char host[256] = {0};
+    char path[512] = {0};
+    int port = 80;
+    
+    // 简单解析 http://host/path 格式
+    if (strncmp(url, "http://", 7) == 0) {
+        const char *url_path = url + 7;
+        const char *path_start = strchr(url_path, '/');
+        if (path_start) {
+            int host_len = path_start - url_path;
+            if (host_len >= sizeof(host)) {
+                printf("Host name too long: %d bytes\n", host_len);
+                return HTTP_EARG;
+            }
+            strncpy(host, url_path, host_len);
+            host[host_len] = '\0';
+            
+            if (strlen(path_start) >= sizeof(path)) {
+                printf("Path too long: %zu bytes\n", strlen(path_start));
+                return HTTP_EARG;
+            }
+            strcpy(path, path_start);
+        } else {
+            printf("Invalid URL format - no path found\n");
+            return HTTP_EARG;
+        }
+    } else {
+        printf("Unsupported URL scheme: %s\n", url);
+        return HTTP_EARG;
+    }
+    
+    // 保存到时间戳文件夹中
+    char filepath[512];
+    char timestamp_folder[64];
+    
+    // 从URL中提取时间戳文件夹名
+    char *folder_pos = strstr(url, "/iot_gnss/");
+    if (folder_pos) {
+        folder_pos += 10; // 跳过 "/iot_gnss/"
+        char *next_slash = strchr(folder_pos, '/');
+        if (next_slash) {
+            int folder_len = next_slash - folder_pos;
+            if (folder_len > 0 && folder_len < sizeof(timestamp_folder) - 1) {
+                strncpy(timestamp_folder, folder_pos, folder_len);
+                timestamp_folder[folder_len] = '\0';
+                
+                // 文件夹已在下载开始前创建,直接使用路径
+                char full_folder_path[512];
+                snprintf(full_folder_path, sizeof(full_folder_path), "%s/%s", PGNSS_DATA_PATH, timestamp_folder);
+                
+                // 保存文件到时间戳文件夹
+                snprintf(filepath, sizeof(filepath), "%s/%s/%s", PGNSS_DATA_PATH, timestamp_folder, filename);
+            } else {
+                // 如果无法提取时间戳,使用默认路径
+                snprintf(filepath, sizeof(filepath), "%s/%s", PGNSS_DATA_PATH, filename);
+            }
+        } else {
+            // 如果无法找到第二个斜杠,使用默认路径
+            snprintf(filepath, sizeof(filepath), "%s/%s", PGNSS_DATA_PATH, filename);
+        }
+    } else {
+        // 如果无法找到 /iot_gnss/,使用默认路径
+        snprintf(filepath, sizeof(filepath), "%s/%s", PGNSS_DATA_PATH, filename);
+    }
+    
+    // 初始化HTTP客户端
+    HttpClient client = {0};
+    HttpClientData clientData = {0};
+    
+    // 设置HTTP客户端参数
+    client.isHttp = true;
+    client.remotePort = port;
+    
+    // 准备客户端数据
+    HTTPC_RESULT prep_result = HttpClientPrepare(&clientData, 2048, 256 * 1024);
+    if (prep_result != HTTP_SUCCESS) {
+        return prep_result;
+    }
+    
+    // 构建完整URL
+    char full_url[512];
+    snprintf(full_url, sizeof(full_url), "http://%s%s", host, path);
+    
+    // 执行HTTP GET请求
+    HTTPC_RESULT result = HttpClientGetRequest(&client, full_url, &clientData);
+    
+    if (result == HTTP_SUCCESS) {
+        // 检查响应状态码
+        int response_code = HttpClientGetResponseCode(&client);
+        
+        if (response_code == 200) {
+            // 将响应数据写入文件
+            if (clientData.responseBuf && clientData.responseBufLen > 0) {
+                // 简化数据长度计算
+                int actual_size = clientData.responseContentLen;
+                if (actual_size <= 0) {
+                    actual_size = clientData.responseBufLen;
+                }
+                
+                FILE *fp = fopen(filepath, "wb");
+                if (fp != NULL) {
+                    size_t written = fwrite(clientData.responseBuf, 1, actual_size, fp);
+                    fclose(fp);
+                    
+                    if (written == actual_size) {
+                        result = HTTP_SUCCESS;
+                    } else {
+                        result = HTTP_ESEND;
+                    }
+                } else {
+                    result = HTTP_ESEND;
+                }
+            } else {
+                result = HTTP_ERECV;
+            }
+        } else {
+            result = HTTP_EPROTO;
+        }
+    } else if (result == HTTP_EAGAIN) {
+        // 检查socket是否仍然有效
+        if (client.socket <= 0) {
+            // 检查响应状态码
+            int response_code = HttpClientGetResponseCode(&client);
+            
+            if (response_code == 200) {
+                // 检查响应数据
+                if (clientData.responseBuf && clientData.responseBufLen > 0) {
+                    // 检查缓冲区内容,查找实际的数据结束位置
+                    int actual_data_end = clientData.responseBufLen;
+                    for (int i = 0; i < clientData.responseBufLen; i++) {
+                        if (clientData.responseBuf[i] == 0) {
+                            // 检查是否连续多个零(可能是填充)
+                            int consecutive_zeros = 0;
+                            for (int j = i; j < clientData.responseBufLen && clientData.responseBuf[j] == 0; j++) {
+                                consecutive_zeros++;
+                            }
+                            if (consecutive_zeros > 100) { // 如果连续100个以上的零,认为是填充
+                                actual_data_end = i;
+                                break;
+                            }
+                        }
+                    }
+                    
+                    // 优先使用服务器返回的实际长度,只有在明显错误时才使用检测结果
+                    int actual_size = clientData.responseContentLen;
+                    if (actual_size <= 0) {
+                        // 如果responseContentLen无效,使用检测到的实际数据结束位置
+                        actual_size = actual_data_end;
+                        if (actual_size <= 0) {
+                            actual_size = clientData.responseBufLen;
+                        }
+                    } else {
+                        // 如果responseContentLen有效,检查是否明显错误(比如太大)
+                        if (actual_data_end > 0 && actual_data_end < actual_size) {
+                            actual_size = actual_data_end;
+                        } else if (actual_size > 50000) { // 如果Content-Length超过50KB,可能错误
+                            // AssistInfo.dat文件:固定大小验证(通常几百字节)
+                            if (strcmp(filename, "AssistInfo.dat") == 0) {
+                                if (actual_size > 0 && actual_size < 10000) { // AssistInfo.dat通常几百字节,最大10KB
+                                    printf("  [DEBUG] AssistInfo.dat 文件大小: %d bytes (固定大小验证通过)\n", actual_size);
+                                } else {
+                                    printf("  WARNING: AssistInfo.dat 文件大小异常: %d bytes\n", actual_size);
+                                    actual_size = actual_data_end;
+                                }
+                            } else {
+                                actual_size = actual_data_end;
+                            }
+                        }
+                    }
+                    
+                    // 将响应数据写入文件
+                    FILE *fp = fopen(filepath, "wb");
+                    if (fp != NULL) {
+                        size_t written = fwrite(clientData.responseBuf, 1, actual_size, fp);
+                        fclose(fp);
+                        
+                        if (written == actual_size) {
+                            printf("✓ %s (%zu bytes)\n", filename, written);
+                            result = HTTP_SUCCESS;
+                        } else {
+                            printf("✗ %s: write failed\n", filename);
+                            result = HTTP_ESEND;
+                        }
+                    } else {
+                        printf("✗ %s: file open failed\n", filename);
+                        result = HTTP_ESEND;
+                    }
+                } else {
+                    printf("✗ %s: no data\n", filename);
+                    result = HTTP_ERECV;
+                }
+            } else {
+                printf("✗ %s: HTTP %d\n", filename, response_code);
+                result = HTTP_EPROTO;
+            }
+        } else {
+            // 尝试接收响应数据
+            HTTPC_RESULT recv_result = HttpClientRecvResponse(&client, &clientData);
+            
+            if (recv_result == HTTP_SUCCESS) {
+                // 检查响应状态码
+                int response_code = HttpClientGetResponseCode(&client);
+                
+                if (response_code == 200) {
+                    // 处理响应数据
+                    if (clientData.responseBuf && clientData.responseBufLen > 0) {
+                        // 检查缓冲区内容,查找实际的数据结束位置
+                        int actual_data_end = clientData.responseBufLen;
+                        for (int i = 0; i < clientData.responseBufLen; i++) {
+                            if (clientData.responseBuf[i] == 0) {
+                                // 检查是否连续多个零(可能是填充)
+                                int consecutive_zeros = 0;
+                                for (int j = i; j < clientData.responseBufLen && clientData.responseBuf[j] == 0; j++) {
+                                    consecutive_zeros++;
+                                }
+                                if (consecutive_zeros > 100) { // 如果连续100个以上的零,认为是填充
+                                    actual_data_end = i;
+                                    break;
+                                }
+                            }
+                        }
+                        
+                        // 优先使用服务器返回的实际长度,只有在明显错误时才使用检测结果
+                        int actual_size = clientData.responseContentLen;
+                        if (actual_size <= 0) {
+                            // 如果responseContentLen无效,使用检测到的实际数据结束位置
+                            actual_size = actual_data_end;
+                            if (actual_size <= 0) {
+                                actual_size = clientData.responseBufLen;
+                            }
+                        } else {
+                            // 如果responseContentLen有效,检查是否明显错误(比如太大)
+                            if (actual_data_end > 0 && actual_data_end < actual_size) {
+                                actual_size = actual_data_end;
+                            } else if (actual_size > 50000) { // 如果Content-Length超过50KB,可能错误
+                                actual_size = actual_data_end;
+                            }
+                        }
+                        
+                        // 将响应数据写入文件
+                        FILE *fp = fopen(filepath, "wb");
+                        if (fp != NULL) {
+                            size_t written = fwrite(clientData.responseBuf, 1, actual_size, fp);
+                            fclose(fp);
+                            
+                            if (written == actual_size) {
+                                printf("✓ %s (%zu bytes)\n", filename, written);
+                                result = HTTP_SUCCESS;
+                            } else {
+                                printf("✗ %s: write failed\n", filename);
+                                result = HTTP_ESEND;
+                            }
+                        } else {
+                            printf("✗ %s: file open failed\n", filename);
+                            result = HTTP_ESEND;
+                        }
+                    } else {
+                        printf("✗ %s: no data\n", filename);
+                        result = HTTP_ERECV;
+                    }
+                } else {
+                    printf("✗ %s: HTTP %d\n", filename, response_code);
+                    result = HTTP_EPROTO;
+                }
+            } else {
+                printf("✗ %s: recv failed %d\n", filename, recv_result);
+                result = recv_result;
+            }
+        }
+    } else {
+        printf("✗ %s: request failed %d\n", filename, result);
+    }
+    
+    // 清理资源
+    HttpClientUnprepare(&clientData);
+    HttpClientClse(&client);
+    
+    return result;
+}
+
+// 从URL中提取文件夹路径
+static char* extract_folder_path(const char *download_url) {
+    static char folder_path[256] = {0};
+    
+    // 跳过协议部分 (http://)
+    const char *path_start = strstr(download_url, "://");
+    if (!path_start) {
+        return NULL;
+    }
+    path_start += 3; // 跳过 "://"
+    
+    // 跳过主机名部分
+    const char *first_slash = strchr(path_start, '/');
+    if (!first_slash) {
+        return NULL;
+    }
+    
+    // 查找最后一个斜杠(文件名之前)
+    const char *last_slash = strrchr(first_slash, '/');
+    if (!last_slash || last_slash == first_slash) {
+        return NULL;
+    }
+    
+    // 提取文件夹路径
+    int folder_len = last_slash - first_slash;
+    if (folder_len > 0 && folder_len < sizeof(folder_path) - 1) {
+        strncpy(folder_path, first_slash, folder_len);
+        folder_path[folder_len] = '\0';
+        return folder_path;
+    }
+    
+    return NULL;
+}
+
+// 创建文件夹路径
+static int create_folder_structure(const char *folder_path) {
+    if (!folder_path || strlen(folder_path) == 0) {
+        return 0; // 没有文件夹路径,直接返回成功
+    }
+    
+    char full_path[512];
+    snprintf(full_path, sizeof(full_path), "%s%s", PGNSS_DATA_PATH, folder_path);
+    
+    printf("  [DEBUG] 创建文件夹: %s\n", full_path);
+    
+    // 使用uapi_create_folder创建文件夹
+    uapi_create_folder(full_path);
+    // if (result == 0) {
+    //     printf("  [DEBUG] 文件夹创建成功: %s\n", full_path);
+    // } else {
+    //     printf("  [WARNING] 文件夹创建失败: %s (错误码: %d)\n", full_path, result);
+    // }
+    
+    return 0;
+}
+
+static int download_agnss_file_with_url(const char *filename, const char *download_url)
+{
+    // 文件夹已在下载开始前创建,无需重复创建
+    
+    // 添加重试机制
+    int max_retries = 2;
+    int retry_count = 0;
+    HTTPC_RESULT result = HTTP_SUCCESS;
+    
+    while (retry_count < max_retries) {
+        if (retry_count > 0) {
+            LOS_Msleep(200);
+        }
+        
+        // 使用新的httpclient.h接口下载文件
+        result = download_file_with_httpclient(filename, download_url);
+        
+        if (result == HTTP_SUCCESS) {
+            break;
+        } else {
+            retry_count++;
+        }
+    }
+    
+    if (result != HTTP_SUCCESS) {
+        return -1;
+    }
+    
+    return 0;
+}
+
+// AGNSS数据处理函数
+static void agnss_accumulate_data(const char *data, size_t len)
+{
+    // 验证输入数据
+    if (data == NULL || len == 0) {
+        printf("Invalid data received: data=%p, len=%zu\n", data, len);
+        return;
+    }
+    
+    // 检查数据是否以JSON开始(简单验证)
+    if (g_agnss_response_size == 0) {
+        // 第一个数据包,检查是否以 { 开始
+        if (len > 0 && data[0] != '{') {
+            printf("Warning: First data packet doesn't start with '{', data[0]=0x%02X\n", (unsigned char)data[0]);
+            // 尝试查找JSON开始位置
+            for (size_t i = 0; i < len; i++) {
+                if (data[i] == '{') {
+                    printf("Found JSON start at position %zu, adjusting data\n", i);
+                    data += i;
+                    len -= i;
+                    break;
+                }
+            }
+        }
+    }
+    
+    // 扩展缓冲区
+    if (g_agnss_response_buffer == NULL) {
+        g_agnss_response_capacity = 512 * 1024;
+        g_agnss_response_buffer = (char *)malloc(g_agnss_response_capacity);
+        if (g_agnss_response_buffer == NULL) {
+            return;
+        }
+        g_agnss_response_size = 0;
+        memset(g_agnss_response_buffer, 0, g_agnss_response_capacity);
+    }
+    
+    // 检查是否需要扩展缓冲区
+    if (g_agnss_response_size + len > g_agnss_response_capacity) {
+        size_t new_capacity = g_agnss_response_capacity * 2;
+        if (new_capacity > 8 * 1024 * 1024) {
+            return;
+        }
+        char *new_buffer = (char *)realloc(g_agnss_response_buffer, new_capacity);
+        if (new_buffer == NULL) {
+            return;
+        }
+        g_agnss_response_buffer = new_buffer;
+        g_agnss_response_capacity = new_capacity;
+    }
+    
+    // 复制数据到缓冲区
+    memcpy(g_agnss_response_buffer + g_agnss_response_size, data, len);
+    g_agnss_response_size += len;
+    g_agnss_response_buffer[g_agnss_response_size] = '\0';
+}
+
+
+// 递归验证下载的文件
+static void verify_files_recursive(const char *base_path, int *total_count)
+{
+    DIR *dir = opendir(base_path);
+    if (dir == NULL) {
+        return;
+    }
+    
+    struct dirent *entry;
+    
+    while ((entry = readdir(dir)) != NULL) {
+        // 跳过 . 和 .. 目录
+        if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
+            continue;
+        }
+        
+        char full_path[512];
+        snprintf(full_path, sizeof(full_path), "%s/%s", base_path, entry->d_name);
+        
+        // 检查是否是目录
+        DIR *sub_dir = opendir(full_path);
+        if (sub_dir != NULL) {
+            // 这是一个目录,递归遍历
+            closedir(sub_dir);
+            verify_files_recursive(full_path, total_count);
+        } else {
+            // 这是一个文件,检查是否是AGNSS相关文件
+            if (strstr(entry->d_name, ".eph") != NULL || 
+                strstr(entry->d_name, ".dat") != NULL ||
+                strstr(entry->d_name, "AssistInfo") != NULL) {
+                
+                // 检查文件是否存在并获取大小
+                FILE *fp = fopen(full_path, "rb");
+                if (fp != NULL) {
+                    // 获取文件大小
+                    fseek(fp, 0, SEEK_END);
+                    long file_size = ftell(fp);
+                    fclose(fp);
+                    
+                    if (file_size > 0) {
+                        // 检查是否在时间戳文件夹中
+                        char *timestamp_folder = strrchr(base_path, '/');
+                        if (timestamp_folder && timestamp_folder != base_path) {
+                            timestamp_folder++; // 跳过 '/'
+                            printf("✓ %s: %ld bytes (in %s)\n", entry->d_name, file_size, timestamp_folder);
+                        } else {
+                            printf("✓ %s: %ld bytes\n", entry->d_name, file_size);
+                        }
+                        (*total_count)++;
+                    }
+                }
+            }
+        }
+    }
+    
+    closedir(dir);
+}
+
+// 验证下载的文件
+static void verify_downloaded_files(uint32_t selected_timestamp)
+{
+    printf("\n=== Downloaded Files ===\n");
+    
+    int total_count = 0;
+    verify_files_recursive(PGNSS_DATA_PATH, &total_count);
+    
+    printf("Total: %d files in timestamp folder: %s/%u\n", total_count, PGNSS_DATA_PATH, selected_timestamp);
+}
+
+
+static void agnss_process_complete_response(void)
+{
+    // 声明所有变量在函数开始,确保作用域正确
+    char **file_list = NULL;
+    int valid_file_count = 0;
+    int file_list_capacity = 0;
+    char **processed_files = NULL;
+    int processed_count = 0;
+    
+    // 防止重复处理
+    g_processing_count++;
+    if (g_processing_count > 5) 
+    {
+        printf("Warning: Too many processing attempts (%d), skipping to prevent infinite loop\n", g_processing_count);
+        emergency_cleanup();
+        return;
+    }
+    
+    // 获取当前时间戳
+    uint32_t current_timestamp = 0;
+    uapi_get_timestampe_ss(&current_timestamp);
+    printf("Current timestamp: %u\n", current_timestamp);
+    
+    // 添加调试信息,显示当前时间的可读格式
+    time_t current_time = (time_t)current_timestamp;
+    printf("Current time: %s", ctime(&current_time));
+    
+    if (g_agnss_response_buffer && g_agnss_response_size > 0) 
+    {
+        printf("Processing complete AGNSS response, size: %zu bytes\n", g_agnss_response_size);
+        
+        // 智能清理JSON数据
+        smart_json_cleanup();
+        
+        // 验证JSON格式并修复截断问题 - 更智能的版本
+        if (g_agnss_response_buffer[0] != '{' || g_agnss_response_buffer[g_agnss_response_size - 1] != '}') 
+        {
+            printf("Warning: Response doesn't appear to be valid JSON\n");
+            printf("First char: '%c', Last char: '%c'\n", 
+                   g_agnss_response_buffer[0], 
+                   g_agnss_response_buffer[g_agnss_response_size - 1]);
+            
+            // 检查是否有明显的截断标记
+            if (strstr(g_agnss_response_buffer, "1ff8") || strstr(g_agnss_response_buffer, "0x0D")) 
+            {
+                printf("Warning: JSON data appears to be truncated with corruption markers\n");
+                // 尝试找到最后一个完整的JSON对象
+                char *last_complete = NULL;
+                char *search_pos = g_agnss_response_buffer;
+                while ((search_pos = strstr(search_pos, "}]")) != NULL)
+                {
+                    last_complete = search_pos + 2;
+                    search_pos += 2;
+                }
+                if (last_complete) 
+                {
+                    size_t new_size = last_complete - g_agnss_response_buffer;
+                    g_agnss_response_size = new_size;
+                    g_agnss_response_buffer[g_agnss_response_size] = '\0';
+                    printf("Truncated JSON to last complete object, new size: %zu bytes\n", g_agnss_response_size);
+                }
+            }
+            
+            // 尝试查找JSON开始和结束
+            char *json_start = strchr(g_agnss_response_buffer, '{');
+            char *json_end = strrchr(g_agnss_response_buffer, '}');
+            
+            // 检查是否有截断的JSON数据
+            if (strstr(g_agnss_response_buffer, "1ff8") || strstr(g_agnss_response_buffer, "0x0D"))
+            {
+                printf("Warning: Detected corrupted JSON data with truncation markers\n");
+                // 尝试找到最后一个完整的JSON对象
+                char *last_complete = NULL;
+                char *search_pos = g_agnss_response_buffer;
+                while ((search_pos = strstr(search_pos, "}]")) != NULL) 
+                {
+                    last_complete = search_pos + 2;
+                    search_pos += 2;
+                }
+                if (last_complete) 
+                {
+                    json_end = last_complete - 1; // 指向 '}' 字符
+                    printf("Truncated to last complete JSON object at position %ld\n", 
+                           json_end - g_agnss_response_buffer);
+                }
+            }
+            
+            if (json_start && json_end && json_end > json_start) 
+            {
+                printf("Found JSON content between positions %ld and %ld\n", 
+                       json_start - g_agnss_response_buffer, 
+                       json_end - g_agnss_response_buffer);
+                
+                // 验证这个JSON片段是否完整
+                int brace_count = 0;
+                int bracket_count = 0;
+                for (char *p = json_start; p <= json_end; p++) 
+                {
+                    if (*p == '{') brace_count++;
+                    else if (*p == '}') brace_count--;
+                    else if (*p == '[') bracket_count++;
+                    else if (*p == ']') bracket_count--;
+                }
+                
+                if (brace_count == 0 && bracket_count == 0) 
+                {
+                    // 调整缓冲区指针和大小
+                    size_t new_size = json_end - json_start + 1;
+                    memmove(g_agnss_response_buffer, json_start, new_size);
+                    g_agnss_response_size = new_size;
+                    g_agnss_response_buffer[g_agnss_response_size] = '\0';
+                    printf("Adjusted buffer size to %zu bytes (complete JSON)\n", g_agnss_response_size);
+                } 
+                else 
+                {
+                    printf("Found JSON fragment but structure incomplete - braces: %d, brackets: %d\n", brace_count, bracket_count);
+                    // 尝试查找最后一个完整的JSON对象
+                    char *last_complete = NULL;
+                    char *search_pos = g_agnss_response_buffer;
+                    
+                    // 查找最后一个完整的 "}]" 
+                    while ((search_pos = strstr(search_pos, "}]")) != NULL) 
+                    {
+                        last_complete = search_pos + 2;
+                        search_pos += 2;
+                    }
+                    
+                    // 如果没有找到 "}]",尝试查找最后一个 "}"
+                    if (!last_complete) 
+                    {
+                        search_pos = g_agnss_response_buffer;
+                        while ((search_pos = strchr(search_pos, '}')) != NULL)
+                        {
+                            last_complete = search_pos + 1;
+                            search_pos += 1;
+                        }
+                    }
+                    
+                    if (last_complete) 
+                    {
+                        size_t new_size = last_complete - g_agnss_response_buffer;
+                        g_agnss_response_size = new_size;
+                        g_agnss_response_buffer[g_agnss_response_size] = '\0';
+                        printf("Truncated to last complete JSON object, size: %zu bytes\n", g_agnss_response_size);
+                    } 
+                    else 
+                    {
+                        printf("Could not find any complete JSON structure, using original data\n");
+                    }
+                }
+            } 
+            else
+            {
+                printf("Error: Could not find valid JSON boundaries\n");
+                printf("JSON start found: %s\n", json_start ? "yes" : "no");
+                printf("JSON end found: %s\n", json_end ? "yes" : "no");
+                
+                // 尝试查找最后一个完整的JSON对象
+                char *last_complete = NULL;
+                char *search_pos = g_agnss_response_buffer;
+                
+                // 查找最后一个完整的 "}]" 
+                while ((search_pos = strstr(search_pos, "}]")) != NULL) 
+                {
+                    last_complete = search_pos + 2;
+                    search_pos += 2;
+                }
+                
+                // 如果没有找到 "}]",尝试查找最后一个 "}"
+                if (!last_complete) 
+                {
+                    search_pos = g_agnss_response_buffer;
+                    while ((search_pos = strchr(search_pos, '}')) != NULL) 
+                    {
+                        last_complete = search_pos + 1;
+                        search_pos += 1;
+                    }
+                }
+                
+                if (last_complete) 
+                {
+                    size_t new_size = last_complete - g_agnss_response_buffer;
+                    g_agnss_response_size = new_size;
+                    g_agnss_response_buffer[g_agnss_response_size] = '\0';
+                    printf("Truncated to last complete JSON object, size: %zu bytes\n", g_agnss_response_size);
+                } 
+                else 
+                {
+                    printf("Could not find any complete JSON structure, using original data\n");
+                }
+            }
+        }
+        
+        printf("AGNSS JSON data:\n%s\n", g_agnss_response_buffer);
+        
+        // 检查JSON数据完整性
+        int brace_count = 0;
+        int bracket_count = 0;
+        for (size_t i = 0; i < g_agnss_response_size; i++) {
+            if (g_agnss_response_buffer[i] == '{') brace_count++;
+            else if (g_agnss_response_buffer[i] == '}') brace_count--;
+            else if (g_agnss_response_buffer[i] == '[') bracket_count++;
+            else if (g_agnss_response_buffer[i] == ']') bracket_count--;
+        }
+        
+        if (brace_count != 0 || bracket_count != 0) {
+            printf("Warning: JSON structure incomplete - braces: %d, brackets: %d\n", brace_count, bracket_count);
+            
+            // 如果JSON结构不完整,尝试修复
+            if (brace_count > 0 || bracket_count > 0) {
+                // 缺少右大括号或右方括号,尝试添加
+                printf("Attempting to fix incomplete JSON by adding missing braces/brackets\n");
+                size_t needed_braces = (brace_count > 0) ? brace_count : 0;
+                size_t needed_brackets = (bracket_count > 0) ? bracket_count : 0;
+                
+                // 防止过度修复
+                if (needed_braces > 10 || needed_brackets > 10) {
+                    printf("Warning: Too many missing braces/brackets (%zu/%zu), skipping fix to prevent corruption\n", 
+                           needed_braces, needed_brackets);
+                } else {
+                    // 计算需要扩展的缓冲区大小
+                    size_t additional_size = needed_braces + needed_brackets;
+                    char *new_buffer = (char *)realloc(g_agnss_response_buffer, g_agnss_response_size + additional_size + 1);
+                    if (new_buffer) {
+                        g_agnss_response_buffer = new_buffer;
+                        
+                        // 添加缺少的右方括号和右大括号
+                        for (size_t i = 0; i < needed_brackets; i++) {
+                            g_agnss_response_buffer[g_agnss_response_size++] = ']';
+                        }
+                        for (size_t i = 0; i < needed_braces; i++) {
+                            g_agnss_response_buffer[g_agnss_response_size++] = '}';
+                        }
+                        g_agnss_response_buffer[g_agnss_response_size] = '\0';
+                        
+                        printf("Fixed JSON structure, new size: %zu bytes\n", g_agnss_response_size);
+                    } else {
+                        printf("Failed to allocate memory for JSON fix\n");
+                    }
+                }
+            }
+        } else {
+            printf("JSON structure appears complete\n");
+        }
+        
+        // 使用已在函数开始处声明的文件列表变量
+        
+        // 优化逻辑:找出符合条件的时间戳文件夹,选择最接近当前时间的
+        printf("\n=== 分析文件夹时间戳,选择最接近的文件夹 ===\n");
+        printf("当前时间戳: %u\n", current_timestamp);
+        
+        // 存储找到的符合条件的时间戳
+        uint32_t selected_timestamp = 0;
+        uint32_t min_time_diff = 0xFFFFFFFF;
+        int valid_folder_count = 0;
+        
+        // 从JSON数据中提取所有downloadUrl,分析文件夹时间戳
+        char *search_pos = g_agnss_response_buffer;
+        while ((search_pos = strstr(search_pos, "\"downloadUrl\":")) != NULL) {
+            search_pos += 14; // 跳过 "downloadUrl":
+            
+            // 找到URL的开始和结束
+            char *url_start = strchr(search_pos, '"');
+            if (!url_start) continue;
+            url_start++; // 跳过开始的引号
+            
+            char *url_end = strchr(url_start, '"');
+            if (!url_end) continue;
+            
+            // 提取URL
+            int url_len = url_end - url_start;
+            if (url_len > 0 && url_len < 512) {
+                char download_url[512] = {0};
+                strncpy(download_url, url_start, url_len);
+                download_url[url_len] = '\0';
+                
+                // 从URL中提取文件夹时间戳
+                char *folder_pos = strstr(download_url, "/iot_gnss/");
+                if (folder_pos) {
+                    folder_pos += 10; // 跳过 "/iot_gnss/"
+                    char *next_slash = strchr(folder_pos, '/');
+                    if (next_slash) {
+                        int folder_len = next_slash - folder_pos;
+                        if (folder_len > 0 && folder_len < 32) {
+                            char folder_timestamp_str[32] = {0};
+                            strncpy(folder_timestamp_str, folder_pos, folder_len);
+                            folder_timestamp_str[folder_len] = '\0';
+                            
+                            uint32_t folder_timestamp = strtoul(folder_timestamp_str, NULL, 10);
+                            
+                            // 检查时间戳是否在24小时内且小于当前时间
+                            if (folder_timestamp <= current_timestamp) {
+                                uint32_t time_diff = current_timestamp - folder_timestamp;
+                                if (time_diff < 86400) { // 24小时 = 86400秒
+                                    valid_folder_count++;
+                                    
+                                    // 选择时间差最小的文件夹
+                                    if (time_diff < min_time_diff) {
+                                        min_time_diff = time_diff;
+                                        selected_timestamp = folder_timestamp;
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            
+            search_pos = url_end + 1;
+        }
+        
+        if (selected_timestamp > 0) {
+            printf("找到 %d 个有效文件夹,选择最接近的: %u (时间差: %u秒)\n", 
+                   valid_folder_count, selected_timestamp, min_time_diff);
+            
+            // 一次性创建选定的时间戳文件夹,避免重复创建
+            char selected_folder_path[512];
+            snprintf(selected_folder_path, sizeof(selected_folder_path), "%s/%u", PGNSS_DATA_PATH, selected_timestamp);
+            
+            // 检查文件夹是否已存在
+            DIR *dir = opendir(selected_folder_path);
+            if (dir == NULL) {
+                // 文件夹不存在,创建它
+                uapi_create_folder(selected_folder_path);
+            } else {
+                // 文件夹已存在,关闭目录句柄
+                closedir(dir);
+            }
+        } else {
+            printf("没有找到符合条件的时间戳文件夹\n");
+        }
+        
+        // 简化逻辑:通过字符串比较筛选downloadURL
+        if (strstr(g_agnss_response_buffer, "\"success\":true") && strstr(g_agnss_response_buffer, "\"code\":20000")) {
+            printf("AGNSS API call successful, parsing file list...\n");
+            
+            // 解析JSON,提取文件列表
+            char *data_start = strstr(g_agnss_response_buffer, "\"data\":[");
+            
+            if (selected_timestamp > 0) {
+                printf("开始下载时间戳 %u 的文件...\n", selected_timestamp);
+            
+            // 将选定的时间戳转换为字符串,用于字符串比较
+            char selected_timestamp_str[32];
+            snprintf(selected_timestamp_str, sizeof(selected_timestamp_str), "%u", selected_timestamp);
+            
+            if (data_start) {
+                data_start += 8; // 跳过 "data":[
+                
+                // 遍历所有文件项
+                char *item_start = data_start;
+                int download_count = 0;
+                
+                while ((item_start = strstr(item_start, "{")) != NULL && 
+                       (item_start - g_agnss_response_buffer) < (long)g_agnss_response_size) {
+                    
+                    // 提取fileName
+                    char *filename_start = strstr(item_start, "\"fileName\":\"");
+                    if (!filename_start) {
+                        item_start++;
+                        continue;
+                    }
+                    filename_start += 12; // 跳过 "fileName":"
+                    
+                    char *filename_end = strchr(filename_start, '"');
+                    if (!filename_end) {
+                        item_start++;
+                        continue;
+                    }
+                    
+                    int filename_len = filename_end - filename_start;
+                    if (filename_len <= 0 || filename_len >= 256) {
+                        item_start++;
+                        continue;
+                    }
+                    
+                    char filename[256] = {0};
+                    strncpy(filename, filename_start, filename_len);
+                    filename[filename_len] = '\0';
+                    
+                    // 提取downloadUrl
+                    char *url_start = strstr(item_start, "\"downloadUrl\":\"");
+                    if (!url_start) {
+                        item_start++;
+                        continue;
+                    }
+                    url_start += 15; // 跳过 "downloadUrl":"
+                    
+                    char *url_end = strchr(url_start, '"');
+                    if (!url_end) {
+                        item_start++;
+                        continue;
+                    }
+                    
+                    int url_len = url_end - url_start;
+                    if (url_len <= 0 || url_len >= 512) {
+                        item_start++;
+                        continue;
+                    }
+                    
+                    char download_url[512] = {0};
+                    strncpy(download_url, url_start, url_len);
+                    download_url[url_len] = '\0';
+                    
+                    // 通过字符串比较检查URL是否属于选定的时间戳文件夹
+                    char *folder_check = strstr(download_url, selected_timestamp_str);
+                    if (folder_check) {
+                        // 确保这是文件夹名,而不是文件名中的时间戳
+                        char *iot_gnss_pos = strstr(download_url, "/iot_gnss/");
+                        if (iot_gnss_pos && folder_check > iot_gnss_pos) {
+                            // 下载文件
+                            if (download_agnss_file_with_url(filename, download_url) == 0) {
+                                download_count++;
+                            }
+                        }
+                    }
+                    
+                    // 移动到下一个文件项
+                    char *next_item = strstr(item_start, "},");
+                    if (next_item) {
+                        item_start = next_item + 2;
+                        } else {
+                            char *last_item = strstr(item_start, "}");
+                            if (last_item) {
+                                item_start = last_item + 1;
+                            } else {
+                                break;
+                            }
+                        }
+                    }
+                    
+                    printf("成功下载 %d 个文件到时间戳文件夹: %s/%u\n", download_count, PGNSS_DATA_PATH, selected_timestamp);
+                } else {
+                    printf("没有找到符合条件的时间戳文件夹,跳过下载\n");
+                }
+            } else {
+                printf("没有找到符合条件的时间戳文件夹\n");
+            }
+        } else {
+            printf("AGNSS API call failed or returned error\n");
+        }
+        
+        // 清理缓冲区
+        free(g_agnss_response_buffer);
+        g_agnss_response_buffer = NULL;
+        g_agnss_response_size = 0;
+        g_agnss_response_capacity = 0;
+        
+        // 重置处理计数器
+        g_processing_count = 0;
+        
+        // 验证下载的文件
+        verify_downloaded_files(selected_timestamp);
+        
+    } else {
+        printf("No response buffer or empty response\n");
+    }
+}
+
+// 使用新的httpclient.h接口的AGNSS文件下载函数
+int download_agnss_file(const char *filename)
+{
+    printf("Downloading file: %s\n", filename);
+    
+    // 获取当前时间戳
+    uint32_t timestamp = 0;
+    uapi_get_timestampe_ss(&timestamp);
+    
+    // 构建完整URL
+    char full_url[512];
+    snprintf(full_url, sizeof(full_url), 
+        "http://iot-pub.tos-cn-guangzhou.volces.com/dev/AGNSS/geteph?deviceId=121314243&timestamp=%u", 
+        timestamp);
+    
+    printf("Download URL: %s\n", full_url);
+    
+    // 使用新的httpclient.h接口下载文件
+    HTTPC_RESULT result = download_file_with_httpclient(filename, full_url);
+    
+    if (result == HTTP_SUCCESS) {
+        printf("File %s downloaded successfully\n", filename);
+        return 0;
+    } else {
+        printf("File %s download failed: %d\n", filename, result);
+        return -1;
+    }
+}
+
+
+// URL解析函数
+static BK_URL parse_url(const char *url) {
+    BK_URL result = {NULL, NULL, 0, NULL, NULL, NULL};
+    
+    if (!url) {
+        result.error = "URL is NULL";
+        return result;
+    }
+    
+    char *temp_url = strdup(url);
+    if (!temp_url) {
+        result.error = "Failed to allocate memory";
+        return result;
+    }
+    
+    char *temp_ptr = temp_url;
+    
+    // 解析协议
+    char *colon = strchr(temp_ptr, ':');
+    if (!colon) {
+        result.error = "Invalid URL: No protocol specified";
+        free(temp_url);
+        return result;
+    }
+    *colon = '\0';
+    result.protocol = strdup(temp_ptr);
+    temp_ptr = colon + 3;  // 跳过 "://"
+    
+    // 解析主机和端口
+    char *slash = strchr(temp_ptr, '/');
+    if (!slash) {
+        result.error = "Invalid URL: No path specified";
+        free(temp_url);
+        return result;
+    }
+    *slash = '\0';
+    
+    char *colon_port = strchr(temp_ptr, ':');
+    if (colon_port) {
+        *colon_port = '\0';
+        result.host = strdup(temp_ptr);
+        result.port = atoi(colon_port + 1);
+        if (!result.port) {
+            result.error = "Invalid port number";
+            free(temp_url);
+            return result;
+        }
+    } else {
+        result.host = strdup(temp_ptr);
+        if (!strcmp(result.protocol, "http")) {
+            result.port = 80;
+        } else if (!strcmp(result.protocol, "https")) {
+            result.port = 443;
+        }
+    }
+    
+    temp_ptr = slash + 1;
+    
+    // 解析路径和查询字符串
+    char *question = strchr(temp_ptr, '?');
+    if (question) {
+        *question = '\0';
+        result.path = strdup(temp_ptr);
+        result.query = strdup(question + 1);
+    } else {
+        result.path = strdup(temp_ptr);
+        result.query = NULL;
+    }
+    
+    free(temp_url);
+    return result;
+}
+
+// 释放URL结构体
+static void free_url(BK_URL *url) {
+    if (url) {
+        free(url->protocol);
+        free(url->host);
+        free(url->path);
+        free(url->query);
+        free(url->error);
+        memset(url, 0, sizeof(BK_URL));
+    }
+}
+
+
+
+
+int download_agnss_files(void)
+{
+    //通讯开始,唤醒cat1
+    cat1_api_add_cat1_vote();
+    cat1_api_wakeup_cat1(1);
+    cat1_api_keep_wakeup(1);
+    cat1_api_disable_cat1_cmd(1);
+    
+    // 等待CAT1就绪
+    LOS_Msleep(1000);
+    
+    // 获取当前时间戳
+    uint32_t timestamp = 0;
+    uapi_get_timestampe_ss(&timestamp);
+    
+    // 构建完整URL
+    char full_url[512];
+    snprintf(full_url, sizeof(full_url), 
+        "http://app.api.thisiot.com/dev/AGNSS/geteph?deviceId=121314243&timestamp=%u", 
+        timestamp);
+    
+    // 清理之前的缓冲区
+    cleanup_agnss_response_buffer();
+    
+    // 添加重试机制
+    int max_retries = 6;
+    int retry_count = 0;
+    HTTPC_RESULT result = HTTP_EDNS;
+    
+    while (retry_count < max_retries) {
+        if (retry_count > 0) {
+            LOS_Msleep(300); // 减少重试等待时间
+        }
+        
+        // 初始化HTTP客户端
+        HttpClient client = {0};
+        HttpClientData clientData = {0};
+        
+        // 设置HTTP客户端参数
+        client.isHttp = true;
+        client.remotePort = 80;
+        
+        // 准备客户端数据
+        HTTPC_RESULT prep_result = HttpClientPrepare(&clientData, 2048, 256 * 1024);
+        if (prep_result != HTTP_SUCCESS) {
+            retry_count++;
+            continue;
+        }
+        
+        // 执行HTTP GET请求
+        result = HttpClientGetRequest(&client, full_url, &clientData);
+        
+        if (result == HTTP_SUCCESS) {
+            // 检查响应状态码
+            int response_code = HttpClientGetResponseCode(&client);
+            
+            if (response_code == 200) {
+                // 处理响应数据
+                if (clientData.responseBuf && clientData.responseBufLen > 0) {
+                    // 调用结果处理函数
+                    agnss_download_result_handler(NULL, HTTP_SUCCESS, response_code, 
+                                                clientData.responseBuf, clientData.responseBufLen);
+                } else {
+                    agnss_download_result_handler(NULL, HTTP_ERECV, response_code, NULL, 0);
+                }
+            } else {
+                agnss_download_result_handler(NULL, HTTP_EPROTO, response_code, NULL, 0);
+            }
+            break;
+        } else {
+            // 简化错误处理,只保留必要的等待
+            if (result == HTTP_EDNS) {
+                LOS_Msleep(500);
+            } else if (result == HTTP_ECONN) {
+                cleanup_agnss_response_buffer();
+                LOS_Msleep(300);
+            } else if (result == HTTP_ENOBUFS) {
+                cleanup_agnss_response_buffer();
+                LOS_Msleep(300);
+            }
+        }
+        
+        // 清理资源
+        HttpClientUnprepare(&clientData);
+        HttpClientClse(&client);
+        
+        retry_count++;
+    }
+    
+    if (result != HTTP_SUCCESS) {
+        agnss_download_result_handler(NULL, result, 0, NULL, 0);
+    }
+    
+    return 0;
+}
+
+
+void do_gnss_http_server_send_data(int cmd,char *data,uint32_t len)
+{
+    errcode_t ret;
+    gnss_http_data_mail_t send_data = {0};
+    send_data.cmd = cmd;
+    if(len && data)
+    {
+        send_data.len = len;
+        send_data.data = (char *)malloc(len);
+        if(send_data.data == NULL)
+        {
+            PRINT("malloc failed\n");
+            return;
+        }
+        memcpy_s(send_data.data,len,data,len);
+    }
+
+    uint32_t send_len = sizeof(send_data);
+
+    ret = osal_msg_queue_write_copy(g_app_send_queue, (void *)&send_data,
+                                    send_len, 0);
+    if (ret != OSAL_SUCCESS) {
+        PRINT("Error gnss Check MSG 0x send failed! err=0x%x! \r\n", ret);
+    }
+}
+
+void do_gnss_http_server_recv_data(int cmd,char *data,uint32_t len)
+{
+    errcode_t ret;
+    gnss_http_data_mail_t send_data = {0};
+    send_data.cmd = cmd;
+    if(len && data)
+    {
+        send_data.len = len;
+        send_data.data = (char *)malloc(len);
+        if(send_data.data == NULL)
+        {
+            PRINT("malloc failed\n");
+            return;
+        }
+        memcpy_s(send_data.data,len,data,len);
+    }
+
+    uint32_t send_len = sizeof(send_data);
+
+    ret = osal_msg_queue_write_copy(g_app_recv_queue, (void *)&send_data,
+                                    send_len, 0);
+    if (ret != OSAL_SUCCESS) {
+        PRINT("Error gnss Check MSG 0x send failed! err=0x%x! \r\n", ret);
+    }
+}
+
+// 清理AGNSS响应缓冲区
+static void cleanup_agnss_response_buffer(void)
+{
+    if (g_agnss_response_buffer) {
+        free(g_agnss_response_buffer);
+        g_agnss_response_buffer = NULL;
+        g_agnss_response_size = 0;
+        g_agnss_response_capacity = 0;
+        printf("AGNSS response buffer cleaned up\n");
+    }
+}
+
+// 紧急清理函数 - 在检测到问题时调用
+static void emergency_cleanup(void)
+{
+    printf("Emergency cleanup initiated\n");
+    cleanup_agnss_response_buffer();
+    
+    // 重置所有静态变量
+    g_processing_count = 0;
+    
+    // 清理可能的内存泄漏
+    printf("Emergency cleanup completed\n");
+}
+
+// 网络连接检查函数
+static int check_network_connectivity(void)
+{
+    printf("=== Checking Network Connectivity ===\n");
+    
+    // 检查CAT1电源状态
+    int cat1_status = uapi_dev_runtime_get_cat1_powerstat();
+    printf("CAT1 power status: %d (1=powered on, 0=powered off)\n", cat1_status);
+    
+    if (cat1_status != 1) {
+        printf("ERROR: CAT1 is not powered on!\n");
+        return -1;
+    }
+    
+    // 检查网络接口状态(如果有相关API)
+    printf("Network interface appears to be available\n");
+    
+    // 等待CAT1完全启动
+    printf("Waiting for CAT1 to fully initialize...\n");
+    LOS_Msleep(1000); // 减少到1秒
+    
+    // 尝试简单的网络测试
+    printf("Network connectivity check completed\n");
+    return 0;
+}
+
+// 内存状态检查函数
+static void check_memory_status(void)
+{
+    printf("=== Checking Memory Status ===\n");
+    
+    // 检查AGNSS响应缓冲区状态
+    if (g_agnss_response_buffer) {
+        printf("AGNSS response buffer: allocated %zu bytes\n", g_agnss_response_capacity);
+    } else {
+        printf("AGNSS response buffer: not allocated\n");
+    }
+    
+    // 清理可能的内存泄漏
+    cleanup_agnss_response_buffer();
+    
+    printf("Memory status check completed\n");
+}
+
+
+// 智能JSON清理函数
+static void smart_json_cleanup(void)
+{
+    if (g_agnss_response_buffer && g_agnss_response_size > 0) {
+        // 查找最后一个完整的JSON对象
+        char *last_complete = NULL;
+        char *search_pos = g_agnss_response_buffer;
+        while ((search_pos = strstr(search_pos, "}]")) != NULL) {
+            last_complete = search_pos + 2;
+            search_pos += 2;
+        }
+        if (last_complete) {
+            size_t new_size = last_complete - g_agnss_response_buffer;
+            if (new_size < g_agnss_response_size) {
+                g_agnss_response_size = new_size;
+                g_agnss_response_buffer[g_agnss_response_size] = '\0';
+                printf("Smart JSON cleanup: truncated to %zu bytes\n", g_agnss_response_size);
+            }
+        }
+    }
+}
+
+static void gnss_http_server_send_task(void const *arg)
+{
+    unused(arg);
+    errcode_t ret;
+
+    gnss_http_data_mail_t mail = {0};
+    uint32_t msgsize = sizeof(gnss_http_data_mail_t);
+
+    while (1) {
+        ret = osal_msg_queue_read_copy(g_app_send_queue, (void *)&mail, &msgsize,
+                                       OSAL_MSGQ_WAIT_FOREVER);
+        if (ret != OSAL_SUCCESS) {
+            continue;
+        }
+
+        if(mail.cmd == GNSS_HTTP_SERVICE_CMD_DATA_UPLOAD)
+        {
+            // http_data_handler((int *)mail.data,mail.len);
+            // http_recv_data_handler(mail.data,mail.len);
+            if(mail.data != NULL)
+            {
+                printf("free(mail.data)\n");
+                free(mail.data);
+            }
+        }
+        else if(mail.cmd == GNSS_HTTP_SERVICE_CMD_SERVER_INIT)
+        {
+            // gnss_http_init();
+            uapi_delete_files(PGNSS_DATA_PATH);
+            // 检查文件夹是否已存在,避免重复创建
+            DIR *dir = opendir(PGNSS_DATA_PATH);
+            if (dir == NULL) {
+                uapi_create_folder(PGNSS_DATA_PATH);
+            } else {
+                closedir(dir);
+            }
+    
+            // gnss_http_sign_up();
+            // if(LK_STATUS == 1)
+            // {
+            //     gnss_agnss_get_ephemeris();
+            // }
+            // else
+            // {
+            //     printf("NOT LK\n");
+            // }
+
+        }
+        else if(mail.cmd == GNSS_HTTP_SERVICE_CMD_SERVER_DEINIT)
+        {
+            // gnss_http_deinit();
+        }
+        else if(mail.cmd == GNSS_HTTP_SERVICE_CMD_DOWNLOAD_AGNSS)
+        {
+            uapi_delete_files(PGNSS_DATA_PATH);
+            // 检查文件夹是否已存在,避免重复创建
+            DIR *dir = opendir(PGNSS_DATA_PATH);
+            if (dir == NULL) {
+                uapi_create_folder(PGNSS_DATA_PATH);
+            } else {
+                closedir(dir);
+            }
+
+            printf("Starting AGNSS files download via queue...\n");
+            download_agnss_files();
+            printf("AGNSS files download completed via queue.\n");
+        }
+    }
+}
+
+
+static void gnss_http_server_recv_task(void const *arg)
+{
+    unused(arg);
+    errcode_t ret;
+
+    gnss_http_data_mail_t mail = {0};
+    uint32_t msgsize = sizeof(gnss_http_data_mail_t);
+    
+    // 添加任务保护计数器
+    int task_loop_count = 0;
+    const int max_loop_count = 10000; // 防止无限循环
+
+    while (1) {
+        task_loop_count++;
+        if (task_loop_count > max_loop_count) {
+            printf("Warning: Task loop count exceeded %d, resetting counter\n", max_loop_count);
+            task_loop_count = 0;
+            // 清理可能的内存泄漏
+            cleanup_agnss_response_buffer();
+        }
+        
+        ret = osal_msg_queue_read_copy(g_app_recv_queue, (void *)&mail, &msgsize,
+                                       OSAL_MSGQ_WAIT_FOREVER);
+        if (ret != OSAL_SUCCESS) {
+            continue;
+        }
+        
+        if(mail.cmd == GNSS_HTTP_SERVICE_CMD_AGNSS_RECV)
+        {
+            if (mail.data == NULL) {
+                // 数据接收完成,处理完整的响应
+                printf("AGNSS data reception completed, processing response...\n");
+                agnss_process_complete_response();
+                task_loop_count = 0; // 重置计数器
+            } else {
+                // 接收数据片段
+                printf("AGNSS data received via queue: %d bytes\n", mail.len);
+                agnss_accumulate_data(mail.data, mail.len);
+                free(mail.data); // 释放数据内存
+            }
+        }
+    }
+}
+
+static void create_gnss_http_send_queue(void)
+{
+
+    if (osal_msg_queue_create("gnss_http_service_send_queue", 24, &g_app_send_queue,
+                              0, sizeof(gnss_http_data_mail_t)) != ERRCODE_SUCC) {
+        PRINT("[gnss][service] app create mail fail\n");
+    }
+}
+
+static void create_gnss_http_recv_queue(void)
+{
+
+    if (osal_msg_queue_create("gnss_http_service_recv_queue", 24, &g_app_recv_queue,
+                              0, sizeof(gnss_http_data_mail_t)) != ERRCODE_SUCC) {
+        PRINT("[gnss][service] app create mail fail\n");
+    }
+}
+
+#define GNSS_HTTP_BOARD_TASK_SIZE   0x2000
+errcode_t uapi_gnss_http_server_init(void)
+{
+    PRINT("uapi_gnss_http_server_init !\r\n");
+
+    send_taskcfg.create_queue_handle = create_gnss_http_send_queue;
+    send_taskcfg.attr.name="gnss_http_server_send_task";
+    send_taskcfg.attr.priority = osPriorityNormal;
+    send_taskcfg.attr.stack_size = GNSS_HTTP_BOARD_TASK_SIZE;
+    send_taskcfg.func = gnss_http_server_send_task;
+    send_taskcfg.use_mem = USE_EXTEND_MEM;
+    
+    errcode_t ret=uapi_create_osThread_custom(&send_taskcfg);
+    if(ret != ERRCODE_SUCC)
+    {
+        PRINT("create gnss_send_service failed %d!\r\n",ret);
+        return ERRCODE_FAIL;
+    }
+
+    recv_taskcfg.create_queue_handle = create_gnss_http_recv_queue;
+    recv_taskcfg.attr.name="gnss_http_server_recv_task";
+    recv_taskcfg.attr.priority = osPriorityNormal1;
+    recv_taskcfg.attr.stack_size = GNSS_HTTP_BOARD_TASK_SIZE;
+    recv_taskcfg.func = gnss_http_server_recv_task;
+    recv_taskcfg.use_mem = USE_EXTEND_MEM;
+    
+    ret=uapi_create_osThread_custom(&recv_taskcfg);
+    if(ret != ERRCODE_SUCC)
+    {
+        PRINT("create gnss_recv_service failed %d!\r\n",ret);
+        return ERRCODE_FAIL;
+    }
+
+    return ERRCODE_SUCC;
+}
diff --git a/code/sdk/zhihui/services/gnss/src/gnss_tcp_server.c b/code/sdk/zhihui/services/gnss/src/gnss_tcp_server.c
deleted file mode 100644 (file)
index 21c9f01..0000000
+++ /dev/null
@@ -1,1216 +0,0 @@
-#include "pinctrl.h"
-#include "debug_print.h"
-#include "rtc.h"
-#include "timer.h"
-#include "systick.h"
-
-#include "tcxo.h"
-
-#include "cmsis_os2.h"
-#include "input_app.h"
-#include "gnss_service.h"
-#include "custom_utils.h"
-#include "gnss_tcp_server.h"
-#include "custom_runtime.h"
-#include <dirent.h>
-#include "lwip/ip.h"
-#include "lwip/netif.h"
-#include "lwip/init.h"
-#include "lwip/inet_chksum.h"
-
-#include "lwip/err.h"
-#include "lwip/sockets.h"
-#include "lwip/sys.h"
-#include <lwip/netdb.h>
-// #include <netinet/in.h>
-#include "lwip/inet.h"
-#include "lwip/ip_addr.h"
-#include "pm_definition.h"
-#include "mbedtls/md5.h"
-#include "mbedtls/base64.h"
-#include "cJSON.h"
-#include "mbedtls/hmac_drbg.h"
-
-#define BID "hu4kZYyYMGO"
-#define KEY "tcUpJpeGpsIBXvjG"
-
-#define HOST "iot.socket.thisiot.com"
-#define PORT 9999
-
-#define URL "https://geo-drcn.platform.dbankcloud.cn/higeo/v1/xgnss/agnss"
-#define APP_ID "coolwearable"
-#define APP_SECRET "a0e0852c9fd25fad56b6e281b542020d7d01c975907c0b9585ed7f9462447a59"
-
-#define PGNSS_DATA_PATH          "/user/userdata/gnss"
-
-static unsigned long g_app_queue= 0xFFFFFFFF;
-
-static int g_tcp_sock = -1;
-
-static uint8_t LK_STATUS = 0;
-
-static char *imei = NULL;
-
-static char *rx_buffer = NULL;
-
-static uint8_t GNSS_TCP_SERVER_STAT = 0;
-
-static app_task_definition_t send_taskcfg={0};
-static app_task_definition_t recv_taskcfg={0};
-
-struct gnss_ipaddr_t
-{
-    osSemaphoreId_t dns_done_sem;
-    ip_addr_t  ip;
-};
-
-
-// Base64 编码函数
-static char *base64_encode(const unsigned char *input, size_t length) 
-{
-    // 计算 Base64 编码后的最大长度
-    size_t encoded_len = 4 * ((length + 2) / 3) + 1;
-    char *encoded = (char *)malloc(encoded_len);
-    if (encoded == NULL) {
-        return NULL;
-    }
-
-    size_t output_len;
-    int ret = mbedtls_base64_encode((unsigned char *)encoded, encoded_len, &output_len, input, length);
-    if (ret != 0) {
-        free(encoded);
-        return NULL;
-    }
-
-    return encoded;
-}
-
-static char *compute_hmac_sha256_base64(const char *str_to_sign) 
-{
-    if (str_to_sign == NULL) {
-        fprintf(stderr, "Error: str_to_sign is NULL\n");
-        return NULL;
-    }
-
-    // 输出缓冲区
-    unsigned char hmac_result[32];
-    size_t hmac_len = sizeof(hmac_result);
-    
-    // Base64 编码结果缓冲区
-    size_t b64_len = 4 * ((hmac_len + 2) / 3) + 1;
-    char *base64_result = (char *)malloc(b64_len);
-    if (base64_result == NULL) {
-        fprintf(stderr, "Memory allocation failed\n");
-        return NULL;
-    }
-
-    // 获取 SHA-256 算法信息
-    const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
-    if (md_info == NULL) {
-        fprintf(stderr, "Failed to get SHA-256 algorithm\n");
-        goto cleanup;
-    }
-
-    // 使用标准 HMAC 计算 API
-    int ret = mbedtls_md_hmac(
-        md_info,                  // 算法信息
-        (const unsigned char *)APP_SECRET,  // 密钥
-        strlen(APP_SECRET),       // 密钥长度
-        (const unsigned char *)str_to_sign, // 待签名数据
-        strlen(str_to_sign),      // 数据长度
-        hmac_result               // 输出结果
-    );
-    
-    if (ret != 0) {
-        fprintf(stderr, "HMAC calculation failed: %d\n", ret);
-        goto cleanup;
-    }
-    
-    // 调试输出
-    printf("HMAC-SHA256 result (hex): ");
-    for (int i = 0; i < hmac_len; i++) {
-        printf("%02x", hmac_result[i]);
-    }
-    printf("\n");
-    
-    // Base64 编码
-    size_t olen;
-    ret = mbedtls_base64_encode(
-        (unsigned char *)base64_result, 
-        b64_len, 
-        &olen, 
-        hmac_result, 
-        hmac_len
-    );
-    
-    if (ret != 0) {
-        fprintf(stderr, "Base64 encoding failed: %d\n", ret);
-        free(base64_result);
-        base64_result = NULL;
-        goto cleanup;
-    }
-    
-    printf("Base64 result: %s\n", base64_result);
-
-cleanup:
-    return base64_result;
-}
-
-static void dns_found(const char* hostname, const ip_addr_t *ipaddr, void *arg) 
-{
-    struct gnss_ipaddr_t *ip_sem = (struct gnss_ipaddr_t *)arg;
-    char ip_str[20] = {0};
-    
-    // if (ipaddr == NULL) {
-    //     printf("DNS解析失败,IP地址为空\n");
-    //     (void)osSemaphoreRelease(ip_sem->dns_done_sem);
-    //     return;
-    // }
-    
-    printf("hostname: %s, ", hostname);
-    
-    // 处理IPv4地址(现在ip4是包含addr成员的结构体)
-    if (IP_IS_V4(ipaddr)) {
-        u32_t ip_num = ipaddr->u_addr.ip4.addr;  // 直接获取32位地址
-        
-        // 分解为4字节打印
-        u8_t byte0 = (ip_num >> 24) & 0xFF;
-        u8_t byte1 = (ip_num >> 16) & 0xFF;
-        u8_t byte2 = (ip_num >> 8) & 0xFF;
-        u8_t byte3 = ip_num & 0xFF;
-        // printf("IPv4: %d.%d.%d.%d\n", byte0, byte1, byte2, byte3);
-        
-        // 转换为struct in_addr(已为网络字节序)
-        struct in_addr ipv4_addr;
-        ipv4_addr.s_addr = ip_num;
-        inet_ntop(AF_INET, &ipv4_addr, ip_str, sizeof(ip_str));
-        printf("ip: %s\n", ip_str);
-    }
-
-    // 复制IP地址到上下文
-    if(ipaddr->u_addr.ip4.addr != 0)
-        memcpy(&(ip_sem->ip), ipaddr, sizeof(ip_addr_t));
-    (void)osSemaphoreRelease(ip_sem->dns_done_sem);
-}
-
-int gnss_tcp_socket_init(void) 
-{
-    uint8_t cnt = pm_veto_get_id_cnt(PM_ID_CAT1);
-    if (cnt == 0) {
-        uapi_pm_add_sleep_veto(PM_ID_CAT1);
-    }
-    
-    struct sockaddr_in server_addr;
-    struct gnss_ipaddr_t ip_sem = {0};  // 定义信号量结构
-    int listen_socket = -1;
-    
-    // 创建信号量
-    ip_sem.dns_done_sem = osSemaphoreNew(1, 0, NULL);
-
-    // 解析域名
-    dns_gethostbyname(HOST, &(ip_sem.ip), dns_found, &ip_sem);
-
-    osSemaphoreAcquire(ip_sem.dns_done_sem, 1000);  // 等待 DNS 解析完成
-
-    memcpy(&server_addr.sin_addr.s_addr, &ip_sem.ip.u_addr.ip4, 4);
-    
-    // 创建套接字
-
-    if(listen_socket < 0)
-    {
-        listen_socket = lwip_socket(AF_INET, SOCK_STREAM, 0);
-        if(listen_socket < 0)
-        {
-            int err = errno;
-            printf("socket create errno: %d, reason: %s\n", err, strerror(err));
-            goto FAILED;
-        }
-    }
-
-    int opt = 1;
-    
-    lwip_setsockopt(listen_socket, SOL_SOCKET, SO_KEEPALIVE, (const void*)&opt, sizeof(opt));
-    lwip_setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR,(const void*)&opt, sizeof(opt));
-    
-    // 设置服务器地址
-    server_addr.sin_family = AF_INET;
-    server_addr.sin_port = htons(PORT);
-    
-    // 连接服务器
-    if (lwip_connect(listen_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) 
-    {
-        printf("server_addr.sin_addr.s_addr:%d\n",server_addr.sin_addr.s_addr);
-        int err = errno;
-        printf("connect failed, errno: %d, reason: %s\n", err, strerror(err));
-        
-        goto FAILED;
-    }
-
-    printf("socket init succed\n");
-    osSemaphoreDelete(ip_sem.dns_done_sem);  // 释放信号量
-
-    cnt = pm_veto_get_id_cnt(PM_ID_CAT1);
-    if (cnt == 1) {
-        uapi_pm_remove_sleep_veto(PM_ID_CAT1);
-    }
-
-    return listen_socket;
-    
-FAILED:
-    if (listen_socket >= 0) 
-    {
-        lwip_close(listen_socket);
-    }
-    if (ip_sem.dns_done_sem != NULL) 
-    {
-        osSemaphoreDelete(ip_sem.dns_done_sem);
-    }
-    cnt = pm_veto_get_id_cnt(PM_ID_CAT1);
-    if (cnt == 1) 
-    {
-        uapi_pm_remove_sleep_veto(PM_ID_CAT1);
-    }
-    return -1;
-}
-
-static int tcp_send(int listen_socket, const char *data, size_t size)
-{
-    if (data == NULL || size == 0)
-        return -1;
-
-    uint8_t retry = 0;
-    while(listen_socket < 0 && retry < 5)
-    {
-        retry++;
-        LOS_Msleep(2000);
-    }
-
-    if(listen_socket < 0)
-    {
-        printf("listen_socket < 0 \n");
-        return -1;
-    }
-
-    int ret = 0;
-
-    // const char *buffer = (const char *)data;
-    const char *buffer = (const char *)malloc(size);
-    if(buffer == NULL)
-        return -1;
-        
-    memcpy_s(buffer,size,(const char *)data,size);
-    // printf("size : %d\n",size);
-    // printf("strlen(buffer) : %d\n",strlen(buffer));
-    // printf("buffer : %s\n",buffer);
-
-    size_t total_sent = 0;
-
-    while (total_sent < size)
-    {
-        ssize_t sent = lwip_send(listen_socket, buffer + total_sent, size - total_sent, 0);
-        if (sent < 0) {
-            printf("errno : %d\n",errno);
-            // 处理错误情况
-            if (errno == EINTR) {
-                PRINT("被信号中断,继续尝试\n");
-                ret = -1;
-                continue;
-            } else if (errno == EAGAIN || errno == EWOULDBLOCK) {
-                PRINT("非阻塞模式下暂时无法发送,可选择等待或返回\n"); 
-                ret = -1;
-                goto FAILED;
-            } else if (errno == ENETUNREACH) {
-                PRINT("网络不可达,检查路由或远程主机状态\n");
-                ret = -1;
-                goto FAILED;
-            }
-            else {
-                PRINT("其他错误(如连接断开)\n"); 
-                ret = -1;
-                goto FAILED;
-            }
-        }
-        
-        total_sent += sent;
-    }
-    printf("tcp send succed size : %d\n",total_sent);
-    ret = 0;
-FAILED:
-
-    if(buffer != NULL)
-    {
-        free(buffer);
-        buffer = NULL;
-    }
-    return ret;
-}
-
-static int active_md5_sign(const char *data,int data_len,char*md5_str)
-{
-    char md5_buf[16]={0};
-
-    char *code_str = (const char*)malloc(data_len);
-    if(md5_str == NULL)
-        return -1;
-
-    memcpy_s(code_str,data_len,data,data_len);
-    mbedtls_md5_context ctx;
-
-    // 初始化MD5上下文
-    mbedtls_md5_init(&ctx);
-
-    // 开始计算MD5哈希
-    mbedtls_md5_starts(&ctx);
-    // 更新要计算哈希的数据
-    mbedtls_md5_update(&ctx, (const unsigned char *)code_str, data_len);
-
-    // 完成哈希计算
-    mbedtls_md5_finish(&ctx, (unsigned char *)md5_buf);
-
-    // printf("md5_buf\r\n");
-    // for (int i = 0; i < 16; i++) {
-    //     printf("%02X\n", (uint8_t)md5_buf[i]);
-    // }
-    // printf("md5_buf end\r\n");
-
-    // 清理MD5上下文
-    mbedtls_md5_free(&ctx);
-    for (int i = 0; i < 16; i++) 
-        sprintf(&md5_str[i * 2], "%02x", (uint8_t)md5_buf[i]);
-
-    md5_str[32] = '\0';
-
-    free(code_str);
-
-    return 0;
-}
-
-static void calculate_md5(const char* input, char* md5_str) 
-{
-    mbedtls_md5_context md5;
-    unsigned char md5_digest[16] = {0};
-    int i;
-
-    // printf("input:%s\n",input);
-    
-    mbedtls_md5_init(&md5);
-    mbedtls_md5_starts(&md5);
-    mbedtls_md5_update(&md5, (const unsigned char*)input, strlen(input));
-    mbedtls_md5_finish(&md5, md5_digest);
-    mbedtls_md5_free(&md5);
-    
-    // 转换为十六进制字符串
-    for (i = 0; i < 16; i++) {
-        sprintf(md5_str + i*2, "%02x", md5_digest[i]);
-    }
-    md5_str[32] = '\0';  // 确保字符串终止
-}
-
-int gnss_tcp_sign_up(void)
-{
-    int ret = 0;
-    char len_str[5] = {0};
-    sprintf(len_str, "%04x", 2);
-
-    if(imei == NULL)
-    {
-        imei = uapi_dev_runtime_get_cat1_imei();
-
-        if(imei == NULL || strlen(imei) == 0)
-        {
-            LOS_Msleep(2000);
-            imei = uapi_dev_runtime_get_cat1_imei();
-        }
-        
-        if (imei == NULL || strlen(imei) == 0) 
-        {
-            printf("IMEI get failed\n");
-            ret = -1;
-            goto FAILED;
-        }
-    }
-    // printf("imei:%s\n", imei);
-
-    // head_str长度:BID + * + IMEI + * + len_str + * + LK + \0
-    int head_len = strlen(BID) + 1 + strlen(imei) + 1 + strlen(len_str) + 1 + strlen("LK") + 1;
-    char *head_str = (char *)malloc(head_len);
-    if(head_str == NULL) 
-    {
-        printf("tcp_sign_up head_str malloc failed\n");
-        ret = -1;
-        goto FAILED;
-    }
-
-    snprintf(head_str, head_len, "%s*%s*%s*LK", BID,imei,len_str);
-    head_len = strlen(head_str);
-
-    char md5_str[33] = {0};  // MD5为32字符+1终止符
-
-    // code_str长度:head_str + KEY + \0
-    int code_len = head_len + strlen(KEY) + 1;
-    char *code_str = (char *)malloc(code_len);
-    if(code_str == NULL) 
-    {
-        printf("code_str malloc failed\n");
-        ret = -1;
-        goto FAILED;
-    }
-
-    snprintf(code_str, code_len, "%s%s", head_str, KEY);
-    code_len = strlen(code_str);
-
-    calculate_md5(code_str,md5_str);
-
-    // if(active_md5_sign(code_str, code_len, md5_str) != 0) 
-    // {
-    //     printf("active_md5_sign failed\n");
-    //     ret = -1;
-    //     goto FAILED;
-    // }
-
-    // 计算send_str长度:[ + md5_str + head_str + ] + \0
-    int send_len = 1 + strlen(md5_str) + strlen(head_str) + 1 + 1;
-    char *send_str = (char *)malloc(send_len);
-    if(send_str == NULL) 
-    {
-        printf("send_str malloc failed\n");
-        ret = -1;
-        goto FAILED;
-    }
-
-    snprintf(send_str, send_len, "[%s%s]", md5_str, head_str);
-    send_len = strlen(send_str);
-
-    // printf("md5_str:%s\n", md5_str);
-    // printf("md5_len:%zu\n", strlen(md5_str));
-    // printf("head_len:%d\n", head_len);
-    // printf("head_str:%s\n", head_str);
-    printf("send_len : %d\n", send_len);
-    printf("send_str : %s\n", send_str);
-
-    // 发送数据
-    while(LK_STATUS != 1)
-    {
-        ret = tcp_send(g_tcp_sock, send_str, send_len);
-        if(ret != 0)
-        {
-            printf("tcp_send failed\n");
-            goto FAILED;
-        }
-        
-        LOS_Msleep(2000);
-    }
-
-
-FAILED:
-    // 释放资源
-    if(head_str != NULL)
-    {
-        free(head_str);
-        head_str = NULL;
-    }
-    if(code_str != NULL)
-    {
-        free(code_str);
-        code_str = NULL;
-    }
-    if(send_str != NULL)
-    {
-        free(send_str);
-        send_str = NULL;
-    }
-
-    return ret;
-}
-
-
-static int calculate_base64_length(int cnt) 
-{
-    if (cnt <= 0)
-        return -1;
-    
-    // 1. 计算int数组转换为字符串的最大可能长度
-    // int的最大字符串长度:11个字符(如"-2147483648")
-    // 每个int后加一个逗号(最后一个int除外)
-    int str_length = cnt * 11 + (cnt - 1);
-    
-    // 2. 计算Base64编码长度
-    // Base64编码规则:每3字节明文→4字节编码,不足3字节用'='填充
-    int base64_length = (str_length * 4 + 2) / 3;
-    
-    // 3. 确保编码长度足够容纳终止符
-    base64_length += 1;  // 预留终止符空间
-    
-    return base64_length;
-}
-
-int gnss_tcp_login(void)
-{
-    int ret = -1;
-    char *data_str = NULL;
-    int data_len = 0;
-    char *encode_str = NULL;
-    int encode_len = 0;
-
-    int head_len = 0;
-    char *code_str = NULL;
-    int code_len = 0;
-    char *send_str = NULL;
-    int send_len = 0;
-    uint32_t output_len = 0;
-    int temp_len = 0;
-    
-    char len_str[5] = {0};
-    char md5_str[33] = {0};
-
-    uint32_t time = 0;
-    uapi_get_timestampe_ss(&time);
-    printf("time:%d \n",time);
-
-    char *sign_str = (char *)malloc(256);
-    if(sign_str == NULL)
-    {
-        printf("sign_str malloc failed\n");
-        goto FAILED;
-    }
-
-    snprintf(sign_str,256, "GET&/higeo/v1/xgnss/agnss&&&appid=%s&timestamp=%lld", APP_ID,(long long)time * 1000);
-    // snprintf(sign_str,256, "GET&/higeo/v1/xgnss/agnss&&appid=%s&timestamp=%lld", APP_ID,(long long)time * 1000);
-    // snprintf(sign_str,256, "GET&/higeo/v1/xgnss/agnss&&appid=%s&timestamp=%d", APP_ID,time*1000);
-    // snprintf(sign_str,256, "GET&/higeo/v1/xgnss/agnss&&&appid=coolwearable&timestamp=1752717734000");
-    
-    printf("sign_str : %s\n",sign_str);
-    char *ret_str = compute_hmac_sha256_base64(sign_str);
-    if(ret_str == NULL)
-    {
-        printf("compute_hmac_sha256_base64 failed\n");
-        goto FAILED;
-    }
-
-    printf("ret_str : %s\n",ret_str);
-
-
-    char *header_json = (char *)malloc(512);
-    if(header_json == NULL)
-        goto FAILED;
-
-    temp_len = 0;
-       // temp_len += snprintf(header_json + temp_len,512 - temp_len, "{\"headers\":[");
-       // temp_len += snprintf(header_json + temp_len,512 - temp_len, "{\"key\":\"Authorization\",");
-       // temp_len += snprintf(header_json + temp_len,512 - temp_len, "\"value\":\"HMAC-SHA256\"},");
-
-    // temp_len += snprintf(header_json + temp_len,512 - temp_len, "{\"key\":\"appid\",");
-    // temp_len += snprintf(header_json + temp_len,512 - temp_len, "\"value\":\"%s\"},", APP_ID);
-
-       // temp_len += snprintf(header_json + temp_len,512 - temp_len, "{\"key\":\"timestamp\",");
-       // temp_len += snprintf(header_json + temp_len,512 - temp_len, "\"value\":\"%lld\"},", (long long)time * 1000);   
-
-       // temp_len += snprintf(header_json + temp_len,512 - temp_len, "{\"key\":\"signature\",");
-       // temp_len += snprintf(header_json + temp_len,512 - temp_len, "\"value\":\"%s\"},", ret_str);  
-
-    // temp_len += snprintf(header_json + temp_len,512 - temp_len, "{\"key\":\"X-Request-ID\",");
-       // temp_len += snprintf(header_json + temp_len,512 - temp_len, "\"value\":\"%s\"}", imei);
-       // temp_len += snprintf(header_json + temp_len,512 - temp_len, "]}");
-
-
-    temp_len += snprintf(header_json + temp_len,256 - temp_len, "{\"headers\":[");
-    temp_len += snprintf(header_json + temp_len,256 - temp_len, "{\"key\":\"X-Request-ID\",");
-       temp_len += snprintf(header_json + temp_len,256 - temp_len, "\"value\":\"%s\"},", imei);
-       temp_len += snprintf(header_json + temp_len,256 - temp_len, "{\"key\":\"Authorization\",");
-       temp_len += snprintf(header_json + temp_len,256 - temp_len, "\"value\":\"HMAC-SHA256 appid=%s,timestamp=%lld,signature=%s\"}", APP_ID,(long long)time * 1000,ret_str);
-       temp_len += snprintf(header_json + temp_len,256 - temp_len, "]}");
-
-    if(temp_len > 512)
-    {
-        printf("temp_len > 512 \n");
-        goto FAILED;
-    }
-    printf("URL : %s\n",URL);
-    printf("header_json : %s\n",header_json);
-
-       int encode_header_len = temp_len * 3 / 2;
-       char *encode_header_str = (char *)malloc(encode_header_len);
-       if(NULL == encode_header_str)
-       {
-               printf("encode_header_str malloc failed\n");
-               goto FAILED;
-       }
-
-       memset(encode_header_str,0, encode_header_len);
-    size_t output_header_len = 0;
-       if(0 != mbedtls_base64_encode((unsigned char*)encode_header_str, encode_header_len, &output_header_len, (const unsigned char*)header_json, temp_len))
-       {
-        printf("encode_header_str base64 encode failed\n");
-               goto FAILED;
-       }       
-
-    data_len = 1 + strlen("GET") + 1 + strlen(URL) + 1 + 1 + output_header_len + 1;
-    data_str = (char *)malloc(data_len);
-    if (data_str == NULL) {
-        printf("data_str malloc failed\n");
-        goto FAILED;
-    }
-    memset(data_str, 0, data_len);
-    snprintf(data_str,data_len, ",GET,%s,%s,", URL,encode_header_str);
-
-    data_len = strlen(data_str);
-    sprintf(len_str, "%04x", data_len + 8);
-
-    head_len = strlen(BID) + 1 + strlen(imei) + 1 + strlen(len_str) + 1 + strlen("TCP_HTTP") + 1;
-    // head_len = strlen(BID) + 1 + 15 + 1 + strlen(len_str) + 1 + strlen("TCP_HTTP") + 1;
-    char *head_str = (char *)malloc(head_len);
-    if (head_str == NULL) {
-        printf("head_str malloc failed\n");
-        goto FAILED;
-    }
-    snprintf(head_str, head_len, "%s*%s*%s*TCP_HTTP", BID, imei, len_str);
-    // snprintf(head_str, head_len, "%s*864430010001091*%s*TCP_HTTP", BID, len_str);
-    
-    head_len = strlen(head_str);
-
-    code_len = head_len + strlen(KEY) + 1;
-    code_str = (char *)malloc(code_len);
-    if (code_str == NULL) {
-        printf("code_str malloc failed\n");
-        goto FAILED;
-    }
-    snprintf(code_str, code_len, "%s%s", head_str, KEY);
-    // printf("code_str:%s\n", code_str);
-    // printf("code_len:%d\n", code_len);
-
-    calculate_md5(code_str,md5_str);
-    if(strlen(md5_str) == 0)
-    {
-        printf("MD5 failed\n");
-        goto FAILED;
-    }
-    // if (active_md5_sign(code_str, code_len, md5_str) != 0) {
-    //     printf("MD5签名失败\n");
-    //     goto FAILED;
-    // }
-
-    send_len = 1 + strlen(md5_str) + head_len + data_len + 1 + 1;  // [ + md5 + head + data + ] + \0
-
-    send_str = (char *)malloc(send_len);
-    if (send_str == NULL) {
-        printf("send_str malloc failed\n");
-        goto FAILED;
-    }
-    snprintf(send_str, send_len, "[%s%s%s]", md5_str, head_str, data_str);
-    send_len = strlen(send_str);
-
-
-    // printf("md5_str:%s\n", md5_str);
-    // printf("md5_len:%zu\n", strlen(md5_str));
-    // printf("head_len:%d\n", head_len);
-    // printf("head_str:%s\n", head_str);
-    // printf("data_len:%d\n", data_len);
-    // printf("data_str:%s\n", data_str);
-    printf("send_len : %d\n", send_len);
-    printf("send_str : %s\n", send_str);
-
-    // 发送数据
-    ret = tcp_send(g_tcp_sock, send_str, send_len);
-    if(ret != 0)
-    {
-        printf("tcp_send failed\n");
-        goto FAILED;
-    }
-
-FAILED:
-    if (header_json != NULL) {
-        free(header_json);
-        header_json = NULL;
-    }
-    if (sign_str != NULL) {
-        free(sign_str);
-        sign_str = NULL;
-    }
-    if (ret_str != NULL) {
-        free(ret_str);
-        ret_str = NULL;
-    }
-    if (send_str != NULL) {
-        free(send_str);
-        send_str = NULL;
-    }
-    if (code_str != NULL) {
-        free(code_str);
-        code_str = NULL;
-    }
-    if (head_str != NULL) {
-        free(head_str);
-        head_str = NULL;
-    }
-    if (data_str != NULL) {
-        free(data_str);
-        data_str = NULL;
-    }
-    if (encode_str != NULL) {
-        free(encode_str);
-        encode_str = NULL;
-    }
-
-    return ret;
-}
-
-void do_gnss_tcp_server_send_data(int cmd,char *data,uint32_t len)
-{
-    if((data == NULL || len == 0) && cmd == GNSS_TCP_SERVICE_CMD_DATA_UPLOAD)
-        return;
-
-    errcode_t ret;
-    gnss_tcp_data_mail_t send_data = {0};
-    send_data.cmd = cmd;
-    if(len && data)
-    {
-        send_data.len = len;
-        send_data.data = (char *)malloc(len);
-        if(send_data.data == NULL)
-        {
-            PRINT("malloc failed\n");
-            return;
-        }
-        memcpy_s(send_data.data,len,data,len);
-    }
-
-    uint32_t send_len = sizeof(send_data);
-
-    ret = osal_msg_queue_write_copy(g_app_queue, (void *)&send_data,
-                                    send_len, 0);
-    if (ret != OSAL_SUCCESS) {
-        PRINT("Error gnss Check MSG 0x send failed! err=0x%x! \r\n", ret);
-    }
-}
-
-static void gnss_tcp_deinit(void)
-{
-    printf("gnss_tcp_deinit \n");
-        
-    GNSS_TCP_SERVER_STAT = 0;
-
-    LK_STATUS = 0;
-
-    if(rx_buffer != NULL)
-    {
-        printf("free rx_buffer\n");
-        free(rx_buffer);
-        rx_buffer = NULL;
-    }
-    if(g_tcp_sock >= 0)
-    {
-        if(lwip_close(g_tcp_sock) != 0)
-            printf("lwip_close failed\n");
-        else
-            printf("lwip_close succed\n");
-
-        g_tcp_sock = -1;
-    }
-
-}
-
-int gnss_tcp_init(void)
-{ 
-    if(LK_STATUS != 1)
-    {
-        printf("NOT LK\n");
-        return -1; 
-    }
-    gnss_tcp_login();
-    return 0;
-}
-
-static void pgnss_data_save(uint8_t *rx_buffer, uint32_t len)
-{
-    if (rx_buffer == NULL || len == 0) {
-        printf("invalid param\n");
-        return;
-    }
-
-    FILE *fp = fopen(PGNSS_DATA_PATH, "a+b");
-    if (fp == NULL) {
-        printf("open %s failed\n", PGNSS_DATA_PATH);
-        return;
-    }
-
-    size_t written = fwrite(rx_buffer, 1, len, fp);
-    if (written != len) {
-        printf("fwrite failed\n");
-    } else {
-        printf("fwrite succed :%d\n", written);
-    }
-
-    fflush(fp);
-    fclose(fp);
-}
-
-static void tcp_recv_data_handler(const char *input, int input_len) 
-{
-    if(input[0] == '[')
-    {
-        const char *data = input + 1;
-        size_t data_len = input_len - 2;
-        
-        const char *comma1 = memchr(data, ',', data_len);
-        const char *comma2 = comma1 ? memchr(comma1 + 1, ',', data_len - (comma1 - data + 1)) : NULL;
-
-        const char *star1 = memchr(data, '*', data_len);
-        const char *star2 = star1 ? memchr(star1 + 1, '*', data_len - (star1 - data + 1)) : NULL;
-        const char *star3 = star2 ? memchr(star2 + 1, '*', data_len - (star2 - data + 1)) : NULL;
-        
-        if (!star1 || !star2 || !star3) 
-        {
-            printf("解析失败: 头部格式错误(缺少星号分隔符)\n");
-            return;
-        }
-        
-        const char *bid = data;
-        const char *imei = star1 + 1;
-        const char *len_str = star2 + 1;
-        const char *cmd = star3 + 1;
-        
-        size_t bid_len = star1 - data;
-        size_t imei_len = star2 - (star1 + 1);
-        size_t len_str_len = star3 - (star2 + 1);
-        size_t cmd_len = data_len - (star3 - data + 1);
-        
-        // 打印头部解析结果
-        // printf("BID: %.*s\n", (int)bid_len, bid);
-        // printf("IMEI: %.*s\n", (int)imei_len, imei);
-        // printf("内容长度: %.*s\n", (int)len_str_len, len_str);
-        // printf("指令: %.*s\n", (int)cmd_len, cmd);
-        
-        // 验证IMEI长度(假设为15位)
-        if (imei_len != 15) 
-        {
-            printf("解析失败: IMEI长度应为15位,实际: %zu位\n", imei_len);
-            return;
-        }
-        
-        uint32_t content_len = 0;
-        sscanf(len_str, "%x", &content_len);
-        printf("解析后的内容长度: %u\n", content_len);
-
-        if (comma1 && comma2) 
-        {
-            size_t status_len = comma2 - (comma1 + 1);
-            size_t base64_len = data_len - (comma2 - data + 1);
-            
-            printf("状态码: %.*s\n", (int)status_len, comma1 + 1);
-            
-            if (strncmp(comma1 + 1, "200", status_len) != 0) 
-            {
-                printf("解析失败: 状态码必须为200,实际: %.*s\n", (int)status_len, comma1 + 1);
-                return;
-            }
-
-            size_t decoded_len = (base64_len * 3) / 4 + 1;
-            unsigned char *decoded_data = malloc(decoded_len);
-            if (!decoded_data) 
-            {
-                printf("解析失败: 内存分配失败\n");
-                return;
-            }
-            
-            size_t actual_decoded_len = 0;
-            int ret = mbedtls_base64_decode(decoded_data, decoded_len, &actual_decoded_len,(const unsigned char *)(comma2 + 1), base64_len);
-            
-            if (ret != 0)
-            {
-                printf("解析失败: Base64解码失败 (错误码: %d) :%s\n", ret,input);
-                free(decoded_data);
-                return;
-            }
-            decoded_data[actual_decoded_len] = '\0';
-
-            for (uint32_t i = 0; i < actual_decoded_len; i++) 
-            {
-                printf("%02X ", decoded_data[i]);
-            }
-            printf("\n");
-
-            // remove(AGNSS_DATA_PATH);
-            pgnss_data_save(decoded_data,actual_decoded_len);
-        }
-    }
-    else if(input[input_len - 1] == ']')
-    {
-        size_t decoded_len = ((input_len - 1) * 3) / 4 + 1;
-        unsigned char *decoded_data = malloc(decoded_len);
-        if (!decoded_data) 
-        {
-            printf("解析失败: 内存分配失败\n");
-            return;
-        }
-        
-        size_t actual_decoded_len = 0;
-        int ret = mbedtls_base64_decode(decoded_data, decoded_len, &actual_decoded_len,(const unsigned char *)(input), input_len - 1);
-        
-        if (ret != 0)
-        {
-            printf("解析失败: Base64解码失败 (错误码: %d) :%s\n", ret,input);
-            free(decoded_data);
-            return;
-        }
-        decoded_data[actual_decoded_len] = '\0';
-
-        for (uint32_t i = 0; i < actual_decoded_len; i++) 
-        {
-            printf("%02X ", decoded_data[i]);
-        }
-        printf("\n");
-        pgnss_data_save(decoded_data,actual_decoded_len);
-        LOS_Msleep(1000);
-        do_gnss_tcp_server_send_data(GNSS_TCP_SERVICE_CMD_SERVER_DEINIT,NULL,0);
-    }
-    else
-    {
-        size_t decoded_len = (input_len * 3) / 4 + 1;
-        unsigned char *decoded_data = malloc(decoded_len);
-        if (!decoded_data) 
-        {
-            printf("解析失败: 内存分配失败\n");
-            return;
-        }
-        
-        size_t actual_decoded_len = 0;
-        int ret = mbedtls_base64_decode(decoded_data, decoded_len, &actual_decoded_len,(const unsigned char *)(input), input_len);
-        
-        if (ret != 0)
-        {
-            printf("解析失败: Base64解码失败 (错误码: %d) :%s\n", ret,input);
-            free(decoded_data);
-            return;
-        }
-        decoded_data[actual_decoded_len] = '\0';
-
-        for (uint32_t i = 0; i < actual_decoded_len; i++) 
-        {
-            printf("%02X ", decoded_data[i]);
-        }
-        printf("\n");
-        pgnss_data_save(decoded_data,actual_decoded_len);
-    }
-        
-}
-
-static void gnss_tcp_server_send_task(void const *arg)
-{
-    unused(arg);
-    errcode_t ret;
-
-    gnss_tcp_data_mail_t mail = {0};
-    uint32_t msgsize = sizeof(gnss_tcp_data_mail_t);
-
-    while (GNSS_TCP_SERVER_STAT) {
-        ret = osal_msg_queue_read_copy(g_app_queue, (void *)&mail, &msgsize,
-                                       OSAL_MSGQ_WAIT_FOREVER);
-        if (ret != OSAL_SUCCESS) {
-            continue;
-        }
-
-        if(mail.cmd == GNSS_TCP_SERVICE_CMD_DATA_UPLOAD)
-        {
-            // tcp_data_handler((int *)mail.data,mail.len);
-            tcp_recv_data_handler(mail.data,mail.len);
-            if(mail.data != NULL)
-            {
-                printf("free(mail.data)\n");
-                free(mail.data);
-            }
-        }
-        else if(mail.cmd == GNSS_TCP_SERVICE_CMD_SERVER_INIT)
-        {
-            // gnss_tcp_init();
-            uapi_delete_files(PGNSS_DATA_PATH);
-            uapi_create_folder(PGNSS_DATA_PATH);
-    
-            gnss_tcp_sign_up();
-            if(LK_STATUS == 1)
-            {
-                gnss_tcp_login();
-            }
-            else
-            {
-                printf("NOT LK\n");
-            }
-
-        }
-        else if(mail.cmd == GNSS_TCP_SERVICE_CMD_SERVER_DEINIT)
-        {
-            gnss_tcp_deinit();
-        }
-    }
-}
-
-
-static void gnss_tcp_server_recv_task(void *pvParameters)
-{
-    while (GNSS_TCP_SERVER_STAT)
-    {
-        if (!uapi_cat1_get_power_stat())
-        {
-            PRINT("wating cat1 power on\n");
-            LOS_Msleep(2000);
-            continue;
-        }
-
-        if (g_tcp_sock < 0) 
-        {
-            g_tcp_sock = gnss_tcp_socket_init();
-            if (g_tcp_sock < 0)
-            {
-                PRINT("wating tcp socket init\n");
-                LOS_Msleep(1000);
-                continue;
-            }
-            else
-                do_gnss_tcp_server_send_data(GNSS_TCP_SERVICE_CMD_SERVER_INIT,NULL,0);
-        }
-
-        if(rx_buffer == NULL)
-        {
-            rx_buffer = (char *)malloc(2048);
-            if(rx_buffer == NULL)
-            {
-                printf("rx_buffer malloc failed\n");
-                do_gnss_tcp_server_send_data(GNSS_TCP_SERVICE_CMD_SERVER_DEINIT,NULL,0);
-                return;
-            }
-        }
-
-        // if (tcp_socket_init() != 0) 
-        // {
-        //     PRINT("wating tcp socket init\n");
-        //     LOS_Msleep(100);
-        //     continue;
-        // }
-
-        // PRINT("tcp socket init succed\n");
-
-        // get_active_code();
-        // if(tcp_sign_up() != 0)
-        // {
-        //     LOS_Msleep(1000);
-        //     continue;
-        // }
-
-        // printf("tcp_sign_up\n");
-
-        memset(rx_buffer, 0, 2048);
-        int len = recv(g_tcp_sock, rx_buffer, 2048 - 1, 0);
-        if (len > 0) 
-        {
-            rx_buffer[len] = '\0';
-            // printf("Received %d bytes: %s\n", len, rx_buffer);
-            if(strstr(rx_buffer,"LK") != NULL)
-            {
-                printf("LK succed\n");
-                LK_STATUS = 1;
-            }
-            else
-            {
-                do_gnss_tcp_server_send_data(GNSS_TCP_SERVICE_CMD_DATA_UPLOAD,rx_buffer,len);
-            }
-        }
-        else if (len == 0) 
-        {
-            printf("Connection closed by peer\n");
-            do_gnss_tcp_server_send_data(GNSS_TCP_SERVICE_CMD_SERVER_DEINIT,NULL,0);
-        }
-    }
-}
-
-static void create_gnss_tcp_queue(void)
-{
-
-    if (osal_msg_queue_create("gnss_tcp_service_queue", 24, &g_app_queue,
-                              0, sizeof(gnss_tcp_data_mail_t)) != ERRCODE_SUCC) {
-        PRINT("[gnss][service] app create mail fail\n");
-    }
-}
-
-#define GNSS_TCP_BOARD_TASK_SIZE   0x2000
-errcode_t uapi_gnss_tcp_server_init(void)
-{
-    PRINT("uapi_gnss_tcp_server_init !\r\n");
-
-    if(GNSS_TCP_SERVER_STAT == 1)
-    {
-        PRINT("uapi_gnss_tcp_server already init !\r\n");
-        return ERRCODE_SUCC;
-    }
-
-    GNSS_TCP_SERVER_STAT = 1;
-
-    send_taskcfg.create_queue_handle = create_gnss_tcp_queue;
-    send_taskcfg.attr.name="gnss_tcp_server_send_task";
-    send_taskcfg.attr.priority = osPriorityNormal;
-    send_taskcfg.attr.stack_size = GNSS_TCP_BOARD_TASK_SIZE;
-    send_taskcfg.func = gnss_tcp_server_send_task;
-    send_taskcfg.use_mem = USE_EXTEND_MEM;
-    
-    errcode_t ret=uapi_create_osThread_custom(&send_taskcfg);
-    if(ret != ERRCODE_SUCC)
-    {
-        PRINT("create gnss_send_service failed %d!\r\n",ret);
-        return ERRCODE_FAIL;
-    }
-
-    recv_taskcfg.create_queue_handle = NULL;
-    recv_taskcfg.attr.name="gnss_tcp_server_recv_task";
-    recv_taskcfg.attr.priority = osPriorityNormal1;
-    recv_taskcfg.attr.stack_size = GNSS_TCP_BOARD_TASK_SIZE;
-    recv_taskcfg.func = gnss_tcp_server_recv_task;
-    recv_taskcfg.use_mem = USE_EXTEND_MEM;
-    
-    ret=uapi_create_osThread_custom(&recv_taskcfg);
-    if(ret != ERRCODE_SUCC)
-    {
-        PRINT("create gnss_recv_service failed %d!\r\n",ret);
-        return ERRCODE_FAIL;
-    }
-
-    // g_gnss_service_timer = osTimerNew((osTimerFunc_t)gnss_service_check_timer_callback, osTimerPeriodic, NULL, NULL);
-
-    return ERRCODE_SUCC;
-}
-
-// void gnss_tcp_server_suspend(void)
-// {
-//     if(recv_taskcfg.task_handle == NULL || send_taskcfg.task_handle)
-//         return;
-
-    
-//     errcode_t ret = uapi_suspend_thread(recv_taskcfg.task_handle);
-//     if(ret != ERRCODE_SUCC)
-//         PRINT("gnss_recv_thread_suspend failed ret : %d \n",ret);
-//     else
-//         PRINT("gnss_recv_thread_suspend succed\n");
-
-//     ret = uapi_suspend_thread(send_taskcfg.task_handle);
-//     if(ret != ERRCODE_SUCC)
-//         PRINT("gnss_send_thread_suspend failed ret : %d \n",ret);
-//     else
-//         PRINT("gnss_send_thread_suspend succed\n");
-
-// }
-
-// void gnss_tcp_server_resume(void)
-// {
-//     if(recv_taskcfg.task_handle == NULL || send_taskcfg.task_handle)
-//         return;
-
-//     errcode_t ret = uapi_suspend_thread(recv_taskcfg.task_handle);
-//     if(ret != ERRCODE_SUCC)
-//         PRINT("gnss_recv_thread_suspend failed ret : %d \n",ret);
-//     else
-//         PRINT("gnss_recv_thread_suspend succed\n");
-
-//     ret = uapi_suspend_thread(send_taskcfg.task_handle);
-//     if(ret != ERRCODE_SUCC)
-//         PRINT("gnss_send_thread_suspend failed ret : %d \n",ret);
-//     else
-//         PRINT("gnss_send_thread_suspend succed\n");
-
-// }
\ No newline at end of file
index ead43e5..fc5be2d 100644 (file)
@@ -1969,17 +1969,25 @@ int removeFilesInFolder(const char *folderPath)
             snprintf(filePath, sizeof(filePath), "%s/%s", folderPath, entry->d_name);
             stat(filePath,&s_buf);
             if(S_ISDIR(s_buf.st_mode))
-                ret = removeFilesInFolder(filePath);
+                ret = removeFilesInFolder(filePath);  // 递归删除子文件夹
             else
-                ret = remove(filePath);
+                ret = remove(filePath);  // 删除文件
             if(ret != 0)
                 PRINT("%s remove failed !!! \r\n",filePath);
-            // else
-            //     // PRINT("%s remove succeed !!! \r\n",filePath);
+            else
+                PRINT("%s remove succeed !!! \r\n",filePath);
         }
     }
 
     closedir(dir);
+    
+    // 删除空文件夹本身
+    ret = rmdir(folderPath);
+    if(ret != 0)
+        PRINT("%s folder remove failed !!! \r\n",folderPath);
+    else
+        PRINT("%s folder remove succeed !!! \r\n",folderPath);
+    
     return ret;
 }
 /*删除文件*/
@@ -1988,27 +1996,45 @@ int uapi_delete_files(const char *file_path)
        struct stat s_buf;
     int ret = 0;
 
+    if(file_path == NULL)
+    {
+        PRINT("file_path is NULL!!!\r\n");
+        return 0;
+    }
+
     if(access(file_path, F_OK) == -1)
     {
         PRINT("%s does not exist!!!\r\n", file_path);
-        return 0 ;
+        return 0;
     }
-    stat(file_path,&s_buf);
+    
+    if(stat(file_path,&s_buf) != 0)
+    {
+        PRINT("Failed to get stat for %s!!!\r\n", file_path);
+        return 0;
+    }
+    
     if(S_ISDIR(s_buf.st_mode))
+    {
+        PRINT("Deleting directory: %s (including subdirectories)\r\n", file_path);
         ret = removeFilesInFolder(file_path);
+    }
     else
+    {
+        PRINT("Deleting file: %s\r\n", file_path);
         ret = remove(file_path);
+    }
+    
     if(ret != 0)
     {
-        // PRINT("%s remove failed !!! \r\n",file_path);
+        PRINT("%s remove failed !!! \r\n",file_path);
         return 0;
     }
     else
     {
-        // PRINT("%s remove succeed !!! \r\n",file_path);
+        PRINT("%s remove succeed !!! \r\n",file_path);
         return 1;
     }
-        
 }
 
 /*删除文件夹*/