// 全局标志位:标记是否已经获取到有效的JSON数据
static int g_has_valid_json_data = 0;
+// 简化的下载状态位
+// 0: 正在建立HTTP连接, 1-9: 下载进度(10%-90%), 10: 完成, -1: 失败
+static int g_download_status = 0;
+
+// 文件下载进度跟踪
+static int g_total_files = 0;
+static int g_downloaded_files = 0;
+
static unsigned long g_app_recv_queue= 0xFFFFFFFF;
static unsigned long g_app_send_queue= 0xFFFFFFFF;
} else {
// AGNSS文件列表下载的结果处理
if (result == HTTP_SUCCESS && response_code == 200) {
+ // 更新状态为下载中
+ g_download_status = 1; // 开始下载进度 10%
+ printf("Status: 1 (开始处理数据 10%%)\n");
+
// 处理接收到的数据
if (data_len > 0 && response_data) {
agnss_accumulate_data(response_data, data_len);
// 发送完成信号到接收任务
do_gnss_http_server_recv_data(GNSS_HTTP_SERVICE_CMD_AGNSS_RECV, NULL, 0);
} else {
- // HTTP请求失败,标志位由download_agnss_files函数管理
- printf("HTTP request failed (result: %d, code: %d)\n", result, response_code);
+ // HTTP请求失败,设置失败状态
+ g_download_status = -1;
+ printf("HTTP request failed (result: %d, code: %d), status: -1\n", result, response_code);
}
}
}
// 使用简单的socket直接下载文件
+// 设置总文件数(在开始下载前调用)
+static void set_total_files(int total)
+{
+ g_total_files = total;
+ g_downloaded_files = 0;
+ printf("设置总文件数: %d\n", total);
+}
+
+// 更新文件下载进度
+static void update_file_progress(const char *filename)
+{
+ g_downloaded_files++;
+
+ if (g_total_files > 0) {
+ // 计算进度百分比 (1-9 对应 10%-90%)
+ int progress_percent = (g_downloaded_files * 90) / g_total_files;
+ int status = (progress_percent / 10) + 1; // 转换为 1-9 的状态
+
+ if (status > 9) status = 9; // 最大不超过9
+ if (status < 1) status = 1; // 最小不小于1
+
+ g_download_status = status;
+
+ int actual_percent = (g_downloaded_files * 100) / g_total_files;
+ printf("Status: %d (下载文件 %s - %d%% [%d/%d])\n",
+ status, filename, actual_percent, g_downloaded_files, g_total_files);
+ } else {
+ // 如果没有设置总文件数,使用原来的逻辑
+ static int file_progress = 2;
+ if (file_progress <= 9) {
+ g_download_status = file_progress;
+ printf("Status: %d (下载文件 %s - %d%%)\n", file_progress, filename, file_progress * 10);
+ file_progress++;
+ }
+ }
+}
+
static HTTPC_RESULT download_file_with_httpclient(const char *filename, const char *url)
{
+ // 更新文件下载进度
+ update_file_progress(filename);
// 解析URL
char host[256] = {0};
int port = 80;
// 简单解析 http://host/path 格式
- if (strncmp(url, "http://", 7) == 0) {
+ if (strncmp(url, "http://", 7) == 0) {
const char *url_path = url + 7;
const char *path_start = strchr(url_path, '/');
if (path_start) {
int host_len = path_start - url_path;
if (host_len >= sizeof(host)) {
printf("Host name too long: %d bytes\n", host_len);
+ g_download_status = -1;
return HTTP_EARG;
}
strncpy(host, url_path, host_len);
if (strlen(path_start) >= sizeof(path)) {
printf("Path too long: %zu bytes\n", strlen(path_start));
+ g_download_status = -1;
return HTTP_EARG;
}
strcpy(path, path_start);
} else {
printf("Invalid URL format - no path found\n");
+ g_download_status = -1;
return HTTP_EARG;
}
} else {
printf("Unsupported URL scheme: %s\n", url);
+ g_download_status = -1;
return HTTP_EARG;
}
// 准备客户端数据
HTTPC_RESULT prep_result = HttpClientPrepare(&clientData, 2048, 256 * 1024);
if (prep_result != HTTP_SUCCESS) {
+ printf("HTTP客户端准备失败: %d\n", prep_result);
+ g_download_status = -1;
return prep_result;
}
if (written == actual_size) {
result = HTTP_SUCCESS;
} else {
+ printf("文件写入失败: %s\n", filename);
+ g_download_status = -1;
result = HTTP_ESEND;
}
} else {
+ printf("文件打开失败: %s\n", filename);
+ g_download_status = -1;
result = HTTP_ESEND;
}
} else {
+ printf("无响应数据: %s\n", filename);
+ g_download_status = -1;
result = HTTP_ERECV;
}
} else {
+ printf("HTTP响应错误 %d: %s\n", response_code, filename);
+ g_download_status = -1;
result = HTTP_EPROTO;
}
} else if (result == HTTP_EAGAIN) {
result = HTTP_SUCCESS;
} else {
printf("✗ %s: write failed\n", filename);
+ g_download_status = -1;
result = HTTP_ESEND;
}
} else {
printf("✗ %s: file open failed\n", filename);
+ g_download_status = -1;
result = HTTP_ESEND;
}
} else {
printf("✗ %s: no data\n", filename);
+ g_download_status = -1;
result = HTTP_ERECV;
}
} else {
printf("✗ %s: HTTP %d\n", filename, response_code);
+ g_download_status = -1;
result = HTTP_EPROTO;
}
} else {
printf("Total: %d files in timestamp folder: %s/%u\n", total_count, PGNSS_DATA_PATH, selected_timestamp);
- // 下载完成,标志位由download_agnss_files函数管理
+ // 下载完成,设置完成状态
+ g_download_status = 10;
+ printf("Status: 10 (所有文件下载完成!)\n");
}
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[512] = {0};
+ strncpy(temp_url, url_start, url_len);
+
+ // 检查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(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 = data_start;
int download_count = 0;
{
// 进入函数时设置标志位,表示正在下载
g_has_valid_json_data = 1;
- printf("Starting AGNSS download, set download flag\n");
+ g_download_status = 0; // 设置为连接状态
+
+ // 设置预估的总文件数(通常有多个.eph文件和一个AssistInfo.dat文件)
+ // 这个数值会在实际解析JSON后更新
+ set_total_files(8); // 预估8个文件
+
+ printf("Starting AGNSS download, set download flag, status: 0 (连接中)\n");
//通讯开始,唤醒cat1
cat1_api_add_cat1_vote();
if (result != HTTP_SUCCESS) {
agnss_download_result_handler(NULL, result, 0, NULL, 0);
- // 下载失败,清除标志位
+ // 下载失败,设置失败状态并清除标志位
+ g_download_status = -1;
g_has_valid_json_data = 0;
- printf("Download failed, cleared download flag\n");
+ printf("Download failed, status: -1, cleared download flag\n");
} else {
// 下载成功,清除标志位
g_has_valid_json_data = 0;
}
else if(mail.cmd == GNSS_HTTP_SERVICE_CMD_SERVER_INIT)
{
- // gnss_http_init();
uapi_delete_files(PGNSS_DATA_PATH);
// 检查文件夹是否已存在,避免重复创建
DIR *dir = opendir(PGNSS_DATA_PATH);
return ERRCODE_SUCC;
}
+
+
+/**
+ * @brief 检查星历文件夹的有效状态
+ * @return 过期返回0,有效返回剩余时间的分钟数,错误返回-1
+ */
+int gnss_check_agnss_status(void)
+{
+
+ // 打开AGNSS数据目录
+ DIR *dir = opendir(PGNSS_DATA_PATH);
+ if (dir == NULL) {
+ printf("Cannot open AGNSS directory: %s\n", PGNSS_DATA_PATH);
+ return -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");
+ closedir(dir);
+ return -1;
+ }
+ memset(best_folder_name, 0, 64);
+
+ printf("=== AGNSS Status Check ===\n");
+ printf("Current timestamp: %u\n", current_timestamp);
+
+ // 遍历目录中的所有文件夹
+ while ((entry = readdir(dir)) != NULL) {
+ // 跳过 . 和 .. 目录
+ if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
+ continue;
+ }
+
+ // 检查是否是数字文件夹(时间戳文件夹)
+ char *endptr;
+ 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;
+ }
+
+ 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;
+ }
+
+ // 检查文件夹内的文件数量
+ 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++;
+ }
+ closedir(sub_dir);
+ }
+
+ 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';
+ }
+ }
+
+ // 释放路径内存
+ free(full_folder_path);
+ }
+ }
+
+ closedir(dir);
+
+ // 检查结果并返回
+ 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");
+ return remaining_minutes;
+ } else {
+ printf("✗ AGNSS Status: EXPIRED or NOT FOUND\n");
+ printf(" No valid AGNSS data within 30 hours\n");
+
+ // 释放内存
+ free(best_folder_name);
+
+ printf("=== AGNSS Status Check Complete ===\n");
+
+ // 过期返回0
+ return 0;
+ }
+}
+
+/**
+ * @brief 简化版测试函数 - 只显示关键信息
+ * @return 0: 测试成功, -1: 测试失败
+ */
+int gnss_test_agnss_status_simple(void)
+{
+ printf("=== 星历状态快速检查 ===\n");
+
+ int result = gnss_check_agnss_status();
+
+ if (result > 0) {
+ int hours = result / 60;
+ int minutes = result % 60;
+ printf("✅ 星历有效 - 剩余: %dh%dm\n", hours, minutes);
+ printf("========================\n");
+ return 0; // 测试成功
+ } else if (result == 0) {
+ printf("❌ 星历过期 - 开始自动下载\n");
+ printf("========================\n");
+
+ // 启动下载
+ printf("\n=== 开始下载星历数据 ===\n");
+ printf("🚀 发送下载任务到队列...\n");
+
+ // 通过队列异步启动下载任务
+ do_gnss_http_server_send_data(GNSS_HTTP_SERVICE_CMD_DOWNLOAD_AGNSS, NULL, 0);
+
+ // 监控下载进度
+ printf("\n=== 下载进度监控 ===\n");
+ int last_status = -2; // 初始化为一个不可能的值
+ int monitor_count = 0;
+ const int max_monitor_time = 120; // 最多监控120秒
+
+ while (monitor_count < max_monitor_time) {
+ int current_status = gnss_get_download_status();
+
+ // 只在状态改变时打印
+ if (current_status != last_status) {
+ switch (current_status) {
+ case -1:
+ printf("❌ 下载失败或连接服务器失败\n");
+ printf("===================\n");
+ return -1;
+
+ case 0:
+ printf("🔗 正在建立HTTP连接...\n");
+ break;
+
+ case 1: case 2: case 3: case 4: case 5:
+ case 6: case 7: case 8: case 9:
+ printf("📥 下载进度: %d%% \n", current_status * 10);
+ break;
+
+ case 10:
+ printf("✅ 下载完成!\n");
+
+ // 再次检查星历状态确认下载成功
+ printf("\n=== 验证下载结果 ===\n");
+ int verify_result = gnss_check_agnss_status();
+ if (verify_result > 0) {
+ int hours = verify_result / 60;
+ int minutes = verify_result % 60;
+ printf("✅ 验证成功 - 星历有效,剩余: %dh%dm\n", hours, minutes);
+ } else {
+ printf("⚠️ 下载完成但验证失败\n");
+ }
+ printf("===================\n");
+ return 0; // 下载成功
+
+ default:
+ if (current_status != -1) { // 避免重复打印-1状态
+ printf("⚠️ 状态: %d\n", current_status);
+ }
+ break;
+ }
+ last_status = current_status;
+ }
+
+ // 如果下载完成或失败,退出循环
+ if (current_status == 10 || current_status == -1) {
+ break;
+ }
+
+ // 等待1秒后再次检查
+ LOS_Msleep(1000);
+ monitor_count++;
+ }
+
+ // 如果超时
+ if (monitor_count >= max_monitor_time) {
+ printf("⏰ 下载监控超时\n");
+ int final_status = gnss_get_download_status();
+ printf("最终状态: %d\n", final_status);
+ printf("===================\n");
+ return -1;
+ }
+
+ return 0;
+ } else {
+ printf("❌ 检查失败 - 可能目录不存在,尝试下载\n");
+ printf("========================\n");
+
+ // 启动下载
+ printf("\n=== 开始下载星历数据 ===\n");
+ printf("🚀 发送下载任务到队列...\n");
+
+ // 通过队列异步启动下载任务
+ do_gnss_http_server_send_data(GNSS_HTTP_SERVICE_CMD_DOWNLOAD_AGNSS, NULL, 0);
+
+ // 监控下载进度
+ printf("\n=== 下载进度监控 ===\n");
+ int last_status = -2; // 初始化为一个不可能的值
+ int monitor_count = 0;
+ const int max_monitor_time = 120; // 最多监控120秒
+
+ while (monitor_count < max_monitor_time) {
+ int current_status = gnss_get_download_status();
+
+ // 只在状态改变时打印
+ if (current_status != last_status) {
+ switch (current_status) {
+ case -1:
+ printf("❌ 下载失败或连接服务器失败\n");
+ printf("===================\n");
+ return -1;
+
+ case 0:
+ printf("🔗 正在建立HTTP连接...\n");
+ break;
+
+ case 1: case 2: case 3: case 4: case 5:
+ case 6: case 7: case 8: case 9:
+ printf("📥 下载进度: %d%% \n", current_status * 10);
+ break;
+
+ case 10:
+ printf("✅ 下载完成!\n");
+
+ // 再次检查星历状态确认下载成功
+ printf("\n=== 验证下载结果 ===\n");
+ int verify_result = gnss_check_agnss_status();
+ if (verify_result > 0) {
+ int hours = verify_result / 60;
+ int minutes = verify_result % 60;
+ printf("✅ 验证成功 - 星历有效,剩余: %dh%dm\n", hours, minutes);
+ } else {
+ printf("⚠️ 下载完成但验证失败\n");
+ }
+ printf("===================\n");
+ return 0; // 下载成功
+
+ default:
+ if (current_status != -1) { // 避免重复打印-1状态
+ printf("⚠️ 状态: %d\n", current_status);
+ }
+ break;
+ }
+ last_status = current_status;
+ }
+
+ // 如果下载完成或失败,退出循环
+ if (current_status == 10 || current_status == -1) {
+ break;
+ }
+
+ // 等待1秒后再次检查
+ LOS_Msleep(1000);
+ monitor_count++;
+ }
+
+ // 如果超时
+ if (monitor_count >= max_monitor_time) {
+ printf("⏰ 下载监控超时\n");
+ int final_status = gnss_get_download_status();
+ printf("最终状态: %d\n", final_status);
+ printf("===================\n");
+ return -1;
+ }
+
+ return 0;
+ }
+}
+
+static int g_download_cancelled = 0;
+
+/**
+ * @brief 获取简化的下载状态
+ * @return 0: 连接中, 1-9: 下载进度(10%-90%), 10: 完成, -1: 失败
+ */
+int gnss_get_download_status(void)
+{
+ return g_download_status;
+}
+
+/**
+ * @brief 简化的AGNSS下载函数
+ * @return 0: 成功启动, -1: 失败
+ */
+int gnss_start_agnss_download_simple(void)
+{
+ printf("=== Simple AGNSS Download Started ===\n");
+
+ // 重置状态
+ g_download_cancelled = 0;
+ g_download_status = 0; // 开始连接
+
+ printf("Status: 0 (建立HTTP连接中...)\n");
+
+ // 模拟连接过程
+ LOS_Msleep(2000);
+
+ if (g_download_cancelled) {
+ g_download_status = -1;
+ printf("Status: -1 (下载已取消)\n");
+ return -1;
+ }
+
+ // 模拟下载过程,分10个阶段
+ for (int progress = 1; progress <= 10; progress++) {
+ if (g_download_cancelled) {
+ g_download_status = -1;
+ printf("Status: -1 (下载已取消)\n");
+ return -1;
+ }
+
+ g_download_status = progress;
+
+ if (progress < 10) {
+ printf("Status: %d (下载进度 %d%%)\n", progress, progress * 10);
+ } else {
+ printf("Status: 10 (下载完成!)\n");
+ }
+
+ // 模拟下载延时
+ LOS_Msleep(1000);
+ }
+
+ printf("=== Simple AGNSS Download Completed ===\n");
+ return 0;
+}