diff --git a/src/httpserver/rest_interface.c b/src/httpserver/rest_interface.c index ebb03620c..874ffb2ca 100644 --- a/src/httpserver/rest_interface.c +++ b/src/httpserver/rest_interface.c @@ -21,7 +21,25 @@ uint32_t flash_read(uint32_t flash, uint32_t addr, void* buf, uint32_t size); #define FLASH_INDEX_XR809 0 #elif PLATFORM_BL602 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include #elif PLATFORM_W600 #include "wm_socket_fwup.h" @@ -212,6 +230,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_BL602 + return http_rest_post_flash(request, -1, -1); #else // TODO #endif @@ -910,10 +930,79 @@ static int http_rest_error(http_request_t* request, int code, char* msg) { return 0; } +#if PLATFORM_BL602 +typedef struct ota_header { + union { + struct { + uint8_t header[16]; + + uint8_t type[4];//RAW XZ + uint32_t len;//body len + uint8_t pad0[8]; + + uint8_t ver_hardware[16]; + uint8_t ver_software[16]; + + uint8_t sha256[32]; +} s; + uint8_t _pad[512]; + } u; +} ota_header_t; +#define OTA_HEADER_SIZE (sizeof(ota_header_t)) + +static int _check_ota_header(ota_header_t *ota_header, uint32_t *ota_len, int *use_xz) +{ + char str[33];//assume max segment size + int i; + + memcpy(str, ota_header->u.s.header, sizeof(ota_header->u.s.header)); + str[sizeof(ota_header->u.s.header)] = '\0'; + puts("[OTA] [HEADER] ota header is "); + puts(str); + puts("\r\n"); + + memcpy(str, ota_header->u.s.type, sizeof(ota_header->u.s.type)); + str[sizeof(ota_header->u.s.type)] = '\0'; + puts("[OTA] [HEADER] file type is "); + puts(str); + puts("\r\n"); + if (strstr(str, "XZ")) { + *use_xz = 1; + } + else { + *use_xz = 0; + } + + memcpy(ota_len, &(ota_header->u.s.len), 4); + printf("[OTA] [HEADER] file length (exclude ota header) is %lu\r\n", *ota_len); + + memcpy(str, ota_header->u.s.ver_hardware, sizeof(ota_header->u.s.ver_hardware)); + str[sizeof(ota_header->u.s.ver_hardware)] = '\0'; + puts("[OTA] [HEADER] ver_hardware is "); + puts(str); + puts("\r\n"); + + memcpy(str, ota_header->u.s.ver_software, sizeof(ota_header->u.s.ver_software)); + str[sizeof(ota_header->u.s.ver_software)] = '\0'; + puts("[OTA] [HEADER] ver_software is "); + puts(str); + puts("\r\n"); + + memcpy(str, ota_header->u.s.sha256, sizeof(ota_header->u.s.sha256)); + str[sizeof(ota_header->u.s.sha256)] = '\0'; + puts("[OTA] [HEADER] sha256 is "); + for (i = 0; i < sizeof(ota_header->u.s.sha256); i++) { + printf("%02X", str[i]); + } + puts("\r\n"); + + return 0; +} +#endif static int http_rest_post_flash(http_request_t* request, int startaddr, int maxaddr) { -#if PLATFORM_XR809 || PLATFORM_BL602 || PLATFORM_W800 +#if PLATFORM_XR809 || PLATFORM_W800 return 0; //Operation not supported yet #endif @@ -1033,6 +1122,115 @@ static int http_rest_post_flash(http_request_t* request, int startaddr, int maxa return http_rest_error(request, nRetCode, error_message); } +#elif PLATFORM_BL602 + int sockfd, i; + int ret; + struct hostent *hostinfo; + uint8_t *recv_buffer; + struct sockaddr_in dest; + iot_sha256_context ctx; + uint8_t sha256_result[32]; + uint8_t sha256_img[32]; + bl_mtd_handle_t handle; + //init_ota(startaddr); + + +#define OTA_PROGRAM_SIZE (512) + int ota_header_found, use_xz; + ota_header_t *ota_header; + + ret = bl_mtd_open(BL_MTD_PARTITION_NAME_FW_DEFAULT, &handle, BL_MTD_OPEN_FLAG_BACKUP); + if (ret) { + return http_rest_error(request, -20, "Open Default FW partition failed"); + } + + recv_buffer = pvPortMalloc(OTA_PROGRAM_SIZE); + + unsigned int buffer_offset, flash_offset, ota_addr; + uint32_t bin_size, part_size; + uint8_t activeID; + HALPartition_Entry_Config ptEntry; + + activeID = hal_boot2_get_active_partition(); + + printf("Starting OTA test. OTA bin addr is %p\r\n", recv_buffer); + + printf("[OTA] [TEST] activeID is %u\r\n", activeID); + + if (hal_boot2_get_active_entries(BOOT2_PARTITION_TYPE_FW, &ptEntry)) { + printf("PtTable_Get_Active_Entries fail\r\n"); + vPortFree(recv_buffer); + bl_mtd_close(handle); + return http_rest_error(request, -20, "PtTable_Get_Active_Entries fail"); + } + ota_addr = ptEntry.Address[!ptEntry.activeIndex]; + bin_size = ptEntry.maxLen[!ptEntry.activeIndex]; + part_size = ptEntry.maxLen[!ptEntry.activeIndex]; + (void)part_size; + /*XXX if you use bin_size is product env, you may want to set bin_size to the actual + * OTA BIN size, and also you need to splilt XIP_SFlash_Erase_With_Lock into + * serveral pieces. Partition size vs bin_size check is also needed + */ + printf("Starting OTA test. OTA size is %lu\r\n", bin_size); + + printf("[OTA] [TEST] activeIndex is %u, use OTA address=%08x\r\n", ptEntry.activeIndex, (unsigned int)ota_addr); + + printf("[OTA] [TEST] Erase flash with size %lu...", bin_size); + hal_update_mfg_ptable(); + bl_mtd_erase_all(handle); + printf("Done\r\n"); + + if (request->contentLength >= 0) { + towrite = request->contentLength; + } + + + buffer_offset = 0; + flash_offset = 0; + ota_header_found = 0; + use_xz = 0; + + utils_sha256_init(&ctx); + utils_sha256_starts(&ctx); + memset(sha256_result, 0, sizeof(sha256_result)); + + do { + //ADDLOG_DEBUG(LOG_FEATURE_OTA, "%d bytes to write", writelen); + //add_otadata((unsigned char*)writebuf, writelen); + + utils_sha256_update(&ctx, (byte*)writebuf, writelen); + bl_mtd_write(handle, flash_offset, writelen, (byte*) writebuf); + flash_offset += writelen; + + total += writelen; + startaddr += writelen; + towrite -= writelen; + + + if (towrite > 0) { + writebuf = request->received; + writelen = recv(request->fd, writebuf, request->receivedLenmax, 0); + if (writelen < 0) { + ADDLOG_DEBUG(LOG_FEATURE_OTA, "recv returned %d - end of data - remaining %d", writelen, towrite); + } + } + } while ((towrite > 0) && (writelen >= 0)); + + + utils_sha256_finish(&ctx, sha256_result); + puts("\r\nCalculated SHA256 Checksum:"); + for (i = 0; i < sizeof(sha256_result); i++) { + printf("%02X", sha256_result[i]); + } + printf("[OTA] [TCP] prepare OTA partition info\r\n"); + ptEntry.len = total; + printf("[OTA] [TCP] Update PARTITION, partition len is %lu\r\n", ptEntry.len); + hal_boot2_update_ptable(&ptEntry); + printf("[OTA] [TCP] Rebooting\r\n"); + //close_ota(); + vPortFree(recv_buffer); + utils_sha256_free(&ctx); + bl_mtd_close(handle); #else init_ota(startaddr);