[Feature][T106][task-view-1029]Add GNSSLOG-function

Only Configure :No
Affected branch: master
Affected module: gnss
Is it affected on both ZXIC and MTK:only ZXIC
Self-test: Yes
Doc Update: No

Change-Id: I8a332f47e16f1f18ff03f3ab7e81f333b3dc7ab3
diff --git a/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/src/mbtk_gnss.cpp b/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/src/mbtk_gnss.cpp
index a7e7ba5..988711c 100755
--- a/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/src/mbtk_gnss.cpp
+++ b/cap/zx297520v3/src/lynq/lib/liblynq-qser-gnss/src/mbtk_gnss.cpp
@@ -26,11 +26,14 @@
 #ifdef __cplusplus
 extern "C" {
 #endif
-
+#ifndef MIN
+#define MIN(A,B) ((A)<(B)?(A):(B))
+#endif
 #define _XOPEN_SOURCE
 #define NMEA_RMC "RMC"
 #define NEMA_LOG_FILE "/mnt/userdata/gnss.conf"
-
+#define NMEA_LOG_MAX_SIZE  MIN(48*1024*1024,(gnsslog_file_size<1024*1024?1024*1024:gnsslog_file_size))
+#define NMEA_LOG_MAX_FILE_NUM  MIN(12,(gnsslog_file_num<1?1:gnsslog_file_num))
 extern long timezone;
 extern int g_gnss_sync_enable_flag;
 extern int g_gnss_sync_done;
@@ -127,10 +130,19 @@
     "debug.frequency"       //NMEA_OUTPUT_FREQ
 };
 #define NUM_CONFIG_FLAGS (sizeof(config_flags) / sizeof(config_flags[0]))
+int global_fd = 0;
+char log_real_name[128];
+char tmp_file_name[128];
+int gnsslog_file_size = 15*1024*1024;   //Max dbg log file size read from config file
+int gnsslog_file_num = 5;  //Max dbg log num read from config file
 int gnss_frq = 1;
 volatile int nmea_state = 0;
 volatile int nmea_reading = 0;
-
+volatile int gnsslog_state = 0;
+static int firmware_extren_state = 0;
+static void *test_gpio_handle[MAX_GPIO_NUM]={NULL};
+static struct mopen_gnss_device_info_t mopen_gnss_device_info;
+static struct mbtk_gnss_handle_t *mbtk_gnss_handle = NULL;
 static struct mbtk_gnss_cmd_msg_t mbtk_gnss_cmd_msg_map[] = {
 { 1,     "$OK",         NULL,                 0},
 { 2,     "$Fail",       NULL,                 0},
@@ -424,6 +436,58 @@
     }
     fclose(file);
 
+    if(configure_pointers[0] != NULL)
+    {
+        gnsslog_state = atoi(configure_pointers[0] + strlen(config_flags[0]) + 1);
+        printf("gnsslog_state = %d\n", gnsslog_state);
+        if(gnsslog_state == 1)
+        {
+            //lynq_gnss_log_handle(1);
+            if(configure_pointers[1] != NULL)
+            {
+                strcpy(log_real_name, configure_pointers[1] + strlen(config_flags[1]) + 1);
+                sprintf(log_real_name,"%s_gpslog", log_real_name);
+                printf("log_real_name = %s\n", log_real_name);
+                
+            }
+            else
+            {
+                sprintf(log_real_name,"/var/log/gpslog");
+                printf("log_real_name = %s\n", log_real_name);
+            }
+        }
+    //     else if(gnsslog_state == 0)
+    //     {
+    //         lynq_gnss_log_handle(0);
+    //     }
+    //     else
+    //         ALOGE("LOG CONFIGURE ERROR\n");
+    }
+    // else
+    //     lynq_gnss_log_handle(0);
+    
+    if(configure_pointers[2] != NULL)
+    {
+        char *token; // 用于分割字符串  
+        const char delimiter[] = "*"; // 分隔符为 
+        char *tmp_token = strdup(configure_pointers[2] + strlen(config_flags[2]) + 1);
+        int result = 1;
+        token = strtok(tmp_token, delimiter);
+        while (token != NULL)
+        {  
+            result *= atoi(token);
+            token = strtok(NULL, delimiter);
+        }
+        gnsslog_file_size = result;
+        printf("log_file_size = %d\n", gnsslog_file_size);
+    }
+    
+    if(configure_pointers[3] != NULL)
+    {
+        printf("%s\n", configure_pointers[3] + strlen(config_flags[3]) + 1);
+        gnsslog_file_num = atoi(configure_pointers[3] + strlen(config_flags[3]) + 1);
+        printf("log_file_num = %d\n", gnsslog_file_num);
+    }
     if(configure_pointers[4] != NULL)
     {
         int ret;
@@ -448,7 +512,93 @@
     
     return 0;
 }
+typedef struct
+{
+    char* name;
+    time_t ctime;
+} FileInfo;
 
+int cmpfunc(const void *a, const void *b)
+{
+    FileInfo *fileA = (FileInfo *)a;
+    FileInfo *fileB = (FileInfo *)b;
+
+    return difftime(fileA->ctime, fileB->ctime);
+}
+int lynq_gnss_log_file_open()
+{
+    DIR *dir;
+    time_t now;
+    int file_count = 0;
+    FileInfo files[24];
+    struct dirent *ent;
+    char time_info[32];
+    
+    char *dir_path = strdup(log_real_name);
+    char *file_name = strrchr(dir_path, '/');
+    *file_name = '\0';
+    file_name++;
+    time(&now);
+    dir = opendir(dir_path);
+
+    while(dir != NULL && (ent = readdir(dir)) != NULL)
+    {
+        if(strstr(ent->d_name, "gpslog") != NULL)
+        {
+            files[file_count].name = strdup(ent->d_name);
+            struct stat st;
+            char tmp_file1[128];
+            snprintf(tmp_file1, sizeof(tmp_file1), "%s/%s", dir_path, ent->d_name);
+            stat(tmp_file1, &st);
+            files[file_count].ctime = st.st_ctime;
+            file_count++;
+            if(file_count >= 24)
+            {
+                ALOGE("the file count is exceed maximum value\n");
+                break;
+            }
+        }//如果文件有超过gnsslog_file_num的文件怎么办
+    }
+
+    if(file_count >= gnsslog_file_num)
+    {
+        int i = file_count - gnsslog_file_num + 1;
+        qsort(files, file_count, sizeof(FileInfo), cmpfunc);
+        for(int j = 0; j < i; j++)
+        {
+            char tmp_file[128];
+            snprintf(tmp_file, sizeof(tmp_file), "%s/%s", dir_path, files[j].name);
+            remove(tmp_file);
+            free(files[j].name);
+            files[j].name == NULL;
+        }
+    }
+    closedir(dir);
+
+    strftime(time_info, 32, "%Y%m%d%H%M%S", localtime(&now));
+    sprintf(tmp_file_name,"%s/%s_%s.log", dir_path, file_name, time_info);
+    global_fd = open(tmp_file_name, O_RDWR | O_APPEND |O_CREAT, 0666);
+    if (global_fd == -1)
+    {
+        ALOGE("Failed to open file\n");
+        printf("Failed to open file\n");
+        return -1;
+    }
+    return 0;
+}
+
+int write_gnss_log(char *buffer, int len)//写log实现 就用write
+{
+    // global_fd = open(tmp_file_name, O_WRONLY | O_APPEND);
+    // if (global_fd == -1)
+    // {
+    //     ALOGE("Failed to open file\n");
+    //     return -1;
+    // }
+
+    write(global_fd, buffer, len);
+    return 0;
+}
 
 static void get_gnss_agnss_state(int cmd, char *str, void *data)
 {
@@ -964,6 +1114,7 @@
 }
 
 int flag = 1;
+int read_buf=0;
 static void gnss_uart_pthread(void* hdl)
 {
     struct mbtk_gnss_handle_t *gnss_handle = (struct mbtk_gnss_handle_t *)hdl;
@@ -981,6 +1132,18 @@
         {
             nmea_reading = 1;
             ret = mopen_gnss_read(gnss_handle->dev_fd, buf, MBTK_UART_RECV_BUFFER_SIZE);
+            if(gnsslog_state)
+            {
+                //write_gnss_log(buf, ret);
+                read_buf += ret;
+                if(read_buf >= NMEA_LOG_MAX_SIZE)
+                {
+                    close(global_fd);
+                    lynq_gnss_log_file_open();
+                    read_buf = ret;
+                }
+                write_gnss_log(buf, ret);
+            }
             nmea_reading = 0;
             if(flag != 0)
             {
@@ -1214,7 +1377,11 @@
     lynq_open_gps(1);
     sleep(1);
     lynq_gnss_configure_init();
-
+    if(gnsslog_state)
+    {
+        usleep(1000);
+        lynq_gnss_log_file_open();
+    }
     lynq_open_gps(0);
 
     ring_buffer_init(&mbtk_gnss_handle->ring_buffer,