Files
kunlun/cli/host_interface/plc/iot_cli_sta_upgrade.c
2024-09-28 14:24:04 +08:00

821 lines
28 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.
****************************************************************************/
#include "iot_cli_plc_module.h"
#include "iot_cli_host_upgrade_internal.h"
#include "iot_cli_plc_tx_rx.h"
extern iot_plc_upgrade_info_t *upgrade_info;
extern iot_plc_host_config_t *host_config;
#if IOT_CLI_UPGRADE_ENABLE
/* sta request data from cco */
void cli_remote_upgrade_sta_send_request_data(bool_t phase3)
{
uint8_t *dst_mac;
if ((cli_remote_upgrade_get_next_block(UPGRADE_DATA_TYPE_PIB, 0)) &&
(upgrade_info->control_upgrade_flag == 0)) {
uint8_t send_type = IOT_PLC_MSG_TYPE_UNICAST_TO_PCO;
iot_plc_upgrade_remote_data_req_ul_t req;
uint16_t written_blocks =
(uint16_t)iot_upgrade_query_written_block_num();
req.file_type = upgrade_info->current_file_type;
req.progress = (uint8_t)(written_blocks * 100 /
(upgrade_info->fw_blocks + upgrade_info->pib_blocks));
if (req.progress > (upgrade_info->reported_percentage +
IOT_PLC_UPGRADE_PROGRESS_REPORT_INTERVAL)) {
upgrade_info->reported_percentage = req.progress;
} else {
req.progress = 0;
}
req.req_block_cnt = upgrade_info->remote_block_cnt;
if (UPGRADE_REMOTE_BLOCK_MAX_NUM < req.req_block_cnt) {
req.req_block_cnt = UPGRADE_REMOTE_BLOCK_MAX_NUM;
}
if ((UPGRADE_DATA_TYPE_FW == req.file_type) &&
((upgrade_info->block_idx + req.req_block_cnt) >
upgrade_info->fw_blocks)) {
req.req_block_cnt =
upgrade_info->fw_blocks - upgrade_info->block_idx;
}
else if ((UPGRADE_DATA_TYPE_PIB == req.file_type) &&
((upgrade_info->block_idx + req.req_block_cnt) >
upgrade_info->pib_blocks)) {
req.req_block_cnt =
upgrade_info->pib_blocks - upgrade_info->block_idx;
}
for (uint16_t i = 0; i < req.req_block_cnt; i++) {
req.block_idx_array[i] = upgrade_info->block_idx + i;
iot_printf("plc_upgrade:sta request, file"
" type:%d, index:%d, cnt:%d, written blocks:%d\n",
req.file_type, req.block_idx_array[i], req.req_block_cnt,
written_blocks);
}
iot_mac_addr_cpy(req.dst, host_config->mac_addr);
req.upgrade_id = upgrade_info->upgrade_id;
req.phase3 = 0;
if (phase3) {
req.phase3 = 1;
send_type = IOT_PLC_MSG_TYPE_UNICAST;
}
if (IOT_PLC_UPGRADE_STA_LIST == upgrade_info->upgrade_type) {
send_type = IOT_PLC_MSG_TYPE_UNICAST;
}
if (send_type == IOT_PLC_MSG_TYPE_UNICAST_TO_PCO) {
dst_mac = (uint8_t *)bcast_mac;
} else {
dst_mac = host_config->cco_mac;
}
iot_cli_host_send_data_plc(send_type,
CLI_MSGID_REMOTE_UPGRADE_DATA_REQUEST,
dst_mac, (uint8_t*)&req, sizeof(req));
} else {
//finished wait for crc check
iot_printf("plc_upgrade:fw file transferred, wait for crc check\n");
}
}
/* sta complete remote upgrade */
void cli_remote_upgrade_sta_complete()
{
upgrade_info->upgrade_state = IOT_PLC_UPGRADE_INIT;
cli_upgrade_reset_timer(0, 0);
}
/* sta stop remote upgrade */
void cli_remote_upgrade_sta_stop()
{
iot_upgrade_cancel_commit(upgrade_info->src.id);
cli_remote_upgrade_sta_complete();
}
/* stat send start ack to cco */
void cli_upgrade_sta_send_start_ack(uint8_t send_type, uint8_t error_code)
{
iot_plc_upgrade_start_ul_t ack;
ack.result = error_code;
iot_mac_addr_cpy(ack.dst, host_config->mac_addr);
iot_cli_host_send_data_plc(send_type,
CLI_MSGID_REMOTE_UPGRADE_START_ACK, host_config->cco_mac,
(uint8_t *)&ack, sizeof(ack));
}
/* sta send upgrade result to cco */
void cli_upgrade_sta_send_upgrade_result(uint8_t send_type,
uint8_t *src_mac, uint8_t *dst_mac, uint8_t error_code)
{
iot_plc_upgrade_result_ul_t result;
result.upgrade_id = upgrade_info->upgrade_id;
result.upgrade_type = upgrade_info->upgrade_type;
iot_mac_addr_cpy(result.dst, src_mac);
result.error_code = error_code;
iot_printf("plc_upgrade:report upgrade result to cco"
"reuslt %d, src mac:\n", result.error_code);
cli_upgrade_print_mac_info(host_config->mac_addr);
iot_cli_module_send_data_with_retry(send_type,
IOT_PLC_UPGRADE_RETRY_COUNT, CLI_MODULEID_HOSTINTERFACE,
CLI_MSGID_UPGRADE_RESULT, NULL, dst_mac, (uint8_t *)&result,
sizeof(result));
}
/* sta send progress to cco */
void cli_upgrade_sta_send_progress(uint8_t *src_mac, uint8_t *dst_mac,
uint8_t progress_value)
{
iot_plc_upgrade_progress_ul_t progress;
progress.upgrade_id = upgrade_info->upgrade_id;
progress.upgrade_type = upgrade_info->upgrade_type;
progress.progress = progress_value;
iot_mac_addr_cpy(progress.dst, src_mac);
iot_cli_host_send_data_plc(IOT_PLC_MSG_TYPE_UNICAST,
CLI_MSGID_UPGRADE_PROGRESS,
dst_mac, (uint8_t *)&progress, sizeof(progress));
}
/* sta get net block type & index*/
bool_t cli_remote_upgrade_get_next_block(uint32_t file_type,
uint32_t block_index)
{
iot_upg_block_info_src src;
iot_upg_block_info_rst rst;
src.file_type = file_type;
src.block_index = block_index;
if ((ERR_OK == iot_upgrade_query_next_block(&rst, &src))) {
upgrade_info->current_file_type =
(uint8_t)rst.file_type;
upgrade_info->block_idx =
(uint16_t)rst.next_blank_block_index;
iot_printf("plc_upgrade:file_type:%d, block_index:%d\n",
upgrade_info->current_file_type,
upgrade_info->block_idx);
return true;
}
return false;
}
#if !IOT_STA_CONTROL_MODE
static uint8_t cli_remote_upgrade_requset_phase_three_data()
{
if (cli_remote_upgrade_get_next_block(UPGRADE_DATA_TYPE_PIB, 0)) {
cli_remote_upgrade_sta_send_request_data(true);
return UPGRADE_START_OK;
}
return UPGRADE_START_END_SINCE_COMPLETED;
}
/* stat request data */
static uint8_t cli_remote_upgrade_start_requset_data()
{
uint32_t period = 0;
if (cli_remote_upgrade_get_next_block(UPGRADE_DATA_TYPE_PIB, 0)) {
period = os_rand() % upgrade_info->time_window;
if (IOT_PLC_DEV_ROLE_PCO == host_config->dev_role) {
period /= 2;
}
cli_upgrade_reset_timer(1, period);
iot_printf("start upgrade timer, time window %lu ms\n", period);
return UPGRADE_START_OK;
}
return UPGRADE_START_END_SINCE_COMPLETED;
}
static uint32_t cli_find_node_from_listnode(uint8_t *list_mac, uint8_t list_size,
uint8_t *src_mac)
{
uint8_t i;
for (i = 0; i < list_size; i++) {
if (iot_mac_addr_cmp(list_mac + i * IOT_MAC_ADDR_LEN, src_mac)) {
return ERR_OK;
}
}
return ERR_FAIL;
}
#endif
/* sta handle remote upgrade start command from cco */
void cli_remote_upgrade_start(
uint8_t *buffer, uint32_t bufferlen, uint8_t *src_mac)
{
#if IOT_STA_CONTROL_MODE
(void)buffer;
(void)bufferlen;
(void)src_mac;
iot_printf("plc_upgrade:sta control mode no need to upgrade");
return;
#else
(void)src_mac;
uint8_t result = UPGRADE_START_OK;
iot_plc_upgrade_cust_start_dl_t cus_info;
iot_plc_upgrade_start_dl_t *data =
(iot_plc_upgrade_start_dl_t *)buffer;
uint32_t version = iot_version_hex();
uint8_t iscco = 0;
uint8_t ret = 0;
if ((!data) || (bufferlen < sizeof(*data))) {
iot_printf("%s param error", __FUNCTION__);
ret = 1;
goto out;
}
if (data->cus_upgrade_flag) {
if (bufferlen < (sizeof(*data) + data->dst_num * IOT_MAC_ADDR_LEN +
sizeof(cus_info))) {
iot_printf("%s param dest mac error", __FUNCTION__);
ret = 2;
goto out;
}
os_mem_cpy((uint8_t *)&cus_info,
(data->dst + data->dst_num * IOT_MAC_ADDR_LEN),
sizeof(iot_plc_upgrade_cust_start_dl_t));
} else {
if (bufferlen < (sizeof(*data) + data->dst_num * IOT_MAC_ADDR_LEN)) {
iot_printf("%s param dest mac error", __FUNCTION__);
ret = 2;
goto out;
}
os_mem_set((uint8_t *)&cus_info, 0, sizeof(cus_info));
}
iot_printf("plc_upgrade:recv remote upgrade start, role:%d, type:%d "
"state:%d\n", host_config->dev_role, host_config->dev_type,
upgrade_info->upgrade_state);
if (IOT_PLC_DEV_TYPE_METER_CONTROLLER == host_config->dev_type) {
/* METER_CONTROLLER no do remote upgrade */
iot_printf("plc_upgrade:controller skip upgrade\n");
ret = 3;
goto out;
}
if ((data->control_flag) &&
(data->phase_flag != UPGRADE_START_UPGRADE_PHASE1)) {
/* if in control upgrade mode, skip phase2/3 requesting cco data */
ret = 4;
iot_printf("plc_upgrade: drop phase2 and phase3 start cmd\n");
goto out;
}
//version check
if (version == data->fw_version) {
if (IOT_PLC_DEV_ROLE_STA == host_config->dev_role) {
iot_printf("plc_upgrade:version equal\n");
//upgrade_info->upgrade_state = IOT_PLC_UPGRADE_TRANSFERRED;
}
}
if (iot_mac_addr_cmp(host_config->cco_mac, src_mac)) {
iscco = 1;
}
if ((IOT_PLC_UPGRADE_TRANSFERRED == upgrade_info->upgrade_state)) {
if (!upgrade_info->stop_upgrade_rpt) {
if (IOT_PLC_DEV_ROLE_STA == host_config->dev_role) {
if (!os_is_timer_active(upgrade_info->upgrade_timer)) {
os_start_timer(upgrade_info->upgrade_timer,
os_rand() % (upgrade_info->time_window *
IOT_PLC_UPGRADE_LONG_TIMER_CNT));
}
} else {
cli_upgrade_sta_send_upgrade_result(
IOT_PLC_MSG_TYPE_UNICAST, host_config->mac_addr,
host_config->cco_mac, UPGRADE_DATA_SUCCESS);
}
}
return;
} else if ((IOT_PLC_UPGRADE_INIT != upgrade_info->upgrade_state) &&
(IOT_PLC_UPGRADE_LISTEN != upgrade_info->upgrade_state)) {
if ((upgrade_info->upgrade_type != data->upgrade_type) ||
(upgrade_info->upgrade_id != data->upgrade_id)) {
if (iscco) {
/* stop before upgrade, ready receive cco new upgrade */
cli_remote_upgrade_sta_stop();
} else {
/* drop invalid start upgrade */
ret = 5;
goto out;
}
} else if (data->phase_flag == UPGRADE_START_UPGRADE_PHASE1) {
/* node had init upgrade */
ret = 6;
goto out;
}
}
// initialize upgrade info
if ((IOT_PLC_UPGRADE_INIT == upgrade_info->upgrade_state) ||
(IOT_PLC_UPGRADE_LISTEN == upgrade_info->upgrade_state)) {
if (data->upgrade_type == IOT_PLC_UPGRADE_STA_LIST) {
if (!iscco) {
// list upgrade, disable pco start upgrade cmd
ret = 7;
goto out;
}
if (data->phase_flag == UPGRADE_START_UPGRADE_PHASE2) {
/*
* drop phase2 start upgrade cmd,
* because cmd dst param is invalid.
*/
ret = 8;
goto out;
}
if (cli_find_node_from_listnode(data->dst, data->dst_num,
host_config->mac_addr) != ERR_OK) {
ret = 9;
goto out;
}
}
result = cli_upgrade_type_check(data);
if (UPGRADE_START_OK != result) {
goto rsp;
}
cli_upgrade_info_initialize(data);
if (IOT_PLC_UPGRADE_INIT == upgrade_info->upgrade_state) {
if (ERR_OK != cli_upgrade_flash_info_initialize(data->block_size,
data->fw_size, data->pib_size, cus_info.cus_size,
data->upgrade_id, data->fw_checksum, data->pib_checksum,
cus_info.cus_checksum, data->fw_version)) {
result = UPGRADE_START_OTHER_ERROR;
goto rsp;
}
}
upgrade_info->upgrade_state = IOT_PLC_UPGRADE_STARTING;
}
if (data->phase_flag == UPGRADE_START_UPGRADE_PHASE3) {
iot_printf("plc_upgrade:start recv phase3 start\n");
result = cli_remote_upgrade_requset_phase_three_data();
} else if (data->phase_flag == UPGRADE_START_UPGRADE_PHASE2) {
if (!os_is_timer_active(upgrade_info->upgrade_timer)) {
/* node had start request data timer */
cli_remote_upgrade_start_requset_data();
}
ret = 10;
goto out;
}
rsp:
if ((data->upgrade_type == IOT_PLC_UPGRADE_STA_LIST) ||
(UPGRADE_START_OK != result)) {
cli_upgrade_sta_send_start_ack(IOT_PLC_MSG_TYPE_UNICAST, result);
}
out:
if (ret) {
iot_printf("%s ret: %d\n", __FUNCTION__, ret);
}
#endif
}
void cli_set_stop_upgrade_rpt(uint8_t *buffer, uint32_t bufferlen,
uint8_t *src_mac)
{
(void)src_mac;
if (!buffer) {
return;
}
iot_plc_sg_upgrade_stop_rpt_dl_t *data =
(iot_plc_sg_upgrade_stop_rpt_dl_t *)buffer;
if (bufferlen >= sizeof(*data)) {
if (data->flag) {
upgrade_info->stop_upgrade_rpt = 1;
}
}
}
iot_pkt_t *cli_rempte_upgrade_get_sta_bitmap(uint16_t start_seq, uint16_t cnt)
{
iot_pkt_t *bitmap_pkt = NULL;
uint8_t *bm;
uint16_t start_sn;
uint16_t bm_byte_size;
uint16_t bm_byte_cnt;
uint16_t i;
/* query upgrade bitmap */
iot_pkg_upg_sts_rst_t rst = {0};
iot_pkg_upg_sts_src_t src = {0};
if (IOT_PLC_UPGRADE_QUERY_BM_ALL == cnt) {
/* return all blocks */
cnt = (uint16_t)upgrade_info->pib_blocks + upgrade_info->fw_blocks;
start_sn = 0;
bm_byte_cnt = 0;
} else {
start_sn = start_seq;
}
bm_byte_size = ((cnt + 7) >> 3);
iot_printf("%s cnt is : %lu\n", __FUNCTION__, bm_byte_size);
bitmap_pkt = iot_pkt_alloc(bm_byte_size, IOT_SMART_GRID_MID);
if (bitmap_pkt == NULL) {
return NULL;
}
bm = iot_pkt_data(bitmap_pkt);
if (upgrade_info->upgrade_state == IOT_PLC_UPGRADE_INIT ||
upgrade_info->upgrade_state == IOT_PLC_UPGRADE_TRANSFERRED) {
/* if sta doesn't start upgrade/upgrad complete, set bm data is zero */
os_mem_set(bm, 0x00, bm_byte_size);
iot_pkt_put(bitmap_pkt, bm_byte_size);
return bitmap_pkt;
}
src.id = upgrade_info->upgrade_id;
src.block_size = upgrade_info->block_size;
src.block_index = start_sn;
src.block_cnt = cnt;
if (ERR_OK == iot_pkg_upgrade_query_state(&rst, &src)) {
bm_byte_cnt = (uint16_t)(rst.block_cnt >> 3);
if (bm_byte_cnt) {
os_mem_cpy(bm, rst.bitmap, bm_byte_cnt);
}
iot_pkt_put(bitmap_pkt, bm_byte_size);
iot_printf("upgrade: bm byte size = %d, start block = %d, len = %d,"
" cnt = %d.\n", bm_byte_cnt, start_seq, bm_byte_size, cnt);
for (i = 0; i < bm_byte_size; ++i) {
if (bm[i] != 0xFF || i + 1 == bm_byte_size) {
iot_printf("upgrade: bm[%d] = %02X\n", i, bm[i]);
}
}
} else {
iot_pkt_free(bitmap_pkt);
bitmap_pkt = NULL;
}
return bitmap_pkt;
}
void cli_remote_upgrade_node_info_query(uint8_t *buffer, uint32_t bufferlen,
uint8_t *src_mac)
{
(void)src_mac;
uint8_t err_code = 0;
uint32_t pkt_len = 0;
iot_pkt_t *bitmap_pkt;
iot_pkt_t *response_pkt = NULL;
iot_plc_upgrade_query_sta_info_dl_t *data =
(iot_plc_upgrade_query_sta_info_dl_t *)buffer;
iot_plc_upgrade_query_sta_info_ul_t *rsp;
if (bufferlen < sizeof(*data)) {
err_code = 1;
goto err;
}
bitmap_pkt = cli_rempte_upgrade_get_sta_bitmap(data->start_idx, data->cnt);
if ((bitmap_pkt == NULL) &&
(upgrade_info->upgrade_state != IOT_PLC_UPGRADE_INIT)) {
return;
}
pkt_len = iot_pkt_data_len(bitmap_pkt) + sizeof(*rsp);
response_pkt = iot_pkt_alloc(pkt_len, IOT_CLI_MID);
IOT_ASSERT(response_pkt);
rsp = (iot_plc_upgrade_query_sta_info_ul_t *)iot_pkt_data(response_pkt);
rsp->start_idx = data->start_idx;
rsp->upgrade_id = upgrade_info->upgrade_id;
rsp->state = (uint8_t)upgrade_info->upgrade_state;
iot_mac_addr_cpy(rsp->dst, host_config->mac_addr);
if (data->cnt == IOT_PLC_UPGRADE_QUERY_BM_ALL) {
rsp->cnt = upgrade_info->fw_blocks + upgrade_info->pib_blocks;
} else {
rsp->cnt = data->cnt;
}
if (bitmap_pkt) {
os_mem_cpy(rsp->bm, iot_pkt_data(bitmap_pkt),
iot_pkt_data_len(bitmap_pkt));
}
iot_cli_host_send_data_plc(IOT_PLC_MSG_TYPE_UNICAST,
CLI_MSGID_UPGRADE_NODE_INFO_RESPONSE, host_config->cco_mac,
iot_pkt_data(response_pkt), pkt_len);
err:
iot_printf("plc_upgrade: %s err code:%d\n", __FUNCTION__, err_code);
if (response_pkt != NULL) {
iot_pkt_free(response_pkt);
}
}
#if !IOT_STA_CONTROL_MODE
static bool_t cli_remote_upgrade_is_broadcast_start(
uint8_t contol_byte, uint8_t file_type)
{
if ((!contol_byte) && (UPGRADE_DATA_TYPE_PIB == file_type)) {
return true;
}
return false;
}
static uint8_t cli_remote_data_trans_type_to_plc(uint16_t fwd_type)
{
uint8_t plc_fwd_type = IOT_PLC_MSG_TYPE_INVALID;
switch (fwd_type) {
case UPGRADE_DATA_FORWARD_LOCAL_BCAST:
{
plc_fwd_type = IOT_PLC_MSG_TYPE_BCAST_1HOP;
break;
}
default:
break;
}
return plc_fwd_type;
}
#endif
/* sta receive remote upgrade data from cco */
void cli_remote_upgrade_data(
uint8_t *buffer, uint32_t bufferlen, uint8_t *src_mac)
{
#if IOT_STA_CONTROL_MODE
(void)buffer;
(void)bufferlen;
(void)src_mac;
iot_printf("plc_upgrade:control mode skip upgrade");
return;
#else
(void)src_mac;
iot_plc_upgrade_result_ul_t result;
iot_plc_upgrade_remote_data_dl *data =
(iot_plc_upgrade_remote_data_dl *)buffer;
bool_t isDest = false;
uint8_t plc_trans_type = IOT_PLC_MSG_TYPE_BCAST_1HOP;
uint8_t is_unicast_to_broad = 0;
if ((!data) || (bufferlen < sizeof(*data))) {
iot_printf("%s param error", __FUNCTION__);
return;
}
if (bufferlen < ((data->block_size * data->block_cnt) + sizeof(*data))) {
iot_printf("%s length error", __FUNCTION__);
return;
}
if ((UPGRADE_REMOTE_STA_LIST_DATA == data->contol_byte) &&
(IOT_PLC_UPGRADE_STA_LIST != upgrade_info->upgrade_type)) {
return;
}
if (IOT_PLC_DEV_TYPE_METER_CONTROLLER == host_config->dev_type) {
/* METER_CONTROLLER no do remote upgrade */
iot_printf("plc_upgrade:controller skip upgrade\n");
return;
}
if (iot_mac_addr_cmp(host_config->mac_addr, data->dst)) {
isDest = true;
}
iot_printf("plc_upgrade: remote data, state %d,"
" type %d, idx %d, size %d\n", upgrade_info->upgrade_state,
data->file_type, data->block_idx_array[0], data->block_size_array[0]);
if ((IOT_PLC_UPGRADE_TRANSFERRED == upgrade_info->upgrade_state) ||
(IOT_PLC_UPGRADE_FAILED == upgrade_info->upgrade_state) ||
(IOT_PLC_UPGRADE_START_FAIL == upgrade_info->upgrade_state) ||
(IOT_PLC_UPGRADE_STOPED == upgrade_info->upgrade_state))
{
if (cli_remote_upgrade_is_broadcast_start(
data->contol_byte, data->file_type)) {
upgrade_info->upgrade_state = IOT_PLC_UPGRADE_INIT;
} else {
return;
}
} else if ((IOT_PLC_UPGRADE_STARTED == upgrade_info->upgrade_state) ||
(IOT_PLC_UPGRADE_LISTEN == upgrade_info->upgrade_state)) {
if (cli_remote_upgrade_is_broadcast_start(
data->contol_byte, data->file_type) &&
(upgrade_info->upgrade_id != data->upgrade_id)) {
cli_remote_upgrade_sta_stop();
upgrade_info->upgrade_state = IOT_PLC_UPGRADE_INIT;
}
}
if (IOT_PLC_UPGRADE_INIT == upgrade_info->upgrade_state) {
if (ERR_OK != cli_upgrade_flash_info_initialize(data->block_size,
data->fw_size, data->pib_size, data->cus_size, data->upgrade_id,
data->fw_checksum, data->pib_checksum, data->cus_checksum,
upgrade_info->fw_version)) {
iot_printf("plc_upgrade:cli_upgrade_flash_info_initialize error\n");
return;
}
cli_remote_upgrade_sta_initialize(IOT_PLC_UPGRADE_ALL,
data->block_size, data->block_size, data->fw_size,
data->pib_size, data->cus_size, data->fw_checksum, data->pib_checksum,
data->cus_checksum, data->time_window, data->remote_block_cnt);
upgrade_info->upgrade_id = data->upgrade_id;
upgrade_info->upgrade_state = IOT_PLC_UPGRADE_LISTEN;
}
result.error_code = cli_upgrade_data_check(data->block_cnt,
data->block_idx_array, data->block_size_array,
data->data, data->file_type);
if (UPGRADE_DATA_SUCCESS == result.error_code ||
UPGRADE_DATA_BLOCK_IDX_ERROR == result.error_code) {
result.error_code = cli_upgrade_write_data_to_flash(data->file_type,
data->block_cnt, data->block_idx_array, data->block_size_array,
data->data);
}
if (ERR_OK == cli_upgrade_is_unicast_to_broadcast(data)) {
is_unicast_to_broad = 1;
plc_trans_type =
cli_remote_data_trans_type_to_plc(data->fwd_type);
}
if (is_unicast_to_broad ||
((UPGRADE_REMOTE_ALL_PHASE2_DATA == data->contol_byte) &&
(IOT_PLC_DEV_ROLE_PCO == host_config->dev_role)) ||
(UPGRADE_REMOTE_ALL_PHASE3_DATA == data->contol_byte)) {
if (UPGRADE_REMOTE_STA_LIST_DATA != data->contol_byte) {
data->contol_byte = UPGRADE_REMOTE_ALL_PHASE3_DATA_1;
}
iot_cli_module_send_data_with_retry(plc_trans_type, 1,
CLI_MODULEID_HOSTINTERFACE, CLI_MSGID_REMOTE_UPGRADE_DATA,
src_mac, host_config->mac_addr, buffer, bufferlen);
if (!is_unicast_to_broad) {
return;
}
} else if (UPGRADE_REMOTE_ALL_PHASE3_DATA_1 == data->contol_byte) {
return;
}
if ((IOT_PLC_UPGRADE_STARTING == upgrade_info->upgrade_state) ||
(IOT_PLC_UPGRADE_STARTED == upgrade_info->upgrade_state)) {
upgrade_info->skip_timer = false;
if (!isDest) {
if ((upgrade_info->last_timer_time +
upgrade_info->time_window) <
(os_boot_time32() + IOT_PLC_UPGRADE_STA_SKIP_REQ_TIME)) {
upgrade_info->skip_timer = true;
}
}
if (UPGRADE_DATA_SUCCESS == result.error_code) {
bool_t recv_done = false;
if (ERR_OK == iot_upgrade_is_completed()) {
recv_done = true;
}
if (recv_done) {
iot_printf("plc_upgrade: recv fw done,"
"wait for crc check\n");
} else if (isDest) {
/* check time_window */
if (data->time_window && ((upgrade_info->time_window >=
(IOT_PLC_UPGRADE_TIME_WINDOW_ADJ_VALUE3 *
data->time_window)) || ((upgrade_info->time_window *
IOT_PLC_UPGRADE_TIME_WINDOW_ADJ_VALUE3) <=
data->time_window))) {
iot_printf("plc_upgrade:time window adjust,"
" %lu to %lu\n", upgrade_info->time_window,
data->time_window);
/* renew time_window */
upgrade_info->time_window = data->time_window;
cli_upgrade_reset_timer(1, upgrade_info->time_window);
} else if (os_is_timer_active(upgrade_info->upgrade_timer)) {
os_reset_timer(upgrade_info->upgrade_timer);
}
}
} else if (UPGRADE_DATA_STA_STOP == result.error_code) {
cli_remote_upgrade_sta_stop();
cli_upgrade_sta_send_upgrade_result(IOT_PLC_MSG_TYPE_UNICAST,
host_config->mac_addr, host_config->cco_mac, result.error_code);
}
} else if (IOT_PLC_UPGRADE_LISTEN == upgrade_info->upgrade_state) {
if (data->contol_byte) {
uint8_t start_result = UPGRADE_START_OK;
iot_printf("plc_upgrade: start since recv data\n");
cli_remote_upgrade_sta_initialize(IOT_PLC_UPGRADE_ALL,
data->block_size, data->block_size, data->fw_size,
data->pib_size, 0, data->fw_checksum, data->pib_checksum, 0,
data->time_window, data->remote_block_cnt);
upgrade_info->upgrade_id = data->upgrade_id;
upgrade_info->upgrade_state = IOT_PLC_UPGRADE_STARTING;
start_result = cli_remote_upgrade_start_requset_data();
if (UPGRADE_START_OK != start_result) {
if ((IOT_PLC_UPGRADE_TRANSFERRED !=
upgrade_info->upgrade_state) &&
(IOT_PLC_UPGRADE_FAILED !=
upgrade_info->upgrade_state)) {
iot_dbglog_input(IOT_DRIVER_MID, DBGLOG_ERR,
IOT_DRIVER_UPGRADE_COMMIT_ID, 1, 3);
}
cli_upgrade_sta_send_start_ack(
IOT_PLC_MSG_TYPE_UNICAST, start_result);
}
}
}
#endif
}
/* sta state change handler */
void iot_cli_sta_state_change(uint8_t prev_nw_sn, uint8_t nw_sn)
{
iot_printf("plc_upgrade: sta state change\n");
cli_upgrade_print_mac_info(host_config->mac_addr);
if (prev_nw_sn != nw_sn) {
iot_printf("prev_nw_sn %lu, nw_sn %lu\n",
prev_nw_sn, nw_sn);
#if (!IOT_SMART_GRID_ENABLE)
if (IOT_PLC_UPGRADE_TRANSFERRED == upgrade_info->upgrade_state) {
iot_printf("plc_upgrade: reset since leave\n");
iot_upgrade_reset();
return;
}
#endif /* !IOT_SMART_GRID_ENABLE */
if (IOT_PLC_UPGRADE_INIT != upgrade_info->upgrade_state) {
cli_remote_upgrade_sta_stop();
}
} else if ((IOT_PLC_UPGRADE_TRANSFERRED == upgrade_info->upgrade_state) &&
(IOT_PLC_DEV_ROLE_PCO == host_config->dev_role)) {
cli_remote_upgrade_pco_start();
}
}
/* sta handle leave */
void iot_cli_sta_leave()
{
iot_printf("plc_upgrade: sta leave\n");
if (host_config->switch_flag) {
iot_printf("plc_upgrade: switch flag is true, reset since leave\n");
iot_upgrade_reset();
return;
}
#if (IOT_SMART_GRID_ENABLE)
if (IOT_PLC_UPGRADE_TRANSFERRED == upgrade_info->upgrade_state) {
iot_printf("plc_upgrade: reset since leave\n");
iot_upgrade_reset();
}
#endif
}
void iot_cli_role_change(uint8_t prev_role, uint8_t cur_role)
{
if ((IOT_PLC_DEV_ROLE_STA == prev_role) && (IOT_PLC_DEV_ROLE_PCO == cur_role) &&
IOT_PLC_UPGRADE_TRANSFERRED == upgrade_info->upgrade_state) {
iot_printf("plc_upgrade: role change\n");
cli_remote_upgrade_pco_start();
}
}
#else /* IOT_CLI_UPGRADE_ENABLE */
/* sta state change handler */
void iot_cli_sta_state_change(uint8_t prev_nw_sn, uint8_t nw_sn)
{
(void)prev_nw_sn;
(void)nw_sn;
}
/* sta handle leave */
void iot_cli_sta_leave()
{
iot_printf("plc_upgrade: sta leave\n");
if (host_config->switch_flag) {
iot_printf("plc_upgrade: switch flag is true, reset since leave\n");
iot_upgrade_reset();
}
}
void iot_cli_role_change(uint8_t prev_role, uint8_t cur_role)
{
(void)prev_role;
(void)cur_role;
}
#endif /* IOT_CLI_UPGRADE_ENABLE */