diff --git a/Makefile b/Makefile index 53ea7dce3..eb7175433 100644 --- a/Makefile +++ b/Makefile @@ -193,7 +193,10 @@ sdk/OpenW600/tools/gcc-arm-none-eabi-4_9-2014q4/bin: submodules .PHONY: OpenW800 OpenW800: sdk/OpenW800/tools/w800/csky/bin sdk/OpenW800/sharedAppContainer/sharedApp prebuild_OpenW800 - $(MAKE) -C sdk/OpenW800 EXTRA_CCFLAGS=-DPLATFORM_W800 CONFIG_W800_USE_LIB=n CONFIG_W800_TOOLCHAIN_PATH="$(shell realpath sdk/OpenW800/tools/w800/csky/bin)/" + # if building new version, make sure "new_http.o" is deleted (it contains build time and version, so build time is set to actual time) + rm -rf sdk/OpenW800/bin/build/w800/obj/sharedAppContainer/sharedApp/src/httpserver/new_http.o + # define APP_Version so it's not "W800_Test" every time + $(MAKE) -C sdk/OpenW800 EXTRA_CCFLAGS="-DPLATFORM_W800 -DUSER_SW_VER=\\\"${APP_VERSION}\\\"" CONFIG_W800_USE_LIB=n CONFIG_W800_TOOLCHAIN_PATH="$(shell realpath sdk/OpenW800/tools/w800/csky/bin)/" mkdir -p output/$(APP_VERSION) cp sdk/OpenW800/bin/w800/w800.fls output/$(APP_VERSION)/OpenW800_$(APP_VERSION).fls cp sdk/OpenW800/bin/w800/w800_ota.img output/$(APP_VERSION)/OpenW800_$(APP_VERSION)_ota.img diff --git a/src/httpserver/http_fns.c b/src/httpserver/http_fns.c index a8889acac..12f918558 100644 --- a/src/httpserver/http_fns.c +++ b/src/httpserver/http_fns.c @@ -3011,11 +3011,30 @@ int http_fn_ota_exec(http_request_t* request) { int http_fn_ota(http_request_t* request) { http_setup(request, httpMimeTypeHTML); http_html_start(request, "OTA system"); - poststr(request, "

For a more user-friendly experience, it is recommended to use the OTA option in the Web Application, where you can easily drag and drop files without needing to set up a server. On Beken platforms, the .rbl file is used for OTA updates. In the OTA section below, paste the link to the .rbl file (an HTTP server is required).

"); - add_label_text_field(request, "URL for new bin file", "host", "", "
"); +#ifndef OBK_OTA_EXTENSION + poststr(request, "

Sorry, OTA update not implemented for " DEVICENAME_PREFIX_FULL "

"); +#else + poststr(request, "

It's recommended to use the OTA option in the Web Application, where you can easily drag and drop files.

If you have an HTTP server providing the OTA file, you may enter the URL below. " +#if PLATFORM_BEKEN + " On Beken platforms, the .rbl file is used for OTA updates." +#endif + "

"); + add_label_text_field(request, "URL for ota firmware file", "host", "", ""); poststr(request, "
\ \
"); + + const char htmlOTA[] = ""; + + poststr(request, "


Expert feature: Upload firmware OTA file.
If unsure, please use Web App!


"); + poststr(request, ""); + poststr(request, ""); + poststr(request, htmlOTA); +#endif poststr(request, htmlFooterReturnToCfgOrMainPage); http_html_end(request); poststr(request, NULL); diff --git a/src/httpserver/rest_interface.c b/src/httpserver/rest_interface.c index 54f593965..d93dc92ec 100644 --- a/src/httpserver/rest_interface.c +++ b/src/httpserver/rest_interface.c @@ -46,6 +46,9 @@ uint32_t flash_read(uint32_t flash, uint32_t addr, void* buf, uint32_t size); #elif PLATFORM_W800 +#include "wm_socket_fwup.h" +#include "wm_fwup.h" + #elif PLATFORM_LN882H #elif PLATFORM_ESPIDF @@ -242,6 +245,8 @@ static int http_rest_post(http_request_t* request) { return http_rest_post_flash(request, START_ADR_OF_BK_PARTITION_OTA, LFS_BLOCKS_END); #elif PLATFORM_W600 return http_rest_post_flash(request, -1, -1); +#elif PLATFORM_W800 + return http_rest_post_flash(request, -1, -1); #elif PLATFORM_BL602 return http_rest_post_flash(request, -1, -1); #elif PLATFORM_LN882H @@ -1421,7 +1426,7 @@ static int ota_verify_download(void) static int http_rest_post_flash(http_request_t* request, int startaddr, int maxaddr) { -#if PLATFORM_XR809 || PLATFORM_W800 || PLATFORM_TR6260 +#if PLATFORM_XR809 || PLATFORM_TR6260 return 0; //Operation not supported yet #endif @@ -1557,6 +1562,138 @@ static int http_rest_post_flash(http_request_t* request, int startaddr, int maxa } +#elif PLATFORM_W800 + int nRetCode = 0; + char error_message[256]; + + if(writelen < 0) + { + ADDLOG_DEBUG(LOG_FEATURE_OTA, "ABORTED: %d bytes to write", writelen); + return http_rest_error(request, -20, "writelen < 0"); + } + + struct pbuf* p; + + //The code below is based on W600 code and adopted to the differences in sdk\OpenW800\src\app\ota\wm_http_fwup.c + // fiexd crashing caused by not checking "writelen" before doing memcpy + // e.g. if more than 2 packets arrived before next loop, writelen could be > 2048 !! +#define FWUP_MSG_SIZE 3 +#define MAX_BUFF_SIZE 2048 + char* Buffer = (char*)os_malloc(MAX_BUFF_SIZE + FWUP_MSG_SIZE); + + if(request->contentLength >= 0) + { + towrite = request->contentLength; + } + + int recvLen = 0; + int totalLen = 0; + uint8_t counter = 0; + printf("\ntowrite %d writelen=%d\n", towrite, writelen); + + do + { + while(writelen > 0) + { + int actwrite = writelen < MAX_BUFF_SIZE ? writelen : MAX_BUFF_SIZE; // mustn't write more than Buffers size! Will crash else! + //bk_printf("Copying %d from writebuf to Buffer (writelen=%d) towrite=%d -- free_heap:%d\n", actwrite, writelen, towrite, xPortGetFreeHeapSize()); + memset(Buffer, 0, MAX_BUFF_SIZE + FWUP_MSG_SIZE); + memcpy(Buffer + FWUP_MSG_SIZE, writebuf, actwrite); + if(recvLen == 0) + { + IMAGE_HEADER_PARAM_ST *booter = (IMAGE_HEADER_PARAM_ST*)(Buffer + FWUP_MSG_SIZE); + bk_printf("magic_no=%u, img_type=%u, zip_type=%u, signature=%u\n", + booter->magic_no, booter->img_attr.b.img_type, booter->img_attr.b.zip_type, booter->img_attr.b.signature); + + if(TRUE == tls_fwup_img_header_check(booter)) + { + totalLen = booter->img_len + sizeof(IMAGE_HEADER_PARAM_ST); + if (booter->img_attr.b.signature) + { + totalLen += 128; + } + } + else + { + sprintf(error_message, "Image header check failed"); + nRetCode = -19; + break; + } + + nRetCode = socket_fwup_accept(0, ERR_OK); + if(nRetCode != ERR_OK) + { + sprintf(error_message, "Firmware update startup failed"); + break; + } + } + + p = pbuf_alloc(PBUF_TRANSPORT, actwrite + FWUP_MSG_SIZE, PBUF_REF); + if(!p) + { + sprintf(error_message, "Unable to allocate memory for buffer"); + nRetCode = -18; + break; + } + + if(recvLen == 0) + { + *Buffer = SOCKET_FWUP_START; + } + else if(recvLen == (totalLen - actwrite)) + { + *Buffer = SOCKET_FWUP_END; + } + else + { + *Buffer = SOCKET_FWUP_DATA; + } + + *(Buffer + 1) = (actwrite >> 8) & 0xFF; + *(Buffer + 2) = actwrite & 0xFF; + p->payload = Buffer; + p->len = p->tot_len = actwrite + FWUP_MSG_SIZE; + + nRetCode = socket_fwup_recv(0, p, ERR_OK); + if(nRetCode != ERR_OK) + { + sprintf(error_message, "Firmware data processing failed"); + break; + } + else + { + recvLen += actwrite; + } + + towrite -= actwrite; + writelen -= actwrite; // calculate, how much is left to write + writebuf += actwrite; // in case, we only wrote part of buffer, advance in buffer + } + + if(towrite > 0) + { + writebuf = request->received; + writelen = recv(request->fd, writebuf, request->receivedLenmax, 0); + if(writelen < 0) + { + sprintf(error_message, "recv returned %d - end of data - remaining %d", writelen, towrite); + nRetCode = -17; + } + } + if (counter++ % 5 == 0) bk_printf("Downloaded %d / %d\n", recvLen, totalLen); + rtos_delay_milliseconds(10); // give some time for flashing - will else increase used memory fast + } while((nRetCode == 0) && (towrite > 0) && (writelen >= 0)); + bk_printf("Download completed (%d / %d)\n", recvLen, totalLen); + tls_mem_free(Buffer); + + if(nRetCode != 0) + { + ADDLOG_ERROR(LOG_FEATURE_OTA, error_message); + socket_fwup_err(0, nRetCode); + return http_rest_error(request, nRetCode, error_message); + } + + #elif PLATFORM_BL602 int sockfd, i; int ret; diff --git a/src/obk_config.h b/src/obk_config.h index bfcc0b304..010f0584f 100644 --- a/src/obk_config.h +++ b/src/obk_config.h @@ -28,6 +28,7 @@ #define ENABLE_DRIVER_BL0937 1 #define ENABLE_DRIVER_DHT 1 #define ENABLE_TASMOTA_JSON 1 +#define OBK_OTA_EXTENSION ".img" #elif PLATFORM_W800 @@ -35,6 +36,7 @@ //#define OBK_DISABLE_ALL_DRIVERS 1 #define ENABLE_TASMOTA_JSON 1 #define ENABLE_DRIVER_DS1820 1 +#define OBK_OTA_EXTENSION ".img" #elif WINDOWS @@ -105,6 +107,8 @@ #define ENABLE_DRIVER_SSDP 1 #define ENABLE_DRIVER_CHT83XX 1 #define ENABLE_DRIVER_DS1820 1 +#define OBK_OTA_EXTENSION ".bin.xz.ota" + #elif PLATFORM_BEKEN @@ -156,8 +160,8 @@ #define ENABLE_DRIVER_IR2 0 #define ENABLE_DRIVER_DS1820 1 #define ENABLE_DRIVER_CHT83XX 1 - //#define ENABLE_DRIVER_OPENWEATHERMAP 1 +#define OBK_OTA_EXTENSION ".rbl" // ENABLE_I2C_ is a syntax for // our I2C system defines for drv_i2c_main.c @@ -182,6 +186,8 @@ //#define ENABLE_DRIVER_TMGN 1 #define ENABLE_TASMOTA_JSON 1 #define ENABLE_DRIVER_DS1820 1 +#define OBK_OTA_EXTENSION ".bin" +#define OBK_OTA_NAME_EXTENSION "_OTA" #elif PLATFORM_ESPIDF @@ -207,6 +213,7 @@ #define ENABLE_DRIVER_DDP 1 #define ENABLE_DRIVER_SSDP 1 #define ENABLE_DRIVER_CHT83XX 1 +#define OBK_OTA_EXTENSION ".img" #elif PLATFORM_TR6260