Docker-Build mit gcc-arm-none-eabi 4.9-2014q4 (statt Homebrew-Cask) verwendet, Dockerfile/tools/docker.sh dafür aus Task 13 vorgezogen. cmake/sdk.cmake schont gcc 4.9 (kennt -fcommon/-Wno-error=... nicht). Zwei zusätzliche SDK-Stubs (EarlyInit, pre_gpio_config) in src/sys/sdk_stubs.c ergänzt, siehe sdk/PATCHES.md.
238 lines
7.9 KiB
C
238 lines
7.9 KiB
C
#include <string.h>
|
|
#include <stdio.h>
|
|
#include "wm_socket_fwup.h"
|
|
#include "wm_fwup.h"
|
|
#include "wm_http_fwup.h"
|
|
#include "wm_debug.h"
|
|
#include "wm_mem.h"
|
|
|
|
#if TLS_CONFIG_HTTP_CLIENT
|
|
|
|
#define HTTP_CLIENT_BUFFER_SIZE 2048
|
|
#define USE_BREAK_POINT_RESUME 1
|
|
#define RECV_TIMEOUT 5
|
|
|
|
|
|
|
|
enum ota_state {PREPARE_PACKET, SETUP_LINK_AND_REQ, RECV_RSP, HANDLE_HEADER, HANDLE_BODY, SHUTDOWN_LINK, QUIT_OTA};
|
|
|
|
int http_fwup(HTTPParameters ClientParams)
|
|
{
|
|
char* Buffer = NULL;
|
|
char token[32];
|
|
char headRange[32] = {0};
|
|
int nRetCode = 0;
|
|
u32 content_length=0, size=32;
|
|
u32 partLen;
|
|
u32 totalLen = 0;
|
|
u32 recvLen = 0;
|
|
T_BOOTER *booter;
|
|
#if USE_BREAK_POINT_RESUME == 0
|
|
u32 breakFlag = 0;
|
|
u32 breakLen = 0;
|
|
#endif
|
|
struct pbuf *p;
|
|
HTTP_SESSION_HANDLE pHTTP;
|
|
enum ota_state now_state = PREPARE_PACKET;
|
|
|
|
Buffer = (char*)tls_mem_alloc(HTTP_CLIENT_BUFFER_SIZE);
|
|
if (!Buffer)
|
|
return HTTP_CLIENT_ERROR_NO_MEMORY;
|
|
memset(Buffer, 0, HTTP_CLIENT_BUFFER_SIZE);
|
|
|
|
while(1)
|
|
{
|
|
switch(now_state)
|
|
{
|
|
case PREPARE_PACKET:
|
|
{
|
|
memset(token, 0, 32);
|
|
size = 32;
|
|
pHTTP = HTTPClientOpenRequest(0);
|
|
#if USE_BREAK_POINT_RESUME
|
|
HTTPClientSetVerb(pHTTP,VerbGet);
|
|
sprintf(headRange, "bytes=%d-", recvLen);
|
|
if((nRetCode = HTTPClientAddRequestHeaders(pHTTP,"Range", headRange, 1))!= HTTP_CLIENT_SUCCESS){
|
|
now_state = QUIT_OTA;
|
|
}
|
|
#else
|
|
if( recvLen != 0 ){
|
|
breakFlag = 1;
|
|
breakLen = 0;
|
|
}
|
|
#endif
|
|
now_state = SETUP_LINK_AND_REQ;
|
|
}
|
|
break;
|
|
|
|
case SETUP_LINK_AND_REQ:
|
|
{
|
|
if( (nRetCode = HTTPClientSendRequest(pHTTP,ClientParams.Uri,NULL,0,FALSE,0,0)) != HTTP_CLIENT_SUCCESS ){
|
|
tls_os_time_delay(HZ*2);
|
|
now_state = SHUTDOWN_LINK;
|
|
}
|
|
else
|
|
now_state = RECV_RSP;
|
|
}
|
|
break;
|
|
|
|
case RECV_RSP:
|
|
{
|
|
if((nRetCode = HTTPClientRecvResponse(pHTTP, RECV_TIMEOUT)) != HTTP_CLIENT_SUCCESS)
|
|
now_state = SHUTDOWN_LINK;
|
|
else
|
|
now_state = HANDLE_HEADER;
|
|
}
|
|
break;
|
|
|
|
case HANDLE_HEADER:
|
|
{
|
|
if((nRetCode = HTTPClientFindFirstHeader(pHTTP, "content-length", (CHAR *)token, &size)) != HTTP_CLIENT_SUCCESS){
|
|
HTTPClientFindCloseHeader(pHTTP);
|
|
now_state = SHUTDOWN_LINK;
|
|
}
|
|
else
|
|
{
|
|
HTTPClientFindCloseHeader(pHTTP);
|
|
content_length = atol(strstr(token,":")+1);
|
|
printf("content_length: %d\n", content_length);
|
|
now_state = HANDLE_BODY;
|
|
if(recvLen == 0){
|
|
nRetCode = socket_fwup_accept(0, ERR_OK);
|
|
if(nRetCode != ERR_OK)
|
|
now_state = QUIT_OTA;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case HANDLE_BODY:
|
|
{
|
|
partLen = 0;
|
|
while(nRetCode != HTTP_CLIENT_EOS )
|
|
{
|
|
u32 nSize = HTTP_CLIENT_BUFFER_SIZE;
|
|
nRetCode = HTTPClientReadData(pHTTP,Buffer+3,nSize,RECV_TIMEOUT,&nSize);
|
|
if( recvLen == 0 ){
|
|
//fileSize = headerSize(fixed: 56) + appCodeSize
|
|
booter =(T_BOOTER *) (Buffer+3);
|
|
if (TRUE == tls_fwup_img_header_check(booter))
|
|
{
|
|
totalLen = booter->upd_img_len + sizeof(T_BOOTER);
|
|
//OTA_ResetProgress();
|
|
//OTA_SetTotalBytes(totalLen);
|
|
}
|
|
else
|
|
{
|
|
now_state = QUIT_OTA;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(nRetCode != HTTP_CLIENT_SUCCESS && nRetCode != HTTP_CLIENT_EOS){
|
|
now_state = SHUTDOWN_LINK;
|
|
break;
|
|
}
|
|
#if USE_BREAK_POINT_RESUME == 0
|
|
if(breakFlag == 1){
|
|
breakLen += nSize;
|
|
if(breakLen <= recvLen){
|
|
continue;
|
|
}
|
|
else{
|
|
Buffer = Buffer+3+nSize-(breakLen-recvLen)-3;
|
|
nSize = (breakLen-recvLen);
|
|
breakFlag = 0;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
p = pbuf_alloc(PBUF_TRANSPORT, nSize + 3, PBUF_REF);
|
|
while( !p){
|
|
tls_os_time_delay(1);
|
|
p = pbuf_alloc(PBUF_TRANSPORT, nSize + 3, PBUF_REF);
|
|
}
|
|
|
|
if(recvLen == 0)
|
|
*(Buffer+0) = SOCKET_FWUP_START;
|
|
else if(nRetCode == HTTP_CLIENT_EOS && recvLen == (totalLen-nSize))
|
|
*(Buffer+0) = SOCKET_FWUP_END;
|
|
else
|
|
*(Buffer+0) = SOCKET_FWUP_DATA;
|
|
|
|
*(Buffer+1) = (nSize>>8) & 0xFF;
|
|
*(Buffer+2) = nSize & 0xFF;
|
|
p->payload = Buffer;
|
|
p->len = p->tot_len = nSize + 3;
|
|
// Send received data to fwup thread and deal with socket issues.
|
|
s8 ret = socket_fwup_recv(0, p, ERR_OK);
|
|
if(ret != ERR_OK){
|
|
now_state = SHUTDOWN_LINK;
|
|
break;
|
|
}
|
|
else{
|
|
//OTA_IncrementProgress(nSize);
|
|
recvLen += nSize;
|
|
partLen += nSize;
|
|
//printf("download %d / %d\n", recvLen, totalLen); //Status is being printed in our source
|
|
if(partLen == content_length){
|
|
now_state = SHUTDOWN_LINK;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (now_state == QUIT_OTA);
|
|
else
|
|
now_state = SHUTDOWN_LINK;
|
|
}
|
|
break;
|
|
|
|
case SHUTDOWN_LINK:
|
|
{
|
|
if(pHTTP){
|
|
HTTPClientCloseRequest(&pHTTP);
|
|
(recvLen == totalLen)?(now_state = QUIT_OTA):(now_state = PREPARE_PACKET);
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
//printf("now_state %d\n", now_state);
|
|
if(now_state == QUIT_OTA)
|
|
break;
|
|
}
|
|
|
|
tls_mem_free(Buffer);
|
|
if(pHTTP)
|
|
HTTPClientCloseRequest(&pHTTP);
|
|
if(ClientParams.Verbose == TRUE)
|
|
{
|
|
printf("\n\nHTTP Client terminated %d (got %d kb)\n\n",nRetCode,(recvLen/ 1024));
|
|
}
|
|
if(nRetCode)
|
|
socket_fwup_err(0, nRetCode);
|
|
return nRetCode;
|
|
}
|
|
|
|
int t_http_fwup(char *url)
|
|
{
|
|
HTTPParameters httpParams;
|
|
memset(&httpParams, 0, sizeof(HTTPParameters));
|
|
if (url == NULL)
|
|
{
|
|
httpParams.Uri = "http://192.168.1.100:8080/WM_W600_SEC.img";
|
|
}
|
|
else
|
|
{
|
|
httpParams.Uri = url;
|
|
}
|
|
printf("Location: %s\n",httpParams.Uri);
|
|
httpParams.Verbose = TRUE;
|
|
return http_fwup(httpParams);
|
|
}
|
|
|
|
#endif //TLS_CONFIG_HTTP_CLIENT && TLS_CONFIG_SOCKET_RAW
|
|
|