优化PGNSS数据注入
authorpenglei <1624952103@qq.com>
Mon, 21 Jul 2025 07:15:59 +0000 (15:15 +0800)
committerpenglei <1624952103@qq.com>
Mon, 21 Jul 2025 07:15:59 +0000 (15:15 +0800)
13 files changed:
code/sdk/application/wearable/fd230app/nativeui/producttest/include/testGPS.h
code/sdk/application/wearable/fd230app/nativeui/producttest/src/testGPS.cpp
code/sdk/application/wearable/fd230app/nativeui/traing/src/TraingModel.cpp
code/sdk/drivers/peripheral/gnss/CMakeLists.txt
code/sdk/drivers/peripheral/gnss/inc/NMEA0183.h
code/sdk/drivers/peripheral/gnss/sample/pgnss_sample/CMakeLists.txt [new file with mode: 0644]
code/sdk/drivers/peripheral/gnss/sample/pgnss_sample/gnss_datatypes.h [new file with mode: 0644]
code/sdk/drivers/peripheral/gnss/sample/pgnss_sample/pgnss_encode.c [new file with mode: 0644]
code/sdk/drivers/peripheral/gnss/sample/pgnss_sample/pgnss_encode.h [new file with mode: 0644]
code/sdk/drivers/peripheral/gnss/sample/pgnss_sample/pgnss_sample.c [new file with mode: 0644]
code/sdk/drivers/peripheral/gnss/sample/pgnss_sample/pgnss_sample.h [new file with mode: 0644]
code/sdk/drivers/peripheral/gnss/src/gnss_ctl.c
code/sdk/drivers/peripheral/gnss/src/uart_gnss.c

index 382013c..95ad12d 100644 (file)
@@ -2,7 +2,7 @@
  * @Author: penglei 1624952103@qq.com
  * @Date: 2025-06-06 15:56:46
  * @LastEditors: penglei 1624952103@qq.com
- * @LastEditTime: 2025-06-06 15:57:04
+ * @LastEditTime: 2025-07-21 14:07:39
  * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/producttest/include/testGPS.h
  * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
  */
@@ -77,6 +77,7 @@ namespace OHOS
         UILabel *InitLabel(LabelConfig &labelConfig);
         bool testGPSScrollViewcrollViewinit(uint8_t);
         UIScrollView *testGPSScrollView{nullptr};
+        UIImageView *tempImage{nullptr};
         UILabel *label_1_GPS_MSG=NULL;
         UILabel *label_1_GPS_on_or_off{nullptr};
         UILabelButtonExt*  GPSbutton[2]{nullptr};
index 4341286..3813dce 100644 (file)
@@ -8,11 +8,12 @@
 #if defined(SUPPORT_GNSS)
 
 #include "NMEA0183.h"
+#include "pgnss_sample.h"
 // code/sdk/zhihui/services/gnss/inc/.h
 
 #include "producttest/include/testView.h"
 #include "producttest/include/testGPS.h"
-#include "gnss_sample.h"
+// #include "gnss_sample.h"
 #include "graphic_service.h"
 namespace OHOS
 {
@@ -85,6 +86,11 @@ namespace OHOS
                 GPSbutton[1]=nullptr;
             }
           
+            if(tempImage)
+            {
+                delete tempImage;
+                tempImage = nullptr;
+            }
           
 
             delete testGPSScrollView;
@@ -142,7 +148,7 @@ namespace OHOS
     {
         if (label_1_GPS_MSG != nullptr) {
         
-            gps_data_t * gpsdata=getGPSGlobaldata();
+            gps_data_t * gpsdata=getPGPSGlobaldata();
             gps_data_t gpsd={0};
             if (gpsdata->last_gps_time_ms>0)
             {
@@ -152,7 +158,7 @@ namespace OHOS
             dump_location_data_to_buf(&gpsd,msgtmp,sizeof(msgtmp));
             label_1_GPS_MSG->SetText(msgtmp);
 
-            if (getGnssServerStat()==1)
+            if (getPGnssServerStat()==1)
             {
                 label_1_GPS_on_or_off->SetText("GPS开");
             }else{
@@ -181,6 +187,7 @@ namespace OHOS
         testGPSScrollView->SetStyle(STYLE_BORDER_RADIUS, 0);
         testGPSScrollView->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full);
         testGPSScrollView->SetStyle(STYLE_BORDER_COLOR, Color::Yellow().blue);
+        testGPSScrollView->SetScrollBlankSize(75);
 
         LabelConfig Config = {
             .left = 50,
@@ -266,6 +273,20 @@ namespace OHOS
         testGPSScrollView->Add(Title);
 
 
+        if (tempImage == nullptr)
+        {
+            tempImage = new UIImageView();
+            if (tempImage == nullptr)
+            {
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "tempImage can not be nullptr!");
+                return false;
+            }
+        }
+        tempImage->SetPosition(193, GPSbutton[0]->GetY()+GPSbutton[0]->GetHeight() + 60, 40, 40);
+        testGPSScrollView->Add(tempImage);
+
+
+
         testGPSScrollView->SetTouchable(true);
         testGPSScrollView->SetDraggable(true);
         uint32_t tick;
index fdcfced..b7ac223 100644 (file)
@@ -58,7 +58,7 @@
 #if defined(SUPPORT_GNSS)
 #include "NMEA0183.h"
 #include "gnss_ctl.h"
-#include "gnss_sample.h"
+#include "pgnss_sample.h"
 #include "graphic_service.h"
 gps_data_t send_gps_data = {0};
 #endif
@@ -204,7 +204,7 @@ static void Training_Notify(void *args, const Topic topic, Request *request) {
 #endif
 #if defined(SUPPORT_GNSS)
   //训练GPS
-  gps_data_t *gps_data = getGPSGlobaldata();
+  gps_data_t *gps_data = getPGPSGlobaldata();
   if (gps_data == NULL) {
     PRINT("gps_data == NULL \n");
     return;
@@ -3046,7 +3046,7 @@ static void Traing_TimerCallbackProc(int data) {
     // return;
   }
 #if defined(SUPPORT_GNSS)
-  gps_data_t *gps_data = getGPSGlobaldata();
+  gps_data_t *gps_data = getPGPSGlobaldata();
   if (gps_data == NULL) {
     PRINT("gps_data == NULL \n");
     return;
index 8516172..52c7e18 100644 (file)
@@ -73,4 +73,5 @@ build_component()
 
 
 
-add_subdirectory(sample/gnss_sample)
+# add_subdirectory(sample/gnss_sample)
+add_subdirectory(sample/pgnss_sample)
\ No newline at end of file
index ba7690c..831baec 100644 (file)
@@ -258,6 +258,7 @@ char* get_gps_sentence_type_str(sentence_types sentencetype);
 void dump_location_data(gps_data_t *locationdata);\r
 void dump_location_data_to_buf(gps_data_t *locationdata,char* buf,int max_buflen);\r
 gps_data_t * getGPSGlobaldata(void);\r
+gps_data_t * getPGPSGlobaldata(void);\r
 \r
 void dump_location_data_to_factory(gps_data_t *locationdata,char* buf,int max_buflen);\r
 \r
diff --git a/code/sdk/drivers/peripheral/gnss/sample/pgnss_sample/CMakeLists.txt b/code/sdk/drivers/peripheral/gnss/sample/pgnss_sample/CMakeLists.txt
new file mode 100644 (file)
index 0000000..2e4b603
--- /dev/null
@@ -0,0 +1,42 @@
+#===============================================================================
+# @brief    cmake make file
+# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved.
+#===============================================================================
+set(COMPONENT_NAME "pgnss_sample")
+
+set(SOURCES
+    ${CMAKE_CURRENT_SOURCE_DIR}/pgnss_sample.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/pgnss_encode.c
+)
+
+set(PRIVATE_HEADER
+    ${TIOT_HEADER_LIST}
+)
+
+set(PUBLIC_HEADER
+    ${CMAKE_CURRENT_SOURCE_DIR}
+)
+
+set(PRIVATE_DEFINES
+)
+
+set(PUBLIC_DEFINES
+CONFIG_PGNSS_SAMPLE
+)
+
+set(COMPONENT_CCFLAGS
+    -Wno-implicit-function-declaration
+)
+
+set(WHOLE_LINK
+true
+)
+
+set(BUILD_AS_OBJ
+false
+)
+
+set(MAIN_COMPONENT
+false
+)
+build_component()
diff --git a/code/sdk/drivers/peripheral/gnss/sample/pgnss_sample/gnss_datatypes.h b/code/sdk/drivers/peripheral/gnss/sample/pgnss_sample/gnss_datatypes.h
new file mode 100644 (file)
index 0000000..4d4a9a3
--- /dev/null
@@ -0,0 +1,65 @@
+/*\r
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved.\r
+ * Description: gnss datatypes\r
+ * Author:\r
+ * Create:\r
+ */\r
+#ifndef GNSS_DATATYPES_H\r
+#define GNSS_DATATYPES_H\r
+\r
+#include <stdint.h>\r
+\r
+#define MSG_CONTENT_IDX             2\r
+#define LISTEN_TIME_THR             1000\r
+#define REPORT_MAX_BYTES            10000\r
+\r
+// 消息类型\r
+typedef enum {\r
+    CMD_INJECT_HIS_INFO = 0x0101,               // 历史信息注入\r
+    CMD_PGNSS_INJECT_REF_GPS_TIME = 0x0201,     // GPS时间注入\r
+    CMD_PGNSS_INJECT_REF_LOC = 0x0202,          // 参考位置注入\r
+    CMD_PGNSS_INJECT_EPH_GPS = 0x0203,          // GPS星历注入\r
+    CMD_PGNSS_INJECT_EPH_GANSS = 0x0204,        // 非GPS星历注入\r
+    CMD_PGNSS_INJECT_UTC_GPS = 0x0205,          // GPS UTC注入\r
+    CMD_PGNSS_INJECT_RTI_GPS = 0x0206,          // GPS完好性信息注入\r
+    CMD_PGNSS_INJECT_RTI_GANSS = 0x0207,        // 非GPS完好性信息注入\r
+    CMD_PGNSS_INJECT_ION_GPS = 0x0208,          // GPS电离层参数注入\r
+    CMD_PGNSS_INJECT_AUX_GANSS = 0x0209,        // 非GPS频点转换关系信息注入\r
+    CMD_XGNSS_INJECT_UTC_TIME = 0x0404,         // 最开始注入的UTC时间\r
+    CMD_BUTT,\r
+} GnssCmdType;\r
+\r
+#pragma pack(1)\r
+typedef struct {\r
+    uint16_t  cmd;          // 消息类型\r
+    uint16_t  checkSum;     // 校验和,只计算实际数据部分,不包含头\r
+    uint16_t  sequence;     // 序列号,host下发\r
+    uint16_t  dataLength;   // 数据长度,实际数据的长度,不包含头\r
+    uint8_t   data[0];\r
+} GnssMsg;\r
+\r
+typedef struct {\r
+    uint16_t year;          // YYYY\r
+    uint8_t  month;         // MM, 1~12\r
+    uint8_t  day;           // DD, 1~31\r
+    uint8_t  hour;          // hh, 0~23\r
+    uint8_t  minute;        // mm, 0~59\r
+    uint8_t  second;        // ss, 0~59\r
+    uint16_t ms;            // ms, 0~999\r
+    uint8_t  valid;         // 0: invalid, 1: valid\r
+} GnssUtcTime;\r
+\r
+typedef struct {\r
+    uint32_t time;          // eph reference time\r
+    uint16_t cmd;           // cmd type to injected eph\r
+    uint32_t len;           // actual length of injected eph\r
+} EphHeadInfo;\r
+\r
+typedef struct {\r
+    uint16_t cmd;           // cmd type to injected other assist info\r
+    uint32_t len;           // actual length of injected other assist info\r
+} OtherAssistHeadInfo;\r
+\r
+#pragma pack()\r
+\r
+#endif
\ No newline at end of file
diff --git a/code/sdk/drivers/peripheral/gnss/sample/pgnss_sample/pgnss_encode.c b/code/sdk/drivers/peripheral/gnss/sample/pgnss_sample/pgnss_encode.c
new file mode 100644 (file)
index 0000000..a205bc4
--- /dev/null
@@ -0,0 +1,603 @@
+/*\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
+#include "cywee_hal.h"\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
+        CWM_OS_dbgPrintf("\nerror: [Utc2UnixTime] null pointer!\n");\r
+        return 0;\r
+    }\r
+\r
+    if (utcTime.month > 12 || utcTime.valid == 0) {\r
+        CWM_OS_dbgPrintf("\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
+        CWM_OS_dbgPrintf("\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
+        CWM_OS_dbgPrintf("\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
+        CWM_OS_dbgPrintf("\nerror: PgnssInjectUtcTime error: %d\r\n", ret);\r
+        free(buff);\r
+        return 0;\r
+    }\r
+    if (Utc2UnixTime((*utcTime), ts) == 0) {\r
+        CWM_OS_dbgPrintf("\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
+        CWM_OS_dbgPrintf("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
+                CWM_OS_dbgPrintf("%s\r\n", (char *)&g_ackBuff[MSG_CONTENT_IDX]);\r
+            }\r
+            i++;\r
+        }\r
+        if (i >= 1) {\r
+            CWM_OS_dbgPrintf("\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
+        CWM_OS_dbgPrintf("\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
+        CWM_OS_dbgPrintf("\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
+        CWM_OS_dbgPrintf("\r\nerror: Inject Cmd failed: %d\r\n", cmdType);\r
+        free(buff);\r
+        return 0;\r
+    }\r
+    ListenAck(handle);\r
+    CWM_OS_dbgPrintf("\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
+        CWM_OS_dbgPrintf("\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
+        CWM_OS_dbgPrintf("\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
+        CWM_OS_dbgPrintf("\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
+        CWM_OS_dbgPrintf("\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
+        CWM_OS_dbgPrintf("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
+                        CWM_OS_dbgPrintf("time:%d,ts:%d,interval:%d\r\n",time,ts,interval);\r
+                    }\r
+                }\r
+            }\r
+        }\r
+    }\r
+    closedir(dir);\r
+    CWM_OS_dbgPrintf("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
+        CWM_OS_dbgPrintf("\r\nerror: GetEphFileName failed\r\n");\r
+        return;\r
+    }\r
+    CWM_OS_dbgPrintf("\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
+    CWM_OS_dbgPrintf("send GPS eph success\r\n");\r
+    PgnssSendEphFile(handle, "GLO", CMD_PGNSS_INJECT_EPH_GANSS, ts);\r
+    osal_msleep(INJECT_SLEEP_MS_TIME);\r
+    CWM_OS_dbgPrintf("send GLO eph success\r\n");\r
+    PgnssSendEphFile(handle, "BDS", CMD_PGNSS_INJECT_EPH_GANSS, ts);\r
+    osal_msleep(INJECT_SLEEP_MS_TIME);\r
+    CWM_OS_dbgPrintf("send BDS eph success\r\n");\r
+    PgnssSendEphFile(handle, "GAL", CMD_PGNSS_INJECT_EPH_GANSS, ts);\r
+    osal_msleep(INJECT_SLEEP_MS_TIME);\r
+    CWM_OS_dbgPrintf("send GAL eph success\r\n");\r
+    PgnssSendEphFile(handle, "QZS", CMD_PGNSS_INJECT_EPH_GANSS, ts);\r
+    osal_msleep(INJECT_SLEEP_MS_TIME);\r
+    CWM_OS_dbgPrintf("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
+    CWM_OS_dbgPrintf("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
+    CWM_OS_dbgPrintf("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
+    CWM_OS_dbgPrintf("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
+    CWM_OS_dbgPrintf("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
+    CWM_OS_dbgPrintf("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
+    CWM_OS_dbgPrintf("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
+    CWM_OS_dbgPrintf("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
+        CWM_OS_dbgPrintf("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
+                        CWM_OS_dbgPrintf("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
+        CWM_OS_dbgPrintf("closest eph fileName:%s\r\n", fileName);\r
+        closedir(dir);\r
+        return ((ret <= 0) ? 0 : 1);\r
+    }\r
+    else\r
+    {\r
+        CWM_OS_dbgPrintf("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
+        CWM_OS_dbgPrintf("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
+                    CWM_OS_dbgPrintf("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
+                        CWM_OS_dbgPrintf("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
+        CWM_OS_dbgPrintf("\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
+        CWM_OS_dbgPrintf("\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
+        CWM_OS_dbgPrintf("\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
+        CWM_OS_dbgPrintf("\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
+        CWM_OS_dbgPrintf("\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
+        CWM_OS_dbgPrintf("\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
+        CWM_OS_dbgPrintf("\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
+        CWM_OS_dbgPrintf("\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
+        CWM_OS_dbgPrintf("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
+        CWM_OS_dbgPrintf("\nerror: GetNonGloEphFileName failed\r\n");\r
+        return;\r
+    }\r
+    PgnssSendNonGloEph(handle, fileName);\r
+    if (GetGloEphFileName(ts, fileName) == 0) {\r
+        CWM_OS_dbgPrintf("\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
+        CWM_OS_dbgPrintf("\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
+        CWM_OS_dbgPrintf("\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
+        CWM_OS_dbgPrintf("\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
+        CWM_OS_dbgPrintf("\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
+}
\ No newline at end of file
diff --git a/code/sdk/drivers/peripheral/gnss/sample/pgnss_sample/pgnss_encode.h b/code/sdk/drivers/peripheral/gnss/sample/pgnss_sample/pgnss_encode.h
new file mode 100644 (file)
index 0000000..a666edc
--- /dev/null
@@ -0,0 +1,16 @@
+/*\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
+#endif
\ No newline at end of file
diff --git a/code/sdk/drivers/peripheral/gnss/sample/pgnss_sample/pgnss_sample.c b/code/sdk/drivers/peripheral/gnss/sample/pgnss_sample/pgnss_sample.c
new file mode 100644 (file)
index 0000000..a153c14
--- /dev/null
@@ -0,0 +1,376 @@
+/*\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 "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
+#ifdef SUPPORT_CYWEE_SERVICE\r
+#include "cywee_hal.h"\r
+#include "cywee_service.h"\r
+#endif\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 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
+        CWM_OS_dbgPrintf("\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
+#ifdef SUPPORT_CYWEE_SERVICE\r
+            if(uapi_dev_runtime_get_train_status())\r
+                do_cywee_service_check_msg(CYWEE_SERVICE_CMD_GNSS_UPDATE,NULL);\r
+#endif\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
+        CWM_OS_dbgPrintf("\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
+    CWM_OS_dbgPrintf("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
+        CWM_OS_dbgPrintf("\nerror: PgnssInjectUtcTime failed!\r\n");\r
+        return 0;\r
+    }\r
+    CWM_OS_dbgPrintf("\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
+        CWM_OS_dbgPrintf("\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
+    CWM_OS_dbgPrintf("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
+        CWM_OS_dbgPrintf("\nerror: PgnssInjectUtcTime failed!\r\n");\r
+        return 0;\r
+    }\r
+    CWM_OS_dbgPrintf("\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
+        CWM_OS_dbgPrintf("\nerror: start gnss error: %d\r\n", ret);\r
+        return 0;\r
+    }\r
+    CWM_OS_dbgPrintf("\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
+        CWM_OS_dbgPrintf("\nerror: stop gnss error: %d\r\n", ret);\r
+        return 0;\r
+    }\r
+    CWM_OS_dbgPrintf("\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
+            CWM_OS_dbgPrintf("\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
+                CWM_OS_dbgPrintf("%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
+                        CWM_OS_dbgPrintf("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
+    CWM_OS_dbgPrintf("\nenter gnss samples\r\n");\r
+    if(g_is_pgnss_poweron == 1)\r
+    {\r
+        CWM_OS_dbgPrintf("gnss already on\r\n");\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
+\r
+    // Step1: init\r
+    int32_t ret = tiot_service_init();\r
+    if (ret != 0) {\r
+        CWM_OS_dbgPrintf("tiot service init fail\r\n");\r
+        g_is_pgnss_poweron = 0;\r
+        g_pgnss_stopflag = 1;\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
+            CWM_OS_dbgPrintf("error: open log file error\n");\r
+            return;\r
+        }\r
+    }\r
+    CWM_OS_dbgPrintf("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
+        CWM_OS_dbgPrintf("open tiot service fail\r\n");\r
+        g_is_pgnss_poweron = 0;\r
+        g_pgnss_stopflag = 1;\r
+        return;\r
+    }\r
+    CWM_OS_dbgPrintf("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
+            CWM_OS_dbgPrintf("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
+    CWM_OS_dbgPrintf("finish gnss samples\r\n");\r
+}\r
diff --git a/code/sdk/drivers/peripheral/gnss/sample/pgnss_sample/pgnss_sample.h b/code/sdk/drivers/peripheral/gnss/sample/pgnss_sample/pgnss_sample.h
new file mode 100644 (file)
index 0000000..37d7d51
--- /dev/null
@@ -0,0 +1,26 @@
+/*\r
+ * @Author: penglei 1624952103@qq.com\r
+ * @Date: 2025-07-11 16:41:59\r
+ * @LastEditors: penglei 1624952103@qq.com\r
+ * @LastEditTime: 2025-07-18 17:39:28\r
+ * @FilePath: /FD230/code/sdk/drivers/peripheral/gnss/sample/pgnss_sample/pgnss_sample.h\r
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE\r
+ */\r
+/*\r
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved.\r
+ * Description: pgnss sample\r
+ * Author:\r
+ * Create:\r
+ */\r
+#ifndef PGNSS_SAMPLE_H\r
+#define PGNSS_SAMPLE_H\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif /* __cplusplus */\r
+void PGnssServerStart(void);\r
+void PGnssServerStop(void);\r
+int getPGnssServerStat(void);\r
+#ifdef __cplusplus\r
+}\r
+#endif /* __cplusplus */\r
+#endif
\ No newline at end of file
index e73a5bf..57eca61 100644 (file)
@@ -30,7 +30,8 @@
 #include "gnss_ctl.h"
 #include "gpio.h"
 #include "uart_gnss.h"
-#include "gnss_sample.h"
+// #include "gnss_sample.h"
+#include "pgnss_sample.h"
 // #include "cywee_hal.h"
 
 errcode_t gnss_power_on(void)
@@ -129,7 +130,8 @@ errcode_t gnss_stop(void)
     // uint8_t cmd = GNSS_CMD_STOP;
     // do_gnss_cmd(GNSS_CMD_WRITEDATA, &cmd,1);
     // g_gnss_status = 0;
-    GnssServerStop();
+    // GnssServerStop();
+    PGnssServerStop();
     return 0;
 
 }
index 024893b..506b3b2 100644 (file)
@@ -30,6 +30,7 @@
 #include "uart_gnss.h"
 #include "gnss_ctl.h"
 #include "tiot_board_pin_port.h"
+#include "pgnss_sample.h"
 // errcode_t gnss_get_next_cmd(uint8_t cmd_index,uint8_t** cmdbuf,int *cmdlen);
 // errcode_t gnss_get_current_cmd(uint8_t cmd_index,uint8_t** cmdbuf,int *cmdlen);
 // errcode_t gnss_get_nmea_cfg_cmd(uint8_t** cmdbuf,int *cmdlen);
@@ -181,7 +182,8 @@ static void uart_event_task(void const *arg)
                 break;
                 case GNSS_CMD_START:
                     // gnss_get_start_cmd(&buf,&len);
-                    GnssServerStart();
+                    // GnssServerStart();
+                    PGnssServerStart();
                     last_cfg_cmd_index = 0xFF; //last_cfg_cmd_index=0xFF 代表cfg结束写入,开始检测其他指令
                 break;
                 case GNSS_CMD_STOP: