gnss: add log save

Change-Id: I5bc9e30eba57c51f70db5b5e0cc7162b785286e8
diff --git a/mbtk/mbtk_gnssd/Makefile b/mbtk/mbtk_gnssd/Makefile
index 521650c..4359afa 100755
--- a/mbtk/mbtk_gnssd/Makefile
+++ b/mbtk/mbtk_gnssd/Makefile
@@ -31,6 +31,7 @@
 					gnss_utils.c \
 					gnss_hd8122.c \
 					gnss_asr5311.c \
+					gnss_log.c \
 					gnss_n50db.c \
 					hd8122_dl/port.c \
 					hd8122_dl/fwup.c
diff --git a/mbtk/mbtk_gnssd/gnss_info.h b/mbtk/mbtk_gnssd/gnss_info.h
index fc4cd37..f29946f 100755
--- a/mbtk/mbtk_gnssd/gnss_info.h
+++ b/mbtk/mbtk_gnssd/gnss_info.h
@@ -92,15 +92,6 @@
     GNSS_STATE_READY,       // GNSS is ready.
 } gnss_state_enum;
 
-typedef enum {
-    LYNQ_TIME_TYPE_CELL = 0,  //NITZ
-    LYNQ_TIME_TYPE_NTP,
-    LYNQ_TIME_TYPE_GNSS,
-    LYNQ_TIME_TYPE_USER,
-    
-    LYNQ_TIME_TYPE_UNUSE
-} lynq_time_type_enum;
-
 typedef struct {
     int cli_fd;
     uint32 ind_flag;
diff --git a/mbtk/mbtk_gnssd/gnss_log.c b/mbtk/mbtk_gnssd/gnss_log.c
new file mode 100755
index 0000000..ef3204c
--- /dev/null
+++ b/mbtk/mbtk_gnssd/gnss_log.c
@@ -0,0 +1,231 @@
+/*

+*    gnss_log.c

+*

+*    gnss test log.

+*

+*/

+/******************************************************************************

+

+                          EDIT HISTORY FOR FILE

+

+  WHEN           WHO           WHAT,WHERE,WHY

+--------    --------------    -------------------------------------------------------

+2024/9/6     wangyouqiang      Initial version

+

+******************************************************************************/

+#include <stdio.h>

+#include <stdlib.h>

+#include <string.h>

+#include <sys/types.h>

+#include <sys/stat.h>

+#include <fcntl.h>

+#include <unistd.h>

+#include <stdarg.h>

+#include <sys/time.h>

+#include <errno.h>

+#include <time.h>

+

+#include "gnss_log.h"

+#include "mbtk_log.h"

+

+#define GNSS_LOG_FOLDER_PATH      "/user_data/mbtk_log"

+#define GNSS_LOG_FILE_PATH        "/user_data/mbtk_log/mbtk_gnss_log.txt"

+#define GNSS_LOG_LAST_FILE_PATH   "/user_data/mbtk_log/mbtk_gnss_last_log.txt"

+#define GNSS_LOG_GNSS_FILE_HEAD   "\n[-------------------mbtk gnss log V1.0-------------------][%d]\n"

+#define GNSS_LOG_FILE_MAX_SIZE    10485760 //10 * 1024 * 1024 10M

+#define GNSS_TIME_CHECK_NUM       10

+

+static int log_file_fd = -1;

+static long log_file_size = 0;

+

+static int mbtk_rmc_num = 0;

+

+static int log_file_init(int *fd, long *size, bool mv_flag)

+{

+    int head_len = 0;

+    int ret = -1;

+    if(access(GNSS_LOG_FOLDER_PATH, F_OK) != 0) 

+    {

+        ret = mkdir(GNSS_LOG_FOLDER_PATH, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);

+        if (ret != 0) 

+        {

+            LOGE("Failed to create folder.");

+            return -1;

+        }

+    }

+

+    if(access(GNSS_LOG_FILE_PATH, F_OK) == 0 && mv_flag) 

+    {

+        char cmd[128] = {0};

+        memset(cmd, 0x0, 128);

+        snprintf(cmd, 128, "mv %s %s", GNSS_LOG_FILE_PATH, GNSS_LOG_LAST_FILE_PATH);

+        LOGE("cmd: [%s].", cmd);

+        system(cmd);

+    }

+

+    *fd = open(GNSS_LOG_FILE_PATH, O_CREAT | O_WRONLY | O_APPEND | O_NONBLOCK, 0644);

+    if(*fd < 0) 

+    {

+        LOGE("Open file fail [errno = %d].", errno);

+        return -1;

+    }

+    else 

+    {

+        char temp[128] = {0};

+        struct stat st;

+        stat(GNSS_LOG_FILE_PATH, &st);

+        *size = st.st_size;

+        snprintf(temp, 128, GNSS_LOG_GNSS_FILE_HEAD, *size);

+        head_len = (int)strlen(temp);

+        ret = write(*fd, temp, head_len);

+        if(ret == head_len) 

+        {

+            *size += ret;

+        }

+        else 

+        {

+            LOGE("write head fail [errno = %d].", errno);

+            goto error;

+        }

+    }

+

+    return 0;

+error:

+    if(*fd > 0) {

+        close(*fd);

+        *fd = -1;

+    }

+    *size = 0;

+    return -1;

+}

+

+void mbtk_gnss_time_check(time_t _time)

+{

+    long diff = 0;

+    struct timeval time;

+    gettimeofday(&time, NULL);

+    time_t sys_time = time.tv_sec;

+    time_t gps_time = _time;

+

+    if(gps_time > sys_time)

+    {

+        diff = gps_time - sys_time;

+    }

+    else

+    {

+        diff = sys_time - gps_time;

+    }

+    

+    gnss_test_log("sys time[%ld], gps time[%ld], diff time[%ld]", sys_time, gps_time, diff);

+}

+

+int mbtk_check_num(void)

+{

+    if(mbtk_rmc_num < GNSS_TIME_CHECK_NUM)

+    {

+        mbtk_rmc_num++;

+        return 1;

+    }

+

+    mbtk_rmc_num = 0;

+    return 0;

+}

+

+void gnss_test_log(const char* format, ...)

+{

+    int ret;

+    

+    if(log_file_fd < 0) 

+    {

+        ret = log_file_init(&log_file_fd, &log_file_size, false);

+        if(ret < 0) 

+        {

+            LOGE("log_file_init fail.");

+            return;

+        }

+        else 

+        {

+            LOGE("log fd: [%d], log size: [%ld].", log_file_fd, log_file_size);

+        }

+    }

+

+    char tmp[50] = {0};

+    char param_buf[1024] = {0};

+    int length = 0;

+    char write_buf[1096] = {0};

+    int write_length = 0;

+    

+    va_list ap;

+    struct timeval log_time;

+

+    va_start(ap, format);

+    length = vsnprintf(param_buf, 1023, format, ap);

+    va_end(ap);

+    

+    if (length < 0 || 0 == length) 

+    {

+        LOGE("vsnprintf fail.");

+        return;

+    }

+    else

+    {

+        if(param_buf[length - 1] != '\n')

+        {

+            param_buf[length] = '\n';

+        }

+    }

+

+    gettimeofday(&log_time, NULL);

+    struct tm* tm_t = localtime(&(log_time.tv_sec));

+    strftime(tmp, 50, "%F %T", tm_t);

+    

+    write_length = snprintf(write_buf, 1096, "[%s %03d]--->%s", tmp, (int)(log_time.tv_usec / 1000), param_buf);

+    if(write_length <= 0)

+    {

+        LOGE("snprintf fail.");

+        return;

+    }

+    

+    if((log_file_size + write_length) > GNSS_LOG_FILE_MAX_SIZE) 

+    {

+        close(log_file_fd);

+        log_file_fd = -1;

+        log_file_size = 0;

+

+        ret = log_file_init(&log_file_fd, &log_file_size, true);

+        if(ret < 0) 

+        {

+            LOGE("log_file_init fail.");

+            goto error;

+        }

+        else 

+        {

+            LOGE("log fd: [%d], log size: [%ld].", log_file_fd, log_file_size);

+        }

+    }

+    

+    ret = write(log_file_fd, write_buf, write_length);

+    if(ret == write_length) 

+    {

+        log_file_size += ret;

+    }

+    else 

+    {

+        goto error;

+    }

+    

+    

+    if (log_file_fd > 2) 

+    {

+        fsync(log_file_fd);

+    } 

+    return;

+error:

+    if(log_file_fd > 0) 

+    {

+        close(log_file_fd);

+        log_file_fd = -1;

+    }

+    log_file_size = 0;

+    return;

+}
\ No newline at end of file
diff --git a/mbtk/mbtk_gnssd/gnss_log.h b/mbtk/mbtk_gnssd/gnss_log.h
new file mode 100755
index 0000000..adf1825
--- /dev/null
+++ b/mbtk/mbtk_gnssd/gnss_log.h
@@ -0,0 +1,19 @@
+/*

+* gnss_log.h

+*

+* GNSS test log.

+*

+* Author : wyq

+* Date   : 2024/9/6 10:20:00

+*/

+

+#ifndef _GNSS_LOG_H

+#define _GNSS_LOG_H

+

+#define MBTK_GNSS_TEST_LOG   1

+#define MBTK_GNSS_TIME_CHECK 1

+

+void mbtk_gnss_time_check(time_t _time);

+int mbtk_check_num(void);

+void gnss_test_log(const char* format, ...);

+#endif
\ No newline at end of file
diff --git a/mbtk/mbtk_gnssd/gnss_main.c b/mbtk/mbtk_gnssd/gnss_main.c
index c820489..3d48ea0 100755
--- a/mbtk/mbtk_gnssd/gnss_main.c
+++ b/mbtk/mbtk_gnssd/gnss_main.c
@@ -19,6 +19,7 @@
 #include "gnss_hd8122.h"
 #include "gnss_asr5311.h"
 #include "gnss_n50db.h"
+#include "gnss_log.h"
 
 #define GNSS_DEBUG 1
 #define GNSS_UBUS_ENABLE 1
@@ -64,8 +65,6 @@
 static int debug_fd_len = 0;
 #endif
 
-static bool mbtk_gnss_time_set_flag = 0;
-
 #if MBTK_GNSS_PTY_AUTO_INIT
 static bool gnss_pty_print_enable = FALSE;
 #endif
@@ -382,220 +381,6 @@
     return TRUE;
 }
 
-static int nmea_tokenizer_init(mbtk_nmeatokenizer* t, const char* head, const char* end, int param_num)
-{
-    int count = 0;
-    const char* p = head;
-    const char* q = end;
-    const char* tmp = NULL;
-    // the initial '$' is optional
-    if (p < q && p[0] == '$')
-    {
-        p += 1;
-    }
-    else
-    {
-        return -1;
-    }
-
-    //find '*',del '*25\r\n'
-    // get rid of checksum at the end of the sentecne
-    if (q >= p + 5 && q[-5] == '*')
-    {
-        q -= 5;
-    }
-    else
-    {
-        return -1;
-    }
-
-    while (p <= q)
-    {
-        tmp = memchr(p, ',', q-p);
-        if (tmp == NULL)
-        {
-            tmp = q;
-        }
-        // if (q > p) {
-        // q >= p include empty token: ,,
-        if (tmp >= p)
-        {
-            if (count < MAX_NMEA_TOKENS)
-            {
-                t->tokens[count].head = p;
-                t->tokens[count].end = tmp;
-                count += 1;
-            }
-        }
-
-        if (tmp <= q)
-        {
-            tmp += 1;
-        }
-
-        p = tmp;
-    }
-
-    if(count != param_num)
-    {
-        LOGD("count [%d], param_num [%d]", count, param_num);
-        return -1;
-    }
-
-    t->count = count;
-    return count;
-}
-
-static mbtk_token nmea_tokenizer_get(mbtk_nmeatokenizer* t, int  index)
-{
-    mbtk_token tok;
-    static const char*  dummy = "";
-
-    if (index < 0 || index >= t->count)
-    {
-        tok.head = tok.end = dummy;
-    }
-    else
-    {
-        tok = t->tokens[index];
-    }
-    return tok;
-}
-
-static int mbtk_time_type_gnss_read() {
-    int type = 0;
-    char time_type[] ={0};
-    property_get("persist.mbtk.time_type", time_type, "0");
-
-    type = atoi(time_type);
-//    LOGD("time_type :%d\n", type);
-    if(type != LYNQ_TIME_TYPE_GNSS)
-        mbtk_gnss_time_set_flag = 0;
-
-    return type;
-}
-
-static int strstr_n(const char *s1, const char *s2)
-{
-    int n;
-    int strlen = 0;
-
-    if(*s2)
-    {
-        while(*s1)
-        {
-            for(n = 0; *(s1+n) == *(s2 + n); n++)
-            {
-                if(!*(s2 + n + 1))
-                {
-                    strlen++;
-                    return strlen;
-                }
-            }
-            s1++;
-            strlen++;
-        }
-        return 0;
-    }
-
-    return 0;
-}
-static int nmea_update_date_time(mbtk_token date, mbtk_token time)
-{
-    char tmp_char[4] = {0};
-    struct tm tmp_time;
-    struct timeval tv;
-
-    memset(&tmp_time, 0x0, sizeof(struct tm));
-    if (date.head + 6 > date.end)
-    {
-        LOGD("date get fail");
-        return -1;
-    }
-
-    memcpy(tmp_char, date.head, 2);
-    tmp_time.tm_mday = atoi(tmp_char);
-    memcpy(tmp_char, date.head + 2, 2);
-    tmp_time.tm_mon = atoi(tmp_char) - 1;
-    memcpy(tmp_char, date.head + 4, 2);
-    tmp_time.tm_year = 100 + atoi(tmp_char);
-
-    if (time.head + 6 > time.end)
-    {
-        LOGD("time get fail");
-        return -1;
-    }
-
-    memcpy(tmp_char, time.head, 2);
-    tmp_time.tm_hour = atoi(tmp_char);
-    memcpy(tmp_char, time.head + 2, 2);
-    tmp_time.tm_min = atoi(tmp_char);
-    memcpy(tmp_char, time.head + 4, 2);
-    tmp_time.tm_sec = atoi(tmp_char);
-    tmp_time.tm_isdst = -1;
-
-
-    LOGD("data:%d-%d-%d %d:%d:%d", tmp_time.tm_year + 1900,
-                                    tmp_time.tm_mon,
-                                    tmp_time.tm_mday,
-                                    tmp_time.tm_hour,
-                                    tmp_time.tm_min,
-                                    tmp_time.tm_sec);
-
-
-    time_t _t = mktime(&tmp_time);//parse location tmp_time
-
-    tzset();   // auto set tz
-    _t = _t - timezone;
-
-    LOGD("timestamp:%ld,  %ld", _t,  timezone);
-
-    tv.tv_sec = _t;
-    if(settimeofday(&tv, NULL)) {
-        LOGD("%s: , Set time fail\n", __func__);
-        mbtk_gnss_time_set_flag = 0;
-    } else {
-        LOGD("%s: , Set time success \n", __func__);
-        system("hwclock -w rtc0");
-        mbtk_gnss_time_set_flag = 1;
-    }
-
-    return 0;
-}
-
-static int ind_nmea_parse(const char *data, int data_len)
-{
-    int ret;
-    mbtk_nmeatokenizer tzer = {0};
-    if(strstr_n(data + 3, "RMC"))
-    {
-        ret = nmea_tokenizer_init(&tzer, data, data + data_len, NMEA_RMC_PARAM_NUM);
-        if(ret < 0)
-        {
-            LOGD("nmea_tokenizer_init fail");
-            return -1;
-        }
-
-        mbtk_token  tok_time      = nmea_tokenizer_get(&tzer,1);
-        mbtk_token  tok_fixStatus = nmea_tokenizer_get(&tzer,2);
-        mbtk_token  tok_date      = nmea_tokenizer_get(&tzer,9);
-
-        if(tok_fixStatus.head[0] == 'A')
-        {
-            ret = nmea_update_date_time(tok_date, tok_time);
-            if(ret < 0)
-            {
-                LOGD("nmea_update_date_time fail");
-                return -1;
-            }
-
-        }
-    }
-
-    return 0;
-}
-
-
 static void gnss_nmea_process(const char *data, int data_len)
 {
 //     LOGD("gnss_nmea_process() : data_len - %d", data_len);
@@ -628,8 +413,9 @@
     log_save(nmea_log_fd, nmea, data_len);
 #endif
 
-    if( (mbtk_time_type_gnss_read() == LYNQ_TIME_TYPE_GNSS) && !mbtk_gnss_time_set_flag)
-        ind_nmea_parse(nmea, data_len);
+#if MBTK_GNSS_PARAM_PARSE
+        gnss_ind_nmea_parse(nmea, data_len);
+#endif
 
     nmea_print(nmea, data_len);
 }
@@ -727,7 +513,11 @@
 
 void* gnss_read_pthread(void* arg)
 {
+#if MBTK_GNSS_TEST_LOG
+    gnss_test_log("gnss_read_pthread enter.");
+#endif
     LOGD("gnss_read_pthread enter.");
+
     char buffer[GNSS_BUFF_SIZE];
     int len = 0;
     int ret = 0;
@@ -754,6 +544,9 @@
     }
 #endif
 
+#if MBTK_GNSS_TEST_LOG
+    gnss_test_log("uart_fd - %d, exit_fd - %d", gnss_info.fd, gnss_info.exit_fd[0]);
+#endif
     LOGD("uart_fd - %d, exit_fd - %d", gnss_info.fd, gnss_info.exit_fd[0]);
 
     while(gnss_info.state >= GNSS_STATE_OPEN) {
@@ -783,6 +576,9 @@
             {
                 continue;
             }
+#if MBTK_GNSS_TEST_LOG
+            gnss_test_log("select error, errno = %d (%s)", errno, strerror(errno));
+#endif
             LOGE("select error, errno = %d (%s)", errno, strerror(errno));
             break;
         }
@@ -833,6 +629,9 @@
         }
         else
         {
+#if MBTK_GNSS_TEST_LOG
+            gnss_test_log("Unknown select event.");
+#endif
             LOGW("Unknown select event.");
             continue;
         }
@@ -912,6 +711,10 @@
 
 int gnss_init(uint32 print_port)
 {
+#if MBTK_GNSS_TEST_LOG
+    gnss_test_log("[gnss_init] gnss state [%d]", gnss_info.state);
+#endif
+
     if(gnss_info.state != GNSS_STATE_CLOSE) {
         LOGW("GNSS not close:%d", gnss_info.state);
         if(gnss_info.state == GNSS_STATE_READY) {
@@ -1020,6 +823,10 @@
 
     LOGD("GNSS open success.");
 
+#if MBTK_GNSS_TEST_LOG
+        gnss_test_log("gnss open success.");
+#endif
+
     return gnss_ports_open(print_port);
 
 exit_with_thread_exit:
@@ -1047,6 +854,10 @@
 
 int gnss_deinit()
 {
+#if MBTK_GNSS_TEST_LOG
+    gnss_test_log("[gnss_deinit] gnss state [%d]", gnss_info.state);
+#endif
+
     if(gnss_info.state == GNSS_STATE_CLOSE) {
         LOGW("GNSS is closed.");
         return GNSS_ERR_OK;
@@ -1069,6 +880,10 @@
     }
 
     gnss_info.state = GNSS_STATE_CLOSING;
+
+#if MBTK_GNSS_TEST_LOG
+    gnss_test_log("wait gnss pthread exit...");
+#endif
     int ret = pthread_join(gnss_info.read_pid, NULL);
     if(ret){
         LOGE("pthrad_join fail(%d)",ret);
@@ -1085,6 +900,9 @@
         return GNSS_ERR_UNKNOWN;
     }
 
+#if MBTK_GNSS_TEST_LOG
+    gnss_test_log("gnss_ports_close() complete.");
+#endif
     LOGD("gnss_ports_close() complete.");
 
     gnss_info.fd = -1;
@@ -1097,7 +915,11 @@
         gnss_info.exit_fd[1] = -1;
     }
     gnss_info.state = GNSS_STATE_CLOSE;
+#if MBTK_GNSS_TEST_LOG
+    gnss_test_log("gnss close success.");
+#endif
     LOGD("GNSS close success.");
+
     return GNSS_ERR_OK;
 }
 
@@ -1336,6 +1158,9 @@
     }
 #endif
 
+#if MBTK_GNSS_TEST_LOG
+    gnss_test_log("gnss init success.");
+#endif
     // Init ubus and waitting IPC commands.
 #ifdef MBTK_GNSS_UBUS_ENABLE
     if(gnss_ubus_init()) {
diff --git a/mbtk/mbtk_gnssd/gnss_utils.c b/mbtk/mbtk_gnssd/gnss_utils.c
index 6f5ad6a..b62aa85 100755
--- a/mbtk/mbtk_gnssd/gnss_utils.c
+++ b/mbtk/mbtk_gnssd/gnss_utils.c
@@ -8,9 +8,13 @@
 #include <stdarg.h>
 #include <pty.h>
 #include <libubox/uloop.h>
+#include <time.h>
+#include <sys/time.h>
 
-#include "mbtk_type.h"
+#include "gnss_utils.h"
 #include "mbtk_log.h"
+#include "gnss_log.h"
+#include "mbtk_gnss.h"
 
 #define DATABITS    CS8
 #define STOPBITS    0
@@ -318,3 +322,236 @@
     return;
 }
 
+#if MBTK_GNSS_PARAM_PARSE
+static bool mbtk_gnss_time_set_flag = 0;
+
+extern long timezone;
+
+static int strstr_n(const char *s1, const char *s2)
+{
+    int n;
+    int strlen = 0;
+
+    if(*s2)
+    {
+        while(*s1)
+        {
+            for(n = 0; *(s1+n) == *(s2 + n); n++)
+            {
+                if(!*(s2 + n + 1))
+                {
+                    strlen++;
+                    return strlen;
+                }
+            }
+            s1++;
+            strlen++;
+        }
+        return 0;
+    }
+
+    return 0;
+}
+
+static int nmea_tokenizer_init(mbtk_nmeatokenizer* t, const char* head, const char* end, int param_num)
+{
+    int count = 0;
+    const char* p = head;
+    const char* q = end;
+    const char* tmp = NULL;
+    // the initial '$' is optional
+    if (p < q && p[0] == '$')
+    {
+        p += 1;
+    }
+    else
+    {
+        return -1;
+    }
+
+    //find '*',del '*25\r\n'
+    // get rid of checksum at the end of the sentecne
+    if (q >= p + 5 && q[-5] == '*')
+    {
+        q -= 5;
+    }
+    else
+    {
+        return -1;
+    }
+
+    while (p <= q)
+    {
+        tmp = memchr(p, ',', q-p);
+        if (tmp == NULL)
+        {
+            tmp = q;
+        }
+        // if (q > p) {
+        // q >= p include empty token: ,,
+        if (tmp >= p)
+        {
+            if (count < MAX_NMEA_TOKENS)
+            {
+                t->tokens[count].head = p;
+                t->tokens[count].end = tmp;
+                count += 1;
+            }
+        }
+
+        if (tmp <= q)
+        {
+            tmp += 1;
+        }
+
+        p = tmp;
+    }
+
+    if(count != param_num)
+    {
+        LOGD("count [%d], param_num [%d]", count, param_num);
+        return -1;
+    }
+
+    t->count = count;
+    return count;
+}
+
+static mbtk_token nmea_tokenizer_get(mbtk_nmeatokenizer* t, int  index)
+{
+    mbtk_token tok;
+    static const char*  dummy = "";
+
+    if (index < 0 || index >= t->count)
+    {
+        tok.head = tok.end = dummy;
+    }
+    else
+    {
+        tok = t->tokens[index];
+    }
+    return tok;
+}
+
+static time_t nmea_get_sec(mbtk_token date, mbtk_token time)
+{
+    char tmp_char[4] = {0};
+    struct tm tmp_time;
+
+    memset(&tmp_time, 0x0, sizeof(struct tm));
+    if (date.head + 6 > date.end)
+    {
+        LOGD("date get fail");
+        return -1;
+    }
+
+    memcpy(tmp_char, date.head, 2);
+    tmp_time.tm_mday = atoi(tmp_char);
+    memcpy(tmp_char, date.head + 2, 2);
+    tmp_time.tm_mon = atoi(tmp_char) - 1;
+    memcpy(tmp_char, date.head + 4, 2);
+    tmp_time.tm_year = 100 + atoi(tmp_char);
+
+    if (time.head + 6 > time.end)
+    {
+        LOGD("time get fail");
+        return -1;
+    }
+
+    memcpy(tmp_char, time.head, 2);
+    tmp_time.tm_hour = atoi(tmp_char);
+    memcpy(tmp_char, time.head + 2, 2);
+    tmp_time.tm_min = atoi(tmp_char);
+    memcpy(tmp_char, time.head + 4, 2);
+    tmp_time.tm_sec = atoi(tmp_char);
+    tmp_time.tm_isdst = -1;
+
+#if 0
+    LOGD("data:%d-%d-%d %d:%d:%d", tmp_time.tm_year + 1900,
+                                    tmp_time.tm_mon,
+                                    tmp_time.tm_mday,
+                                    tmp_time.tm_hour,
+                                    tmp_time.tm_min,
+                                    tmp_time.tm_sec);
+#endif
+
+    time_t _t = mktime(&tmp_time);//parse location tmp_time
+
+    
+
+    return _t;
+}
+
+static int mbtk_time_type_gnss_read() {
+    int type = 0;
+    char time_type[] ={0};
+    property_get("persist.mbtk.time_type", time_type, "0");
+
+    type = atoi(time_type);
+//    LOGD("time_type :%d\n", type);
+    if(type != LYNQ_TIME_TYPE_GNSS)
+        mbtk_gnss_time_set_flag = 0;
+
+    return type;
+}
+
+int gnss_ind_nmea_parse(const char *data, int data_len)
+{
+    int ret;
+    mbtk_nmeatokenizer tzer = {0};
+    if(strstr_n(data + 3, "RMC"))
+    {
+        ret = nmea_tokenizer_init(&tzer, data, data + data_len, NMEA_RMC_PARAM_NUM);
+        if(ret < 0)
+        {
+            LOGD("nmea_tokenizer_init fail");
+            return -1;
+        }
+
+        mbtk_token  tok_time      = nmea_tokenizer_get(&tzer,1);
+        mbtk_token  tok_fixStatus = nmea_tokenizer_get(&tzer,2);
+        mbtk_token  tok_date      = nmea_tokenizer_get(&tzer,9);
+
+        if(tok_fixStatus.head[0] == 'A')
+        {
+            time_t _t = 0;
+            _t = nmea_get_sec(tok_date, tok_time);
+            if(_t < 0)
+            {
+                LOGD("nmea_update_date_time fail");
+                return -1;
+            }
+            else
+            {
+#ifdef MBTK_GNSS_TIME_CHECK
+                if(mbtk_check_num() == 0)
+                {
+                    mbtk_gnss_time_check(_t);
+                    gnss_test_log("%s", data);
+                }
+#endif
+                if( (mbtk_time_type_gnss_read() == LYNQ_TIME_TYPE_GNSS) && !mbtk_gnss_time_set_flag)
+                {
+                    struct timeval tv;
+                    tzset();   // auto set tz
+                    _t = _t - timezone;
+
+                    LOGD("timestamp:%ld,  %ld", _t,  timezone);
+
+                    tv.tv_sec = _t;
+                    if(settimeofday(&tv, NULL)) {
+                        LOGD("%s: , Set time fail\n", __func__);
+                        mbtk_gnss_time_set_flag = 0;
+                    } else {
+                        LOGD("%s: , Set time success \n", __func__);
+                        system("hwclock -w rtc0");
+                        mbtk_gnss_time_set_flag = 1;
+                    }
+                }
+            }
+        }
+    }
+
+    return 0;
+}
+#endif
\ No newline at end of file
diff --git a/mbtk/mbtk_gnssd/gnss_utils.h b/mbtk/mbtk_gnssd/gnss_utils.h
index 319315e..e3a308a 100755
--- a/mbtk/mbtk_gnssd/gnss_utils.h
+++ b/mbtk/mbtk_gnssd/gnss_utils.h
@@ -12,6 +12,19 @@
 
 #include "mbtk_type.h"
 
+#define MBTK_GNSS_PARAM_PARSE 1
+
+#if MBTK_GNSS_PARAM_PARSE
+typedef enum {
+    LYNQ_TIME_TYPE_CELL = 0,  //NITZ
+    LYNQ_TIME_TYPE_NTP,
+    LYNQ_TIME_TYPE_GNSS,
+    LYNQ_TIME_TYPE_USER,
+    
+    LYNQ_TIME_TYPE_UNUSE
+} lynq_time_type_enum;
+#endif
+
 int uart_baud_get(int baud);
 
 int gnss_port_open(const char *dev, int flag, int baud, bool tty);
@@ -30,5 +43,8 @@
 
 void gnssStopTimer(struct uloop_timeout *timeout);
 
+#if MBTK_GNSS_PARAM_PARSE
+int gnss_ind_nmea_parse(const char *data, int data_len);
+#endif
 
 #endif /* _GNSS_UTILS_H */