luckfox-pico-sdk/sysdrv/source/mcu/rt-thread/components/ota/ota_http.c
luckfox-eng29 8f34c2760d project:build.sh: Added fastboot support; custom modifications to U-Boot and kernel implemented using patches.
project:cfg:BoardConfig_IPC: Added fastboot BoardConfig file and firmware post-scripts, distinguishing between
the BoardConfigs for Luckfox Pico Pro and Luckfox Pico Max. project:app: Added fastboot_client and rk_smart_door
for quick boot applications; updated rkipc app to adapt to the latest media library. media:samples: Added more
usage examples. media:rockit: Fixed bugs; removed support for retrieving data frames from VPSS. media:isp:
Updated rkaiq library and related tools to support connection to RKISP_Tuner. sysdrv:Makefile: Added support for
compiling drv_ko on Luckfox Pico Ultra W using Ubuntu; added support for custom root filesystem.
sysdrv:tools:board: Updated Buildroot optional mirror sources, updated some software versions, and stored device
tree files and configuration files that undergo multiple modifications for U-Boot and kernel separately.
sysdrv:source:mcu: Used RISC-V MCU SDK with RT-Thread system, mainly for initializing camera AE during quick
boot. sysdrv:source:uboot: Added support for fastboot; added high baud rate DDR bin for serial firmware upgrades.
sysdrv:source:kernel: Upgraded to version 5.10.160; increased NPU frequency for RV1106G3; added support for
fastboot.

Signed-off-by: luckfox-eng29 <eng29@luckfox.com>
2024-10-14 09:47:04 +08:00

1194 lines
39 KiB
C

/**
* Copyright (c) 2020 Fuzhou Rockchip Electronics Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <rtdevice.h>
#include <rtthread.h>
#include <dfs_posix.h>
#include <drivers/mtd_nor.h>
#include "hal_base.h"
#ifdef RT_USING_OTA_FROM_HTTP
#include "link_queue.h"
#include "../fwmgr/fw_analysis.h"
#include "../fwmgr/rkpart.h"
#include "http_api.h"
//#include "audio_server.h"
//#include "http_preprocessor.h"
#include "ota.h"
//#include "ota_debug.h"
#include "ota_http.h"
extern uint32_t g_fw_curr_slot;
extern uint32_t g_user_curr_slot;
extern uint32_t g_os_real_size;
extern uint32_t g_data_real_size;
extern uint32_t g_root_real_size;
static ota_http_cfg_t *g_otaHttpCfg;
static ota_http_parameters *g_http_param;
static long gImgFileSize;
static int http_socket = -1;
static unsigned char g_is_chunked = 0;
static unsigned long http_totalsize;
static uint32_t g_fw_pos;
static uint32_t g_skip_size;
#if OTA_OPT_PROTOCOL_HTTP
#define DBG_SECTION_NAME "OTA_HTTP"
#include "rkdebug.h"
int http_opts_init(struct ota_http_opts_t *self, ota_http_cfg_t *cfg)
{
int rst = -RT_ERROR;
int mem_size = HTTP_DOWNLOAD_FILE_NAME_LENGTH;
char *response = NULL;
REDO:
response = (char *)rt_malloc(mem_size * sizeof(char));
LOGD("rt_malloc response %p\n", response);
if (response == RT_NULL)
return rst;
http_socket = -1;
if (http_open(cfg->target, &response, &http_socket, HTTP_GET, NULL, 0) != HTTP_STATUS_OK)
{
goto END;
}
g_is_chunked = -RT_ERROR;
struct http_res_header resp = parse_header(response);
LOGD("\n>>>>http header parse success:<<<<");
LOGD("\tHTTP reponse: %d", resp.status_code);
if (resp.status_code != 200 && resp.status_code != 206)
{
if (resp.status_code == 301 || resp.status_code == 302) //301 Moved Permanently / 302 Found
{
if (response)
rt_free(response);
cfg->target = resp.httpRedirectURL.pParam;
goto REDO;
}
else
{
LOGD("file can't be download,status code: %d\n", resp.status_code);
rst = -RT_ERROR;
goto END;
}
}
LOGD("\tHTTP file type: %s", resp.content_type);
g_is_chunked = is_chunked(resp);
if (g_is_chunked)
{
LOGD("\tHTTP transfer-encoding: %s", resp.transfer_encoding);
}
else
{
LOGD("\tHTTP file length: %ld byte", resp.content_length);
http_totalsize = resp.content_length;
}
cfg->file_size = resp.content_length;
self->userdata = (void *)&http_socket;
cfg->frame_size = HTTP_PREPROCESSOR_FRAME_SIZE;
// LOGD("[%s] open native http ok, http: %s, audio type:%s",
// cfg->tag,
// cfg->target,
// cfg->type);
rst = RT_EOK;
END:
if (response)
rt_free(response);
if (rst == -RT_ERROR)
{
if (http_socket != -1)
{
close(http_socket);
LOGW("****** close socket. ******");
}
}
return rst;
}
int http_opts_read(struct ota_http_opts_t *self, char *data, size_t data_len)
{
int rs = RT_FALSE;
if (!self->userdata)
{
return rs;
}
if (g_is_chunked)
{
rs = http_socket_read_chunk(*(int *)self->userdata, data, data_len);
}
else
{
if (http_totalsize == 0)
return 0;
if (data_len > http_totalsize)
data_len = http_totalsize;
rs = http_socket_read(*(int *)self->userdata, data, data_len);
if (rs > 0)
{
if (rs != data_len)
{
// LOGD("read data underrun,data_len:%d has_read:%d\n", data_len, rs);
}
http_totalsize -= rs;
}
else if (rs == 0)
{
if (http_totalsize > 0)
{
LOGE("http read data fail\n");
return -101; //http not end, return this val for app stop player
}
else
{
LOGD("http read data over\n");
}
}
else if (rs == -1)
{
//socket error, if return -101, watch dog will reset system
LOGE("socket error\n");
return 0;
}
}
return rs;
}
void http_opts_destroy(struct ota_http_opts_t *self)
{
if (!self)
return;
if (!self->userdata)
return;
int client_socket = *(int *)self->userdata;
http_close(client_socket);
}
ota_status ota_update_http_init(void *url)
{
LOGD("%s Enter", __func__);
if (g_http_param == RT_NULL)
{
g_http_param = (ota_http_parameters *)rt_malloc(sizeof(ota_http_parameters));
if (g_http_param == RT_NULL)
{
LOGE("http param malloc fail");
return OTA_STATUS_ERR;
}
}
/* check wifi whether connect */
while (rt_wlan_is_ready() != RT_TRUE)
{
rt_thread_delay(100);
LOGW("wlan NG. Pls connect wifi!");
}
if (!url)
{
if (g_http_param)
rt_free(g_http_param);
LOGE("file URL is NULL");
return OTA_STATUS_ERR;
}
rt_memset(g_http_param, 0, sizeof(ota_http_parameters));
rt_memcpy(g_http_param->url, url, strlen(url));
LOGD("ota file url = %s", g_http_param->url);
g_otaHttpCfg = rt_malloc(sizeof(ota_http_cfg_t));
if (g_otaHttpCfg == RT_NULL)
{
LOGE("ota http cfg malloc fail");
if (g_http_param)
rt_free(g_http_param);
return OTA_STATUS_ERR;
}
g_otaHttpCfg->target = g_http_param->url;
g_http_param->http_opts = (ota_http_opts)DEFAULT_HTTP_OPTS;
int ret = g_http_param->http_opts.init(&g_http_param->http_opts, g_otaHttpCfg);
if (ret != 0)
{
LOGE("### %s(), http_opts.init fail ###", __func__);
if (g_otaHttpCfg)
{
rt_free(g_otaHttpCfg);
g_otaHttpCfg = RT_NULL;
}
if (g_http_param)
{
rt_free(g_http_param);
g_http_param = RT_NULL;
}
LOGE("%s(), Fail", __func__);
return OTA_STATUS_ERR;
}
RT_ASSERT(g_http_param->http_opts.read != RT_NULL);
//the whole update.img's size, we should get the echo slot fw size in http download handle task.
gImgFileSize = g_otaHttpCfg->file_size;
LOGD("File size : %ld Bytes", gImgFileSize);
if (!gImgFileSize)
return OTA_STATUS_ERR;
return OTA_STATUS_OK;
}
rt_thread_t gOtaHttpDownloadHdl;
LinkQueue *gDnQueue;
uint8_t eof_flag;
uint8_t ota_http_run;
uint32_t ota_image_left;
volatile uint32_t ota_total_count = 0;
volatile uint32_t ota_downld_count = 0;
volatile uint32_t ota_write_count = 0;
//static rt_uint32_t fw_slot_size;
static void ota_http_seek_to(rt_uint32_t offset)
{
rt_int32_t readSize = -1;
rt_uint32_t seek_size = 0;
rt_uint32_t recv_size;
rt_uint32_t each_read_size = 0;
char tmpBuf[OTA_BUF_SIZE] = {0};
//LOGD("%s Enter...", __func__);
//LOGD("need to seek to offset %d(%#x)", offset, offset);
each_read_size = OTA_BUF_SIZE;
seek_size = offset;
while (1)
{
recv_size = 0;
rt_memset(tmpBuf, 0, OTA_BUF_SIZE);
if (seek_size < each_read_size)
{
each_read_size = seek_size;
//LOGD("Total seek pos left: %d", seek_size);
}
RETRY:
readSize = g_http_param->http_opts.read(&g_http_param->http_opts, tmpBuf, each_read_size);
if (readSize <= 0) //means read fail.retry here.
{
LOGE("read size %d, retry...", readSize);
rt_thread_delay(10);
goto RETRY;
}
seek_size -= readSize;
//LOGD("leftt seek_size = %d", seek_size);
//if (seek_size < each_read_size)
// LOGD("seek left size = %ld, have readed = %d", seek_size, readSize);
if (readSize == each_read_size)
{
if (seek_size > 0)
continue; //do nothing, read data we discard.
else if (seek_size == 0)
break; // we have seek to needed postion.
}
else if (readSize != each_read_size)
{
if (readSize < each_read_size)
{
int left = 0;
recv_size = readSize;
if (seek_size > 0)
{
if (seek_size >= each_read_size || (seek_size + readSize) >= each_read_size)
{
/* left data size big than buf_size */
do
{
left = each_read_size - recv_size;
REDO0:
readSize = g_http_param->http_opts.read(&g_http_param->http_opts, &tmpBuf[recv_size], left);
//LOGD("[retry to read]:have readsize = %ld", readSize);
if (readSize < 0)
{
rt_thread_delay(10);
goto REDO0;
}
recv_size += readSize;
seek_size -= readSize;
if (recv_size == each_read_size)
break;
}
while (readSize != left);
}
else
{
/* left data size small than buf_size */
do
{
REDO1:
readSize = g_http_param->http_opts.read(&g_http_param->http_opts, &tmpBuf[recv_size], seek_size);
if (readSize < 0)
{
rt_thread_delay(10);
goto REDO1;
}
recv_size += readSize;
seek_size -= readSize;
if (seek_size == 0)
break;
}
while (seek_size != 0);
}
if (seek_size == 0)
break;
}
else if (seek_size == 0)
break;
}
}
}
//LOGD("Have sought to %d(%#x) position", offset, offset);
}
static void ota_http_os_downlaod_hdl(void *arg)
{
int ret = 0;
int readSize = -1;
rt_uint32_t recv_size = 0;
rt_uint32_t fw_buf_size = 0;
char *fw_data = RT_NULL;
rt_uint32_t seek_pos = 0;
char tmpBuf[OTA_BUF_SIZE] = {0};
//LOGD("%s Enter ...", __func__);
fw_buf_size = OTA_BUF_SIZE;
gDnQueue = create_empty_linkqueue();
if (gDnQueue == RT_NULL)
{
LOGE("gRecordQueue create failed.");
return;
}
/* pre-process: seek to desired fw slot position in firmware.img*/
{
char *head_data = RT_NULL;
rt_uint32_t recv = 0;
rt_uint8_t end_flag = 0;
PFIRMWARE_HEADER pFwHead = RT_NULL;
unsigned char magic[8] = {'R', 'E', 'S', 'C', 0, 0, 0, 0};
if (g_fw_curr_slot == 0)
seek_pos = firmware_addr2;
else if (g_fw_curr_slot == 1)
seek_pos = firmware_addr1;
else
return;
ota_http_seek_to(seek_pos); //like lseek to seek_pos.
g_fw_pos = seek_pos;
/*we get fw slot head */
head_data = (char *)rt_malloc(OTA_BUF_SIZE);
if (head_data == RT_NULL)
{
LOGE("malloc head_data buffer error.");
return;
}
if (ota_fw_head_http_get((uint8_t *)head_data, OTA_BUF_SIZE, &recv, &end_flag) != OTA_STATUS_OK)
{
LOGE("get fw slot %d head data fail");
return;
}
pFwHead = (PFIRMWARE_HEADER)head_data;
if (0 != rt_memcmp(pFwHead->magic, magic, 8))
{
LOGE("Fw head magic Error!");
return;
}
/* update fw slot size here */
gImgFileSize = pFwHead->data_size + 512 + 4;
g_os_real_size = gImgFileSize;
g_fw_pos += gImgFileSize;
//LOGD("fw data offset = %u(0x%#08x)", pFwHead->data_offset, pFwHead->data_offset);
//LOGD("fw data size = %u(0x%#08x)", pFwHead->data_size, pFwHead->data_size);
//LOGD("fw slot size = %u(0x%#08x)", gImgFileSize, gImgFileSize);
/*have read OTA_BUF_SIZE to buff*/
gImgFileSize -= OTA_BUF_SIZE;
//LOGD("Total image file left: %d", gImgFileSize);
/* we should push have read 4K data to LinkQueue*/
ret = push_linkqueue(gDnQueue, head_data);
if (ret)
{
LOGE("[line:%d]push link queue fail", __LINE__);
rt_free(head_data);
LOGE(">>>>>%d gDnQueue invalid ret = %d", __LINE__, ret);
return;
}
ota_total_count++;
ota_downld_count++;
rt_thread_delay(20);
}
while (1)
{
while (ota_http_run)
{
recv_size = 0;
if (gImgFileSize < fw_buf_size)
{
fw_buf_size = gImgFileSize;
//LOGD("Total image file left: %d", gImgFileSize);
}
fw_data = (char *)rt_malloc(fw_buf_size);
if (fw_data == RT_NULL)
{
LOGE("malloc fw_data buffer fail.");
break;
}
rt_memset(fw_data, 0, fw_buf_size);
ota_image_left = fw_buf_size;
rt_memset(tmpBuf, 0, OTA_BUF_SIZE);
RT_ASSERT(g_http_param->http_opts.read != RT_NULL);
RETRY:
readSize = g_http_param->http_opts.read(&g_http_param->http_opts, tmpBuf, fw_buf_size);
if (readSize <= 0) //means read fail.retry here.
{
LOGE("read size %d, retry...", readSize);
rt_thread_delay(10);
goto RETRY;
}
//LOGD("=== have read %u ===", readSize);
gImgFileSize -= readSize;
//LOGD("===Fw left %u to download.===", gImgFileSize);
//if (gImgFileSize < fw_buf_size)
// LOGD("left size = %ld, have readed = %d", gImgFileSize, readSize);
if (readSize == fw_buf_size)
{
if (gImgFileSize > 0)
{
ota_total_count++;
ota_downld_count++;
eof_flag = 0;
rt_memcpy(fw_data, tmpBuf, fw_buf_size);
ret = push_linkqueue(gDnQueue, fw_data);
if (ret)
{
LOGE("[line:%d]push link queue fail", __LINE__);
rt_free(fw_data);
LOGE(">>>>>%d gDnQueue invalid ret = %d", __LINE__, ret);
break;
}
//LOGD(">>>>>>>>>>>>>>>>>>> download %d times", ota_downld_count);
rt_thread_delay(10);
continue;
}
else if (0 == gImgFileSize)
{
ota_total_count++;
ota_downld_count++;
eof_flag = 1;
ota_http_run = 0;
rt_memcpy(fw_data, tmpBuf, fw_buf_size);
ret = push_linkqueue(gDnQueue, fw_data);
if (ret)
{
LOGE("[line:%d]push link queue fail", __LINE__);
rt_free(fw_data);
LOGE(">>>>>%d gDnQueue invalid ret = %d", __LINE__, ret);
break;
}
//LOGD("Last time download size: %d", fw_buf_size);
//LOGD("Total download fw size: %d", g_otaHttpCfg->file_size);
//LOGD(">>>>>>>>>>>>>>>>>>> download over,total download %d times", ota_total_count);
break;
}
}
if (readSize != fw_buf_size)
{
if (readSize <= 0)
{
goto RETRY;
}
else if (readSize < fw_buf_size)
{
int left = 0;
//uint8_t *tmpBuf = fw_data;
recv_size = readSize;
if (gImgFileSize > 0)
{
if (gImgFileSize >= fw_buf_size || (gImgFileSize + readSize) >= fw_buf_size)
{
/* left data size big than buf_size */
do
{
left = fw_buf_size - recv_size;
//LOGD("[left to request]: # %ld #", left);
//tmpBuf += recv_size;
REDO0:
readSize = g_http_param->http_opts.read(&g_http_param->http_opts, &tmpBuf[recv_size], left);
//LOGD("[retry to read]: readsize = %ld", readSize);
if (readSize < 0)
{
LOGE("read size %d, retry...", readSize);
rt_thread_delay(10);
goto REDO0;
}
recv_size += readSize;
gImgFileSize -= readSize;
//LOGD("[retry to read]: have get %u,total left = %ld",recv_size, gImgFileSize);
if (recv_size == fw_buf_size)
{
break;
}
}
while (readSize != left);
rt_memcpy(fw_data, tmpBuf, fw_buf_size);
}
else
{
/* left data size small than buf_size */
do
{
//tmpBuf += recv_size;
//LOGD("will reqeust %d", gImgFileSize);
REDO1:
readSize = g_http_param->http_opts.read(&g_http_param->http_opts, &tmpBuf[recv_size], gImgFileSize);
if (readSize < 0)
{
LOGE("read size %d, retry...", readSize);
rt_thread_delay(10);
goto REDO1;
}
//LOGD("retry to read: readsize = %ld", readSize);
recv_size += readSize;
gImgFileSize -= readSize;
//LOGD("retry to read: left size = %ld", gImgFileSize);
if (gImgFileSize == 0)
{
break;
}
}
while (gImgFileSize != 0);
rt_memcpy(fw_data, tmpBuf, fw_buf_size);
}
if (gImgFileSize)
{
/*not read to end*/
//eof_flag = 0;
//LOGD("recv size = %u , request size = %u", recv_size, fw_buf_size);
//LOGD("# Total left %u #", gImgFileSize);
ota_total_count++;
ota_downld_count++;
eof_flag = 0;
//rt_memcpy(fw_data, tmpBuf, fw_buf_size);
ret = push_linkqueue(gDnQueue, fw_data);
if (ret)
{
LOGE("[line:%d]push link queue fail", __LINE__);
rt_free(fw_data);
LOGE(">>>>>%d gDnQueue invalid ret = %d", __LINE__, ret);
break;
}
//LOGD(">>>>>>>>>>>>>>>>>>> downlaod 2 %d times", ota_downld_count);
rt_thread_delay(10);
continue;
}
else
{
/*means read over*/
eof_flag = 1;
//LOGD("http download file over!");
ota_total_count++;
ota_downld_count++;
ota_http_run = 0;
//rt_memcpy(fw_data, tmpBuf, fw_buf_size);
ret = push_linkqueue(gDnQueue, fw_data);
if (ret)
{
LOGE("[line:%d]push link queue fail", __LINE__);
rt_free(fw_data);
LOGE(">>>>>%d gDnQueue invalid ret = %d", __LINE__, ret);
break;
}
rt_thread_delay(10);
//LOGD(">>>>>>>>>>>>>>>>>>> download over,total download %d times", ota_total_count);
/* destroy http preprocessor*/
g_http_param->http_opts.destroy(&g_http_param->http_opts);
}
}
else
{
/*means read over*/
eof_flag = 1;
//LOGD("http download file over!!");
ota_total_count++;
ota_downld_count++;
ota_http_run = 0;
rt_memcpy(fw_data, tmpBuf, fw_buf_size);
ret = push_linkqueue(gDnQueue, fw_data);
if (ret)
{
LOGE("[line:%d]push link queue fail", __LINE__);
rt_free(fw_data);
LOGE(">>>>>%d gDnQueue invalid ret = %d", __LINE__, ret);
break;
}
//LOGD(">>>>>>>>>>>>>>>>>>> download over,total download %d times", ota_total_count);
/* destroy http preprocessor*/
g_http_param->http_opts.destroy(&g_http_param->http_opts);
}
}
}
}
push_linkqueue(gDnQueue, "download_end");
break;
}
//LOGD("exit ota_http_os_dn_hdl task.\n");
gOtaHttpDownloadHdl = RT_NULL;
}
#ifdef RT_SUPPORT_ROOT_AB
static void ota_http_root_downlaod_hdl(void *arg)
{
int ret = 0;
int readSize = -1;
rt_uint32_t recv_size = 0;
rt_uint32_t fw_buf_size = 0;
char *fw_data = RT_NULL;
rt_uint32_t seek_pos = 0;
char tmpBuf[OTA_BUF_SIZE] = {0};
//LOGD("%s Enter ...", __func__);
fw_buf_size = OTA_BUF_SIZE;
gDnQueue = create_empty_linkqueue();
if (gDnQueue == RT_NULL)
{
LOGE("gRecordQueue create failed.");
return;
}
/* pre-process: seek to desired root slot position in firmware.img*/
if (g_user_curr_slot == 0)
seek_pos = user_start_addr2;
else if (g_user_curr_slot == 1)
seek_pos = user_start_addr1;
else
return;
g_skip_size = seek_pos - g_fw_pos;
ota_http_seek_to(g_skip_size); //skip to desired root position.
gImgFileSize = user_part_size;
while (1)
{
while (ota_http_run)
{
recv_size = 0;
if (gImgFileSize < fw_buf_size)
{
fw_buf_size = gImgFileSize;
LOGD("Total image file left: %d", gImgFileSize);
}
fw_data = (char *)rt_malloc(fw_buf_size);
if (fw_data == RT_NULL)
{
LOGE("malloc fw_data buffer fail.");
break;
}
rt_memset(fw_data, 0, fw_buf_size);
ota_image_left = fw_buf_size;
rt_memset(tmpBuf, 0, OTA_BUF_SIZE);
RT_ASSERT(g_http_param->http_opts.read != RT_NULL);
RETRY:
readSize = g_http_param->http_opts.read(&g_http_param->http_opts, tmpBuf, fw_buf_size);
if (readSize <= 0) //means read fail.retry here.
{
LOGE("read size %d, retry...", readSize);
rt_thread_delay(10);
goto RETRY;
}
//LOGD("=== have read %u ===", readSize);
gImgFileSize -= readSize;
//LOGD("===Fw left %u to download.===", gImgFileSize);
if (gImgFileSize < fw_buf_size)
LOGD("left size = %ld, have readed = %d", gImgFileSize, readSize);
if (readSize == fw_buf_size)
{
if (gImgFileSize > 0)
{
ota_total_count++;
ota_downld_count++;
eof_flag = 0;
rt_memcpy(fw_data, tmpBuf, fw_buf_size);
ret = push_linkqueue(gDnQueue, fw_data);
if (ret)
{
LOGE("[line:%d]push link queue fail", __LINE__);
rt_free(fw_data);
LOGE(">>>>>%d gDnQueue invalid ret = %d", __LINE__, ret);
break;
}
LOGD(">>>>>>>>>>>>>>>>>>> download root data %d times", ota_downld_count);
rt_thread_delay(10);
continue;
}
else if (0 == gImgFileSize)
{
ota_total_count++;
ota_downld_count++;
eof_flag = 1;
ota_http_run = 0;
rt_memcpy(fw_data, tmpBuf, fw_buf_size);
ret = push_linkqueue(gDnQueue, fw_data);
if (ret)
{
LOGE("[line:%d]push link queue fail", __LINE__);
rt_free(fw_data);
LOGE(">>>>>%d gDnQueue invalid ret = %d", __LINE__, ret);
break;
}
//LOGD("Last time download size: %d", fw_buf_size);
//LOGD(">>>>>>>>>>>>>>>>>>> download over,total download %d times", ota_total_count);
break;
}
}
if (readSize != fw_buf_size)
{
if (readSize <= 0)
{
goto RERRY;
}
else if (readSize < fw_buf_size)
{
int left = 0;
//uint8_t *tmpBuf = fw_data;
recv_size = readSize;
if (gImgFileSize > 0)
{
if (gImgFileSize >= fw_buf_size || (gImgFileSize + readSize) >= fw_buf_size)
{
/* left data size big than buf_size */
do
{
left = fw_buf_size - recv_size;
//LOGD("[left to request]: # %ld #", left);
//tmpBuf += recv_size;
REDO0:
readSize = g_http_param->http_opts.read(&g_http_param->http_opts, &tmpBuf[recv_size], left);
//LOGD("[retry to read]: readsize = %ld", readSize);
if (readSize < 0)
{
LOGE("read size %d, retry...", readSize);
rt_thread_delay(10);
goto REDO0;
}
recv_size += readSize;
gImgFileSize -= readSize;
//LOGD("[retry to read]: have get %u,total left = %ld",recv_size, gImgFileSize);
if (recv_size == fw_buf_size)
{
break;
}
}
while (readSize != left);
rt_memcpy(fw_data, tmpBuf, fw_buf_size);
}
else
{
/* left data size small than buf_size */
do
{
//tmpBuf += recv_size;
//LOGD("will reqeust %d", gImgFileSize);
REDO1:
readSize = g_http_param->http_opts.read(&g_http_param->http_opts, &tmpBuf[recv_size], gImgFileSize);
if (readSize < 0)
{
LOGE("read size %d, retry...", readSize);
rt_thread_delay(10);
goto REDO1;
}
//LOGD("retry to read: readsize = %ld", readSize);
recv_size += readSize;
gImgFileSize -= readSize;
//LOGD("retry to read: left size = %ld", gImgFileSize);
if (gImgFileSize == 0)
{
break;
}
}
while (gImgFileSize != 0);
rt_memcpy(fw_data, tmpBuf, fw_buf_size);
}
if (gImgFileSize)
{
/*not read to end*/
//LOGD("recv size = %u , request size = %u", recv_size, fw_buf_size);
//LOGD("# Total left %u #", gImgFileSize);
ota_total_count++;
ota_downld_count++;
eof_flag = 0;
//rt_memcpy(fw_data, tmpBuf, fw_buf_size);
ret = push_linkqueue(gDnQueue, fw_data);
if (ret)
{
LOGE("[line:%d]push link queue fail", __LINE__);
rt_free(fw_data);
LOGE(">>>>>%d gDnQueue invalid ret = %d", __LINE__, ret);
break;
}
//LOGD(">>>>>>>>>>>>>>>>>>> downlaod 2 %d times", ota_downld_count);
rt_thread_delay(10);
continue;
}
else
{
/*means read over*/
eof_flag = 1;
//LOGD("http download root data over!");
ota_total_count++;
ota_downld_count++;
ota_http_run = 0;
//rt_memcpy(fw_data, tmpBuf, fw_buf_size);
ret = push_linkqueue(gDnQueue, fw_data);
if (ret)
{
LOGE("[line:%d]push link queue fail", __LINE__);
rt_free(fw_data);
LOGE(">>>>>%d gDnQueue invalid ret = %d", __LINE__, ret);
break;
}
rt_thread_delay(10);
//LOGD(">>>>>>>>>>>>>>>>>>> download over,total download root %d times", ota_total_count);
/* destroy http preprocessor*/
g_http_param->http_opts.destroy(&g_http_param->http_opts);
}
}
else
{
/*means read over*/
eof_flag = 1;
//LOGD("http download root data over!!");
ota_total_count++;
ota_downld_count++;
ota_http_run = 0;
rt_memcpy(fw_data, tmpBuf, fw_buf_size);
ret = push_linkqueue(gDnQueue, fw_data);
if (ret)
{
LOGE("[line:%d]push link queue fail", __LINE__);
rt_free(fw_data);
LOGE(">>>>>%d gDnQueue invalid ret = %d", __LINE__, ret);
break;
}
//LOGD(">>>>>>>>>>>>>>>>>>> download over,total download root %d times", ota_total_count);
/* destroy http preprocessor*/
g_http_param->http_opts.destroy(&g_http_param->http_opts);
}
}
}
}
push_linkqueue(gDnQueue, "download_end");
break;
}
LOGD("exit ota_http_root_hdl task.\n");
gOtaHttpDownloadHdl = RT_NULL;
}
#endif
int ota_start_download_task(void *arg)
{
ota_http_run = 1;
/* http download os partiton */
if ((uint32_t)arg == 0)
{
gOtaHttpDownloadHdl = rt_thread_create("ota_os_downld",
ota_http_os_downlaod_hdl,
RT_NULL,
8192 * 4,
16,
20);
if (!gOtaHttpDownloadHdl)
{
LOGE("ota_os_downld thread create fail");
return RT_NULL;
}
else
rt_thread_startup(gOtaHttpDownloadHdl);
}
#ifdef RT_SUPPORT_ROOT_AB
else if ((uint32_t)arg == 1)
{
gOtaHttpDownloadHdl = rt_thread_create("ota_root_downld",
ota_http_root_downlaod_hdl,
RT_NULL,
8192 * 4,
16,
20);
if (!gOtaHttpDownloadHdl)
{
LOGE("ota_root_downld thread create fail");
return RT_NULL;
}
else
rt_thread_startup(gOtaHttpDownloadHdl);
}
#endif
return 0;
}
void ota_exit_download_task(void)
{
ota_http_run = 0;
ota_total_count = 0;
ota_downld_count = 0;
ota_write_count = 0;
if (gDnQueue)
{
delete_empty_linkqueue(gDnQueue);
gDnQueue = NULL;
}
}
ota_status ota_update_http_get(uint8_t *buf, uint32_t buf_size, uint32_t *recv_size, uint8_t *eof)
{
char *fw_data;
while (1)
{
if (!gDnQueue)
{
//LOGD("gDnQueue = NULL !");
rt_thread_delay(50);
continue;
}
else if (is_empty_linkqueue(gDnQueue))
{
//LOGD("LinkQueue is empty !");
rt_thread_delay(50);
continue;
}
fw_data = pop_linkqueue(gDnQueue);
if ((int)fw_data < 0)
LOGE(" ######********* ERROR ********###### fw_data = %d\n ", (int)fw_data);
if ((int)fw_data == -1)
{
rt_thread_delay(10);
//LOGD("gDnQueue pop Error");
continue;
}
else if (!strncmp(fw_data, "download_end", strlen("download_end")))
{
if (!eof_flag)
{
*eof = 0;
*recv_size = 0;
return OTA_STATUS_ERR;
}
//LOGD("---------------- have reached End of Partiton ----------------");
break;
}
else
{
//LOGD("FW have writed @ %d @", ota_write_count);
ota_write_count++;
}
if (ota_write_count == ota_total_count && !ota_http_run)
{
//LOGD("****** last will write %d ******", ota_image_left);
rt_memcpy(buf, fw_data, ota_image_left);
*recv_size = ota_image_left;
rt_free((void *)fw_data);
//LOGD("****** total write == total download ******");
while (1)
{
fw_data = pop_linkqueue(gDnQueue); //last time
if ((int)fw_data != -1 && !strncmp(fw_data, "download_end", strlen("download_end")))
{
*eof = 1;
//LOGD("FW have End of File");
break;
}
rt_thread_delay(10);
}
}
else
{
//LOGD(" write @ %d @", ota_write_count);
rt_memcpy(buf, fw_data, buf_size);
//LOGD(" free data %p ",fw_data);
rt_free((void *)fw_data);
*recv_size = buf_size;
*eof = 0;
}
//LOGD("################### will write %d, @ %d @ time", *recv_size, ota_write_count);
break;
}
return OTA_STATUS_OK;
}
ota_status ota_fw_head_http_get(uint8_t *buf, uint32_t buf_size, uint32_t *recv_size, uint8_t *eof_flag)
{
uint8_t bSucc = RT_FALSE;
int readSize = 0;
int leftSize = 0;
leftSize = buf_size;
readSize = g_http_param->http_opts.read(&g_http_param->http_opts, (char *)buf, buf_size);
leftSize -= readSize;
//LOGD("%s Enter...", __func__);
if (readSize == buf_size)
{
*recv_size = buf_size;
*eof_flag = 1;
bSucc = RT_TRUE;
//LOGD("recv size = %u \n", readSize);
goto END;;
}
if (readSize != buf_size)
{
if (readSize <= 0)
{
LOGE("get data error");
bSucc = RT_FALSE;
goto END;
}
else if (readSize < buf_size)
{
uint8_t *tmpBuf = buf;
*recv_size = readSize;
if (leftSize)
{
/* left data size small than buf_size */
do
{
tmpBuf += readSize;
//LOGD("will reqeust %d", leftSize);
readSize = g_http_param->http_opts.read(&g_http_param->http_opts, (char *)tmpBuf, leftSize);
//LOGD("retry to read: readsize = %ld", readSize);
*recv_size += readSize;
leftSize -= readSize;
//LOGD("retry to read: left size = %ld", leftSize);
if (leftSize == 0)
{
break;
}
}
while (leftSize != 0);
if (leftSize == 0)
{
/*means read over*/
*eof_flag = 1;
//LOGD("http read need fw head data!");
bSucc = RT_TRUE;
}
}
}
}
END:
/* destroy http preprocessor*/
if (!bSucc)
return OTA_STATUS_ERR;
else
return OTA_STATUS_OK;
}
#endif /*OTA_OPT_PROTOCOL_HTTP*/
#endif