#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
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
#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
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
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
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*)
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)
typedef enum\r
{\r
TESTVIEW = 0, // 系统视图(slice)\r
+ QRCODE, // 添加二维码视图\r
VISON,\r
LCD,\r
TP,\r
// pressuretest,\r
PRESSURETEST,\r
OLDTEST,\r
- QRCODE, // 添加二维码视图\r
DEEPSLEEP,\r
\r
shutdown,\r
{
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;
int get_save_runtime_log_switch(void);
+/*手表是否绑定*/
+bool cm_getisFirstTimeStart(void);
+
#ifdef __cplusplus
#if __cplusplus
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");
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;
\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
${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
--- /dev/null
+/*
+ * @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
+++ /dev/null
-/*
- * @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
-/*\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
-/*\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
-/*\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(¤t_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();
+ }
+
+}
--- /dev/null
+#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(¤t_timestamp);
+ printf("Current timestamp: %u\n", current_timestamp);
+
+ // 添加调试信息,显示当前时间的可读格式
+ time_t current_time = (time_t)current_timestamp;
+ printf("Current time: %s", ctime(¤t_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(×tamp);
+
+ // 构建完整URL
+ char full_url[512];
+ snprintf(full_url, sizeof(full_url),
+ "http://iot-pub.tos-cn-guangzhou.volces.com/dev/AGNSS/geteph?deviceId=121314243×tamp=%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(×tamp);
+
+ // 构建完整URL
+ char full_url[512];
+ snprintf(full_url, sizeof(full_url),
+ "http://app.api.thisiot.com/dev/AGNSS/geteph?deviceId=121314243×tamp=%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;
+}
+++ /dev/null
-#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×tamp=%lld", APP_ID,(long long)time * 1000);
- // snprintf(sign_str,256, "GET&/higeo/v1/xgnss/agnss&&appid=%s×tamp=%lld", APP_ID,(long long)time * 1000);
- // snprintf(sign_str,256, "GET&/higeo/v1/xgnss/agnss&&appid=%s×tamp=%d", APP_ID,time*1000);
- // snprintf(sign_str,256, "GET&/higeo/v1/xgnss/agnss&&&appid=coolwearable×tamp=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
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;
}
/*删除文件*/
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;
}
-
}
/*删除文件夹*/