487 lines
15 KiB
C
487 lines
15 KiB
C
/****************************************************************************
|
|
|
|
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
|
|
|
|
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
|
|
be copied by any method or incorporated into another program without
|
|
the express written consent of Aerospace C.Power. This Information or any portion
|
|
thereof remains the property of Aerospace C.Power. The Information contained herein
|
|
is believed to be accurate and Aerospace C.Power assumes no responsibility or
|
|
liability for its use in any way and conveys no license or title under
|
|
any patent or copyright and makes no representation or warranty that this
|
|
Information is free from patent or copyright infringement.
|
|
|
|
****************************************************************************/
|
|
/* iot common header files */
|
|
#include "iot_io_api.h"
|
|
#include "iot_plc_cco_api.h"
|
|
#include "iot_module_api.h"
|
|
#include "iot_errno_api.h"
|
|
#include "iot_dbglog_api.h"
|
|
#include "iot_task_api.h"
|
|
#include "iot_plc_msg_api.h"
|
|
#include "iot_version_api.h"
|
|
#include "iot_oem_api.h"
|
|
#include "iot_board_api.h"
|
|
|
|
/* smart grid internal header files */
|
|
#include "iot_sg_fr.h"
|
|
#include "iot_sg.h"
|
|
#include "iot_sg_msg.h"
|
|
#include "iot_sg_sta_ext_upgrade.h"
|
|
#include "iot_sg_sta_upgrade.h"
|
|
#include "iot_upgrade_api.h"
|
|
#include "iot_crc_api.h"
|
|
|
|
#if (IOT_SG_STA_UPGRADE_EXT_DEV_ENABLE)
|
|
|
|
/* upgrade timer time out function */
|
|
void iot_sg_sta_ext_dev_upgrade_func(timer_id_t timer_id, void *arg)
|
|
{
|
|
(void)timer_id;
|
|
(void)arg;
|
|
iot_sg_msg_t *msg;
|
|
|
|
msg = (iot_sg_msg_t *)iot_task_alloc_msg(p_sg_glb->task_h);
|
|
if (msg) {
|
|
msg->task_msg.type = IOT_SG_MSG_TYPE_TIMER;
|
|
msg->task_msg.id = IOT_SG_MSG_ID_TIMER_EXT_DEV_UPGRADE;
|
|
iot_task_queue_msg(p_sg_glb->task_h, &msg->task_msg,
|
|
IOT_SG_MSG_QUEUE_LP);
|
|
} else {
|
|
IOT_ASSERT(0);
|
|
}
|
|
}
|
|
|
|
static void iot_sg_sta_start_ext_dev_upgrade_timer(uint32_t duration)
|
|
{
|
|
iot_sg_sta_upgrade_info_t *upgrade_info = &p_sg_glb->desc.sta->upgrade_info;
|
|
|
|
os_stop_timer(upgrade_info->ext_dev_upgrade_timer);
|
|
iot_task_clean_msg(p_sg_glb->task_h, IOT_SG_MSG_TYPE_TIMER,
|
|
IOT_SG_MSG_ID_TIMER_EXT_DEV_UPGRADE);
|
|
os_start_timer(upgrade_info->ext_dev_upgrade_timer, duration);
|
|
}
|
|
|
|
static void iot_sg_sta_stop_ext_dev_upgrade_timer()
|
|
{
|
|
iot_sg_sta_upgrade_info_t *upgrade_info = &p_sg_glb->desc.sta->upgrade_info;
|
|
|
|
os_stop_timer(upgrade_info->ext_dev_upgrade_timer);
|
|
iot_task_clean_msg(p_sg_glb->task_h, IOT_SG_MSG_TYPE_TIMER,
|
|
IOT_SG_MSG_ID_TIMER_EXT_DEV_UPGRADE);
|
|
}
|
|
|
|
static void iot_sg_sta_ext_dev_upgrade_goto_state(uint8_t new_state)
|
|
{
|
|
iot_sg_sta_upgrade_info_t *upgrade_info = &p_sg_glb->desc.sta->upgrade_info;
|
|
uint8_t pre_state = upgrade_info->ext_dev_state;
|
|
|
|
if (pre_state != new_state) {
|
|
iot_sg_printf("sg_ext_upgrade: state from %d to %d.\n", pre_state,
|
|
new_state);
|
|
upgrade_info->ext_dev_state = new_state;
|
|
iot_dbglog_input(IOT_SMART_GRID_MID, DBGLOG_ERR,
|
|
IOT_SG_STA_EXT_UPGRADE_DBG_ID, 2, 1, new_state);
|
|
}
|
|
}
|
|
|
|
void iot_sg_ext_dev_reset_upgrade_info()
|
|
{
|
|
iot_sg_sta_upgrade_info_t *upgrade_info = &p_sg_glb->desc.sta->upgrade_info;
|
|
|
|
upgrade_info->ext_dev_start_offset = 0;
|
|
upgrade_info->ext_dev_send_len = 0;
|
|
upgrade_info->ext_dev_file_size = 0;
|
|
upgrade_info->ext_dev_upgrade_block_index = 0;
|
|
upgrade_info->ext_dev_file_crc = 0;
|
|
upgrade_info->ext_dev_upgrade_retry_cnt = 0;
|
|
upgrade_info->ext_dev_restart_flag = 0;
|
|
iot_sg_sta_ext_dev_upgrade_goto_state(IOT_SG_STA_EXT_DEV_UPGRADE_IDLE);
|
|
iot_sg_sta_stop_ext_dev_upgrade_timer();
|
|
}
|
|
|
|
static void iot_sg_sta_ext_upgrade_save_to_flash()
|
|
{
|
|
iot_sg_sta_upgrade_info_t *upgrade_info = &p_sg_glb->desc.sta->upgrade_info;
|
|
|
|
iot_sg_printf("%s current part:%d\n", __FUNCTION__,
|
|
upgrade_info->current_part);
|
|
|
|
upgrade_info->current_crc = upgrade_info->file_crc;
|
|
iot_upgrade_save_fw_crc(upgrade_info->current_part, upgrade_info->file_crc);
|
|
}
|
|
|
|
static void iot_sg_sta_ext_upgrade_finish(uint8_t complete)
|
|
{
|
|
iot_sg_sta_upgrade_info_t *upgrade_info = &p_sg_glb->desc.sta->upgrade_info;
|
|
|
|
if (complete) {
|
|
iot_sg_sta_ext_upgrade_save_to_flash();
|
|
} else {
|
|
if (!upgrade_info->ext_dev_restart_flag) {
|
|
upgrade_info->ext_dev_restart_flag = 1;
|
|
upgrade_info->ext_dev_last_send_len = 0;
|
|
upgrade_info->ext_dev_send_len = 0;
|
|
upgrade_info->ext_dev_upgrade_block_index = 0;
|
|
upgrade_info->ext_dev_upgrade_retry_cnt = 0;
|
|
|
|
iot_sg_sta_ext_dev_upgrade_goto_state(
|
|
IOT_SG_STA_EXT_DEV_UPGRADE_START);
|
|
iot_sg_sta_start_ext_dev_upgrade_timer(
|
|
IOT_SG_STA_EXT_DEV_UPGRADE_TIMER_INTERVAL);
|
|
return;
|
|
}
|
|
}
|
|
|
|
upgrade_info->ext_dev_need_upgrade_flag = 0;
|
|
iot_sg_sta_upgrade_clear(upgrade_info->upgrade_id, 0);
|
|
return;
|
|
}
|
|
|
|
static uint32_t iot_sg_sta_ext_upgrade_send_exe()
|
|
{
|
|
iot_pkt_t *pkt = NULL;
|
|
uint8_t sta_addr[IOT_MAC_ADDR_LEN];
|
|
iot_time_tm_t time;
|
|
uint32_t ret;
|
|
|
|
time.tm_year = 0xffff;
|
|
time.tm_mon = 0xff;
|
|
time.tm_mday = 0xff;
|
|
time.tm_hour = 0xff;
|
|
time.tm_min = 0xff;
|
|
time.tm_sec = 0xff;
|
|
p_sg_glb->desc.sta->drv->get_login_addr(sta_addr);
|
|
pkt = proto_69845_build_file_exe_msg(&time, sta_addr);
|
|
if (pkt == NULL) {
|
|
IOT_ASSERT(0);
|
|
}
|
|
|
|
ret = iot_sg_sta_add_mr_req(IOT_SG_STA_MR_SRC_ID_EXT_UPGRADE, sta_addr, 0,
|
|
IOT_SG_STA_DATA_TYPE_69845, iot_pkt_data(pkt),
|
|
(uint16_t)iot_pkt_data_len(pkt), IOT_SG_STA_EXT_DEV_UPGRADE_CMD_TIMEOUT);
|
|
iot_pkt_free(pkt);
|
|
if (ret) {
|
|
return IOT_SG_STA_EXT_DEV_UPGRADE_RESULT_FAIL;
|
|
}
|
|
return IOT_SG_STA_EXT_DEV_UPGRADE_RESULT_OK;
|
|
}
|
|
|
|
static uint8_t iot_sg_sta_ext_upgrade_check_send_complete()
|
|
{
|
|
iot_sg_sta_upgrade_info_t *p_info = &p_sg_glb->desc.sta->upgrade_info;
|
|
|
|
if (p_info->ext_dev_send_len >= p_info->ext_dev_file_size) {
|
|
return IOT_SG_STA_EXT_DEV_UPGRADE_RESULT_COMPLETE;
|
|
}
|
|
return IOT_SG_STA_EXT_DEV_UPGRADE_RESULT_FAIL;
|
|
}
|
|
|
|
static uint32_t iot_sg_sta_ext_upgrade_send_data()
|
|
{
|
|
iot_sg_sta_upgrade_info_t *p_info = &p_sg_glb->desc.sta->upgrade_info;
|
|
iot_pkt_t *pkt = NULL;
|
|
iot_pkt_t *data_pkt = NULL;
|
|
uint8_t sta_addr[IOT_MAC_ADDR_LEN];
|
|
uint32_t read_len;
|
|
uint32_t offset;
|
|
uint32_t ret = ERR_OK;
|
|
|
|
data_pkt = iot_pkt_alloc(IOT_SG_STA_EXT_DEV_UPGRADE_BLOCK_SIZE,
|
|
IOT_SMART_GRID_MID);
|
|
if (data_pkt == NULL) {
|
|
IOT_ASSERT(0);
|
|
}
|
|
|
|
offset = p_info->ext_dev_start_offset + p_info->ext_dev_send_len;
|
|
read_len = min(p_info->ext_dev_file_size - p_info->ext_dev_send_len,
|
|
IOT_SG_STA_EXT_DEV_UPGRADE_BLOCK_SIZE);
|
|
iot_pkg_upgrade_read(iot_pkt_data(data_pkt), read_len, offset,
|
|
UPGRADE_DATA_TYPE_FW, 1);
|
|
|
|
p_sg_glb->desc.sta->drv->get_login_addr(sta_addr);
|
|
pkt = proto_69845_build_file_data_msg(iot_pkt_data(data_pkt),
|
|
(uint16_t)read_len, p_info->ext_dev_upgrade_block_index, sta_addr);
|
|
if (pkt == NULL) {
|
|
IOT_ASSERT(0);
|
|
}
|
|
iot_pkt_free(data_pkt);
|
|
|
|
iot_sg_printf("sg ext upgrade send index:%d send len:%d\n",
|
|
p_info->ext_dev_upgrade_block_index, read_len);
|
|
ret = iot_sg_sta_add_mr_req(IOT_SG_STA_MR_SRC_ID_EXT_UPGRADE, sta_addr, 0,
|
|
IOT_SG_STA_DATA_TYPE_69845, iot_pkt_data(pkt),
|
|
(uint16_t)iot_pkt_data_len(pkt), IOT_SG_STA_EXT_DEV_UPGRADE_CMD_TIMEOUT);
|
|
iot_pkt_free(pkt);
|
|
p_info->ext_dev_last_send_len = read_len;
|
|
if (ret) {
|
|
return IOT_SG_STA_EXT_DEV_UPGRADE_RESULT_FAIL;
|
|
}
|
|
return IOT_SG_STA_EXT_DEV_UPGRADE_RESULT_OK;
|
|
}
|
|
|
|
static uint32_t iot_sg_sta_ext_upgrade_send_start()
|
|
{
|
|
iot_sg_sta_upgrade_info_t *p_info = &p_sg_glb->desc.sta->upgrade_info;
|
|
iot_pkt_t *pkt = NULL;
|
|
uint8_t sta_addr[IOT_MAC_ADDR_LEN];
|
|
uint16_t cmpt_hw_ver = 0;
|
|
uint16_t cmpt_sw_ver = 0;
|
|
uint32_t ret;
|
|
|
|
p_sg_glb->desc.sta->drv->get_login_addr(sta_addr);
|
|
pkt = proto_69845_build_file_info_msg(p_info->ext_dev_file_size,
|
|
p_info->ext_dev_file_crc & 0xFFFF,
|
|
IOT_SG_STA_EXT_DEV_UPGRADE_BLOCK_SIZE, cmpt_hw_ver, cmpt_sw_ver,
|
|
p_info->upgrade_id, sta_addr);
|
|
if (pkt == NULL) {
|
|
IOT_ASSERT(0);
|
|
}
|
|
|
|
ret = iot_sg_sta_add_mr_req(IOT_SG_STA_MR_SRC_ID_EXT_UPGRADE, sta_addr, 0,
|
|
IOT_SG_STA_DATA_TYPE_69845, iot_pkt_data(pkt),
|
|
(uint16_t)iot_pkt_data_len(pkt), IOT_SG_STA_EXT_DEV_UPGRADE_CMD_TIMEOUT);
|
|
iot_pkt_free(pkt);
|
|
if (ret) {
|
|
return IOT_SG_STA_EXT_DEV_UPGRADE_RESULT_FAIL;
|
|
}
|
|
return IOT_SG_STA_EXT_DEV_UPGRADE_RESULT_OK;
|
|
}
|
|
|
|
static uint32_t iot_sg_sta_ext_upgrade_get_file_info()
|
|
{
|
|
iot_sg_sta_upgrade_info_t *p_info = &p_sg_glb->desc.sta->upgrade_info;
|
|
iot_upg_ext_file_info_rst ext_rst = { 0 };
|
|
uint32_t ret = ERR_FAIL;
|
|
|
|
ret = iot_upgrade_get_ext_file_info(&ext_rst);
|
|
if (ret) {
|
|
iot_sg_printf("sg ext upgrade: get external upgrade file info fail\n");
|
|
return ret;
|
|
}
|
|
|
|
p_info->ext_dev_start_offset = ext_rst.offset;
|
|
p_info->ext_dev_file_size = ext_rst.file_size;
|
|
p_info->ext_dev_file_crc = ext_rst.file_crc;
|
|
return ret;
|
|
}
|
|
|
|
static uint32_t iot_sg_sta_ext_upgrade_check_crc()
|
|
{
|
|
iot_sg_sta_upgrade_info_t *p_info = &p_sg_glb->desc.sta->upgrade_info;
|
|
uint16_t cacl_crc = 0xFFFF;
|
|
uint16_t hrd_crc = p_info->ext_dev_file_crc & 0xFFFF;
|
|
uint32_t crc_size = p_info->ext_dev_file_size;
|
|
uint32_t offset;
|
|
uint32_t calc_len = 0;
|
|
uint32_t read_len = 0;
|
|
uint8_t buffer[64] = {0};
|
|
|
|
while (calc_len < crc_size) {
|
|
offset = p_info->ext_dev_start_offset + calc_len;
|
|
read_len = min(64, crc_size - calc_len);
|
|
iot_pkg_upgrade_read(buffer, read_len, offset, UPGRADE_DATA_TYPE_FW, 1);
|
|
cacl_crc = iot_getcrc16_update(cacl_crc, buffer, read_len, 0);
|
|
calc_len += read_len;
|
|
}
|
|
cacl_crc = cacl_crc ^ 0xFFFF;
|
|
if (cacl_crc != hrd_crc) {
|
|
iot_sg_printf("%s crc check error, cacl_crc %x hrd_crc %x\n",
|
|
__FUNCTION__, cacl_crc, hrd_crc);
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
return ERR_OK;
|
|
}
|
|
|
|
void iot_sg_sta_ext_upgrade_pre_process()
|
|
{
|
|
iot_sg_sta_upgrade_info_t *p_info = &p_sg_glb->desc.sta->upgrade_info;
|
|
uint32_t reason = 0;
|
|
|
|
iot_sg_printf("sg ext upgrade: start upgrade extern dev\n");
|
|
|
|
if (p_info->ext_dev_state != IOT_SG_STA_EXT_DEV_UPGRADE_IDLE) {
|
|
iot_sg_printf("sg ext upgrade: external upgrade has been started\n");
|
|
return;
|
|
}
|
|
|
|
p_info->ext_dev_send_len = 0;
|
|
if (iot_sg_sta_ext_upgrade_get_file_info() != ERR_OK) {
|
|
reason = 1;
|
|
goto exit;
|
|
}
|
|
|
|
if (iot_sg_sta_ext_upgrade_check_crc() != ERR_OK) {
|
|
reason = 2;
|
|
goto exit;
|
|
}
|
|
|
|
iot_sg_sta_ext_dev_upgrade_goto_state(IOT_SG_STA_EXT_DEV_UPGRADE_START);
|
|
iot_sg_sta_start_ext_dev_upgrade_timer(
|
|
IOT_SG_STA_EXT_DEV_UPGRADE_TIMER_INTERVAL);
|
|
exit:
|
|
iot_sg_printf("%s reason:%d\n", __FUNCTION__, reason);
|
|
|
|
if (reason) {
|
|
iot_sg_sta_upgrade_clear(p_info->upgrade_id, 0);
|
|
}
|
|
return;
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief: timer handler for upgrading
|
|
*/
|
|
void iot_sg_sta_ext_dev_upgrade_timer_handle()
|
|
{
|
|
uint32_t ext_ret = IOT_SG_STA_EXT_DEV_UPGRADE_RESULT_OK;
|
|
iot_sg_sta_upgrade_info_t *p_info = &p_sg_glb->desc.sta->upgrade_info;
|
|
iot_sg_printf("sg_ext_upgrade: sta external upgrade timer. state = %d\n",
|
|
p_info->ext_dev_state);
|
|
switch (p_info->ext_dev_state) {
|
|
case IOT_SG_STA_EXT_DEV_UPGRADE_START:
|
|
{
|
|
ext_ret = iot_sg_sta_ext_upgrade_send_start();
|
|
}
|
|
break;
|
|
case IOT_SG_STA_EXT_DEV_UPGRADE_SEND:
|
|
{
|
|
ext_ret = iot_sg_sta_ext_upgrade_send_data();
|
|
}
|
|
break;
|
|
case IOT_SG_STA_EXT_DEV_UPGRADE_EXE:
|
|
{
|
|
ext_ret = iot_sg_sta_ext_upgrade_send_exe();
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (ext_ret == IOT_SG_STA_EXT_DEV_UPGRADE_RESULT_FAIL) {
|
|
if (p_info->ext_dev_upgrade_retry_cnt >
|
|
IOT_SG_STA_EXT_DEV_UPGRADE_RETRY_MAX) {
|
|
iot_sg_sta_ext_upgrade_finish(0);
|
|
} else {
|
|
p_info->ext_dev_upgrade_retry_cnt++;
|
|
iot_sg_sta_start_ext_dev_upgrade_timer(
|
|
IOT_SG_STA_EXT_DEV_UPGRADE_RETRY_INTERVAL);
|
|
}
|
|
}
|
|
}
|
|
|
|
void iot_sg_sta_upgrade_ext_handle(uint16_t seq, uint8_t data_type,
|
|
uint8_t *resp_data, uint16_t resp_len, uint8_t *req_data, uint16_t req_len)
|
|
{
|
|
(void)seq;
|
|
(void)req_data;
|
|
(void)req_len;
|
|
uint32_t ret = ERR_OK;
|
|
uint8_t start_timer = 1;
|
|
iot_sg_sta_upgrade_info_t *p_info = &p_sg_glb->desc.sta->upgrade_info;
|
|
|
|
if (data_type != IOT_SG_STA_DATA_TYPE_69845) {
|
|
iot_sg_printf("%s invalid response data\n", __FUNCTION__);
|
|
goto out;
|
|
}
|
|
|
|
if (!resp_data) {
|
|
iot_sg_printf("%s response timeout\n", __FUNCTION__);
|
|
goto out;
|
|
}
|
|
|
|
switch (p_info->ext_dev_state) {
|
|
case IOT_SG_STA_EXT_DEV_UPGRADE_START:
|
|
{
|
|
ret = proto_69845_handle_file_info_rsp(resp_data, resp_len);
|
|
if (ret == ERR_OK) {
|
|
iot_sg_sta_ext_dev_upgrade_goto_state(
|
|
IOT_SG_STA_EXT_DEV_UPGRADE_SEND);
|
|
} else {
|
|
iot_sg_sta_ext_upgrade_finish(0);
|
|
start_timer = 0;
|
|
}
|
|
}
|
|
break;
|
|
case IOT_SG_STA_EXT_DEV_UPGRADE_SEND:
|
|
{
|
|
ret = proto_69845_handle_file_data_rsp(resp_data, resp_len);
|
|
if (ret == ERR_OK) {
|
|
p_info->ext_dev_send_len += p_info->ext_dev_last_send_len;
|
|
if (iot_sg_sta_ext_upgrade_check_send_complete() ==
|
|
IOT_SG_STA_EXT_DEV_UPGRADE_RESULT_COMPLETE) {
|
|
iot_sg_sta_ext_dev_upgrade_goto_state(
|
|
IOT_SG_STA_EXT_DEV_UPGRADE_EXE);
|
|
} else {
|
|
p_info->ext_dev_upgrade_block_index++;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case IOT_SG_STA_EXT_DEV_UPGRADE_EXE:
|
|
{
|
|
ret = proto_69845_handle_file_exe_rsp(resp_data, resp_len);
|
|
if (ret == ERR_OK) {
|
|
iot_sg_sta_ext_upgrade_finish(1);
|
|
start_timer = 0;
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (ret) {
|
|
if (p_info->ext_dev_upgrade_retry_cnt >
|
|
IOT_SG_STA_EXT_DEV_UPGRADE_RETRY_MAX) {
|
|
iot_sg_sta_ext_upgrade_finish(0);
|
|
start_timer = 0;
|
|
} else {
|
|
p_info->ext_dev_upgrade_retry_cnt++;
|
|
}
|
|
} else {
|
|
p_info->ext_dev_upgrade_retry_cnt = 0;
|
|
}
|
|
out:
|
|
if (start_timer) {
|
|
iot_sg_sta_start_ext_dev_upgrade_timer(
|
|
IOT_SG_STA_EXT_DEV_UPGRADE_TIMER_INTERVAL);
|
|
}
|
|
}
|
|
|
|
#else /* IOT_SG_STA_UPGRADE_EXT_DEV_ENABLE */
|
|
|
|
void iot_sg_ext_dev_reset_upgrade_info()
|
|
{
|
|
|
|
}
|
|
|
|
void iot_sg_ext_dev_upgrade_init()
|
|
{
|
|
|
|
}
|
|
|
|
void iot_sg_sta_ext_upgrade_pre_process()
|
|
{
|
|
|
|
}
|
|
|
|
void iot_sg_sta_upgrade_ext_handle(uint16_t seq, uint8_t data_type,
|
|
uint8_t *resp_data, uint16_t resp_len, uint8_t *req_data, uint16_t req_len)
|
|
{
|
|
(void)seq;
|
|
(void)data_type;
|
|
(void)resp_data;
|
|
(void)resp_len;
|
|
(void)req_data;
|
|
(void)req_len;
|
|
}
|
|
|
|
void iot_sg_sta_ext_dev_upgrade_timer_handle()
|
|
{
|
|
|
|
}
|
|
|
|
#endif /* IOT_SG_STA_UPGRADE_EXT_DEV_ENABLE */ |