优化gnss http星历下载
authorpenglei <1624952103@qq.com>
Thu, 11 Dec 2025 09:17:58 +0000 (17:17 +0800)
committerpenglei <1624952103@qq.com>
Thu, 11 Dec 2025 09:17:58 +0000 (17:17 +0800)
code/sdk/zhihui/services/gnss/src/gnss_http_server.c

index 5f992d9..13635de 100644 (file)
 // JSON处理控制宏 - 设置为0可以屏蔽复杂的JSON处理逻辑
 #define ENABLE_COMPLEX_JSON_PROCESSING   0
 
+#define MAX_VALID_TIMESTAMPS     10             // 固定时间戳数组长度
+#define TIME_PERIOD 7 * 24 * 60 * 60
+
+static uint32_t g_valid_timestamps[MAX_VALID_TIMESTAMPS] = {0};  // 固定长度10,默认填0
+static int g_valid_timestamp_count = 0;                          // 有效时间戳数量
+
 
 // 全局变量用于存储接收到的数据
 static char *g_agnss_response_buffer = NULL;
@@ -95,6 +101,90 @@ int download_agnss_file(const char *filename);
 
 void do_gnss_http_server_recv_data(int cmd,char *data,uint32_t len);
 
+
+// 创建文件夹路径
+static int create_folder_structure(const char *folder_path) 
+{
+    if (!folder_path || strlen(folder_path) == 0) {
+        return 0; // 没有文件夹路径,直接返回成功
+    }
+    
+    char *full_path = malloc(512);
+    if (full_path == NULL) {
+        printf("Error: Failed to allocate memory for full_path\n");
+        return -1;
+    }
+    snprintf(full_path, 512, "%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);
+    // }
+    
+    free(full_path);
+    return 0;
+}
+
+
+// 3. 辅助函数:检查时间戳是否已存在(去重)
+static int is_timestamp_exists(uint32_t ts)
+{
+    for (int i = 0; i < g_valid_timestamp_count; i++) {
+        if (g_valid_timestamps[i] == ts) {
+            return 1;
+        }
+    }
+    return 0;
+}
+
+// 4. 辅助函数:添加有效时间戳(固定长度10,自动去重)
+static void add_valid_timestamp(uint32_t ts)
+{
+    if (ts == 0) return;                  // 跳过无效时间戳
+    if (is_timestamp_exists(ts)) return;  // 去重
+    
+    // 未超过最大长度则添加,否则提示
+    if (g_valid_timestamp_count < MAX_VALID_TIMESTAMPS) {
+        g_valid_timestamps[g_valid_timestamp_count++] = ts;
+    } else {
+        printf("Warning: 有效时间戳数量已达上限%d\n", MAX_VALID_TIMESTAMPS);
+    }
+}
+
+// 辅助函数:根据时间戳获取文件夹路径
+static char* get_timestamp_folder_path(uint32_t timestamp)
+{
+    // 动态分配内存存储路径,使用后需释放
+    char *folder_path = (char *)malloc(512);
+    if (folder_path == NULL) {
+        printf("Error: 分配文件夹路径内存失败\n");
+        return NULL;
+    }
+    // 拼接路径:根路径/时间戳
+    snprintf(folder_path, 512, "%s/%u", PGNSS_DATA_PATH, timestamp);
+    return folder_path;
+}
+
+// 辅助函数:创建文件夹(若不存在)
+static int create_folder_if_not_exists(const char *folder_path)
+{
+    if (folder_path == NULL) return -1;
+    DIR *dir = opendir(folder_path);
+    if (dir == NULL) {
+        // 文件夹不存在,创建(使用平台对应的创建函数,如uapi_create_folder)
+        uapi_create_folder(folder_path);
+        printf("创建文件夹: %s\n", folder_path);
+    } else {
+        closedir(dir);
+    }
+    return 0;
+}
+
 // 使用新的httpclient.h接口的下载结果处理函数
 static void agnss_download_result_handler(const char *filename, HTTPC_RESULT result, int response_code, const char *response_data, int data_len)
 {
@@ -376,45 +466,78 @@ static HTTPC_RESULT download_file_with_httpclient(const char *filename, const ch
         g_download_status = -1;
         return HTTP_EARG;
     }
-    
-    // 从URL中提取时间戳文件夹名
+    memset(filepath, 0, 512);
+    memset(timestamp_folder, 0, 64);
+    // 先设置默认路径
+    snprintf(filepath, 512, "%s/%s", PGNSS_DATA_PATH, filename);
+
+    // 从URL中提取 /iot_gnss/ 后的完整路径(时间戳文件夹/星历文件名)
     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 < 63) {
-                strncpy(timestamp_folder, folder_pos, folder_len);
-                timestamp_folder[folder_len] = '\0';
-                
-                // 文件夹已在下载开始前创建,直接使用路径
-                char *full_folder_path = malloc(512);
-                if (full_folder_path == NULL) {
-                    printf("Error: Failed to allocate memory for full_folder_path\n");
-                    free(host);
-                    free(path);
-                    free(filepath);
-                    free(timestamp_folder);
-                    g_download_status = -1;
-                    return HTTP_EARG;
+        // 跳过 "/iot_gnss/",获取后续的完整路径(如:1765184382/GLO_1765263582.eph)
+        char *full_remote_path = folder_pos + 10; // 10是"/iot_gnss/"的长度
+        // 检查是否存在有效的路径(避免空路径)
+        if (strlen(full_remote_path) > 0) {
+            // 查找第一个斜杠,拆分出时间戳文件夹和星历文件名
+            char *first_slash = strchr(full_remote_path, '/');
+            if (first_slash) {
+                // 1. 提取时间戳文件夹名(如:1765184382)
+                int folder_len = first_slash - full_remote_path;
+                if (folder_len > 0 && folder_len < 63) { // 限制文件夹名长度,避免溢出
+                    strncpy(timestamp_folder, full_remote_path, folder_len);
+                    timestamp_folder[folder_len] = '\0';
+
+
+
+                    // 2. 提取星历文件名(如:GLO_1765263582.eph)
+                    char *remote_filename = first_slash + 1;
+                    // 确保星历文件名不为空(避免URL以/结尾的情况)
+                    if (strlen(remote_filename) > 0) {
+                        // 3. 构建完整的文件夹路径,并创建文件夹(核心:先创建文件夹)
+                        char *full_folder_path = malloc(512);
+                        if (full_folder_path != NULL) {
+                            snprintf(full_folder_path, 512, "%s", timestamp_folder);
+                            // 调用文件夹创建函数(需确保该函数已定义,见下方说明)
+                            create_folder_structure(full_folder_path);
+                            printf("Created/Existed directory: %s\n", full_folder_path);
+
+                            // 4. 拼接本地文件路径:PGNSS_DATA_PATH/时间戳文件夹/星历文件名
+                            snprintf(filepath, 512, "%s/%s/%s", PGNSS_DATA_PATH,full_folder_path, remote_filename);
+                            printf("File will be saved to: %s\n", filepath);
+
+                            free(full_folder_path); // 用完释放内存
+                        } else {
+                            printf("Error: Failed to allocate memory for full_folder_path\n");
+                        }
+                    } else {
+                        printf("Warning: Remote filename is empty in URL\n");
+                    }
+                } else {
+                    printf("Warning: Timestamp folder name is too long or empty\n");
                 }
-                snprintf(full_folder_path, 512, "%s/%s", PGNSS_DATA_PATH, timestamp_folder);
-                free(full_folder_path); // 这里只是用来构建路径,可以立即释放
-                
-                // 保存文件到时间戳文件夹
-                snprintf(filepath, 512, "%s/%s/%s", PGNSS_DATA_PATH, timestamp_folder, filename);
             } else {
-                // 如果无法提取时间戳,使用默认路径
-                snprintf(filepath, 512, "%s/%s", PGNSS_DATA_PATH, filename);
+                // 没有找到斜杠,说明URL中只有文件夹名,无文件名(使用原文件名)
+                printf("Warning: No filename in remote path, use original filename\n");
+                // 提取文件夹名作为时间戳文件夹
+                int folder_len = strlen(full_remote_path);
+                if (folder_len > 0 && folder_len < 63) {
+                    strncpy(timestamp_folder, full_remote_path, folder_len);
+                    timestamp_folder[folder_len] = '\0';
+                    // 创建文件夹并使用原文件名
+                    char *full_folder_path = malloc(512);
+                    if (full_folder_path != NULL) {
+                        snprintf(full_folder_path, 512, "%s",  timestamp_folder);
+                        create_folder_structure(full_folder_path);
+                        snprintf(filepath, 512, "%s/%s", full_folder_path, filename);
+                        free(full_folder_path);
+                    }
+                }
             }
         } else {
-            // 如果无法找到第二个斜杠,使用默认路径
-            snprintf(filepath, 512, "%s/%s", PGNSS_DATA_PATH, filename);
+            printf("Warning: Remote path is empty after /iot_gnss/\n");
         }
     } else {
-        // 如果无法找到 /iot_gnss/,使用默认路径
-        snprintf(filepath, 512, "%s/%s", PGNSS_DATA_PATH, filename);
+        printf("Warning: /iot_gnss/ not found in URL, use default path\n");
     }
     
     // 初始化HTTP客户端
@@ -749,33 +872,6 @@ static void cleanup_extract_folder_path(void) {
     extract_folder_path(NULL);
 }
 
-// 创建文件夹路径
-static int create_folder_structure(const char *folder_path) {
-    if (!folder_path || strlen(folder_path) == 0) {
-        return 0; // 没有文件夹路径,直接返回成功
-    }
-    
-    char *full_path = malloc(512);
-    if (full_path == NULL) {
-        printf("Error: Failed to allocate memory for full_path\n");
-        return -1;
-    }
-    snprintf(full_path, 512, "%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);
-    // }
-    
-    free(full_path);
-    return 0;
-}
-
 static int download_agnss_file_with_url(const char *filename, const char *download_url)
 {
     // 文件夹已在下载开始前创建,无需重复创建
@@ -952,6 +1048,46 @@ static void verify_downloaded_files(uint32_t selected_timestamp)
     }
 }
 
+// 从下载URL中提取文件夹的时间戳(/iot_gnss/后的数字)
+// 返回值:成功返回文件夹时间戳,失败返回0
+static uint32_t extract_folder_timestamp_from_url(const char *download_url) {
+    if (download_url == NULL || strlen(download_url) == 0) {
+        return 0;
+    }
+
+    // 查找/iott_gnss/的位置(URL格式:xxx/iot_gnss/1234567890/xxx.eph)
+    char *iot_gnss_pos = strstr(download_url, "/iot_gnss/");
+    if (iot_gnss_pos == NULL) {
+        return 0;
+    }
+
+    // 移动到/iott_gnss/之后的位置
+    char *folder_ts_start = iot_gnss_pos + strlen("/iot_gnss/");
+    if (*folder_ts_start == '\0') {
+        return 0;
+    }
+
+    // 查找文件夹时间戳后的斜杠(即文件名的开始)
+    char *folder_ts_end = strchr(folder_ts_start, '/');
+    if (folder_ts_end == NULL) {
+        return 0;
+    }
+
+    // 提取文件夹时间戳的字符串并转换为数字
+    int ts_str_len = folder_ts_end - folder_ts_start;
+    char folder_ts_str[32] = {0};
+    strncpy(folder_ts_str, folder_ts_start, ts_str_len);
+    folder_ts_str[ts_str_len] = '\0';
+
+    // 转换为无符号32位整数(时间戳)
+    char *endptr;
+    uint32_t folder_timestamp = strtoul(folder_ts_str, &endptr, 10);
+    if (*endptr != '\0' || folder_timestamp == 0) {
+        return 0;
+    }
+
+    return folder_timestamp;
+}
 
 static void agnss_process_complete_response(void)
 {
@@ -1292,13 +1428,16 @@ static void agnss_process_complete_response(void)
                             folder_timestamp_str[folder_len] = '\0';
                             
                             uint32_t folder_timestamp = strtoul(folder_timestamp_str, NULL, 10);
-                            
+
+                            // printf("folder_timestamp : %d ,current_timestamp : %d\n",folder_timestamp,current_timestamp);
+
                             // 检查时间戳是否在24小时内且小于当前时间
                             if (folder_timestamp <= current_timestamp) {
                                 uint32_t time_diff = current_timestamp - folder_timestamp;
+                                // printf("time_diff : %d\n",time_diff);
                                 if (time_diff < 86400) { // 24小时 = 86400秒
                                     valid_folder_count++;
-                                    
+                                    add_valid_timestamp(folder_timestamp);
                                     // 选择时间差最小的文件夹
                                     if (time_diff < min_time_diff) {
                                         min_time_diff = time_diff;
@@ -1306,6 +1445,10 @@ static void agnss_process_complete_response(void)
                                     }
                                 }
                             }
+                            else if(folder_timestamp > current_timestamp)
+                            {
+                                add_valid_timestamp(folder_timestamp);
+                            }
                             free(folder_timestamp_str);
                         }
                     }
@@ -1358,183 +1501,239 @@ static void agnss_process_complete_response(void)
                     printf("Error: Failed to allocate memory for selected_timestamp_str\n");
                     return;
                 }
-                snprintf(selected_timestamp_str, 32, "%u", selected_timestamp);
+                // snprintf(selected_timestamp_str, 32, "%u", selected_timestamp);
             
-            if (data_start) {
-                data_start += 8; // 跳过 "data":[
-                
-                // 第一步:统计符合条件的文件总数
-                char *count_start = data_start;
-                int total_files_count = 0;
-                
-                while ((count_start = strstr(count_start, "{")) != NULL && 
-                       (count_start - g_agnss_response_buffer) < (long)g_agnss_response_size) {
-                    
-                    // 提取downloadUrl进行检查
-                    char *url_start = strstr(count_start, "\"downloadUrl\":\"");
-                    if (url_start) {
-                        url_start += 15; // 跳过 "downloadUrl":"
-                        char *url_end = strchr(url_start, '"');
-                        if (url_end) {
-                            int url_len = url_end - url_start;
-                            if (url_len > 0 && url_len < 512) {
-                                char *temp_url = malloc(512);
-                                if (temp_url == NULL) {
-                                    printf("Error: Failed to allocate memory for temp_url\n");
+                    for (int i = 0; i < g_valid_timestamp_count; i++) 
+                    {
+                        // 跳过数组中值为0的元素(数组剩余位置填充0)
+                        uint32_t current_ts = g_valid_timestamps[i];
+                        if (current_ts == 0)
+                            continue;
+                        
+
+                        // // 每次遍历更新时间戳字符串(覆盖原有内容)
+                        snprintf(selected_timestamp_str, 32, "%d", current_ts);
+                        // printf("当前遍历的时间戳:%s(索引:%d)\n", selected_timestamp_str, i);
+                        // printf("当前遍历的时间戳:%s\n", selected_timestamp_str);
+                        // 【重置当前时间戳的文件计数(如果按文件夹统计)】
+
+                        if (data_start) {
+                            data_start += 8; // 跳过 "data":[
+                            
+                            // 第一步:统计符合条件的文件总数
+                            char *count_start = data_start;
+                            int total_files_count = 0;
+                            
+                            while ((count_start = strstr(count_start, "{")) != NULL && 
+                                (count_start - g_agnss_response_buffer) < (long)g_agnss_response_size) {
+
+                                // 提取downloadUrl进行检查
+                                char *url_start = strstr(count_start, "\"downloadUrl\":\"");
+                                if (url_start) {
+                                    url_start += 15; // 跳过 "downloadUrl":"
+                                    char *url_end = strchr(url_start, '"');
+                                    if (url_end) {
+                                        int url_len = url_end - url_start;
+                                        if (url_len > 0 && url_len < 512) {
+                                            char *temp_url = malloc(512);
+                                            if (temp_url == NULL) {
+                                                printf("Error: Failed to allocate memory for temp_url\n");
+                                                continue;
+                                            }
+                                            memset(temp_url, 0, 512);
+                                            strncpy(temp_url, url_start, url_len);
+
+                                            // 检查URL是否属于选定的时间戳文件夹
+                                            char *folder_check = strstr(temp_url, selected_timestamp_str);
+                                            // printf("selected_timestamp_str : %s\n",selected_timestamp_str);
+                                            // printf("temp_url : %s\n",temp_url);
+                                            if (folder_check) {
+                                                char *iot_gnss_pos = strstr(temp_url, "/iot_gnss/");
+                                                if (iot_gnss_pos && folder_check > iot_gnss_pos) {
+                                                    total_files_count++;
+                                                }
+                                            }
+                                            free(temp_url);
+                                        }
+                                    }
+                                }
+                                
+                                // 移动到下一个文件项
+                                char *next_item = strstr(count_start, "},");
+                                if (next_item) {
+                                    count_start = next_item + 2;
+                                } else {
+                                    char *last_item = strstr(count_start, "}");
+                                    if (last_item) {
+                                        count_start = last_item + 1;
+                                    } else {
+                                        break;
+                                    }
+                                }
+                            }
+                            
+                            // 设置实际的总文件数
+                            if (total_files_count > 0) {
+                                set_total_files(total_files_count);
+                                printf("检测到 %d 个需要下载的文件\n", total_files_count);
+                            } else {
+                                printf("警告:没有找到需要下载的文件\n");
+                            }
+                            
+                            // 第二步:开始下载文件
+                            char *item_start = g_agnss_response_buffer;  // 修正:从缓冲区起始位置开始
+                            int download_count = 0;
+                            int total_item_count = 0;  // 统计遍历的项数
+
+                            while ((item_start = strstr(item_start, "{")) != NULL) {
+                                // 检查是否超出缓冲区范围(防止越界)
+                                long buffer_offset = item_start - g_agnss_response_buffer;
+                                if (buffer_offset >= (long)g_agnss_response_size) {
+                                    break;
+                                }
+                                total_item_count++;
+
+                                // 提取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;
                                 }
-                                memset(temp_url, 0, 512);
-                                strncpy(temp_url, url_start, url_len);
+
+                                int filename_len = filename_end - filename_start;
+                                if (filename_len <= 0 || filename_len >= 256) {
+                                    item_start++;
+                                    continue;
+                                }
+
+                                // 分配文件名内存
+                                char *filename = (char *)malloc(256);
+                                if (filename == NULL) {
+                                    printf("Error: Failed to allocate memory for filename (item: %d)\n", total_item_count);
+                                    item_start++;
+                                    continue;
+                                }
+                                memset(filename, 0, 256);
+                                strncpy(filename, filename_start, filename_len);
+                                filename[filename_len] = '\0';
+
+                                // 提取downloadUrl
+                                char *url_start = strstr(item_start, "\"downloadUrl\":\"");
+                                if (!url_start) {
+                                    free(filename);  // 释放内存
+                                    item_start++;
+                                    continue;
+                                }
+                                url_start += 15;  // 跳过 "downloadUrl":"
+
+                                char *url_end = strchr(url_start, '"');
+                                if (!url_end) {
+                                    free(filename);  // 释放内存
+                                    item_start++;
+                                    continue;
+                                }
+
+                                int url_len = url_end - url_start;
+                                if (url_len <= 0 || url_len >= 512) {
+                                    free(filename);  // 释放内存
+                                    item_start++;
+                                    continue;
+                                }
+
+                                // 分配URL内存
+                                char *download_url = (char *)malloc(512);
+                                if (download_url == NULL) {
+                                    printf("Error: Failed to allocate memory for download_url (item: %d)\n", total_item_count);
+                                    free(filename);  // 释放内存
+                                    item_start++;
+                                    continue;
+                                }
+                                memset(download_url, 0, 512);
+                                strncpy(download_url, url_start, url_len);
+                                download_url[url_len] = '\0';
+
+                                // 核心修改:从URL中提取文件夹时间戳
+                                uint32_t folder_timestamp = extract_folder_timestamp_from_url(download_url);
+                                if (folder_timestamp == 0) {
+                                    printf("Warning: Failed to extract folder timestamp from URL (item: %d, url: %s)\n",
+                                        total_item_count, download_url);
+                                    free(filename);
+                                    free(download_url);
+                                    item_start++;
+                                    continue;
+                                }
+
+                                // 核心过滤逻辑:只下载24小时内或未来的文件夹的文件
+                                int is_valid = 0;
+                                uint32_t time_diff = 0;
+                                if (current_timestamp >= folder_timestamp) {
+                                    // 过去的文件夹:检查是否在24小时内
+                                    time_diff = current_timestamp - folder_timestamp;
+                                    if (time_diff < 86400) {
+                                        is_valid = 1;
+                                    }
+                                } else {
+                                    // 未来的文件夹:直接有效
+                                    time_diff = folder_timestamp - current_timestamp;
+                                    is_valid = 1;
+                                }
+
+                                if (is_valid) {
+                                    // 满足条件,下载文件
+                                    printf("Downloading file: %s (folder timestamp: %u, time diff: %u seconds)\n",
+                                        filename, folder_timestamp, time_diff);
+                                    if (download_agnss_file_with_url(filename, download_url) == 0) {
+                                        download_count++;
+                                        printf("Success: Downloaded %s\n", filename);
+                                    } else {
+                                        printf("Failed: Download %s\n", filename);
+                                    }
+                                } else {
+                                    // 不满足条件,跳过下载
+                                    printf("Skip: File %s (folder timestamp: %u, expired by %u seconds)\n",
+                                        filename, folder_timestamp, time_diff);
+                                }
+
+                                
+                                // 释放内存
+                                free(filename);
+                                free(download_url);
                                 
-                                // 检查URL是否属于选定的时间戳文件夹
-                                char *folder_check = strstr(temp_url, selected_timestamp_str);
-                                if (folder_check) {
-                                    char *iot_gnss_pos = strstr(temp_url, "/iot_gnss/");
-                                    if (iot_gnss_pos && folder_check > iot_gnss_pos) {
-                                        total_files_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;
+                                        }
                                     }
                                 }
-                                free(temp_url);
+                                
+                                printf("成功下载 %d 个文件到时间戳文件夹: %s/%u\n", download_count, PGNSS_DATA_PATH, selected_timestamp);
+                            } else {
+                                printf("没有找到符合条件的时间戳文件夹,跳过下载\n");
                             }
-                        }
+                            free(selected_timestamp_str);
                     }
-                    
-                    // 移动到下一个文件项
-                    char *next_item = strstr(count_start, "},");
-                    if (next_item) {
-                        count_start = next_item + 2;
                     } else {
-                        char *last_item = strstr(count_start, "}");
-                        if (last_item) {
-                            count_start = last_item + 1;
-                        } else {
-                            break;
-                        }
+                        printf("没有找到符合条件的时间戳文件夹\n");
                     }
-                }
                 
-                // 设置实际的总文件数
-                if (total_files_count > 0) {
-                    set_total_files(total_files_count);
-                    printf("检测到 %d 个需要下载的文件\n", total_files_count);
-                } else {
-                    printf("警告:没有找到需要下载的文件\n");
-                }
-                
-                // 第二步:开始下载文件
-                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 = malloc(256);
-                    if (filename == NULL) {
-                        printf("Error: Failed to allocate memory for filename\n");
-                        item_start++;
-                        continue;
-                    }
-                    memset(filename, 0, 256);
-                    strncpy(filename, filename_start, filename_len);
-                    filename[filename_len] = '\0';
-                    
-                    // 提取downloadUrl
-                    char *url_start = strstr(item_start, "\"downloadUrl\":\"");
-                    if (!url_start) {
-                        free(filename);
-                        item_start++;
-                        continue;
-                    }
-                    url_start += 15; // 跳过 "downloadUrl":"
-                    
-                    char *url_end = strchr(url_start, '"');
-                    if (!url_end) {
-                        free(filename);
-                        item_start++;
-                        continue;
-                    }
-                    
-                    int url_len = url_end - url_start;
-                    if (url_len <= 0 || url_len >= 512) {
-                        free(filename);
-                        item_start++;
-                        continue;
-                    }
-                    
-                    char *download_url = malloc(512);
-                    if (download_url == NULL) {
-                        printf("Error: Failed to allocate memory for download_url\n");
-                        free(filename);
-                        item_start++;
-                        continue;
-                    }
-                    memset(download_url, 0, 512);
-                    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++;
-                            }
-                        }
-                    }
-                    
-                    // 释放内存
-                    free(filename);
-                    free(download_url);
-                    
-                    // 移动到下一个文件项
-                    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");
-                }
-                free(selected_timestamp_str);
             } else {
-                printf("没有找到符合条件的时间戳文件夹\n");
+                printf("AGNSS API call failed or returned error\n");
+                // API调用失败,标志位由download_agnss_files函数管理
             }
-        } else {
-            printf("AGNSS API call failed or returned error\n");
-            // API调用失败,标志位由download_agnss_files函数管理
-        }
         
         // 清理缓冲区
         free(g_agnss_response_buffer);
@@ -1726,6 +1925,8 @@ int download_agnss_files(void)
         "http://app.api.thisiot.com/dev/AGNSS/geteph?deviceId=121314243&timestamp=%u", 
         timestamp);
     
+    printf("full_url : %s\n",full_url);
+
     // 清理之前的缓冲区
     cleanup_agnss_response_buffer();
     
@@ -2174,143 +2375,138 @@ errcode_t uapi_gnss_http_server_init(void)
     return ERRCODE_SUCC;
 }
 
-
 /**
- * @brief 检查星历文件夹的有效状态
+ * @brief 检查星历文件夹的有效状态(修复遍历逻辑问题)
  * @return 过期返回0,有效返回剩余时间的分钟数,错误返回-1
  */
 int gnss_check_agnss_status(void)
 {
-    
-    // 打开AGNSS数据目录
+
+    if (PGNSS_DATA_PATH == NULL || strlen(PGNSS_DATA_PATH) == 0) {
+        printf("ERROR: PGNSS_DATA_PATH is empty\n");
+        return -1;
+    }
+
     DIR *dir = opendir(PGNSS_DATA_PATH);
     if (dir == NULL) {
         printf("Cannot open AGNSS directory: %s\n", PGNSS_DATA_PATH);
         return -1;
     }
-    
-    // 获取当前时间戳
+
+    // 1. 正确获取当前系统时间戳(仅获取一次,不要在遍历中重复获取)
     uint32_t current_timestamp = 0;
     uapi_get_timestampe_ss(&current_timestamp);
-    
-    struct dirent *entry;
-    int found_valid_folder = 0;
-    uint32_t min_time_diff = 0xFFFFFFFF;
-    uint32_t best_folder_timestamp = 0;
-    int best_file_count = 0;
-    
-    // 使用malloc分配内存
-    char *best_folder_name = malloc(64);
-    if (best_folder_name == NULL) {
-        printf("ERROR: Failed to allocate memory for best_folder_name\n");
+    if (current_timestamp == 0) {
+        printf("ERROR: Failed to get current timestamp\n");
         closedir(dir);
         return -1;
     }
-    memset(best_folder_name, 0, 64);
-    
-    // printf("=== AGNSS Status Check ===\n");
-    // printf("Current timestamp: %u\n", current_timestamp);
-    
-    // 遍历目录中的所有文件夹
+    // 调试日志:打印正确的当前时间戳
+    // printf("=== Current system timestamp: %u ===\n", current_timestamp);
+
+    struct dirent *entry = NULL;
+    int found_valid_folder = 0;
+    uint32_t min_time_diff = UINT_MAX;
+    uint32_t best_folder_timestamp = 0;
+    int best_file_count = 0;
+    char best_folder_name[64] = {0};
+    const uint32_t VALID_TIME_WINDOW = 86400; // 24小时
+    const int MIN_FILE_COUNT = 20;
+
+    // 未来文件夹统计变量
+    int future_folder_count = 0;
+    uint32_t future_min_ts = UINT_MAX;
+    uint32_t future_max_ts = 0;
+
+    // 2. 遍历目录中的文件夹(核心修复:正确遍历文件夹时间戳)
     while ((entry = readdir(dir)) != NULL) {
-        // 跳过 . 和 .. 目录
         if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
             continue;
         }
-        
-        // 检查是否是数字文件夹(时间戳文件夹)
-        char *endptr;
+
+        // 转换文件夹名称为时间戳(星历文件夹是纯数字命名)
+        char *endptr = NULL;
         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;
-            }
-            
-            // 构建完整路径以检查文件数量 - 使用malloc
-            char *full_folder_path = malloc(512);
-            if (full_folder_path == NULL) {
-                printf("ERROR: Failed to allocate memory for full_folder_path\n");
-                continue;
+        // 过滤非数字文件夹
+        if (*endptr != '\0' || folder_timestamp == 0) {
+            printf("Skip non-numeric folder: %s\n", entry->d_name);
+            continue;
+        }
+
+        // 调试日志:打印当前遍历的文件夹时间戳(核心修正:不再颠倒)
+        // printf("folder_timestamp : %u, current_timestamp : %u\n", folder_timestamp, current_timestamp);
+
+        // 3. 正确统计未来文件夹(文件夹时间戳 > 当前系统时间戳)
+        if (folder_timestamp > current_timestamp) {
+            future_folder_count++;
+            if (folder_timestamp < future_min_ts) {
+                future_min_ts = folder_timestamp;
             }
-            
-            int path_ret = snprintf(full_folder_path, 512, "%s/%s", PGNSS_DATA_PATH, entry->d_name);
-            if (path_ret < 0 || path_ret >= 512) {
-                printf("ERROR: snprintf failed for folder path\n");
-                free(full_folder_path);
-                continue;
+            if (folder_timestamp > future_max_ts) {
+                future_max_ts = folder_timestamp;
             }
-            
-            // 检查文件夹内的文件数量
-            DIR *sub_dir = opendir(full_folder_path);
-            int file_count = 0;
-            if (sub_dir != NULL) {
-                struct dirent *sub_entry;
-                while ((sub_entry = readdir(sub_dir)) != NULL) {
-                    // 跳过 . 和 .. 目录
-                    if (strcmp(sub_entry->d_name, ".") == 0 || strcmp(sub_entry->d_name, "..") == 0) {
-                        continue;
-                    }
-                    file_count++;
+        }
+
+        // 4. 原有逻辑:筛选24小时内的有效文件夹
+        uint32_t time_diff = 0;
+        if (current_timestamp >= folder_timestamp) {
+            time_diff = current_timestamp - folder_timestamp;
+        } else {
+            continue;
+        }
+
+        // 构建文件夹路径
+        char full_folder_path[512] = {0};
+        int ret = snprintf(full_folder_path, sizeof(full_folder_path), "%s/%s",
+                           PGNSS_DATA_PATH, entry->d_name);
+        if (ret < 0 || ret >= (int)sizeof(full_folder_path)) {
+            printf("ERROR: Folder path too long: %s/%s\n", PGNSS_DATA_PATH, entry->d_name);
+            continue;
+        }
+
+        // 统计文件夹内的文件数
+        DIR *sub_dir = opendir(full_folder_path);
+        int file_count = 0;
+        if (sub_dir != NULL) {
+            struct dirent *sub_entry = NULL;
+            while ((sub_entry = readdir(sub_dir)) != NULL) {
+                if (strcmp(sub_entry->d_name, ".") == 0 || strcmp(sub_entry->d_name, "..") == 0) {
+                    continue;
                 }
-                closedir(sub_dir);
+                file_count++;
             }
-            
-            // printf("Found AGNSS folder: %s (age: %u seconds, files: %d)\n", 
-            //        entry->d_name, time_diff, file_count);
-            
-            // 检查是否在24小时内且文件数量足够
-            if (time_diff < 86400 && file_count >= 20) { // 24小时 = 86400秒
-                found_valid_folder = 1;
-                if (time_diff < min_time_diff) {
-                    min_time_diff = time_diff;
-                    best_folder_timestamp = folder_timestamp;
-                    best_file_count = file_count;
-                    strncpy(best_folder_name, entry->d_name, 63);
-                    best_folder_name[63] = '\0';
-                }
+            closedir(sub_dir);
+        } else {
+            printf("WARNING: Cannot open sub folder: %s\n", full_folder_path);
+            continue;
+        }
+
+        // 筛选有效文件夹
+        if (time_diff < VALID_TIME_WINDOW && file_count >= MIN_FILE_COUNT) {
+            found_valid_folder = 1;
+            if (time_diff < min_time_diff) {
+                min_time_diff = time_diff;
+                best_folder_timestamp = folder_timestamp;
+                best_file_count = file_count;
+                strncpy(best_folder_name, entry->d_name, sizeof(best_folder_name) - 1);
+                best_folder_name[sizeof(best_folder_name) - 1] = '\0';
             }
-            
-            // 释放路径内存
-            free(full_folder_path);
         }
     }
-    
+
     closedir(dir);
-    
-    // 检查结果并返回
+
+    // 打印未来文件夹数量(调试用)
+    // printf("future_folder_count : %d\n", future_folder_count);
+
+    // 返回剩余有效分钟数
     if (found_valid_folder) {
-        uint32_t remaining_time = 86400 - min_time_diff; // 24小时 - 已过时间
-        
-        // printf("✓ AGNSS Status: VALID\n");
-        // printf("  Folder: %s\n", best_folder_name);
-        // printf("  File count: %d\n", best_file_count);
-        // printf("  Remaining time: %u seconds (%.1f hours)\n", 
-        //        remaining_time, remaining_time / 3600.0);
-        
-        // 释放内存
-        free(best_folder_name);
-        
-        // 返回剩余时间的分钟数
-        int remaining_minutes = remaining_time / 60;
-        // printf("=== AGNSS Status Check Complete ===\n");
+        uint32_t remaining_seconds = VALID_TIME_WINDOW - min_time_diff;
+        int remaining_minutes = (int)(remaining_seconds / 60) + (future_folder_count * 24 * 60);
+        printf("Valid folder remaining minutes: %d\n", remaining_minutes);
         return remaining_minutes;
     } else {
-        // printf("✗ AGNSS Status: EXPIRED or NOT FOUND\n");
-        // printf("  No valid AGNSS data within 24 hours\n");
-        
-        // 释放内存
-        free(best_folder_name);
-        
-        // printf("=== AGNSS Status Check Complete ===\n");
-        
-        // 过期返回0
+        printf("No valid folder in 24 hours\n");
         return 0;
     }
 }