mirror of
https://github.com/Ai-Thinker-Open/Ai-Thinker-Open_RTL8710BX_ALIOS_SDK.git
synced 2026-07-08 19:45:39 +00:00
rel_1.6.0 init
This commit is contained in:
commit
27b3e2883d
19359 changed files with 8093121 additions and 0 deletions
80
Living_SDK/framework/uOTA/hal/README.md
Normal file
80
Living_SDK/framework/uOTA/hal/README.md
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
## Contents
|
||||
|
||||
```sh
|
||||
hal
|
||||
├── aos.mk
|
||||
├── Config.in
|
||||
├── ota_hal_host.c
|
||||
├── ota_hal_module.c
|
||||
├── ota_hal_os.c
|
||||
├── ota_hal_os.h
|
||||
├── ota_hal_plat.c
|
||||
├── ota_hal_plat.h
|
||||
└── README.md
|
||||
```
|
||||
|
||||
## Introduction
|
||||
|
||||
An over-the-air update is the wireless delivery of new software or data to smart devices, especially IoT devices. Wireless carriers and OEMs typically use over-the-air (OTA) updates to deploy the new operating systems and the software app to these devices.
|
||||
|
||||
## Features
|
||||
|
||||
1. Differential incremental upgrade;
|
||||
2. Dual banker:AB partition upgrade to support rollback to old version;
|
||||
3. Secure download channel;
|
||||
4. Firmware digital signature verification.
|
||||
|
||||
## Dependencies
|
||||
|
||||
Linkkit MQTT channel
|
||||
Linkkit CoAP channel
|
||||
|
||||
## API
|
||||
|
||||
User service APIs:
|
||||
|
||||
```c
|
||||
typedef struct {
|
||||
unsigned char inited; /*If is inted*/
|
||||
char pk[20+1];/*Product Key*/
|
||||
char ps[64+1];/*Product secret*/
|
||||
char dn[32+1];/*Device name*/
|
||||
char ds[64+1];/*Device secret*/
|
||||
OTA_PROTCOL_E trans_protcol; /*default:0--> MQTT 1-->COAP*/
|
||||
OTA_PROTCOL_E dl_protcol; /*default:3--> HTTPS 1-->COAP 2-->HTTP*/
|
||||
unsigned char sign_type; /*default:0--> sha256 1--> md5 2-->RSA*/
|
||||
char ota_ver[OTA_MAX_VER_LEN]; /*OTA FW version*/
|
||||
char sys_ver[OTA_MAX_VER_LEN]; /*OTA System version*/
|
||||
ota_transport_t *h_tr; /*OTA tansport manager*/
|
||||
ota_download_t *h_dl; /*OTA download manager*/
|
||||
void* h_ch; /*OTA channel handle:mqtt,coap*/
|
||||
} ota_service_t;
|
||||
|
||||
/*OTA export service APIs*/
|
||||
int ota_service_init(ota_service_t* ctx);
|
||||
int ota_service_deinit(ota_service_t* ctx);
|
||||
```
|
||||
|
||||
for sample code please check [otaapp](../../../app/example/otaapp/).
|
||||
## RTOS build
|
||||
```sh
|
||||
cd ROOT DIR;
|
||||
aos make otaapp@board;
|
||||
```
|
||||
|
||||
## run CLI CMDs
|
||||
1. connect network
|
||||
```
|
||||
netmgr connect ssid passwd
|
||||
```
|
||||
2. run ota demo
|
||||
|
||||
```
|
||||
OTA_APP pk dn ds ps
|
||||
```
|
||||
|
||||
## Reference
|
||||
|
||||
* [AliOS-Things OTA使用说明](https://github.com/alibaba/AliOS-Things/wiki/OTA-Tutorial)
|
||||
* [OTA flash分区说明文档](https://github.com/alibaba/AliOS-Things/wiki/OTA-Flash-Partitions-Overview)
|
||||
* [云端一体化差分+安全升级,AliOS Things物联网升级“利器”](https://mp.weixin.qq.com/s/Pb8Lleuww1r7qQJHu5ON8g)
|
||||
71
Living_SDK/framework/uOTA/hal/hal.mk
Executable file
71
Living_SDK/framework/uOTA/hal/hal.mk
Executable file
|
|
@ -0,0 +1,71 @@
|
|||
NAME := ota_hal
|
||||
|
||||
$(NAME)_MBINS_TYPE := kernel
|
||||
$(NAME)_VERSION := 1.0.0
|
||||
$(NAME)_SUMMARY := ota porting HAL APIs
|
||||
|
||||
#default gcc
|
||||
ifeq ($(COMPILER),)
|
||||
$(NAME)_CFLAGS += -Wall -Werror
|
||||
else ifeq ($(COMPILER),gcc)
|
||||
$(NAME)_CFLAGS += -Wall -Werror
|
||||
endif
|
||||
|
||||
$(NAME)_COMPONENTS += base64
|
||||
|
||||
$(NAME)_SOURCES := \
|
||||
ota_hal_module.c \
|
||||
ota_hal_os.c \
|
||||
|
||||
ifeq ($(CONFIG_SUPPORT_MCU_OTA), ENABLE)
|
||||
$(NAME)_SOURCES += ota_hal_mcu.c
|
||||
endif
|
||||
|
||||
ifneq (,$(filter linux,$(HOST_MCU_FAMILY)))
|
||||
$(NAME)_SOURCES += ota_hal_host.c
|
||||
else
|
||||
ifneq (,$(filter esp32,$(HOST_MCU_FAMILY)))
|
||||
GLOBAL_DEFINES += AOS_OTA_BANK_DUAL
|
||||
GLOBAL_DEFINES += AOS_OTA_DISABLE_MD5
|
||||
$(NAME)_SOURCES += ota_hal_$(HOST_MCU_FAMILY).c
|
||||
else
|
||||
ifneq (,$(filter bk7231u,$(HOST_MCU_FAMILY)))
|
||||
$(NAME)_SOURCES += ota_hal_beken.c
|
||||
else
|
||||
ifneq (,$(filter bk7231s,$(HOST_MCU_FAMILY)))
|
||||
$(NAME)_SOURCES += ota_hal_beken.c
|
||||
else
|
||||
ifneq (,$(filter rtl8710bn,$(HOST_MCU_FAMILY)))
|
||||
else
|
||||
ifneq (,$(filter asr5501,$(HOST_MCU_FAMILY)))
|
||||
GLOBAL_DEFINES += AOS_OTA_DISABLE_MD5
|
||||
GLOBAL_DEFINES += OTA_BOOT_PAPA_COMPATIBAL
|
||||
else
|
||||
$(NAME)_SOURCES += ota_hal_plat.c
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq (,$(filter rtl8710bn esp8266,$(HOST_MCU_FAMILY)))
|
||||
GLOBAL_DEFINES += AOS_OTA_BANK_DUAL
|
||||
GLOBAL_DEFINES += AOS_OTA_DISABLE_MD5
|
||||
endif
|
||||
|
||||
ifeq ($(FEATURE_SUPPORT_ITLS),y)
|
||||
GLOBAL_DEFINES += AOS_OTA_ITLS
|
||||
$(NAME)_COMPONENTS += itls
|
||||
else
|
||||
$(NAME)_COMPONENTS += imbedtls
|
||||
endif
|
||||
|
||||
ifeq ($(MD5_CHECK),0)
|
||||
GLOBAL_DEFINES += AOS_OTA_DISABLE_MD5
|
||||
endif
|
||||
|
||||
GLOBAL_INCLUDES += . \
|
||||
../inc \
|
||||
../src/verify/crc \
|
||||
../src/2nd_boot
|
||||
541
Living_SDK/framework/uOTA/hal/ota_hal_beken.c
Normal file
541
Living_SDK/framework/uOTA/hal/ota_hal_beken.c
Normal file
|
|
@ -0,0 +1,541 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include "aos/kernel.h"
|
||||
#include "aos/kv.h"
|
||||
|
||||
#include "hal/soc/flash.h"
|
||||
|
||||
#include "ota_hal_plat.h"
|
||||
#include "ota_hal_os.h"
|
||||
#include "ota_log.h"
|
||||
|
||||
#define KV_HAL_OTA_CRC16 "hal_ota_get_crc16"
|
||||
#define OTA_UPG_FLAG 0xA55A
|
||||
#define OTA_PINGPONG_FLAG 0xB55B
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t ota_len;
|
||||
uint32_t ota_crc;
|
||||
} ota_reboot_info_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t dst_adr;
|
||||
uint32_t src_adr;
|
||||
uint32_t size;
|
||||
uint16_t crc;
|
||||
uint16_t upg_flag;
|
||||
} __attribute__((packed)) ota_hdl_t;
|
||||
|
||||
static ota_reboot_info_t ota_info = {0};
|
||||
static ota_crc16_ctx contex = {0};
|
||||
static uint32_t _off_set = 0;
|
||||
|
||||
static uint16_t hal_ota_get_crc16(void);
|
||||
static void hal_ota_save_crc16(uint16_t crc16);
|
||||
|
||||
#ifdef AOS_OTA_BANK_DUAL
|
||||
#define OTA_IMAGE_A 0
|
||||
#define OTA_IMAGE_B 1
|
||||
#define KV_HAL_OTA_HDR "hal_ota_get_hdr"
|
||||
typedef struct
|
||||
{
|
||||
uint32_t version;
|
||||
uint32_t hdr_num;
|
||||
struct
|
||||
{
|
||||
uint32_t img_ID;
|
||||
uint32_t hdr_len;
|
||||
uint32_t checksum;
|
||||
uint32_t img_len;
|
||||
uint32_t img_offset;
|
||||
uint32_t flash_offset;
|
||||
}ota_file[2];
|
||||
}ota_hdr_t;
|
||||
|
||||
static ota_hdr_t ota_hdr_info = {0};
|
||||
static uint8_t ota_index = 0;
|
||||
static uint8_t ota_hdr_check = 0;
|
||||
|
||||
static int hal_get_ota_hdr(void)
|
||||
{
|
||||
int len, ret;
|
||||
|
||||
len = sizeof(ota_hdr_t);
|
||||
ret = aos_kv_get(KV_HAL_OTA_HDR, &ota_hdr_info, &len);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int hal_ota_save_hdr(void)
|
||||
{
|
||||
int len, ret;
|
||||
|
||||
len = sizeof(ota_hdr_t);
|
||||
ret = aos_kv_set(KV_HAL_OTA_HDR, &ota_hdr_info, len, 1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void hal_get_ota_index(void)
|
||||
{
|
||||
uint32_t offset, boot_addr;
|
||||
hal_logic_partition_t *partition_info;
|
||||
offset = 0x00;
|
||||
hal_flash_read(HAL_PARTITION_PARAMETER_1, &offset, (void *)&boot_addr, sizeof(boot_addr));
|
||||
partition_info = hal_flash_get_info(HAL_PARTITION_OTA_TEMP);
|
||||
if(boot_addr == partition_info->partition_start_addr) {
|
||||
ota_index = OTA_IMAGE_A; //update to image A
|
||||
}
|
||||
else {
|
||||
ota_index = OTA_IMAGE_B; //update to image B
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static int hal_verify_ota_head(void)
|
||||
{
|
||||
char imgid[5];
|
||||
|
||||
if(~ota_hdr_info.version) {
|
||||
OTA_LOG_E("check ota version error %x", ota_hdr_info.version);
|
||||
return 1;
|
||||
}
|
||||
if(ota_hdr_info.hdr_num != 2) {
|
||||
OTA_LOG_E("check ota number error %d", ota_hdr_info.hdr_num);
|
||||
return 1;
|
||||
}
|
||||
memset(imgid, 0, sizeof(imgid));
|
||||
memcpy(imgid, (char *)&ota_hdr_info.ota_file[0].img_ID, 4);
|
||||
if(strcmp(imgid, "OTA1")) {
|
||||
OTA_LOG_E("OTA1 image id error.");
|
||||
return 1;
|
||||
}
|
||||
memcpy(imgid, (char *)&ota_hdr_info.ota_file[1].img_ID, 4);
|
||||
if(strcmp(imgid, "OTA2")) {
|
||||
OTA_LOG_E("OTA2 image id error.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(ota_hdr_info.ota_file[0].checksum == 0) {
|
||||
OTA_LOG_E("OTA1 checksum is zaro.");
|
||||
return 1;
|
||||
}
|
||||
if(ota_hdr_info.ota_file[1].checksum == 0) {
|
||||
OTA_LOG_E("OTA2 checksum is zaro.");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hal_verify_ota_checksum(uint8_t crc_partition_idx, uint32_t crc_len)
|
||||
{
|
||||
uint8_t *f_data;
|
||||
ota_crc16_ctx ctx;
|
||||
uint16_t ota_crc;
|
||||
uint32_t i = 0, j = 0, len = 0, checksum = 0;
|
||||
|
||||
ota_crc16_final(&contex, &ota_info.ota_crc);//download crc
|
||||
if(ota_info.ota_crc == 0) {
|
||||
OTA_LOG_E("crc is zaro.");
|
||||
return -1;
|
||||
}
|
||||
f_data = (uint8_t *)aos_malloc(0x1000);
|
||||
if(f_data == NULL) {
|
||||
OTA_LOG_E("hal_ota_crc16_compute malloc fail.");
|
||||
return -1;
|
||||
}
|
||||
_off_set = 0;
|
||||
ota_crc16_init(&ctx);
|
||||
while(i < crc_len) {
|
||||
if((0x1000 + i) < crc_len) {
|
||||
len = 0x1000;
|
||||
}
|
||||
else {
|
||||
len = crc_len - i;
|
||||
}
|
||||
hal_flash_read(crc_partition_idx, &_off_set, f_data, len);
|
||||
/*update checksum*/
|
||||
for(j = 0; j < len; j++) {
|
||||
checksum += f_data[j];
|
||||
}
|
||||
/*update crc16*/
|
||||
ota_crc16_update(&ctx, f_data, len);
|
||||
i += len;
|
||||
}
|
||||
ota_crc16_final(&ctx, &ota_crc);
|
||||
|
||||
if(f_data) {
|
||||
aos_free(f_data);
|
||||
}
|
||||
/*verify crc*/
|
||||
if(ota_info.ota_crc != ota_crc) {
|
||||
OTA_LOG_E("crc check error: download_crc=0x%x, comput_crc=0x%x.", ota_info.ota_crc, ota_crc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*verify checksum*/
|
||||
if(ota_hdr_info.ota_file[ota_index].checksum != checksum) {
|
||||
OTA_LOG_E("checksum error: gen_chcksum=0x%x, comput_checksum=0x%x.",
|
||||
ota_hdr_info.ota_file[ota_index].checksum, checksum);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ota_init(void *something)
|
||||
{
|
||||
ota_boot_param_t *param = (ota_boot_param_t *)something;
|
||||
uint32_t offset = 0, delta = 0;
|
||||
hal_logic_partition_t *partition_info;
|
||||
|
||||
if(param == NULL) {
|
||||
return;
|
||||
}
|
||||
offset = param->off_bp;
|
||||
hal_flash_dis_secure(0, 0, 0);//disable flash protect
|
||||
hal_get_ota_index();
|
||||
if(offset == 0) {
|
||||
OTA_LOG_I("ota start :%d off:%d", ota_index, offset);
|
||||
if(ota_index == OTA_IMAGE_A) {
|
||||
partition_info = hal_flash_get_info(HAL_PARTITION_APPLICATION);
|
||||
hal_flash_erase(HAL_PARTITION_APPLICATION, 0, partition_info->partition_length);
|
||||
}
|
||||
else {
|
||||
partition_info = hal_flash_get_info(HAL_PARTITION_OTA_TEMP);
|
||||
hal_flash_erase(HAL_PARTITION_OTA_TEMP, 0, partition_info->partition_length);
|
||||
}
|
||||
_off_set = 0;
|
||||
ota_hdr_check = 0;
|
||||
memset(&ota_info, 0, sizeof(ota_info));
|
||||
memset(&ota_hdr_info, 0, sizeof(ota_hdr_info));
|
||||
ota_crc16_init(&contex);
|
||||
}
|
||||
else {
|
||||
OTA_LOG_I("header:%d off:%d", ota_hdr_check, offset);
|
||||
ota_info.ota_len = offset;
|
||||
ota_info.ota_crc = 0;
|
||||
if(hal_get_ota_hdr()) {
|
||||
OTA_LOG_E("get ota header fail");
|
||||
return -1;
|
||||
}
|
||||
if(offset < sizeof(ota_hdr_t)) {
|
||||
ota_hdr_check = 0;
|
||||
}
|
||||
else {
|
||||
OTA_LOG_I("verfiy header");
|
||||
ota_hdr_check = hal_verify_ota_head();
|
||||
if(ota_hdr_check == 0) {
|
||||
if(offset < ota_hdr_info.ota_file[1].img_offset) {
|
||||
delta = offset - sizeof(ota_hdr_t);
|
||||
if(ota_index == OTA_IMAGE_A) {
|
||||
_off_set = delta;
|
||||
}
|
||||
}
|
||||
else {
|
||||
delta = offset - ota_hdr_info.ota_file[1].img_offset;
|
||||
if(ota_index == OTA_IMAGE_B) {
|
||||
_off_set = delta;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
OTA_LOG_E("check ota header error.");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
contex.crc = hal_ota_get_crc16();
|
||||
}
|
||||
OTA_LOG_I("ota init over");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ota_read(int* off, char* out_buf, int out_buf_len)
|
||||
{
|
||||
if(ota_index == OTA_IMAGE_A) {
|
||||
hal_flash_read(HAL_PARTITION_APPLICATION, off, out_buf, out_buf_len);
|
||||
}
|
||||
else {
|
||||
hal_flash_read(HAL_PARTITION_OTA_TEMP, off, out_buf, out_buf_len);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ota_write(int* off, char* in_buf, int in_buf_len)
|
||||
{
|
||||
uint32_t offset = 0;
|
||||
if(ota_hdr_check) {
|
||||
OTA_LOG_E("check ota header fail.");
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
/*OTA_LOG_I(".");*/
|
||||
}
|
||||
if(ota_info.ota_len < sizeof(ota_hdr_t)) {
|
||||
OTA_LOG_I("ota header w check:%d", ota_hdr_check);
|
||||
offset = sizeof(ota_hdr_t) - ota_info.ota_len;
|
||||
if(in_buf_len < offset) {
|
||||
memcpy((uint8_t *)&ota_hdr_info + ota_info.ota_len, in_buf, in_buf_len);
|
||||
}
|
||||
else {
|
||||
memcpy((uint8_t *)&ota_hdr_info + ota_info.ota_len, in_buf, offset);
|
||||
ota_hdr_check = hal_verify_ota_head();
|
||||
if(ota_hdr_check == 0 && ota_index == OTA_IMAGE_A) {
|
||||
ota_crc16_update(&contex, in_buf + offset, in_buf_len - offset);
|
||||
hal_flash_write(HAL_PARTITION_APPLICATION, &_off_set, in_buf + offset, in_buf_len - offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(ota_index == OTA_IMAGE_A) {
|
||||
if(ota_info.ota_len + in_buf_len < ota_hdr_info.ota_file[1].img_offset) {
|
||||
ota_crc16_update(&contex, in_buf, in_buf_len);
|
||||
hal_flash_write(HAL_PARTITION_APPLICATION, &_off_set, in_buf, in_buf_len);
|
||||
}
|
||||
else {
|
||||
if(ota_info.ota_len < ota_hdr_info.ota_file[1].img_offset) {
|
||||
offset = ota_hdr_info.ota_file[1].img_offset - ota_info.ota_len;
|
||||
ota_crc16_update(&contex, in_buf, offset);
|
||||
hal_flash_write(HAL_PARTITION_APPLICATION, &_off_set, in_buf, offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(ota_info.ota_len > ota_hdr_info.ota_file[1].img_offset) {
|
||||
ota_crc16_update(&contex, in_buf, in_buf_len);
|
||||
hal_flash_write(HAL_PARTITION_OTA_TEMP, &_off_set, in_buf, in_buf_len);
|
||||
}
|
||||
else {
|
||||
if(ota_info.ota_len + in_buf_len > ota_hdr_info.ota_file[1].img_offset) {
|
||||
offset = ota_hdr_info.ota_file[1].img_offset - ota_info.ota_len;
|
||||
ota_crc16_update(&contex, in_buf + offset, in_buf_len - offset);
|
||||
hal_flash_write(HAL_PARTITION_OTA_TEMP, &_off_set, in_buf + offset, in_buf_len - offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ota_info.ota_len += in_buf_len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ota_boot(void *something)
|
||||
{
|
||||
int ret = 0;
|
||||
uint32_t offset;
|
||||
uint32_t crc_partition_idx, crc_len;
|
||||
hal_logic_partition_t *partition_info;
|
||||
ota_boot_param_t *param;
|
||||
ota_hdl_t ota_hdl, ota_hdl_rb;
|
||||
|
||||
param = (ota_boot_param_t *)something;
|
||||
if (param == NULL) {
|
||||
OTA_LOG_E("finish type is null.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(ota_hdr_check) {
|
||||
OTA_LOG_E("check ota head fail.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(param->res_type == OTA_FINISH) {
|
||||
if(ota_index == OTA_IMAGE_A) {
|
||||
crc_partition_idx = HAL_PARTITION_APPLICATION;
|
||||
crc_len = ota_hdr_info.ota_file[0].img_len;
|
||||
partition_info = hal_flash_get_info(HAL_PARTITION_APPLICATION);
|
||||
}
|
||||
else {
|
||||
crc_partition_idx = HAL_PARTITION_OTA_TEMP;
|
||||
crc_len = ota_hdr_info.ota_file[1].img_len;
|
||||
partition_info = hal_flash_get_info(HAL_PARTITION_OTA_TEMP);
|
||||
}
|
||||
ret = hal_verify_ota_checksum(crc_partition_idx, crc_len);
|
||||
if(ret) {
|
||||
return -1;
|
||||
}
|
||||
offset = 0x00;
|
||||
hal_flash_erase(HAL_PARTITION_PARAMETER_1, offset, sizeof(ota_hdl));
|
||||
offset = 0x00;
|
||||
memset(&ota_hdl, 0, sizeof(ota_hdl_t));
|
||||
ota_hdl.dst_adr = partition_info->partition_start_addr;
|
||||
ota_hdl.upg_flag = OTA_PINGPONG_FLAG;
|
||||
hal_flash_write(HAL_PARTITION_PARAMETER_1, &offset, (const void *)&ota_hdl, sizeof(ota_hdl));
|
||||
offset = 0x00;
|
||||
memset(&ota_hdl_rb, 0, sizeof(ota_hdl_t));
|
||||
hal_flash_read(HAL_PARTITION_PARAMETER_1, &offset, &ota_hdl_rb, sizeof(ota_hdl_rb));
|
||||
if(memcmp(&ota_hdl, &ota_hdl_rb, sizeof(ota_hdl_t)) != 0) {
|
||||
OTA_LOG_I("write boot address fail.\r\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ret = hal_ota_save_hdr();
|
||||
if(ret) {
|
||||
OTA_LOG_E("save ota header fail.");
|
||||
return -1;
|
||||
}
|
||||
hal_ota_save_crc16(contex.crc);
|
||||
}
|
||||
hal_reboot();
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
static int hal_ota_switch_to_new_fw(void)
|
||||
{
|
||||
hal_logic_partition_t *partition_info;
|
||||
uint32_t offset;
|
||||
ota_hdl_t ota_hdl, ota_hdl_rb;
|
||||
|
||||
offset = 0x00;
|
||||
hal_flash_erase(HAL_PARTITION_PARAMETER_1, offset, sizeof(ota_hdl_t));
|
||||
offset = 0x00;
|
||||
memset(&ota_hdl, 0, sizeof(ota_hdl_t));
|
||||
partition_info = hal_flash_get_info(HAL_PARTITION_APPLICATION);
|
||||
ota_hdl.dst_adr = partition_info->partition_start_addr;
|
||||
partition_info = hal_flash_get_info(HAL_PARTITION_OTA_TEMP);
|
||||
ota_hdl.src_adr = partition_info->partition_start_addr;
|
||||
ota_hdl.size = ota_info.ota_len;
|
||||
ota_hdl.crc = ota_info.ota_crc;
|
||||
ota_hdl.upg_flag = OTA_UPG_FLAG;
|
||||
hal_flash_write(HAL_PARTITION_PARAMETER_1, &offset, (const void *)&ota_hdl, sizeof(ota_hdl_t));
|
||||
offset = 0x00;
|
||||
memset(&ota_hdl_rb, 0, sizeof(ota_hdl_t));
|
||||
hal_flash_read(HAL_PARTITION_PARAMETER_1, &offset, &ota_hdl_rb, sizeof(ota_hdl_t));
|
||||
if(memcmp(&ota_hdl, &ota_hdl_rb, sizeof(ota_hdl_t)) != 0) {
|
||||
OTA_LOG_I("OTA header compare failed.\r\n");
|
||||
return -1;
|
||||
}
|
||||
/* reboot */
|
||||
hal_reboot();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ota_init(void *something)
|
||||
{
|
||||
ota_boot_param_t *param = (ota_boot_param_t *)something;
|
||||
if(param == NULL) {
|
||||
return -1;
|
||||
}
|
||||
hal_logic_partition_t *part_info = hal_flash_get_info(HAL_PARTITION_OTA_TEMP);
|
||||
if(part_info->partition_length < param->len || param->len == 0) {
|
||||
return -1;
|
||||
}
|
||||
ota_info.ota_len = param->off_bp;
|
||||
hal_flash_dis_secure(0, 0, 0);//disable flash protect
|
||||
if(param->off_bp == 0) {
|
||||
hal_flash_erase(HAL_PARTITION_OTA_TEMP, 0, part_info->partition_length);
|
||||
ota_crc16_init(&contex);
|
||||
}
|
||||
else {
|
||||
contex.crc = hal_ota_get_crc16();
|
||||
OTA_LOG_I("--------get crc16 context.crc=%d!--------\n", contex.crc);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ota_write(int *off_set, char *in_buf , int in_buf_len)
|
||||
{
|
||||
int ret = 0;
|
||||
if(ota_info.ota_len == 0) {
|
||||
_off_set = 0;
|
||||
ota_crc16_init(&contex);
|
||||
memset(&ota_info, 0, sizeof(ota_info));
|
||||
}
|
||||
ota_crc16_update(&contex, in_buf, in_buf_len);
|
||||
ret = hal_flash_write(HAL_PARTITION_OTA_TEMP, &_off_set, in_buf, in_buf_len);
|
||||
ota_info.ota_len += in_buf_len;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ota_read(int *off_set, char *out_buf , int out_buf_len)
|
||||
{
|
||||
hal_flash_read(HAL_PARTITION_OTA_TEMP, off_set, out_buf, out_buf_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ota_boot(void *something)
|
||||
{
|
||||
ota_boot_param_t *param = (ota_boot_param_t *)something;
|
||||
if(param == NULL) {
|
||||
return -1;
|
||||
}
|
||||
if(param->res_type == OTA_FINISH) {
|
||||
ota_crc16_final(&contex, &ota_info.ota_crc);
|
||||
OTA_LOG_I("beken set boot\n");
|
||||
hal_ota_switch_to_new_fw();
|
||||
}
|
||||
else if(param->res_type == OTA_BREAKPOINT) {
|
||||
OTA_LOG_I("-------save bp crc=%d--------------\n", contex.crc);
|
||||
hal_ota_save_crc16(contex.crc);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static uint16_t hal_ota_get_crc16(void)
|
||||
{
|
||||
int len = 2;
|
||||
uint16_t crc16 = 0;
|
||||
aos_kv_get(KV_HAL_OTA_CRC16, &crc16, &len);
|
||||
return crc16;
|
||||
}
|
||||
|
||||
static void hal_ota_save_crc16(uint16_t crc16)
|
||||
{
|
||||
aos_kv_set(KV_HAL_OTA_CRC16, &crc16, 2, 1);
|
||||
}
|
||||
|
||||
static int ota_rollback(void *something)
|
||||
{
|
||||
int offset = 0x00;
|
||||
int param_part = HAL_PARTITION_PARAMETER_1;
|
||||
ota_boot_param_t param_w, param_r;
|
||||
memset(¶m_w, 0, sizeof(ota_boot_param_t));
|
||||
hal_flash_read(param_part, (uint32_t*)&offset, ¶m_w, sizeof(ota_boot_param_t));
|
||||
if((param_w.boot_count != 0) && (param_w.boot_count != 0xff)) {
|
||||
ota_crc16_ctx ctx1;
|
||||
unsigned short crc;
|
||||
param_w.upg_flag = 0;
|
||||
param_w.boot_count = 0; /*Clear bootcount to avoid rollback*/
|
||||
ota_crc16_init(&ctx1);
|
||||
ota_crc16_update(&ctx1, ¶m_w, sizeof(ota_boot_param_t) - sizeof(unsigned short));
|
||||
ota_crc16_final(&ctx1, &crc);
|
||||
param_w.param_crc = crc;
|
||||
offset = 0x00;
|
||||
hal_flash_erase(param_part, offset, sizeof(ota_boot_param_t));
|
||||
offset = 0x00;
|
||||
hal_flash_write(param_part, (uint32_t*)&offset, ¶m_w, sizeof(ota_boot_param_t));
|
||||
offset = 0x00;
|
||||
memset(¶m_r, 0, sizeof(ota_boot_param_t));
|
||||
hal_flash_read(param_part, (uint32_t*)&offset, ¶m_r, sizeof(ota_boot_param_t));
|
||||
if(memcmp(¶m_w, ¶m_r, sizeof(ota_boot_param_t)) != 0) {
|
||||
OTA_LOG_E("rollback failed\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *aos_get_app_version(void);
|
||||
static const char *ota_get_version(unsigned char dev_type)
|
||||
{
|
||||
if(dev_type) {
|
||||
return "v1.0.0-20180101-1000";//SYSINFO_APP_VERSION;
|
||||
} else {
|
||||
return aos_get_app_version();
|
||||
}
|
||||
}
|
||||
|
||||
ota_hal_module_t ota_hal_module = {
|
||||
.init = ota_init,
|
||||
.write = ota_write,
|
||||
.read = ota_read,
|
||||
.boot = ota_boot,
|
||||
.rollback = ota_rollback,
|
||||
.version = ota_get_version,
|
||||
};
|
||||
153
Living_SDK/framework/uOTA/hal/ota_hal_esp32.c
Normal file
153
Living_SDK/framework/uOTA/hal/ota_hal_esp32.c
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
#include "esp_ota_ops.h"
|
||||
#include "ota_log.h"
|
||||
#include "ota_hal_plat.h"
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#include "esp_spi_flash.h"
|
||||
#include "rom/spi_flash.h"
|
||||
#include "hal/soc/flash.h"
|
||||
|
||||
static esp_partition_t operate_partition;
|
||||
static esp_ota_handle_t out_handle;
|
||||
static esp_err_t esp_write_error;
|
||||
|
||||
extern void esp_restart(void);
|
||||
|
||||
bool esp_ota_prepare()
|
||||
{
|
||||
esp_err_t err;
|
||||
const esp_partition_t *esp_current_partition = esp_ota_get_boot_partition();
|
||||
if (esp_current_partition == NULL) {
|
||||
OTA_LOG_E("Got null partition.");
|
||||
return false;
|
||||
}
|
||||
if (esp_current_partition->type != ESP_PARTITION_TYPE_APP) {
|
||||
OTA_LOG_E("Err part type");
|
||||
return false;
|
||||
}
|
||||
esp_partition_t find_partition;
|
||||
/*choose which OTA image should we write to*/
|
||||
switch (esp_current_partition->subtype) {
|
||||
case ESP_PARTITION_SUBTYPE_APP_FACTORY:
|
||||
find_partition.subtype = ESP_PARTITION_SUBTYPE_APP_OTA_0;
|
||||
break;
|
||||
case ESP_PARTITION_SUBTYPE_APP_OTA_0:
|
||||
find_partition.subtype = ESP_PARTITION_SUBTYPE_APP_OTA_1;
|
||||
break;
|
||||
case ESP_PARTITION_SUBTYPE_APP_OTA_1:
|
||||
find_partition.subtype = ESP_PARTITION_SUBTYPE_APP_OTA_0;
|
||||
break;
|
||||
default:
|
||||
find_partition.subtype = ESP_PARTITION_SUBTYPE_APP_OTA_0;
|
||||
break;
|
||||
}
|
||||
|
||||
find_partition.type = ESP_PARTITION_TYPE_APP;
|
||||
const esp_partition_t *partition = esp_partition_find_first(find_partition.type, find_partition.subtype, NULL);
|
||||
assert(partition != NULL);
|
||||
memset(&operate_partition, 0, sizeof(esp_partition_t));
|
||||
|
||||
OTA_LOG_I("ota_begin part type 0x%x sub:0x%x addr:0x%x size:0x%x label:%s encry:0x%x\n", partition->type, partition->subtype, partition->address, partition->size, partition->label, partition->encrypted);
|
||||
esp_write_error = ESP_OK;
|
||||
err = esp_ota_begin(partition, OTA_SIZE_UNKNOWN, &out_handle);
|
||||
if (err != ESP_OK) {
|
||||
OTA_LOG_E("begin err=0x%x!", err);
|
||||
return false;
|
||||
} else {
|
||||
memcpy(&operate_partition, partition, sizeof(esp_partition_t));
|
||||
OTA_LOG_I("ota init OK");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static int ota_init(void *something)
|
||||
{
|
||||
ota_boot_param_t *param = (ota_boot_param_t *)something;
|
||||
uint32_t offset = param->off_bp;
|
||||
OTA_LOG_I("ota_init off:0x%x \n",offset);
|
||||
if(offset==0) {
|
||||
/* prepare to os update */
|
||||
if (esp_ota_prepare() != true) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ota_write(int* off, char* buf ,int buf_len)
|
||||
{
|
||||
esp_err_t err = ESP_OK;
|
||||
err = esp_ota_write(out_handle, (const void *)buf, (size_t)buf_len);
|
||||
if (err != ESP_OK) {
|
||||
esp_write_error = err;
|
||||
OTA_LOG_E("write err=%x", err);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ota_boot(void *something)
|
||||
{
|
||||
esp_err_t err = ESP_OK;
|
||||
ota_boot_param_t *param = (ota_boot_param_t *)something;
|
||||
if (param == NULL) {
|
||||
return -1;
|
||||
}
|
||||
if (param->res_type == OTA_FINISH) {
|
||||
if (esp_ota_end(out_handle) != ESP_OK) {
|
||||
OTA_LOG_E("end failed!");
|
||||
return -1;
|
||||
}
|
||||
if(esp_write_error ) {
|
||||
OTA_LOG_E("write_error %d!",esp_write_error);
|
||||
return -1;
|
||||
}
|
||||
err = esp_ota_set_boot_partition(&operate_partition);
|
||||
if (err != ESP_OK) {
|
||||
OTA_LOG_E("set part failed! err=0x%x", err);
|
||||
return -1;
|
||||
}
|
||||
OTA_LOG_I("restart system!");
|
||||
esp_restart();
|
||||
}
|
||||
else if (param->res_type==OTA_BREAKPOINT) {
|
||||
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int ota_read(int* off, char* out_buf, int out_buf_len)
|
||||
{
|
||||
return hal_flash_read(HAL_PARTITION_OTA_TEMP, (uint32_t*)off, out_buf, out_buf_len);
|
||||
}
|
||||
|
||||
static int ota_rollback(void *something)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *aos_get_app_version(void);
|
||||
static const char *ota_get_version(unsigned char dev_type)
|
||||
{
|
||||
if(dev_type) {
|
||||
return "v1.0.0-20180101-1000";//SYSINFO_APP_VERSION;
|
||||
} else {
|
||||
return SYSINFO_APP_VERSION;
|
||||
}
|
||||
}
|
||||
|
||||
ota_hal_module_t ota_hal_module = {
|
||||
.init = ota_init,
|
||||
.write = ota_write,
|
||||
.read = ota_read,
|
||||
.boot = ota_boot,
|
||||
.rollback = ota_rollback,
|
||||
.version = ota_get_version,
|
||||
};
|
||||
216
Living_SDK/framework/uOTA/hal/ota_hal_host.c
Normal file
216
Living_SDK/framework/uOTA/hal/ota_hal_host.c
Normal file
|
|
@ -0,0 +1,216 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include "ota_log.h"
|
||||
#include "ota_hal_plat.h"
|
||||
|
||||
static FILE* ota_fd = NULL;
|
||||
static int offset = 0;
|
||||
#if defined PLAT_RASPBERRY /*raspberry*/
|
||||
static int boot_part = 2;
|
||||
static int boot_part_in = 3;
|
||||
#define OTA_IMAGE_FILE "/dev/mmcblk0p"
|
||||
#else
|
||||
static int boot_part = 4;
|
||||
static int boot_part_in = 5;
|
||||
#define OTA_IMAGE_FILE "rkflash0p"
|
||||
#endif
|
||||
|
||||
int getCmdVal(const char *cmd)
|
||||
{
|
||||
char ps[1024]={0};
|
||||
FILE *ptr = NULL;
|
||||
char *sstr = NULL;
|
||||
if((ptr=popen(cmd, "r"))!=NULL)
|
||||
{
|
||||
while(fgets(ps, 1024, ptr)!=NULL)
|
||||
{
|
||||
}
|
||||
pclose(ptr);
|
||||
ptr = NULL;
|
||||
OTA_LOG_I("ret:%s\n",ps);
|
||||
}
|
||||
else
|
||||
{
|
||||
OTA_LOG_E("popen %s error\n", ps);
|
||||
}
|
||||
sstr = strstr(ps, "mender_boot_part=");
|
||||
if (sstr) {
|
||||
sscanf(sstr, "%*[^ ]%d", &boot_part);
|
||||
OTA_LOG_I("mender_boot_part:%d \n", boot_part);
|
||||
}
|
||||
#if defined PLAT_RASPBERRY
|
||||
if(boot_part == 3) {
|
||||
boot_part_in = 2;
|
||||
} else {
|
||||
boot_part_in = 3;
|
||||
}
|
||||
#else
|
||||
if(boot_part == 5) {
|
||||
boot_part_in = 4;
|
||||
} else {
|
||||
boot_part_in = 5;
|
||||
}
|
||||
#endif
|
||||
OTA_LOG_I("ota init:%d boot_part_in:%d\n", boot_part,boot_part_in);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ota_init(void *something)
|
||||
{
|
||||
char path[64] = {0};
|
||||
int ret = 0;
|
||||
ota_boot_param_t * param = (ota_boot_param_t*)something;
|
||||
getCmdVal("fw_printenv mender_boot_part");
|
||||
snprintf(path,sizeof(path),"%s%d",OTA_IMAGE_FILE,boot_part_in);
|
||||
offset= param->off_bp;
|
||||
OTA_LOG_I("init off: %d size:0x%x \n", offset,param->len);
|
||||
if(param->len == 0) {
|
||||
OTA_LOG_E("ota init size error:");
|
||||
return -1;
|
||||
}
|
||||
#if !defined PLAT_RASPBERRY
|
||||
if(param->len > 0x3100000){
|
||||
OTA_LOG_E("firmware size is too big.\n");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
if(offset!=0){ /*breakpoint resume*/
|
||||
if(ota_fd==NULL){
|
||||
if((ota_fd = fopen(path, "a+"))==NULL) {
|
||||
OTA_LOG_E("init err: %d, %s\n", ret, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
if(ftell(ota_fd)<=0){
|
||||
OTA_LOG_E("init error: %d, %s\n", ret, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ota_write(int *off_set, char *in_buf, int in_buf_len)
|
||||
{
|
||||
int ret = 0;
|
||||
if(ota_fd == NULL)
|
||||
{
|
||||
char path[64] = {0};
|
||||
snprintf(path,sizeof(path),"%s%d",OTA_IMAGE_FILE,boot_part_in);
|
||||
ota_fd = fopen(path, "w");
|
||||
}
|
||||
ret = fwrite(in_buf, in_buf_len, 1, ota_fd);
|
||||
if (ret < 0) {
|
||||
OTA_LOG_E("write err: %d, %d ,%s\n", ret, in_buf_len,
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ota_read(int *off_set, char *out_buf, int out_buf_len)
|
||||
{
|
||||
if (ota_fd != NULL) {
|
||||
fflush(ota_fd);
|
||||
fclose(ota_fd);
|
||||
ota_fd = NULL;
|
||||
}
|
||||
int ret = 0;
|
||||
if(ota_fd == NULL)
|
||||
{
|
||||
char path[64] = {0};
|
||||
snprintf(path,sizeof(path),"%s%d",OTA_IMAGE_FILE,boot_part_in);
|
||||
ota_fd = fopen(path, "r");
|
||||
}
|
||||
ret = fseek(ota_fd, *off_set, SEEK_SET);
|
||||
ret = fread(out_buf, out_buf_len, 1, ota_fd);
|
||||
if (ret != 1) {
|
||||
OTA_LOG_E("read err: %d, %d ,%s\n", ret, out_buf_len, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
fclose(ota_fd);
|
||||
ota_fd = NULL;
|
||||
*off_set += out_buf_len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ota_boot(void *something)
|
||||
{
|
||||
int ret = 0;
|
||||
if (ota_fd != NULL) {
|
||||
fflush(ota_fd);
|
||||
fclose(ota_fd);
|
||||
ota_fd = NULL;
|
||||
}
|
||||
char cmd1[64] = { 0 };
|
||||
ota_boot_param_t *param = (ota_boot_param_t *)something;
|
||||
if (param==NULL){
|
||||
OTA_LOG_E("boot err\n");
|
||||
return -1;
|
||||
}
|
||||
if (param->res_type==OTA_FINISH) {
|
||||
sprintf(cmd1, "fw_setenv mender_boot_part %d",boot_part_in);
|
||||
ret = system(cmd1);
|
||||
if(ret < 0) {
|
||||
OTA_LOG_E("set boot part err.\n");
|
||||
return -1;
|
||||
}
|
||||
OTA_LOG_E("boot:%s \n",cmd1);
|
||||
memset(cmd1,0x00,sizeof(cmd1));
|
||||
sprintf(cmd1, "fw_setenv upgrade_available 1");
|
||||
ret = system(cmd1);
|
||||
if(ret < 0) {
|
||||
OTA_LOG_E("upgrade_available err\n");
|
||||
return -1;
|
||||
}
|
||||
OTA_LOG_E("boot:%s \n",cmd1);
|
||||
memset(cmd1,0x00,sizeof(cmd1));
|
||||
sprintf(cmd1, "sync;reboot");
|
||||
ret = system(cmd1);
|
||||
if(ret < 0) {
|
||||
OTA_LOG_E("sync err\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
OTA_LOG_I("Rebooting and updating FLASH now....\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ota_rollback(void *something)
|
||||
{
|
||||
char cmd1[128] = {0};
|
||||
int ret = 0;
|
||||
sprintf(cmd1, "fw_setenv upgrade_available 0; fw_setenv bootcount 0; sync");
|
||||
ret = system(cmd1);
|
||||
if(ret < 0) {
|
||||
OTA_LOG_E("roll system fail .");
|
||||
}
|
||||
OTA_LOG_I("roll:%s \n",cmd1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *aos_get_app_version(void);
|
||||
static const char *ota_get_version(unsigned char dev_type)
|
||||
{
|
||||
if(dev_type) {
|
||||
return "v1.0.0-20180101-1000";//SYSINFO_APP_VERSION;
|
||||
} else {
|
||||
return aos_get_app_version();
|
||||
}
|
||||
}
|
||||
|
||||
ota_hal_module_t ota_hal_module = {
|
||||
.init = ota_init,
|
||||
.write = ota_write,
|
||||
.read = ota_read,
|
||||
.boot = ota_boot,
|
||||
.rollback = ota_rollback,
|
||||
.version = ota_get_version,
|
||||
};
|
||||
87
Living_SDK/framework/uOTA/hal/ota_hal_mcu.c
Executable file
87
Living_SDK/framework/uOTA/hal/ota_hal_mcu.c
Executable file
|
|
@ -0,0 +1,87 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include "aos/kernel.h"
|
||||
#include "aos/kv.h"
|
||||
|
||||
#include "ota_hal_plat.h"
|
||||
#include "ota_hal_os.h"
|
||||
#include "ota_log.h"
|
||||
#include "ota_verify.h"
|
||||
#include "ota_hal_mcu.h"
|
||||
|
||||
#define OTA_CRC16 "ota_file_crc16"
|
||||
static unsigned int wdata_len = 0;
|
||||
static ota_crc16_ctx ctx = {0};
|
||||
|
||||
static unsigned short ota_get_crc16(void)
|
||||
{
|
||||
int len = 2;
|
||||
unsigned short crc16=0;
|
||||
aos_kv_get(OTA_CRC16, &crc16, &len);
|
||||
return crc16;
|
||||
}
|
||||
|
||||
static void ota_set_crc16(unsigned short crc16)
|
||||
{
|
||||
aos_kv_set(OTA_CRC16, &crc16, 2, 1);
|
||||
}
|
||||
|
||||
int ota_mcu_init(void *something)
|
||||
{
|
||||
int ret = 0;
|
||||
ota_boot_param_t *param = (ota_boot_param_t *)something;
|
||||
param->off_bp = ota_get_break_point();
|
||||
if (param->off_bp >= param->len) {
|
||||
param->off_bp = 0;
|
||||
}
|
||||
wdata_len = param->off_bp;
|
||||
|
||||
if (param->off_bp == 0) {
|
||||
ota_crc16_init(&ctx);
|
||||
} else {
|
||||
ctx.crc = ota_get_crc16();
|
||||
}
|
||||
OTA_LOG_I("ota mcu init off:0x%08x len:%d crc:0x%04x\n", param->off_bp, param->len, ctx.crc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ota_mcu_write(int* off, char* in_buf ,int in_buf_len)
|
||||
{
|
||||
int ret = 0;
|
||||
if (off != NULL) {
|
||||
OTA_LOG_I("recv MCU data off:%d", *off);
|
||||
}
|
||||
|
||||
/* for only test */
|
||||
wdata_len = wdata_len + in_buf_len;
|
||||
OTA_LOG_I("recv MCU data wdata_len:%d, in_buf_len:%d", wdata_len, in_buf_len);
|
||||
|
||||
ota_crc16_update(&ctx, in_buf, in_buf_len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ota_mcu_boot(void *something)
|
||||
{
|
||||
int ret = 0;
|
||||
ota_boot_param_t *param = (ota_boot_param_t *)something;
|
||||
if (param == NULL) {
|
||||
ret = OTA_REBOOT_FAIL;
|
||||
return ret;
|
||||
}
|
||||
if (param->res_type == OTA_FINISH) {
|
||||
ota_crc16_final(&ctx, ¶m->crc);
|
||||
ota_set_break_point(0);
|
||||
ota_msleep(1500);
|
||||
ota_reboot();
|
||||
} else if(param->res_type == OTA_BREAKPOINT) {
|
||||
OTA_LOG_I("save bp crc:0x%04x", ctx.crc);
|
||||
ota_set_crc16(ctx.crc);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
21
Living_SDK/framework/uOTA/hal/ota_hal_mcu.h
Executable file
21
Living_SDK/framework/uOTA/hal/ota_hal_mcu.h
Executable file
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef MCU_HAL_OTA_H
|
||||
#define MCU_HAL_OTA_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int ota_mcu_init(void *something);
|
||||
int ota_mcu_write(int* off, char* in_buf ,int in_buf_len);
|
||||
int ota_mcu_boot(void *something);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* MCU_HAL_OTA_H */
|
||||
|
||||
154
Living_SDK/framework/uOTA/hal/ota_hal_module.c
Normal file
154
Living_SDK/framework/uOTA/hal/ota_hal_module.c
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "ota_log.h"
|
||||
#include "ota_hal_plat.h"
|
||||
|
||||
static ota_hal_module_t *ota_module = NULL;
|
||||
|
||||
void ota_hal_register_module(ota_hal_module_t *module)
|
||||
{
|
||||
ota_module = module;
|
||||
}
|
||||
|
||||
int ota_hal_init(void *something)
|
||||
{
|
||||
#ifdef OTA_BOOT_PAPA_COMPATIBAL
|
||||
struct {
|
||||
unsigned int dst_adr;
|
||||
unsigned int src_adr;
|
||||
unsigned int len;
|
||||
unsigned short crc;
|
||||
unsigned int upg_flag;
|
||||
unsigned char boot_count;
|
||||
unsigned int rec_size;
|
||||
unsigned int splict_size;
|
||||
int off_bp; /*Break point offset*/
|
||||
OTA_RES_TYPE_E res_type; /*result type: OTA_FINISH, OTA_BREAKPOINT*/
|
||||
unsigned short param_crc; /*Parameter crc*/
|
||||
} __attribute__((packed)) boot_para_more;
|
||||
|
||||
ota_boot_param_t *boot_para_less = (ota_boot_param_t *)something;
|
||||
|
||||
boot_para_more.dst_adr = boot_para_less->dst_adr ;
|
||||
boot_para_more.src_adr = boot_para_less->src_adr ;
|
||||
boot_para_more.len = boot_para_less->len ;
|
||||
boot_para_more.crc = boot_para_less->crc ;
|
||||
boot_para_more.upg_flag = boot_para_less->upg_flag ;
|
||||
boot_para_more.boot_count = boot_para_less->boot_count ;
|
||||
boot_para_more.rec_size = 0 ;
|
||||
boot_para_more.splict_size = boot_para_less->splict_size;
|
||||
boot_para_more.off_bp = boot_para_less->off_bp ;
|
||||
boot_para_more.res_type = boot_para_less->res_type ;
|
||||
boot_para_more.param_crc = boot_para_less->param_crc ;
|
||||
|
||||
something = (void *)&boot_para_more;
|
||||
#endif
|
||||
|
||||
if (ota_module == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ota_module != NULL && ota_module->init != NULL) {
|
||||
return ota_module->init(something);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ota_hal_write(int *off_set, char *in_buf , int in_buf_len)
|
||||
{
|
||||
if (ota_module == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ota_module != NULL && ota_module->write != NULL) {
|
||||
return ota_module->write(off_set, in_buf, in_buf_len);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ota_hal_read(int *off_set, char *out_buf, int out_buf_len)
|
||||
{
|
||||
if (ota_module == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ota_module != NULL && ota_module->read != NULL) {
|
||||
return ota_module->read(off_set, out_buf, out_buf_len);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ota_hal_boot(void *something)
|
||||
{
|
||||
#ifdef OTA_BOOT_PAPA_COMPATIBAL
|
||||
struct {
|
||||
unsigned int dst_adr;
|
||||
unsigned int src_adr;
|
||||
unsigned int len;
|
||||
unsigned short crc;
|
||||
unsigned int upg_flag;
|
||||
unsigned char boot_count;
|
||||
unsigned int rec_size;
|
||||
unsigned int splict_size;
|
||||
int off_bp; /*Break point offset*/
|
||||
OTA_RES_TYPE_E res_type; /*result type: OTA_FINISH, OTA_BREAKPOINT*/
|
||||
unsigned short param_crc; /*Parameter crc*/
|
||||
} __attribute__((packed)) boot_para_more;
|
||||
|
||||
ota_boot_param_t *boot_para_less = (ota_boot_param_t *)something;
|
||||
|
||||
boot_para_more.dst_adr = boot_para_less->dst_adr ;
|
||||
boot_para_more.src_adr = boot_para_less->src_adr ;
|
||||
boot_para_more.len = boot_para_less->len ;
|
||||
boot_para_more.crc = boot_para_less->crc ;
|
||||
boot_para_more.upg_flag = boot_para_less->upg_flag ;
|
||||
boot_para_more.boot_count = boot_para_less->boot_count ;
|
||||
boot_para_more.rec_size = 0 ;
|
||||
boot_para_more.splict_size = boot_para_less->splict_size;
|
||||
boot_para_more.off_bp = boot_para_less->off_bp ;
|
||||
boot_para_more.res_type = boot_para_less->res_type ;
|
||||
boot_para_more.param_crc = boot_para_less->param_crc ;
|
||||
|
||||
something = (void *)&boot_para_more;
|
||||
#endif
|
||||
|
||||
if (ota_module == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ota_module != NULL && ota_module->boot != NULL) {
|
||||
return ota_module->boot(something);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ota_hal_rollback(void *something)
|
||||
{
|
||||
if (ota_module == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ota_module != NULL && ota_module->rollback != NULL) {
|
||||
return ota_module->rollback(something);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *ota_hal_get_version(unsigned char dev_type)
|
||||
{
|
||||
if (ota_module == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ota_module != NULL && ota_module->version != NULL) {
|
||||
return ota_module->version(dev_type);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
843
Living_SDK/framework/uOTA/hal/ota_hal_os.c
Normal file
843
Living_SDK/framework/uOTA/hal/ota_hal_os.c
Normal file
|
|
@ -0,0 +1,843 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include "ota_hal_os.h"
|
||||
#include "ota_log.h"
|
||||
#if !defined (AOS_OTA_RSA)
|
||||
#if defined AOS_OTA_ITLS
|
||||
#include "itls/sha256.h"
|
||||
#include "itls/md5.h"
|
||||
#else
|
||||
#include "mbedtls/sha256.h"
|
||||
#include "mbedtls/md5.h"
|
||||
#endif
|
||||
#endif
|
||||
#if (OTA_SIGNAL_CHANNEL) == 1
|
||||
#include "iot_export.h"
|
||||
#include "iot_import.h"
|
||||
#include "iot_export_coap.h"
|
||||
#endif
|
||||
|
||||
#if (OTA_SIGNAL_CHANNEL) == 2
|
||||
#include "iot_import.h"
|
||||
#endif
|
||||
|
||||
#ifdef OTA_LINUX
|
||||
#include <unistd.h>
|
||||
#include <semaphore.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/reboot.h>
|
||||
#else
|
||||
#include "aos/kernel.h"
|
||||
#include "aos/kv.h"
|
||||
|
||||
#endif
|
||||
|
||||
/*Memory realloc*/
|
||||
void *ota_realloc(void *ptr, int size)
|
||||
{
|
||||
#if defined OTA_WITH_LINKKIT
|
||||
return HAL_Realloc(ptr, size);
|
||||
#elif !defined OTA_LINUX
|
||||
return aos_realloc(ptr, size);
|
||||
#else
|
||||
return realloc(ptr, size);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*Memory calloc*/
|
||||
void *ota_calloc(int n, int size)
|
||||
{
|
||||
#if defined OTA_WITH_LINKKIT
|
||||
return HAL_Malloc(size);
|
||||
#elif !defined OTA_LINUX
|
||||
return aos_calloc(n, size);
|
||||
#else
|
||||
return calloc(n, size);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*Reboot*/
|
||||
void ota_reboot(void)
|
||||
{
|
||||
#if defined OTA_WITH_LINKKIT
|
||||
HAL_Reboot();
|
||||
#elif !defined OTA_LINUX
|
||||
aos_reboot();
|
||||
#else
|
||||
reboot(0x1234567);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*Memory malloc*/
|
||||
void *ota_malloc(int size)
|
||||
{
|
||||
#if defined OTA_WITH_LINKKIT
|
||||
return HAL_Malloc(size);
|
||||
#elif !defined OTA_LINUX
|
||||
return aos_malloc(size);
|
||||
#else
|
||||
return malloc(size);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*Memory free*/
|
||||
void ota_free(void *ptr)
|
||||
{
|
||||
#if defined OTA_WITH_LINKKIT
|
||||
return HAL_Free(ptr);
|
||||
#elif !defined OTA_LINUX
|
||||
aos_free(ptr);
|
||||
#else
|
||||
free(ptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*Semaphore init*/
|
||||
void *ota_semaphore_create(void)
|
||||
{
|
||||
#if defined OTA_WITH_LINKKIT
|
||||
return HAL_SemaphoreCreate();
|
||||
#elif !defined OTA_LINUX
|
||||
aos_sem_t *sem = (aos_sem_t *)ota_malloc(sizeof(aos_sem_t));
|
||||
if (NULL == sem) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (0 != aos_sem_new(sem, 0)) {
|
||||
ota_free(sem);
|
||||
return NULL;
|
||||
}
|
||||
return sem;
|
||||
#else
|
||||
sem_t *sem = (sem_t *)ota_malloc(sizeof(sem_t));
|
||||
if (NULL == sem) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (0 != sem_init(sem, 0, 0)) {
|
||||
ota_free(sem);
|
||||
return NULL;
|
||||
}
|
||||
return sem;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*Semaphore wait*/
|
||||
int ota_semaphore_wait(void *sem, int ms)
|
||||
{
|
||||
#if defined OTA_WITH_LINKKIT
|
||||
return HAL_SemaphoreWait(sem, ms);
|
||||
#elif !defined OTA_LINUX
|
||||
return aos_sem_wait((aos_sem_t *)sem, ms);
|
||||
#else
|
||||
if ((~0) == ms) {
|
||||
sem_wait(sem);
|
||||
return 0;
|
||||
} else {
|
||||
struct timespec ts;
|
||||
int s;
|
||||
/* Restart if interrupted by handler */
|
||||
do {
|
||||
if (clock_gettime(CLOCK_REALTIME, &ts) == -1) {
|
||||
return -1;
|
||||
}
|
||||
s = 0;
|
||||
ts.tv_nsec += (ms % 1000) * 1000000;
|
||||
if (ts.tv_nsec >= 1000000000) {
|
||||
ts.tv_nsec -= 1000000000;
|
||||
s = 1;
|
||||
}
|
||||
ts.tv_sec += ms / 1000 + s;
|
||||
} while (((s = sem_timedwait(sem, &ts)) != 0) && errno == EINTR);
|
||||
return (s == 0) ? 0 : -1;
|
||||
}
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*Semaphore post*/
|
||||
void ota_semaphore_post(void *sem)
|
||||
{
|
||||
#if defined OTA_WITH_LINKKIT
|
||||
return HAL_SemaphorePost(sem);
|
||||
#elif !defined OTA_LINUX
|
||||
aos_sem_signal((aos_sem_t *)sem);
|
||||
#else
|
||||
sem_post((sem_t *)sem);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*Semaphore destroy*/
|
||||
void ota_semaphore_destroy(void *sem)
|
||||
{
|
||||
#if defined OTA_WITH_LINKKIT
|
||||
return HAL_SemaphoreDestroy(sem);
|
||||
#elif !defined OTA_LINUX
|
||||
aos_sem_free((aos_sem_t *)sem);
|
||||
aos_free(sem);
|
||||
#else
|
||||
sem_destroy((sem_t *)sem);
|
||||
free(sem);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*Sleep ms*/
|
||||
void ota_msleep(int ms)
|
||||
{
|
||||
#if defined OTA_WITH_LINKKIT
|
||||
return HAL_SleepMs(ms);
|
||||
#elif !defined OTA_LINUX
|
||||
aos_msleep(ms);
|
||||
#else
|
||||
usleep(1000 * ms);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined OTA_WITH_LINKKIT
|
||||
;
|
||||
#elif !defined OTA_LINUX
|
||||
typedef struct
|
||||
{
|
||||
aos_task_t task;
|
||||
int detached;
|
||||
void * arg;
|
||||
void *(*routine)(void *arg);
|
||||
} task_context_t;
|
||||
|
||||
static void task_wrapper(void *arg)
|
||||
{
|
||||
task_context_t *task = arg;
|
||||
|
||||
task->routine(task->arg);
|
||||
|
||||
if (task) {
|
||||
aos_free(task);
|
||||
task = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#define OTA_THREAD_NAME "OTA_Thread"
|
||||
#if defined AOS_OTA_TLS
|
||||
#define OTA_THREAD_SIZE (8 * 1024)
|
||||
#else
|
||||
#define OTA_THREAD_SIZE (4 * 1024)
|
||||
#endif
|
||||
#define OTA_THREAD_PRI 30
|
||||
|
||||
/*Thread create*/
|
||||
int ota_thread_create(void **thread_handle, void *(*work_routine)(void *), void *arg, void *pm, int stack_size)
|
||||
{
|
||||
int ret = -1;
|
||||
#if defined OTA_WITH_LINKKIT
|
||||
hal_os_thread_param_t task_parms;
|
||||
task_parms.stack_size = OTA_THREAD_SIZE;
|
||||
task_parms.name = OTA_THREAD_NAME;
|
||||
ret = HAL_ThreadCreate(thread_handle, work_routine, arg, &task_parms, 0);
|
||||
#elif !defined OTA_LINUX
|
||||
char * tname = OTA_THREAD_NAME;
|
||||
if(stack_size <= 0) {
|
||||
stack_size = OTA_THREAD_SIZE;
|
||||
}
|
||||
task_context_t *task = aos_malloc(sizeof(task_context_t));
|
||||
if (!task) {
|
||||
return -1;
|
||||
}
|
||||
memset(task, 0, sizeof(task_context_t));
|
||||
task->arg = arg;
|
||||
task->routine = work_routine;
|
||||
|
||||
ret = aos_task_new_ext(&task->task, tname, task_wrapper, task, stack_size, OTA_THREAD_PRI);
|
||||
*thread_handle = (void *)task;
|
||||
#else
|
||||
ret = pthread_create((pthread_t *)thread_handle, NULL, work_routine, arg);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*Thread exit*/
|
||||
void ota_thread_exit(void *thread)
|
||||
{
|
||||
#if defined OTA_WITH_LINKKIT
|
||||
return HAL_ThreadDelete(thread);
|
||||
#elif !defined OTA_LINUX
|
||||
aos_task_exit(0);
|
||||
#else
|
||||
pthread_exit(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined OTA_WITH_LINKKIT
|
||||
/*KV set*/
|
||||
int ota_kv_set(const char *key, const void *val, int len, int sync)
|
||||
{
|
||||
return HAL_Kv_Set(key, val, len, sync);
|
||||
}
|
||||
/*KV get*/
|
||||
int ota_kv_get(const char *key, void *buffer, int *len)
|
||||
{
|
||||
return HAL_Kv_Get(key, buffer, len);
|
||||
}
|
||||
|
||||
#elif !defined OTA_LINUX
|
||||
/*KV set*/
|
||||
int ota_kv_set(const char *key, const void *val, int len, int sync)
|
||||
{
|
||||
return aos_kv_set(key, val, len, sync);
|
||||
}
|
||||
|
||||
/*KV get*/
|
||||
int ota_kv_get(const char *key, void *buffer, int *len)
|
||||
{
|
||||
return aos_kv_get(key, buffer, len);
|
||||
}
|
||||
|
||||
#else
|
||||
#define KV_FILE_PATH "./uota.kv"
|
||||
#define ITEM_MAX_KEY_LEN 128
|
||||
#define ITEM_MAX_VAL_LEN 256
|
||||
#define ITEM_LEN 512
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int flag;
|
||||
int val_len;
|
||||
} kv_state_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char key[ITEM_MAX_KEY_LEN];
|
||||
char val[ITEM_MAX_VAL_LEN];
|
||||
kv_state_t state;
|
||||
} kv_t;
|
||||
|
||||
static pthread_mutex_t mutex_kv = PTHREAD_MUTEX_INITIALIZER;
|
||||
/* get file size and item num */
|
||||
static int hal_fopen(FILE **fp, int *size, int *num)
|
||||
{
|
||||
/* create an file to save the kv */
|
||||
if ((*fp = fopen(KV_FILE_PATH, "a+")) == NULL) {
|
||||
OTA_LOG_E("open err:%s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
fseek(*fp, 0L, SEEK_END);
|
||||
if ((*size = ftell(*fp)) % ITEM_LEN) {
|
||||
fclose(*fp);
|
||||
return -1;
|
||||
}
|
||||
*num = ftell(*fp) / ITEM_LEN;
|
||||
fseek(*fp, 0L, SEEK_SET);
|
||||
return 0;
|
||||
}
|
||||
/*KV set*/
|
||||
int ota_kv_set(const char *key, const void *val, int len, int sync)
|
||||
{
|
||||
FILE *fp = NULL;
|
||||
int file_size = 0, block_num = 0, ret = 0, cur_pos = 0;
|
||||
kv_t kv_item;
|
||||
int i;
|
||||
/* check parameter */
|
||||
if (key == NULL || val == NULL) {
|
||||
return -1;
|
||||
}
|
||||
pthread_mutex_lock(&mutex_kv);
|
||||
if (hal_fopen(&fp, &file_size, &block_num) != 0) {
|
||||
goto ERR;
|
||||
}
|
||||
for (i = 0; i < block_num; i++) {
|
||||
memset(&kv_item, 0, sizeof(kv_t));
|
||||
cur_pos = ftell(fp);
|
||||
/* read an kv item(512 bytes) from file */
|
||||
if ((ret = fread(&kv_item, 1, ITEM_LEN, fp)) != ITEM_LEN) {
|
||||
goto ERR;
|
||||
}
|
||||
/* key compared */
|
||||
if (strcmp(kv_item.key, key) == 0) {
|
||||
/* set value and write to file */
|
||||
memset(kv_item.val, 0, ITEM_MAX_VAL_LEN);
|
||||
memcpy(kv_item.val, val, len);
|
||||
kv_item.state.val_len = len;
|
||||
fseek(fp, cur_pos, SEEK_SET);
|
||||
fwrite(&kv_item, 1, ITEM_LEN, fp);
|
||||
goto END;
|
||||
}
|
||||
}
|
||||
|
||||
/* key not compared, append an kv to file */
|
||||
memset(&kv_item, 0, sizeof(kv_t));
|
||||
strcpy(kv_item.key, key);
|
||||
memcpy(kv_item.val, val, len);
|
||||
kv_item.state.val_len = len;
|
||||
fseek(fp, 0L, SEEK_END);
|
||||
fwrite(&kv_item, 1, ITEM_LEN, fp);
|
||||
goto END;
|
||||
ERR:
|
||||
if (fp == NULL) {
|
||||
pthread_mutex_unlock(&mutex_kv);
|
||||
return -1;
|
||||
}
|
||||
OTA_LOG_E("read err:%s\n", strerror(errno));
|
||||
fflush(fp);
|
||||
fclose(fp);
|
||||
pthread_mutex_unlock(&mutex_kv);
|
||||
|
||||
return -1;
|
||||
END:
|
||||
fflush(fp);
|
||||
fclose(fp);
|
||||
pthread_mutex_unlock(&mutex_kv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*KV get*/
|
||||
int ota_kv_get(const char *key, void *buffer, int *len)
|
||||
{
|
||||
FILE *fp = NULL;
|
||||
int i;
|
||||
/* read from file */
|
||||
int file_size = 0, block_num = 0;
|
||||
kv_t kv_item;
|
||||
/* check parameter */
|
||||
if (key == NULL || buffer == NULL || len == NULL) {
|
||||
return -1;
|
||||
}
|
||||
pthread_mutex_lock(&mutex_kv);
|
||||
if (hal_fopen(&fp, &file_size, &block_num) != 0) {
|
||||
goto ERR;
|
||||
}
|
||||
for (i = 0; i < block_num; i++) {
|
||||
memset(&kv_item, 0, sizeof(kv_t));
|
||||
/* read an kv item(512 bytes) from file */
|
||||
if (fread(&kv_item, 1, ITEM_LEN, fp) != ITEM_LEN) {
|
||||
goto ERR;
|
||||
}
|
||||
/* key compared */
|
||||
if (strcmp(kv_item.key, key) == 0) {
|
||||
/* set value and write to file */
|
||||
*len = kv_item.state.val_len;
|
||||
memcpy(buffer, kv_item.val, *len);
|
||||
goto END;
|
||||
}
|
||||
}
|
||||
goto END;
|
||||
ERR:
|
||||
if (fp == NULL) {
|
||||
pthread_mutex_unlock(&mutex_kv);
|
||||
return -1;
|
||||
}
|
||||
OTA_LOG_E("read err:%s\n", strerror(errno));
|
||||
fflush(fp);
|
||||
fclose(fp);
|
||||
pthread_mutex_unlock(&mutex_kv);
|
||||
return -1;
|
||||
END:
|
||||
fflush(fp);
|
||||
fclose(fp);
|
||||
pthread_mutex_unlock(&mutex_kv);
|
||||
return 0;
|
||||
}
|
||||
#endif /*Linux end*/
|
||||
|
||||
/*Socket API*/
|
||||
void* ota_socket_connect(char *host, int port)
|
||||
{
|
||||
#ifdef OTA_WITH_LINKKIT
|
||||
return (void*)HAL_TCP_Establish(host, port);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int ota_socket_send(void* fd, char *buf, int len)
|
||||
{
|
||||
#ifdef OTA_WITH_LINKKIT
|
||||
return HAL_TCP_Write((uintptr_t)fd, buf, len, OTA_SSL_TIMEOUT);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int ota_socket_recv(void* fd, char *buf, int len)
|
||||
{
|
||||
#ifdef OTA_WITH_LINKKIT
|
||||
return HAL_TCP_Read((uintptr_t)fd, buf, len, OTA_SSL_TIMEOUT);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void ota_socket_close(void* fd)
|
||||
{
|
||||
#ifdef OTA_WITH_LINKKIT
|
||||
HAL_TCP_Destroy((uintptr_t)fd);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*SSL connect*/
|
||||
void *ota_ssl_connect(const char *host, unsigned short port, const char *ca_crt, int ca_crt_len)
|
||||
{
|
||||
#ifdef OTA_WITH_LINKKIT
|
||||
return (void*)HAL_SSL_Establish(host, port, ca_crt, ca_crt_len);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*SSL send*/
|
||||
int ota_ssl_send(void *ssl, char *buf, int len)
|
||||
{
|
||||
#ifdef OTA_WITH_LINKKIT
|
||||
return HAL_SSL_Write((uintptr_t)ssl, buf, len, OTA_SSL_TIMEOUT);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*SSL recv*/
|
||||
int ota_ssl_recv(void *ssl, char *buf, int len)
|
||||
{
|
||||
#ifdef OTA_WITH_LINKKIT
|
||||
return HAL_SSL_Read((uintptr_t)ssl, buf, len, OTA_SSL_TIMEOUT);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !defined (AOS_OTA_RSA)
|
||||
/*SHA256*/
|
||||
extern void mbedtls_sha256_free(mbedtls_sha256_context* ctx);
|
||||
extern void mbedtls_sha256_init(mbedtls_sha256_context*ctx);
|
||||
extern void mbedtls_sha256_starts(mbedtls_sha256_context*ctx, int is224);
|
||||
extern void mbedtls_sha256_update(mbedtls_sha256_context*ctx, const unsigned char *input, unsigned int ilen);
|
||||
extern void mbedtls_sha256_finish(mbedtls_sha256_context*ctx, unsigned char output[32]);
|
||||
|
||||
void ota_sha256_free(ota_sha256_context *ctx)
|
||||
{
|
||||
mbedtls_sha256_free((mbedtls_sha256_context*)ctx);
|
||||
}
|
||||
|
||||
void ota_sha256_init(ota_sha256_context *ctx)
|
||||
{
|
||||
mbedtls_sha256_init((mbedtls_sha256_context*)ctx);
|
||||
}
|
||||
|
||||
void ota_sha256_starts(ota_sha256_context *ctx, int is224)
|
||||
{
|
||||
mbedtls_sha256_starts((mbedtls_sha256_context*)ctx, is224);
|
||||
}
|
||||
|
||||
void ota_sha256_update(ota_sha256_context *ctx, const unsigned char *input, unsigned int ilen)
|
||||
{
|
||||
mbedtls_sha256_update((mbedtls_sha256_context*)ctx, input, ilen);
|
||||
}
|
||||
|
||||
void ota_sha256_finish(ota_sha256_context *ctx, unsigned char output[32])
|
||||
{
|
||||
mbedtls_sha256_finish((mbedtls_sha256_context*)ctx, output);
|
||||
}
|
||||
/*MD5*/
|
||||
extern void mbedtls_md5_free(mbedtls_md5_context*ctx);
|
||||
extern void mbedtls_md5_init(mbedtls_md5_context*ctx);
|
||||
extern void mbedtls_md5_starts(mbedtls_md5_context*ctx);
|
||||
extern void mbedtls_md5_update(mbedtls_md5_context*ctx, const unsigned char *input, unsigned int ilen);
|
||||
extern void mbedtls_md5_finish(mbedtls_md5_context*ctx, unsigned char output[32]);
|
||||
|
||||
void ota_md5_free(ota_md5_context *ctx)
|
||||
{
|
||||
mbedtls_md5_free((mbedtls_md5_context*)ctx);
|
||||
}
|
||||
|
||||
void ota_md5_init(ota_md5_context *ctx)
|
||||
{
|
||||
mbedtls_md5_init((mbedtls_md5_context*)ctx);
|
||||
}
|
||||
|
||||
void ota_md5_starts(ota_md5_context *ctx)
|
||||
{
|
||||
mbedtls_md5_starts((mbedtls_md5_context*)ctx);
|
||||
}
|
||||
|
||||
void ota_md5_update(ota_md5_context *ctx, const unsigned char *input, unsigned int ilen)
|
||||
{
|
||||
mbedtls_md5_update((mbedtls_md5_context*)ctx, input, ilen);
|
||||
}
|
||||
|
||||
void ota_md5_finish(ota_md5_context *ctx, unsigned char output[16])
|
||||
{
|
||||
mbedtls_md5_finish((mbedtls_md5_context*)ctx, output);
|
||||
}
|
||||
/*RSA*/
|
||||
extern int ali_rsa_get_pubkey_size(unsigned int keybits, unsigned int *size);
|
||||
extern int ali_rsa_init_pubkey(unsigned int keybits, const unsigned char *n, unsigned int n_size,
|
||||
const unsigned char *e, unsigned int e_size, ota_rsa_pubkey_t *pubkey);
|
||||
extern int ali_rsa_verify(const ota_rsa_pubkey_t *pub_key, const unsigned char *dig, unsigned int dig_size,
|
||||
const unsigned char *sig, unsigned int sig_size, ota_rsa_padding_t padding, bool *p_result);
|
||||
|
||||
int ota_rsa_get_pubkey_size(unsigned int keybits, unsigned int *size)
|
||||
{
|
||||
return ali_rsa_get_pubkey_size(keybits, size);
|
||||
}
|
||||
|
||||
int ota_rsa_init_pubkey(unsigned int keybits, const unsigned char *n, unsigned int n_size,
|
||||
const unsigned char *e, unsigned int e_size, ota_rsa_pubkey_t *pubkey){
|
||||
return ali_rsa_init_pubkey(keybits, n, n_size, e, e_size, pubkey);
|
||||
}
|
||||
|
||||
int ota_rsa_verify(const ota_rsa_pubkey_t *pub_key, const unsigned char *dig, unsigned int dig_size,
|
||||
const unsigned char *sig, unsigned int sig_size, ota_rsa_padding_t padding, bool *p_result)
|
||||
{
|
||||
return ali_rsa_verify(pub_key,dig,dig_size,sig,sig_size,padding,p_result);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static const unsigned char base64_dec_map[128] =
|
||||
{
|
||||
127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
|
||||
127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
|
||||
127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
|
||||
127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
|
||||
127, 127, 127, 62, 127, 127, 127, 63, 52, 53,
|
||||
54, 55, 56, 57, 58, 59, 60, 61, 127, 127,
|
||||
127, 64, 127, 127, 127, 0, 1, 2, 3, 4,
|
||||
5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
||||
25, 127, 127, 127, 127, 127, 127, 26, 27, 28,
|
||||
29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
|
||||
39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
|
||||
49, 50, 51, 127, 127, 127, 127, 127
|
||||
};
|
||||
|
||||
|
||||
int ota_base64_decode(const unsigned char *src, int slen, unsigned char *dst, int *dlen)
|
||||
{
|
||||
unsigned int i, n;
|
||||
unsigned int j, x;
|
||||
unsigned char *p;
|
||||
|
||||
for( i = n = j = 0; i < slen; i++ )
|
||||
{
|
||||
if( ( slen - i ) >= 2 &&
|
||||
src[i] == '\r' && src[i + 1] == '\n' )
|
||||
continue;
|
||||
|
||||
if( src[i] == '\n' )
|
||||
continue;
|
||||
|
||||
if( src[i] == '=' && ++j > 2 )
|
||||
return -1;
|
||||
|
||||
if( src[i] > 127 || base64_dec_map[src[i]] == 127 )
|
||||
return -1;
|
||||
|
||||
if( base64_dec_map[src[i]] < 64 && j != 0 )
|
||||
return -1;
|
||||
|
||||
n++;
|
||||
}
|
||||
|
||||
if( n == 0 )
|
||||
return 0;
|
||||
|
||||
n = ( ( n * 6 ) + 7 ) >> 3;
|
||||
n -= j;
|
||||
|
||||
if( dst == 0 || *dlen < n )
|
||||
{
|
||||
*dlen = n;
|
||||
return -2;
|
||||
}
|
||||
|
||||
for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ )
|
||||
{
|
||||
if( *src == '\r' || *src == '\n' )
|
||||
continue;
|
||||
|
||||
j -= ( base64_dec_map[*src] == 64 );
|
||||
x = ( x << 6 ) | ( base64_dec_map[*src] & 0x3F );
|
||||
|
||||
if( ++n == 4 )
|
||||
{
|
||||
n = 0;
|
||||
if( j > 0 ) *p++ = (unsigned char)( x >> 16 );
|
||||
if( j > 1 ) *p++ = (unsigned char)( x >> 8 );
|
||||
if( j > 2 ) *p++ = (unsigned char)( x );
|
||||
}
|
||||
}
|
||||
|
||||
*dlen = p - dst;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*CRC16*/
|
||||
static unsigned short update_crc16(unsigned short crcIn, unsigned char byte)
|
||||
{
|
||||
unsigned int crc = crcIn;
|
||||
unsigned int in = byte | 0x100;
|
||||
|
||||
do {
|
||||
crc <<= 1;
|
||||
in <<= 1;
|
||||
if (in & 0x100) {
|
||||
++crc;
|
||||
}
|
||||
if (crc & 0x10000) {
|
||||
crc ^= 0x1021;
|
||||
}
|
||||
} while (!(in & 0x10000));
|
||||
return crc & 0xffffu;
|
||||
}
|
||||
|
||||
void ota_crc16_init(ota_crc16_ctx *inCtx)
|
||||
{
|
||||
inCtx->crc = 0;
|
||||
}
|
||||
|
||||
|
||||
void ota_crc16_update(ota_crc16_ctx *inCtx, const void *inSrc, unsigned int inLen)
|
||||
{
|
||||
const unsigned char *src = (const unsigned char *) inSrc;
|
||||
const unsigned char *srcEnd = src + inLen;
|
||||
while ( src < srcEnd ) {
|
||||
inCtx->crc = update_crc16(inCtx->crc, *src++);
|
||||
}
|
||||
}
|
||||
|
||||
void ota_crc16_final(ota_crc16_ctx *inCtx, unsigned short *outResult )
|
||||
{
|
||||
inCtx->crc = update_crc16(inCtx->crc, 0);
|
||||
inCtx->crc = update_crc16(inCtx->crc, 0);
|
||||
*outResult = inCtx->crc & 0xffffu;
|
||||
}
|
||||
|
||||
/*MQTT API*/
|
||||
int ota_hal_mqtt_publish(char *topic, int qos, void *data, int len)
|
||||
{
|
||||
#if (OTA_SIGNAL_CHANNEL) == 1
|
||||
return IOT_MQTT_Publish_Simple(NULL, topic, qos, data, len);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int ota_hal_mqtt_subscribe(char *topic, void *cb, void *ctx)
|
||||
{
|
||||
#if (OTA_SIGNAL_CHANNEL) == 1
|
||||
#ifdef MQTT_AUTO_SUBSCRIBE
|
||||
return IOT_MQTT_Subscribe_Sync(NULL, topic, IOTX_MQTT_QOS3_SUB_LOCAL, cb, ctx, 1000);
|
||||
#else
|
||||
return IOT_MQTT_Subscribe_Sync(NULL, topic, IOTX_MQTT_QOS0, cb, ctx, 1000);
|
||||
#endif
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int ota_hal_mqtt_deinit(void)
|
||||
{
|
||||
#if (OTA_SIGNAL_CHANNEL) == 1
|
||||
return IOT_MQTT_Destroy(NULL);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int ota_hal_mqtt_init(void)
|
||||
{
|
||||
#if (OTA_SIGNAL_CHANNEL) == 1
|
||||
return (IOT_MQTT_Construct(NULL) == NULL)? -1 : 0;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*CoAP API*/
|
||||
int ota_coap_send(void *p_context, char *p_path, void *p_message)
|
||||
{
|
||||
#if (OTA_SIGNAL_CHANNEL) == 2
|
||||
return IOT_CoAP_SendMessage(p_context, p_path, p_message);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int ota_coap_parse_block(void *p_message, int type, int *num, int *more, int *size)
|
||||
{
|
||||
#if (OTA_SIGNAL_CHANNEL) == 2
|
||||
return IOT_CoAP_ParseOption_block(p_message, type, num, more, size);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int ota_coap_send_block(void *p_context, char *p_path, void *p_message, int block_type, int num, int more, int size)
|
||||
{
|
||||
#if (OTA_SIGNAL_CHANNEL) == 2
|
||||
return IOT_CoAP_SendMessage_block(p_context, p_path, p_message, block_type,num, more, size);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
int ota_coap_get_payload(void *p_message, const char **pp_payload, int *p_len)
|
||||
{
|
||||
#if (OTA_SIGNAL_CHANNEL) == 2
|
||||
return IOT_CoAP_GetMessagePayload(p_message, pp_payload, p_len);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
int ota_coap_get_code(void *p_message, void *p_resp_code)
|
||||
{
|
||||
#if (OTA_SIGNAL_CHANNEL) == 2
|
||||
return IOT_CoAP_GetMessageCode(p_message, p_resp_code);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
int ota_coap_init(void)
|
||||
{
|
||||
#if (OTA_SIGNAL_CHANNEL) == 2
|
||||
#define COAP_ONLINE_DTLS_SERVER_URL "coaps://%s.iot-as-coap.cn-shanghai.aliyuncs.com:5684"
|
||||
int ret = 0;
|
||||
iotx_coap_config_t config;
|
||||
iotx_device_info_t dev;
|
||||
memset(&config, 0, sizeof(config));
|
||||
memset(&dev, 0, sizeof(dev));
|
||||
strncpy(dev.device_id, get_ota_service()->ps, sizeof(dev.device_id)-1);
|
||||
strncpy(dev.product_key, get_ota_service()->pk, sizeof(dev.product_key)-1);
|
||||
strncpy(dev.device_name, get_ota_service()->dn, sizeof(dev.device_name)-1);
|
||||
strncpy(dev.device_secret, get_ota_service()->ds, sizeof(dev.device_secret)-1);
|
||||
config.p_devinfo = &dev;
|
||||
char url[256] = { 0 };
|
||||
ota_snprintf(url, sizeof(url), COAP_ONLINE_DTLS_SERVER_URL,get_ota_service()->pk);
|
||||
config.p_url = url;
|
||||
get_ota_service()->h_ch = (void *)ota_IOT_CoAP_Init(&config);
|
||||
if (get_ota_service()->h_ch) {
|
||||
ret = ota_IOT_CoAP_DeviceNameAuth(get_ota_service()->h_ch);
|
||||
if (ret < 0) {
|
||||
OTA_LOG_E("COAP error");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
int ota_coap_deinit(void)
|
||||
{
|
||||
#if (OTA_SIGNAL_CHANNEL) == 2
|
||||
IOT_CoAP_Deinit(get_ota_service()->h_ch);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
173
Living_SDK/framework/uOTA/hal/ota_hal_os.h
Normal file
173
Living_SDK/framework/uOTA/hal/ota_hal_os.h
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef OTA_PLATFORM_OS_H_
|
||||
#define OTA_PLATFORM_OS_H_
|
||||
#include "ota_service.h"
|
||||
|
||||
#define OTA_SSL_TIMEOUT 5000
|
||||
#define ota_snprintf snprintf
|
||||
|
||||
#ifndef false
|
||||
#define false 0
|
||||
#endif
|
||||
|
||||
#ifndef true
|
||||
#define true 1
|
||||
#endif
|
||||
|
||||
#ifndef bool
|
||||
#define bool char
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
|
||||
#define OTA_IMAGE_MD5_LEN (16)
|
||||
#define OTA_IMAGE_RESERVER_SIZE (2)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned int image_magic;
|
||||
unsigned int image_size;
|
||||
unsigned char image_md5_value[OTA_IMAGE_MD5_LEN];
|
||||
unsigned char image_reserver[OTA_IMAGE_RESERVER_SIZE];
|
||||
unsigned short image_crc16;
|
||||
} ota_image_t;
|
||||
|
||||
/*memory*/
|
||||
void *ota_malloc(int size);
|
||||
void *ota_realloc(void *ptr, int size);
|
||||
void *ota_calloc(int n, int size);
|
||||
void ota_free(void *ptr);
|
||||
|
||||
/*Semaphore*/
|
||||
void *ota_semaphore_create(void);
|
||||
int ota_semaphore_wait(void *sem, int ms);
|
||||
void ota_semaphore_post(void *sem);
|
||||
void ota_semaphore_destroy(void *sem);
|
||||
|
||||
/*Thread*/
|
||||
int ota_thread_create(
|
||||
void **thread_handle,
|
||||
void *(*work_routine)(void *),
|
||||
void *arg,
|
||||
void *param,
|
||||
int stack_size);
|
||||
void ota_thread_exit(void *thread);
|
||||
void ota_msleep(int ms);
|
||||
|
||||
/*KV store*/
|
||||
int ota_kv_set(const char *key, const void *val, int len, int sync);
|
||||
int ota_kv_get(const char *key, void *buffer, int *len);
|
||||
|
||||
/*Reboot*/
|
||||
void ota_reboot(void);
|
||||
|
||||
/*Socket API*/
|
||||
void* ota_socket_connect(char *host, int port);
|
||||
int ota_socket_send(void* fd, char *buf, int len);
|
||||
int ota_socket_recv(void* fd, char *buf, int len);
|
||||
void ota_socket_close(void* fd);
|
||||
|
||||
/*SSL*/
|
||||
void* ota_ssl_connect(const char *host, unsigned short port, const char *ca, int len);
|
||||
int ota_ssl_send(void* ssl, char *buf, int len);
|
||||
int ota_ssl_recv(void* ssl, char *buf, int len);
|
||||
|
||||
/*Verify API*/
|
||||
typedef struct
|
||||
{
|
||||
unsigned int total[2];
|
||||
unsigned int state[4];
|
||||
unsigned char buffer[64];
|
||||
}ota_md5_context;
|
||||
typedef struct {
|
||||
unsigned int total[2];
|
||||
unsigned int state[8];
|
||||
unsigned char buffer[64];
|
||||
int is224;
|
||||
}ota_sha256_context;
|
||||
/*SHA256*/
|
||||
void ota_sha256_free(ota_sha256_context *ctx);
|
||||
void ota_sha256_init(ota_sha256_context *ctx);
|
||||
void ota_sha256_starts(ota_sha256_context *ctx, int is224);
|
||||
void ota_sha256_update(ota_sha256_context *ctx, const unsigned char *input, unsigned int ilen);
|
||||
void ota_sha256_finish(ota_sha256_context *ctx, unsigned char output[32]);
|
||||
/*MD5*/
|
||||
void ota_md5_free(ota_md5_context *ctx);
|
||||
void ota_md5_init(ota_md5_context *ctx);
|
||||
void ota_md5_starts(ota_md5_context *ctx);
|
||||
void ota_md5_update(ota_md5_context *ctx, const unsigned char *input, unsigned int ilen);
|
||||
void ota_md5_finish(ota_md5_context *ctx, unsigned char output[16]);
|
||||
/*CRC16*/
|
||||
typedef struct {
|
||||
unsigned short crc;
|
||||
} ota_crc16_ctx;
|
||||
void ota_crc16_init(ota_crc16_ctx *ctx);
|
||||
void ota_crc16_update(ota_crc16_ctx *ctx, const void *inSrc, unsigned int inLen);
|
||||
void ota_crc16_final(ota_crc16_ctx *ctx, unsigned short *outResult);
|
||||
/*Base64*/
|
||||
int ota_base64_decode(const unsigned char *input, int input_len, unsigned char *output, int *output_len);
|
||||
/*RSA*/
|
||||
#define HASH_NONE OTA_HASH_NONE
|
||||
#define SHA256 OTA_SHA256
|
||||
#define MD5 OTA_MD5
|
||||
#define RSASSA_PKCS1_V1_5 OTA_RSASSA_PKCS1_V1_5
|
||||
typedef enum {
|
||||
HASH_NONE = 0,
|
||||
SHA256 = 3,
|
||||
MD5 = 6,
|
||||
} OTA_HASH_E;
|
||||
typedef enum {
|
||||
RSASSA_PKCS1_V1_5 = 20,
|
||||
} ota_rsa_pad_type_t;
|
||||
|
||||
typedef struct{
|
||||
ota_rsa_pad_type_t type;
|
||||
union {
|
||||
struct {
|
||||
OTA_HASH_E type;
|
||||
} rsaes_oaep;
|
||||
struct {
|
||||
OTA_HASH_E type;
|
||||
} rsassa_v1_5;
|
||||
struct {
|
||||
OTA_HASH_E type;
|
||||
unsigned int salt_len;
|
||||
} rsassa_pss;
|
||||
} pad;
|
||||
} ota_rsa_padding_t;
|
||||
|
||||
#define TEE_MIN_RSA_KEY_SIZE (256)
|
||||
#define TEE_MAX_RSA_KEY_SIZE (2048)
|
||||
|
||||
typedef struct{
|
||||
unsigned int magic;
|
||||
unsigned int n_size;
|
||||
unsigned int e_size;
|
||||
unsigned char n[(TEE_MAX_RSA_KEY_SIZE >> 3)];
|
||||
unsigned char e[(TEE_MAX_RSA_KEY_SIZE >> 3)];
|
||||
} ota_rsa_pubkey_t;
|
||||
int ota_rsa_get_pubkey_size(unsigned int keybits, unsigned int *size);
|
||||
int ota_rsa_init_pubkey(unsigned int keybits, const unsigned char *n, unsigned int n_size,
|
||||
const unsigned char *e, unsigned int e_size, ota_rsa_pubkey_t *pubkey);
|
||||
/*MQTT*/
|
||||
int ota_hal_mqtt_publish(char *topic, int qos, void *data, int len);
|
||||
int ota_hal_mqtt_subscribe(char *topic, void* cb, void *ctx);
|
||||
int ota_hal_mqtt_deinit(void);
|
||||
int ota_hal_mqtt_init(void);
|
||||
|
||||
/*COAP*/
|
||||
int ota_coap_send(void *p_context, char *p_path, void *p_message);
|
||||
int ota_coap_send_block(void *p_context, char *p_path, void *p_message,
|
||||
int block_type, int num, int more, int size);
|
||||
int ota_coap_parse_block(void *p_message, int type, int *num,int *more, int *size);
|
||||
int ota_coap_get_payload(void *p_message, const char **pp_payload, int *p_len);
|
||||
int ota_coap_get_code(void *p_message, void *p_resp_code);
|
||||
int ota_coap_init(void);
|
||||
int ota_coap_deinit(void);
|
||||
#endif
|
||||
362
Living_SDK/framework/uOTA/hal/ota_hal_plat.c
Executable file
362
Living_SDK/framework/uOTA/hal/ota_hal_plat.c
Executable file
|
|
@ -0,0 +1,362 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include "aos/kernel.h"
|
||||
#include "aos/kv.h"
|
||||
|
||||
#include "hal/soc/flash.h"
|
||||
|
||||
#include "ota_hal_plat.h"
|
||||
#include "ota_hal_os.h"
|
||||
#include "ota_log.h"
|
||||
|
||||
#if defined (AOS_OTA_RECOVERY_TYPE)
|
||||
#include "rec_define.h"
|
||||
#endif
|
||||
|
||||
#if defined (BOARD_ESP8266)
|
||||
#include "esp_system.h"
|
||||
#include "upgrade.h"
|
||||
#include "esp_wifi.h"
|
||||
#elif defined (STM32L496xx)
|
||||
#define OTA_CACHE_SIZE 2048
|
||||
uint8_t *ota_cache = NULL;
|
||||
uint8_t *ota_cache_actual = NULL;
|
||||
uint32_t ota_cache_len = 0;
|
||||
uint32_t ota_fw_size = 0;
|
||||
uint32_t ota_receive_total_len = 0;
|
||||
#endif
|
||||
|
||||
#define OTA_CRC16 "ota_file_crc16"
|
||||
static int boot_part = HAL_PARTITION_OTA_TEMP;
|
||||
static unsigned int _offset = 0;
|
||||
static ota_crc16_ctx ctx = {0};
|
||||
|
||||
#if defined (SUPPORT_MCU_OTA)
|
||||
char cur_ota_ver[OTA_MAX_VER_LEN] = {0};
|
||||
#endif
|
||||
|
||||
unsigned short ota_get_crc16(void)
|
||||
{
|
||||
int len = 2;
|
||||
unsigned short crc16=0;
|
||||
aos_kv_get(OTA_CRC16, &crc16, &len);
|
||||
return crc16;
|
||||
}
|
||||
|
||||
void ota_set_crc16(unsigned short crc16)
|
||||
{
|
||||
aos_kv_set(OTA_CRC16, &crc16, 2, 1);
|
||||
}
|
||||
|
||||
void ota_reboot_bank(void)
|
||||
{
|
||||
#if defined (BOARD_ESP8266)
|
||||
wifi_set_sleep_type(NONE_SLEEP_T);
|
||||
ota_msleep(300);
|
||||
system_upgrade_init();
|
||||
system_upgrade_flag_set(UPGRADE_FLAG_FINISH);
|
||||
printf("---reboot_system---\n");
|
||||
system_upgrade_reboot();
|
||||
#elif defined (STM32L496xx) || defined (SV6266)
|
||||
extern int flash_sw_bank(void);
|
||||
flash_sw_bank();
|
||||
#endif
|
||||
}
|
||||
|
||||
static int ota_init(void *something)
|
||||
{
|
||||
int ret = 0;
|
||||
ota_boot_param_t *param = (ota_boot_param_t *)something;
|
||||
param->off_bp = 0;
|
||||
hal_flash_dis_secure(0, 0, 0);
|
||||
_offset = param->off_bp;
|
||||
hal_logic_partition_t *part_info = hal_flash_get_info(boot_part);
|
||||
if(part_info->partition_length < param->len || param->len == 0) {
|
||||
ret = OTA_PARAM_FAIL;
|
||||
return ret;
|
||||
}
|
||||
#if defined (STM32L496xx)
|
||||
ota_fw_size = param->len;
|
||||
ota_receive_total_len = _offset;
|
||||
ota_cache = ota_malloc(OTA_CACHE_SIZE + 8);
|
||||
if (ota_cache != NULL) {
|
||||
/*Align with 8 bytes*/
|
||||
ota_cache_actual = (uint8_t *)((uint32_t)ota_cache & ~0x7);
|
||||
}
|
||||
else {
|
||||
ret = OTA_INIT_FAIL;
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
if(param->off_bp == 0) {
|
||||
int ret = 0;
|
||||
ret = hal_flash_erase(boot_part, _offset, part_info->partition_length);
|
||||
if(ret != 0) {
|
||||
ret = OTA_INIT_FAIL;
|
||||
return ret;
|
||||
}
|
||||
ota_crc16_init(&ctx);
|
||||
}
|
||||
else {
|
||||
ctx.crc=ota_get_crc16();
|
||||
}
|
||||
OTA_LOG_I("ota init off:0x%08x part:%d len:%d crc:0x%04x\n",param->off_bp,boot_part,param->len,ctx.crc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ota_write(int* off, char* in_buf ,int in_buf_len)
|
||||
{
|
||||
int ret = 0;
|
||||
#if defined (STM32L496xx)
|
||||
uint32_t tocopy = 0;
|
||||
if(in_buf_len > OTA_CACHE_SIZE) {
|
||||
ret = OTA_UPGRADE_FAIL;
|
||||
return ret;
|
||||
}
|
||||
ota_crc16_update(&ctx, in_buf, in_buf_len);
|
||||
if (in_buf_len <= OTA_CACHE_SIZE - ota_cache_len) {
|
||||
tocopy = in_buf_len;
|
||||
}
|
||||
else {
|
||||
tocopy = OTA_CACHE_SIZE - ota_cache_len;
|
||||
}
|
||||
|
||||
/*Start from last byte of remaing data*/
|
||||
memcpy(ota_cache_actual + ota_cache_len, in_buf, tocopy);
|
||||
ota_cache_len += tocopy;
|
||||
|
||||
if (ota_cache_len == OTA_CACHE_SIZE) {
|
||||
ret = hal_flash_write(HAL_PARTITION_OTA_TEMP, &_offset, ota_cache_actual, OTA_CACHE_SIZE);
|
||||
}
|
||||
|
||||
/*keep remaining data*/
|
||||
if (in_buf_len - tocopy > 0) {
|
||||
/*Now ota_cache only contains remaing data*/
|
||||
memcpy(ota_cache_actual, in_buf + tocopy, in_buf_len - tocopy);
|
||||
ota_cache_len = in_buf_len - tocopy;
|
||||
}
|
||||
|
||||
ota_receive_total_len += in_buf_len;
|
||||
if(ota_receive_total_len == ota_fw_size) {
|
||||
if (ota_cache_len != 0) {
|
||||
int ret = hal_flash_write(HAL_PARTITION_OTA_TEMP, &_offset, ota_cache_actual, ota_cache_len);
|
||||
ota_free(ota_cache);
|
||||
}
|
||||
}
|
||||
#else
|
||||
ota_crc16_update(&ctx, in_buf, in_buf_len);
|
||||
ret = hal_flash_write(boot_part, (uint32_t*)&_offset, in_buf, in_buf_len);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ota_read(int* off, char* out_buf, int out_buf_len)
|
||||
{
|
||||
return hal_flash_read(boot_part, (uint32_t*)off, out_buf, out_buf_len);
|
||||
}
|
||||
|
||||
static int ota_boot(void *something)
|
||||
{
|
||||
int ret = 0;
|
||||
ota_boot_param_t *param = (ota_boot_param_t *)something;
|
||||
if (param == NULL) {
|
||||
ret = OTA_REBOOT_FAIL;
|
||||
return ret;
|
||||
}
|
||||
if (param->res_type == OTA_FINISH) {
|
||||
ota_crc16_final(&ctx, ¶m->crc);
|
||||
if (param->upg_flag == OTA_DIFF) {
|
||||
#if defined (AOS_OTA_RECOVERY_TYPE)
|
||||
int offset = 0x00;
|
||||
int param_part = HAL_PARTITION_PARAMETER_1;
|
||||
PatchStatus ota_param,ota_param_r;
|
||||
memset(&ota_param, 0, sizeof(PatchStatus));
|
||||
ota_param.dst_adr = HAL_PARTITION_APPLICATION;
|
||||
ota_param.src_adr = HAL_PARTITION_OTA_TEMP;
|
||||
ota_param.len = 0;
|
||||
ota_param.crc = param->crc;
|
||||
ota_param.splict_size = param->splict_size;
|
||||
ota_param.rec_size = param->rec_size;
|
||||
ota_param.diff = 1;
|
||||
ota_param.upg_flag = REC_RECOVERY_FLAG;
|
||||
ota_crc16_ctx ctx1;
|
||||
unsigned short crc;
|
||||
ota_crc16_init(&ctx1);
|
||||
ota_crc16_update(&ctx1, &ota_param, sizeof(PatchStatus) - sizeof(unsigned short));
|
||||
ota_crc16_final(&ctx1, &crc);
|
||||
ota_param.patch_crc = crc;
|
||||
offset = 0x00;
|
||||
hal_flash_erase(param_part, offset, sizeof(PatchStatus));
|
||||
offset = 0x00;
|
||||
hal_flash_write(param_part, (uint32_t*)&offset, &ota_param, sizeof(PatchStatus));
|
||||
offset = 0x00;
|
||||
memset(&ota_param_r, 0, sizeof(PatchStatus));
|
||||
hal_flash_read(param_part, (uint32_t*)&offset, &ota_param_r, sizeof(PatchStatus));
|
||||
if(memcmp(&ota_param, &ota_param_r, sizeof(PatchStatus)) != 0) {
|
||||
ret = OTA_REBOOT_FAIL;
|
||||
return ret;
|
||||
}
|
||||
OTA_LOG_I("diff dst:0x%08x src:0x%08x len:0x%08x, crc:0x%04x pcrc:0x%04x splict:%d.\r\n",
|
||||
ota_param_r.dst_adr,ota_param_r.src_adr, ota_param_r.rec_size, ota_param_r.crc,
|
||||
ota_param_r.patch_crc, ota_param_r.splict_size);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
#if defined AOS_OTA_BANK_DUAL
|
||||
int offset = 0x00;
|
||||
ota_crc16_ctx tmp_ctx;
|
||||
unsigned short crc;
|
||||
int param_part = HAL_PARTITION_PARAMETER_1;
|
||||
param->src_adr = 0x00;
|
||||
param->dst_adr = 0x00;
|
||||
#if defined (AOS_OTA_RECOVERY_TYPE)
|
||||
param->upg_flag = REC_DUAL_UPDATE_FLAG;
|
||||
#else
|
||||
param->upg_flag = 0x00;
|
||||
#endif
|
||||
ota_crc16_init(&tmp_ctx);
|
||||
ota_crc16_update(&tmp_ctx, param, sizeof(ota_boot_param_t) - sizeof(unsigned short));
|
||||
ota_crc16_final(&tmp_ctx, &crc);
|
||||
param->param_crc = crc;
|
||||
ota_boot_param_t param_r;
|
||||
offset = 0x00;
|
||||
hal_flash_erase(param_part, offset, sizeof(ota_boot_param_t));
|
||||
offset = 0x00;
|
||||
hal_flash_write(param_part, (uint32_t*)&offset, param, sizeof(ota_boot_param_t));
|
||||
offset = 0x00;
|
||||
memset(¶m_r, 0, sizeof(ota_boot_param_t));
|
||||
hal_flash_read(param_part, (uint32_t*)&offset, ¶m_r, sizeof(ota_boot_param_t));
|
||||
if(memcmp(param, ¶m_r, sizeof(ota_boot_param_t)) != 0) {
|
||||
return -1;
|
||||
}
|
||||
OTA_LOG_I("OTA finish dst:0x%08x src:0x%08x len:0x%08x, crc:0x%04x.\r\n", param_r.dst_adr, param_r.src_adr, param_r.len, param_r.crc);
|
||||
ota_reboot_bank();
|
||||
#else
|
||||
#ifndef SV6266
|
||||
int offset = 0x00;
|
||||
ota_crc16_ctx ctx1;
|
||||
unsigned short crc;
|
||||
int param_part = HAL_PARTITION_PARAMETER_1;
|
||||
#if !defined (RDA5981x) && !defined (RDA5981A)
|
||||
extern int app_download_addr;
|
||||
extern int kernel_download_addr;
|
||||
#endif
|
||||
hal_logic_partition_t *part_info = hal_flash_get_info(boot_part);
|
||||
#ifndef AOS_OTA_2BOOT_UPDATE_SUPPORT
|
||||
#if !defined (RDA5981x) && !defined (RDA5981A)
|
||||
param->src_adr = part_info->partition_start_addr;
|
||||
param->dst_adr = (param->upg_flag == OTA_APP)? (int)&app_download_addr : (int)&kernel_download_addr;
|
||||
#endif
|
||||
#else
|
||||
param->src_adr = 0;
|
||||
param->dst_adr = 0;
|
||||
param->len = 0;
|
||||
param->upg_flag = REC_SWAP_UPDATE_FLAG;
|
||||
#endif
|
||||
ota_crc16_init(&ctx1);
|
||||
ota_crc16_update(&ctx1, param, sizeof(ota_boot_param_t) - sizeof(unsigned short));
|
||||
ota_crc16_final(&ctx1, &crc);
|
||||
param->param_crc = crc;
|
||||
ota_boot_param_t param_r;
|
||||
offset = 0x00;
|
||||
hal_flash_erase(param_part, offset, sizeof(ota_boot_param_t)); //PARTITION_BACKUP_PARAM
|
||||
offset = 0x00;
|
||||
hal_flash_write(param_part, (uint32_t*)&offset, param, sizeof(ota_boot_param_t));
|
||||
offset = 0x00;
|
||||
memset(¶m_r, 0, sizeof(ota_boot_param_t));
|
||||
hal_flash_read(param_part, (uint32_t*)&offset, ¶m_r, sizeof(ota_boot_param_t));
|
||||
if(memcmp(param, ¶m_r, sizeof(ota_boot_param_t)) != 0) {
|
||||
ret = OTA_REBOOT_FAIL;
|
||||
return ret;
|
||||
}
|
||||
OTA_LOG_I("OTA finish dst:0x%08x src:0x%08x len:0x%08x, crc:0x%04x.\r\n", param_r.dst_adr, param_r.src_adr, param_r.len, param_r.crc);
|
||||
#else
|
||||
ota_reboot_bank();
|
||||
OTA_LOG_I("OTA finish, boot para self defined!");
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
ota_msleep(1500);
|
||||
ota_reboot();
|
||||
}
|
||||
else if(param->res_type == OTA_BREAKPOINT) {
|
||||
OTA_LOG_I("save bp crc:0x%04x", ctx.crc);
|
||||
#if defined (STM32L496xx)
|
||||
if (ota_cache_len != 0) {
|
||||
int ret = hal_flash_write(HAL_PARTITION_OTA_TEMP, &_offset, ota_cache_actual, ota_cache_len);
|
||||
ota_free(ota_cache);
|
||||
}
|
||||
#endif
|
||||
ota_set_crc16(ctx.crc);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ota_rollback(void *something)
|
||||
{
|
||||
int offset = 0x00;
|
||||
int param_part = HAL_PARTITION_PARAMETER_1;
|
||||
ota_boot_param_t param_w, param_r;
|
||||
memset(¶m_w, 0, sizeof(ota_boot_param_t));
|
||||
hal_flash_read(param_part, (uint32_t*)&offset, ¶m_w, sizeof(ota_boot_param_t));
|
||||
if((param_w.boot_count != 0) && (param_w.boot_count != 0xff)) {
|
||||
ota_crc16_ctx ctx1;
|
||||
unsigned short crc;
|
||||
param_w.upg_flag = 0;
|
||||
param_w.boot_count = 0; /*Clear bootcount to avoid rollback*/
|
||||
ota_crc16_init(&ctx1);
|
||||
ota_crc16_update(&ctx1, ¶m_w, sizeof(ota_boot_param_t) - sizeof(unsigned short));
|
||||
ota_crc16_final(&ctx1, &crc);
|
||||
param_w.param_crc = crc;
|
||||
offset = 0x00;
|
||||
hal_flash_erase(param_part, offset, sizeof(ota_boot_param_t));
|
||||
offset = 0x00;
|
||||
hal_flash_write(param_part, (uint32_t*)&offset, ¶m_w, sizeof(ota_boot_param_t));
|
||||
offset = 0x00;
|
||||
memset(¶m_r, 0, sizeof(ota_boot_param_t));
|
||||
hal_flash_read(param_part, (uint32_t*)&offset, ¶m_r, sizeof(ota_boot_param_t));
|
||||
if(memcmp(¶m_w, ¶m_r, sizeof(ota_boot_param_t)) != 0) {
|
||||
OTA_LOG_E("rollback failed\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *aos_get_app_version(void);
|
||||
static const char *ota_get_version(unsigned char dev_type)
|
||||
{
|
||||
if(dev_type) {
|
||||
return "v1.0.0-20180101-1000";//SYSINFO_APP_VERSION;
|
||||
} else {
|
||||
#if defined (SUPPORT_MCU_OTA)
|
||||
char mcu_ver[16] = {0};
|
||||
int len = sizeof(mcu_ver);
|
||||
aos_kv_get("mcu_version", mcu_ver, &len);
|
||||
if (0 == strlen(mcu_ver)) {
|
||||
strcpy((char *)mcu_ver, "mcu-1.0.0");
|
||||
OTA_LOG_I("use default MCU version:%s", mcu_ver);
|
||||
}
|
||||
memset(cur_ota_ver, 0, OTA_MAX_VER_LEN);
|
||||
snprintf(cur_ota_ver, OTA_MAX_VER_LEN, "%s-%s", mcu_ver, aos_get_app_version());
|
||||
OTA_LOG_I("current ota version:%s", cur_ota_ver);
|
||||
return (const char *)cur_ota_ver;
|
||||
#else
|
||||
return aos_get_app_version();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
ota_hal_module_t ota_hal_module = {
|
||||
.init = ota_init,
|
||||
.write = ota_write,
|
||||
.read = ota_read,
|
||||
.boot = ota_boot,
|
||||
.rollback = ota_rollback,
|
||||
.version = ota_get_version,
|
||||
};
|
||||
120
Living_SDK/framework/uOTA/hal/ota_hal_plat.h
Normal file
120
Living_SDK/framework/uOTA/hal/ota_hal_plat.h
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
|
||||
*/
|
||||
|
||||
#ifndef HAL_OTA_H
|
||||
#define HAL_OTA_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
OTA_RAW = 0,
|
||||
OTA_DIFF = 1,
|
||||
OTA_KERNEL = 2,
|
||||
OTA_APP = 4,
|
||||
} OTA_UPD_TYPE_E;
|
||||
|
||||
typedef enum {
|
||||
OTA_FINISH,
|
||||
OTA_BREAKPOINT
|
||||
} OTA_RES_TYPE_E;
|
||||
|
||||
typedef struct {
|
||||
unsigned int dst_adr;
|
||||
unsigned int src_adr;
|
||||
unsigned int len;
|
||||
unsigned short crc;
|
||||
unsigned int upg_flag;
|
||||
unsigned char boot_count;
|
||||
unsigned int splict_size;
|
||||
int off_bp; /*Break point offset*/
|
||||
OTA_RES_TYPE_E res_type; /*result type: OTA_FINISH, OTA_BREAKPOINT*/
|
||||
unsigned short param_crc; /*Parameter crc*/
|
||||
} __attribute__((packed)) ota_boot_param_t;
|
||||
|
||||
typedef struct ota_hal_module_s {
|
||||
int (*init)(void *something);
|
||||
int (*write)(int *off_set, char *in_buf , int in_buf_len);
|
||||
int (*read)(int *off_set, char *out_buf , int out_buf_len);
|
||||
int (*boot)(void *something);
|
||||
int (*rollback)(void *something);
|
||||
const char *(*version)(unsigned char dev_type);
|
||||
}ota_hal_module_t;
|
||||
|
||||
/**
|
||||
* Arch register a new module before HAL startup
|
||||
*/
|
||||
void ota_hal_register_module(ota_hal_module_t *module);
|
||||
|
||||
/**
|
||||
* init ota partition
|
||||
*
|
||||
* @note when ota start, maybe it need init something
|
||||
* @param something extra info for ota init
|
||||
*
|
||||
* @return 0 : On success, 1 : If an error occurred with any step
|
||||
*/
|
||||
int ota_hal_init(void *something);
|
||||
|
||||
/**
|
||||
* Write data to an area on ota partition
|
||||
*
|
||||
* @param off_set Point to the start address that the data is written to, and
|
||||
* point to the last unwritten address after this function is
|
||||
* returned, so you can call this function serval times without
|
||||
* update this start address.
|
||||
* @param inbuf point to the data buffer that will be written to flash
|
||||
* @param in_buf_len The length of the buffer
|
||||
*
|
||||
* @return 0 : On success, 1 : If an error occurred with any step
|
||||
*/
|
||||
int ota_hal_write(int *off_set,char *in_buf , int in_buf_len);
|
||||
|
||||
/**
|
||||
* Read data from an area on ota Flash to data buffer in RAM
|
||||
*
|
||||
* @param off_set Point to the start address that the data is read, and
|
||||
* point to the last unread address after this function is
|
||||
* returned, so you can call this function serval times without
|
||||
* update this start address.
|
||||
* @param out_buf Point to the data buffer that stores the data read from flash
|
||||
* @param out_buf_len The length of the buffer
|
||||
*
|
||||
* @return 0 : On success, 1 : If an error occurred with any step
|
||||
*/
|
||||
int ota_hal_read(int *off_set,char *out_buf, int out_buf_len);
|
||||
|
||||
/**
|
||||
* Set boot options when ota reboot
|
||||
*
|
||||
* @param something boot parms
|
||||
*
|
||||
* @return kNoErr : On success. kGeneralErr : If an error occurred with any step
|
||||
*/
|
||||
int ota_hal_boot(void *something);
|
||||
|
||||
/**
|
||||
* Set rollback when failed to boot
|
||||
*
|
||||
* @param something
|
||||
*
|
||||
* @return kNoErr : On success. kGeneralErr : If an error occurred with any step
|
||||
*/
|
||||
int ota_hal_rollback(void *something);
|
||||
|
||||
|
||||
/**
|
||||
* get system version
|
||||
*
|
||||
* @param device type
|
||||
*
|
||||
* @return version
|
||||
*/
|
||||
const char *ota_hal_get_version(unsigned char dev_type);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* HAL_OTA_H */
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue