return 0;
}
+/* 采用http_download风格实现的文件下载函数
+ * 功能:从指定URL下载文件到指定路径(已知总大小)
+ * 参数:full_url - 完整下载URL
+ * save_path - 保存路径
+ * total_size - 已知的文件总大小(字节)
+ * 返回:0 - 成功,非0 - 失败
+ */
+static int ln_download_file_to_path(const char *full_url, const char *save_path, int total_size)
+{
+ // 参数校验(包含total_size的检查)
+ if (!full_url || !save_path || total_size <= 0)
+ {
+ printf("[OTA] invalid parameters: url=%p, path=%p, total_size=%d\n",
+ full_url, save_path, total_size);
+ return -1;
+ }
+ printf("[OTA] starting download: %s -> %s, total_size=%d bytes\n",
+ full_url, save_path, total_size);
+
+ /* CAT1 网络保活处理 */
+ cat1_api_add_cat1_vote();
+ cat1_api_wakeup_cat1(1);
+ cat1_api_keep_wakeup(1);
+ cat1_api_disable_cat1_cmd(0);
+ LOS_Msleep(300); // 等待模块就绪
+
+ /* 初始化HTTP客户端(与http_download风格一致) */
+ HttpClient client = {0};
+ HttpClientData client_data = {0};
+ int ret = -1;
+ size_t total_written = 0; // 已写入文件的总字节数
+
+ // 打开文件准备写入
+ FILE *fd = fopen(save_path, "wb");
+ if (!fd)
+ {
+ printf("[OTA] fopen failed for %s:\n", save_path);
+ return -1;
+ }
+
+ HTTPC_RESULT prep = ln_http_prepare_auto(&client_data, 2048, LN_CLIENT_PREPARE_SIZE);
+ if (prep != HTTP_SUCCESS)
+ {
+ printf("[OTA] range prepare failed: %d\n", prep);
+ fclose(fd);
+ return -1;
+ }
+
+ // 建立连接(与http_download流程一致)
+ ret = HttpClientConn(&client, full_url);
+ if (ret != 0)
+ {
+ printf("[OTA] connection failed, ret=0x%x\n", ret);
+ fclose(fd);
+ HttpClientUnprepare(&client_data);
+ return ret;
+ }
+
+ // 发送GET请求
+ ret = HttpClientSend(&client, full_url, HTTP_GET, &client_data);
+ if (ret != 0)
+ {
+ printf("[OTA] send request failed, ret=0x%x\n", ret);
+ HttpClientClse(&client);
+ fclose(fd);
+ HttpClientUnprepare(&client_data);
+ return ret;
+ }
+
+ // 循环接收响应数据(参考http_download的do-while循环)
+ printf("[OTA] starting to receive data...\n");
+ do
+ {
+ ret = HttpClientRecvResponse(&client, &client_data);
+ printf("[OTA] receive response: %d\n", ret);
+ if (ret == HTTP_SUCCESS || ret == HTTP_EAGAIN)
+ {
+ // 处理接收到的数据块
+ if (client_data.contentBlockLen > 0)
+ {
+ printf("[OTA] received block: %d bytes\n", client_data.contentBlockLen);
+ // 写入文件(与http_download的写入逻辑一致)
+ size_t written = fwrite(client_data.responseBuf, 1,
+ client_data.contentBlockLen, fd);
+ if (written != client_data.contentBlockLen)
+ {
+ printf("[OTA] write file failed, written=%zu, expected=%d\n",
+ written, client_data.contentBlockLen);
+ ret = -1;
+ break;
+ }
+ total_written += written;
+ // 进度上报(使用已知的total_size计算)
+ int percent = (int)((total_written * 100) / total_size);
+ if (percent > 100)
+ percent = 100; // 防止超过100%
+ char prog[128];
+ snprintf(prog, sizeof(prog),
+ "{\"status\":%d,\"progress\":%d}",
+ OTA_DOWNLOAD_STATUS_PROGRESS, percent);
+ do_ln_http_server_recv_data(LN_HTTP_RECV_OTA_DOWNLOAD_MSG,
+ prog, strlen(prog));
+ printf("[OTA] progress: %d%% (%zu/%d)\n",
+ percent, total_written, total_size);
+
+ // 检查是否超过预期总大小
+ if (total_written > (size_t)total_size)
+ {
+ printf("[OTA] received more than expected! total_written=%zu > total_size=%d\n",
+ total_written, total_size);
+ ret = -1;
+ break;
+ }
+ }
+ }
+ else
+ {
+ printf("[OTA] receive failed, ret=0x%x\n", ret);
+ break;
+ }
+ } while (client_data.isMore && total_written < (size_t)total_size); // 双重条件判断
+ // 检查下载结果(参考http_download的结果校验)
+ if (ret == 0 && client.responseCode == 200)
+ {
+ // 验证是否下载完整(使用已知的total_size)
+ if (total_written == (size_t)total_size)
+ {
+ printf("[OTA] download complete! total size: %d bytes\n", total_size);
+ ret = 0;
+ }
+ else
+ {
+ printf("[OTA] download incomplete! received=%zu, expected=%d\n",
+ total_written, total_size);
+ ret = -1;
+ }
+ }
+ else
+ {
+ printf("[OTA] download failed! response code: %d, ret=0x%x\n",
+ client.responseCode, ret);
+ }
+
+ // 资源清理(与http_download保持一致)
+ fclose(fd);
+ HttpClientClse(&client);
+ HttpClientUnprepare(&client_data);
+ printf("[OTA] download process finished\n");
+
+ return ret;
+}
+
uint32_t ln_ota_download_flow_http(const char *device_id,
const char *device_token,
const char *source_version)
int dres;
if (g_ln_last_package_size > 0)
{
- dres = ln_download_file_to_path_range(g_ln_last_package_url, save_path, g_ln_last_package_size);
+ dres = ln_download_file_to_path(g_ln_last_package_url, save_path, g_ln_last_package_size);
}
if (dres != 0)
{