821 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			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 */
							 |