From 1e0366a9ac793093acaaa7439e12469bb59fa661 Mon Sep 17 00:00:00 2001 From: penglei <1624952103@qq.com> Date: Thu, 11 Dec 2025 17:17:58 +0800 Subject: [PATCH] =?utf8?q?=E4=BC=98=E5=8C=96gnss=20http=E6=98=9F=E5=8E=86?= =?utf8?q?=E4=B8=8B=E8=BD=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- .../services/gnss/src/gnss_http_server.c | 856 +++++++++++------- 1 file changed, 526 insertions(+), 330 deletions(-) diff --git a/code/sdk/zhihui/services/gnss/src/gnss_http_server.c b/code/sdk/zhihui/services/gnss/src/gnss_http_server.c index 5f992d97a..13635de84 100644 --- a/code/sdk/zhihui/services/gnss/src/gnss_http_server.c +++ b/code/sdk/zhihui/services/gnss/src/gnss_http_server.c @@ -39,6 +39,12 @@ // 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×tamp=%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(¤t_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; } } -- 2.17.1