1958 lines
		
	
	
		
			63 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1958 lines
		
	
	
		
			63 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_oem_api.h"
 | 
						|
#include "iot_img_hdr.h"
 | 
						|
#include "iot_ntoh_api.h"
 | 
						|
#include "iot_system.h"
 | 
						|
 | 
						|
#include "iot_cli_plc_tx_rx.h"
 | 
						|
#include "iot_cli_plc_module.h"
 | 
						|
#include "iot_cli_upgrade_api.h"
 | 
						|
#include "iot_cli_host_upgrade_internal.h"
 | 
						|
#include "iot_cli_upgrade_status_type_def.h"
 | 
						|
#include "iot_cli_sg.h"
 | 
						|
#include "iot_bitmap_api.h"
 | 
						|
#include "plc_utils.h"
 | 
						|
#include "iot_mtd.h"
 | 
						|
 | 
						|
extern iot_plc_upgrade_info_t *upgrade_info;
 | 
						|
extern iot_plc_host_config_t *host_config;
 | 
						|
extern iot_cli_host_info_t *host_info;
 | 
						|
 | 
						|
#if PLC_SUPPORT_CCO_ROLE
 | 
						|
 | 
						|
iot_cli_upgrade_app_handler sg_upgrade_handler = NULL;
 | 
						|
 | 
						|
#if IOT_CLI_UPGRADE_ENABLE
 | 
						|
 | 
						|
/* remote upgrade dst list check */
 | 
						|
static uint8_t cli_upgrade_dst_list_check(
 | 
						|
    iot_plc_upgrade_dst_list_t *data)
 | 
						|
{
 | 
						|
    if (!data) {
 | 
						|
        return UPGRADE_DST_LIST_INVALID_DATA;
 | 
						|
    }
 | 
						|
 | 
						|
    if (upgrade_info->dst_list_idx != data->dst_list_idx) {
 | 
						|
        iot_printf("plc_upgrade:recv dst list, expect %d, recv %x",
 | 
						|
            upgrade_info->dst_list_idx, data->dst_list_idx);
 | 
						|
        return UPGRADE_DST_LIST_IDX_ERROR;
 | 
						|
    }
 | 
						|
 | 
						|
    return UPGRADE_DST_LIST_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
static void cli_upgrade_set_dst_status_ack(
 | 
						|
    iot_plc_upgrade_dst_status_query *query)
 | 
						|
{
 | 
						|
    if (!query) {
 | 
						|
        return;
 | 
						|
    }
 | 
						|
    query->dst_total_num = upgrade_info->dest_info.dst_total_num;
 | 
						|
    query->dst_num = UPGRADE_REMOTE_DST_STATUS_ONCE_MAX_NUM;
 | 
						|
    query->upgrade_state = upgrade_info->upgrade_state;
 | 
						|
}
 | 
						|
 | 
						|
/* cco handle destination status query from plc manager */
 | 
						|
static void cli_upgrade_dst_status_query_internal(uint8_t *src_mac)
 | 
						|
{
 | 
						|
    iot_plc_upgrade_dst_status_query_ul query_ack;
 | 
						|
 | 
						|
    cli_upgrade_set_dst_status_ack(&(query_ack.query));
 | 
						|
 | 
						|
    iot_cli_send_to_host(CLI_MSGID_UPGRADE_DST_STATUS_QUERY_ACK,
 | 
						|
        (uint8_t *)&query_ack, sizeof(query_ack), src_mac);
 | 
						|
}
 | 
						|
 | 
						|
static void cli_upgrade_set_dst_status_list(uint16_t start_idx,
 | 
						|
    uint8_t count, iot_plc_upgrade_dst_status_list *status_list)
 | 
						|
{
 | 
						|
    uint16_t end_idx = 0;
 | 
						|
    uint16_t total_dst_num;
 | 
						|
    iot_plc_upgrade_dest_desc_t **org_dest_desc;
 | 
						|
    iot_plc_upgrade_dest_desc_t *dest_desc;
 | 
						|
 | 
						|
    if (!status_list) {
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    if (upgrade_info->upgrade_type == IOT_PLC_UPGRADE_STA_LIST) {
 | 
						|
        total_dst_num = upgrade_info->dst_list_idx;
 | 
						|
        org_dest_desc = &upgrade_info->dest_info.upgrading_list[0];
 | 
						|
    } else {
 | 
						|
        total_dst_num = upgrade_info->dest_info.dst_total_num;
 | 
						|
        org_dest_desc = upgrade_info->dest_info.entry_ptr;
 | 
						|
    }
 | 
						|
 | 
						|
    if ((!count) || (start_idx >= total_dst_num)) {
 | 
						|
        status_list->dst_num = 0;
 | 
						|
        status_list->end = 1;
 | 
						|
        return;
 | 
						|
    }
 | 
						|
    if (count > UPGRADE_REMOTE_DST_STATUS_ONCE_MAX_NUM) {
 | 
						|
        count = UPGRADE_REMOTE_DST_STATUS_ONCE_MAX_NUM;
 | 
						|
    }
 | 
						|
    end_idx = start_idx + count - 1;
 | 
						|
    status_list->dst_status_list_idx = start_idx;
 | 
						|
    status_list->end = 0;
 | 
						|
    if (end_idx > (total_dst_num - 1)) {
 | 
						|
        end_idx = total_dst_num - 1;
 | 
						|
        status_list->end = 1;
 | 
						|
    }
 | 
						|
 | 
						|
    if (upgrade_info->dest_info.entry_ptr) {
 | 
						|
        status_list->dst_num = (uint8_t)(end_idx - start_idx + 1);
 | 
						|
        os_mem_set(status_list->dst_status_list, 0,
 | 
						|
            UPGRADE_REMOTE_DST_STATUS_ONCE_MAX_NUM *
 | 
						|
            sizeof(iot_plc_upgrade_dst_status_t));
 | 
						|
        org_dest_desc += start_idx;
 | 
						|
        for (uint8_t i = 0; i < status_list->dst_num; i++, org_dest_desc++) {
 | 
						|
            dest_desc = *org_dest_desc;
 | 
						|
            if (dest_desc) {
 | 
						|
                status_list->dst_status_list[i].status =
 | 
						|
                    dest_desc->status;
 | 
						|
                status_list->dst_status_list[i].percentage =
 | 
						|
                    dest_desc->percentage;
 | 
						|
                status_list->dst_status_list[i].error_code =
 | 
						|
                    dest_desc->error_code;
 | 
						|
                iot_mac_addr_cpy(status_list->dst_status_list[i].dst,
 | 
						|
                    dest_desc->entry.addr);
 | 
						|
            }
 | 
						|
        }
 | 
						|
    } else {
 | 
						|
        status_list->dst_num = 0;
 | 
						|
        status_list->end = 1;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/* coo handle destination status list query from plc manager*/
 | 
						|
void cli_upgrade_dst_status_list_internal(uint16_t start_index,
 | 
						|
    uint8_t dst_num, uint8_t *src_mac)
 | 
						|
{
 | 
						|
    iot_plc_upgrade_dst_status_list_ul *list_ul;
 | 
						|
    iot_pkt_t *buf_pkt;
 | 
						|
    uint16_t rsp_len;
 | 
						|
    uint8_t i;
 | 
						|
    uint8_t temp_percent;
 | 
						|
 | 
						|
    /* allocate buffer for response */
 | 
						|
    rsp_len = sizeof(iot_plc_upgrade_dst_status_list_ul);
 | 
						|
    buf_pkt = iot_pkt_alloc(rsp_len, IOT_CLI_MID);
 | 
						|
 | 
						|
    if (!buf_pkt) {
 | 
						|
        iot_printf("%s pkt malloc fail\n", __FUNCTION__);
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    list_ul = (iot_plc_upgrade_dst_status_list_ul*)iot_pkt_data(buf_pkt);
 | 
						|
 | 
						|
    cli_upgrade_set_dst_status_list(start_index, dst_num,
 | 
						|
        &(list_ul->status_list));
 | 
						|
 | 
						|
    if (upgrade_info->upgrade_state == IOT_PLC_UPGRADE_TRANSFERRED) {
 | 
						|
        for (i = 0; i < list_ul->status_list.dst_num; i++) {
 | 
						|
            temp_percent = list_ul->status_list.dst_status_list->percentage;
 | 
						|
            list_ul->status_list.dst_status_list->percentage =
 | 
						|
                UPGRADE_BDCT_PROGRESS_IN_BCAST_PHASE +
 | 
						|
                (temp_percent * (100 - UPGRADE_BDCT_PROGRESS_IN_BCAST_PHASE));
 | 
						|
        }
 | 
						|
    }
 | 
						|
    iot_pkt_put(buf_pkt, rsp_len);
 | 
						|
 | 
						|
    iot_printf("upgrade status rpt sta cnt %d \n",
 | 
						|
        list_ul->status_list.dst_num);
 | 
						|
    iot_cli_send_to_host(CLI_MSGID_UPGRADE_DST_STATUS_LIST_ACK,
 | 
						|
        (uint8_t *)list_ul, rsp_len, src_mac);
 | 
						|
 | 
						|
    iot_pkt_free(buf_pkt);
 | 
						|
}
 | 
						|
 | 
						|
/* cco handle destination list from plc manager */
 | 
						|
void cli_upgrade_dst_list(uint8_t *buffer, uint32_t bufferlen, uint8_t *src_mac)
 | 
						|
{
 | 
						|
    (void)bufferlen;
 | 
						|
    (void)src_mac;
 | 
						|
    iot_plc_upgrade_dst_list_ul_t ack;
 | 
						|
    iot_plc_upgrade_dst_list_dl_t *data;
 | 
						|
    iot_plc_upgrade_dst_list_t *info;
 | 
						|
 | 
						|
    data = (iot_plc_upgrade_dst_list_dl_t *)buffer;
 | 
						|
    info = (iot_plc_upgrade_dst_list_t *)&(data->info);
 | 
						|
    ack.dst_list_idx = data->info.dst_list_idx;
 | 
						|
    ack.error_code = cli_upgrade_dst_list_check(info);
 | 
						|
    if (UPGRADE_DST_LIST_SUCCESS != ack.error_code) {
 | 
						|
        goto err_exit;
 | 
						|
    }
 | 
						|
 | 
						|
    iot_cli_upgrade_set_dst_list(info, 0);
 | 
						|
 | 
						|
    ack.error_code = UPGRADE_DST_LIST_SUCCESS;
 | 
						|
err_exit:
 | 
						|
    iot_cli_send_to_host(CLI_MSGID_UPGRADE_DST_LIST_ACK, (uint8_t *)&ack,
 | 
						|
        sizeof(ack), src_mac);
 | 
						|
}
 | 
						|
 | 
						|
/* cco send upgrade progress to PLC Manager */
 | 
						|
void cli_remote_upgrade_send_upgrade_progress(uint8_t progress_value,
 | 
						|
    uint8_t *mac)
 | 
						|
{
 | 
						|
    iot_plc_upgrade_progress_ul_t progress;
 | 
						|
 | 
						|
    if (!mac) {
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
#if PLC_SUPPORT_UPGRADE_DEBUG
 | 
						|
    iot_printf("plc_upgrade:cco send upgrade progress"
 | 
						|
        " to plc manager, sta mac:\n");
 | 
						|
    cli_upgrade_print_mac_info(mac);
 | 
						|
#endif
 | 
						|
 | 
						|
    progress.progress = progress_value;
 | 
						|
    progress.upgrade_id = upgrade_info->upgrade_id;
 | 
						|
    progress.upgrade_type = IOT_PLC_UPGRADE_ALL;
 | 
						|
    os_mem_cpy(progress.dst, mac, IOT_MAC_ADDR_LEN);
 | 
						|
 | 
						|
    iot_cli_send_to_host(CLI_MSGID_UPGRADE_PROGRESS,
 | 
						|
        (uint8_t*)&progress, sizeof(progress), upgrade_info->upgrade_src_mac);
 | 
						|
}
 | 
						|
 | 
						|
static uint32_t cli_upgrade_get_dest_index(uint16_t *index)
 | 
						|
{
 | 
						|
    uint16_t i = 0;
 | 
						|
 | 
						|
    for (i = 0; i < IOT_PLC_UPGRADE_STATUS_ITEM_MAX_CNT; i++) {
 | 
						|
        if (!upgrade_info->dest_info.entry_ptr[i]) {
 | 
						|
            *index = i;
 | 
						|
            return ERR_OK;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    return ERR_FAIL;
 | 
						|
}
 | 
						|
 | 
						|
/* cco add dest info into hash table */
 | 
						|
iot_plc_upgrade_dest_desc_t *cli_upgrade_add_dest_info(uint8_t *mac)
 | 
						|
{
 | 
						|
    iot_plc_upgrade_dest_desc_t *dest = NULL;
 | 
						|
    uint16_t idx;
 | 
						|
 | 
						|
    dest = (iot_plc_upgrade_dest_desc_t *)iot_addr_hash_table_find(
 | 
						|
        upgrade_info->dest_info.table, mac);
 | 
						|
 | 
						|
    if (dest) {
 | 
						|
        return dest;
 | 
						|
    }
 | 
						|
 | 
						|
    if (!mac || (IOT_PLC_UPGRADE_STATUS_ITEM_MAX_CNT <=
 | 
						|
        upgrade_info->dest_info.dst_total_num)) {
 | 
						|
        return dest;
 | 
						|
    }
 | 
						|
    if (ERR_OK != cli_upgrade_get_dest_index(&idx)) {
 | 
						|
        return dest;
 | 
						|
    }
 | 
						|
    dest = (iot_plc_upgrade_dest_desc_t *)iot_addr_hash_table_alloc(
 | 
						|
        upgrade_info->dest_info.table);
 | 
						|
    if (dest) {
 | 
						|
        dest->status = IOT_PLC_UPGRADE_INIT;
 | 
						|
        dest->percentage = 0;
 | 
						|
        dest->reported_percentage = 0;
 | 
						|
        dest->start_retry_times = 0;
 | 
						|
        dest->upgrade_type = CLI_UPGRADE_TYPE_UNKNOWN;
 | 
						|
        if (IOT_PLC_UPGRADE_INIT != upgrade_info->upgrade_state) {
 | 
						|
            dest->error_code = UPGRADE_DATA_STA_IN_PROGRESS;
 | 
						|
        } else {
 | 
						|
            dest->error_code = 0;
 | 
						|
        }
 | 
						|
        iot_mac_addr_cpy(dest->entry.addr, mac);
 | 
						|
        upgrade_info->dest_info.entry_ptr[idx] = dest;
 | 
						|
        iot_addr_hash_table_add(upgrade_info->dest_info.table,
 | 
						|
            &dest->entry);
 | 
						|
        upgrade_info->dest_info.dst_total_num++;
 | 
						|
    } else {
 | 
						|
        iot_printf("add dest failed, alloc failed\n");
 | 
						|
    }
 | 
						|
 | 
						|
    return dest;
 | 
						|
}
 | 
						|
 | 
						|
uint16_t cli_upgrade_add_upgrade_list_dest_info(
 | 
						|
    uint8_t *node_mac, uint16_t node_cnt, uint8_t is_renew)
 | 
						|
{
 | 
						|
    uint16_t i;
 | 
						|
    iot_plc_upgrade_dest_desc_t *desc;
 | 
						|
    uint16_t cnt = 0;
 | 
						|
 | 
						|
    if (is_renew) {
 | 
						|
        for (i = 0; i < IOT_PLC_UPGRADE_PHASE_THREE_MAX_SAT_CNT; i++) {
 | 
						|
            upgrade_info->dest_info.upgrading_list[i] = NULL;
 | 
						|
        }
 | 
						|
        upgrade_info->dst_list_idx = 0;
 | 
						|
    }
 | 
						|
    for (i = 0; i < node_cnt; i++) {
 | 
						|
        desc = cli_upgrade_add_dest_info(node_mac + (i * IOT_MAC_ADDR_LEN));
 | 
						|
        if (desc) {
 | 
						|
            upgrade_info->dest_info.upgrading_list[upgrade_info->dst_list_idx] =
 | 
						|
                desc;
 | 
						|
            upgrade_info->dst_list_idx++;
 | 
						|
            cnt++;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    return cnt;
 | 
						|
}
 | 
						|
 | 
						|
/* cco destroy buffer for remote upgrade */
 | 
						|
void cli_remote_upgrade_destroy_buffer()
 | 
						|
{
 | 
						|
    if (upgrade_info->file_data) {
 | 
						|
        os_mem_free(upgrade_info->file_data);
 | 
						|
        upgrade_info->file_data = NULL;
 | 
						|
        upgrade_info->pib_data = NULL;
 | 
						|
        upgrade_info->fw_data = NULL;
 | 
						|
        upgrade_info->cus_data = NULL;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/* cco init dest info */
 | 
						|
void cli_remote_upgrade_init_dest_info()
 | 
						|
{
 | 
						|
    if (upgrade_info->dest_info.table) {
 | 
						|
        cli_remote_upgrade_destroy_dest_info();
 | 
						|
    }
 | 
						|
    upgrade_info->dest_info.dst_total_num = 0;
 | 
						|
    upgrade_info->dest_info.dst_transferred_num = 0;
 | 
						|
    upgrade_info->dest_info.dest_idx = 0;
 | 
						|
    upgrade_info->dest_info.upgrading_list_idx = 0;
 | 
						|
    upgrade_info->dest_info.query_node_timeout = 0;
 | 
						|
    upgrade_info->dest_info.entry_ptr = (iot_plc_upgrade_dest_desc_t **)
 | 
						|
    os_mem_malloc(IOT_CLI_MID, IOT_PLC_UPGRADE_STATUS_ITEM_MAX_CNT *
 | 
						|
        sizeof(iot_plc_upgrade_dest_desc_t *));
 | 
						|
    IOT_ASSERT(upgrade_info->dest_info.entry_ptr);
 | 
						|
    upgrade_info->dest_info.table = iot_addr_hash_table_create(
 | 
						|
        IOT_CLI_MID, IOT_PLC_UPGRADE_STATUS_ITEM_MAX_CNT,
 | 
						|
        sizeof(iot_plc_upgrade_dest_desc_t),
 | 
						|
        IOT_PLC_UPGRADE_STATUS_TABLE_SIZE);
 | 
						|
    IOT_ASSERT(upgrade_info->dest_info.table);
 | 
						|
}
 | 
						|
 | 
						|
/* reset cli upgrade dest info when begin cli upgrade */
 | 
						|
void cli_remote_upgrade_dest_info_reset()
 | 
						|
{
 | 
						|
    uint16_t i;
 | 
						|
    iot_plc_upgrade_dest_desc_t     *entry_ptr;
 | 
						|
 | 
						|
    /* init node upgrade info */
 | 
						|
    for (i = 0; i < IOT_PLC_UPGRADE_STATUS_ITEM_MAX_CNT; i++) {
 | 
						|
        entry_ptr = upgrade_info->dest_info.entry_ptr[i];
 | 
						|
        if (!entry_ptr) {
 | 
						|
            continue;
 | 
						|
        }
 | 
						|
        entry_ptr->status = IOT_PLC_UPGRADE_INIT;
 | 
						|
        entry_ptr->error_code = 0;
 | 
						|
        entry_ptr->percentage = 0;
 | 
						|
        entry_ptr->reported_percentage = 0;
 | 
						|
        entry_ptr->start_retry_times = 0;
 | 
						|
        entry_ptr->updated = 0;
 | 
						|
        entry_ptr->error_code = UPGRADE_DATA_STA_IN_PROGRESS;
 | 
						|
        entry_ptr->upgrade_type = CLI_UPGRADE_TYPE_UNKNOWN;
 | 
						|
    }
 | 
						|
    /* init cli upgrade info */
 | 
						|
    upgrade_info->dest_info.dst_transferred_num = 0;
 | 
						|
    upgrade_info->dest_info.dest_idx = 0;
 | 
						|
    upgrade_info->dest_info.upgrading_list_idx = 0;
 | 
						|
    upgrade_info->dest_info.query_node_timeout = 0;
 | 
						|
}
 | 
						|
 | 
						|
/* cco destroy dest info */
 | 
						|
void cli_remote_upgrade_destroy_dest_info()
 | 
						|
{
 | 
						|
    for (uint16_t i = 0; i < upgrade_info->dest_info.dst_total_num; i++) {
 | 
						|
        if (upgrade_info->dest_info.entry_ptr[i]) {
 | 
						|
            iot_addr_hash_table_free(upgrade_info->dest_info.table,
 | 
						|
                (iot_addr_hash_entry_t *)
 | 
						|
                upgrade_info->dest_info.entry_ptr[i]);
 | 
						|
        }
 | 
						|
    }
 | 
						|
    if (upgrade_info->dest_info.entry_ptr) {
 | 
						|
        os_mem_free(upgrade_info->dest_info.entry_ptr);
 | 
						|
        upgrade_info->dest_info.entry_ptr = NULL;
 | 
						|
    }
 | 
						|
    if (upgrade_info->dest_info.table) {
 | 
						|
        iot_addr_hash_table_delete(upgrade_info->dest_info.table);
 | 
						|
        upgrade_info->dest_info.table = NULL;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/* cco send stop report upgrade result command to target pco/sta */
 | 
						|
void cli_remote_upgrade_send_stop_rpt_notify(uint8_t *dest_mac)
 | 
						|
{
 | 
						|
    iot_plc_sg_upgrade_stop_rpt_dl_t stop_rpt_dl = { 0 };
 | 
						|
 | 
						|
    stop_rpt_dl.flag = 1;
 | 
						|
 | 
						|
    iot_printf("%s set sta: %x:%x:%x:%x:%x:%x stop report\n", __FUNCTION__,
 | 
						|
        dest_mac[0], dest_mac[1], dest_mac[2], dest_mac[3], dest_mac[4],
 | 
						|
        dest_mac[5]);
 | 
						|
    iot_cli_module_send_data_with_retry(IOT_PLC_MSG_TYPE_UNICAST,
 | 
						|
        IOT_PLC_UPGRADE_RETRY_COUNT, CLI_MODULEID_HOSTINTERFACE,
 | 
						|
        CLI_MSGID_SET_STOP_UPGRADE_RPT, NULL, dest_mac, (uint8_t *)&stop_rpt_dl,
 | 
						|
        sizeof(stop_rpt_dl));
 | 
						|
}
 | 
						|
 | 
						|
/* cco stop remote upgrade */
 | 
						|
void cli_remote_upgrade_coo_stop()
 | 
						|
{
 | 
						|
    //stop all logic
 | 
						|
    //todo: add stop one sta logic
 | 
						|
    upgrade_info->dest_info.dest_idx = upgrade_info->dest_info.dst_total_num;
 | 
						|
    cli_upgrade_reset_timer(0, 0);
 | 
						|
    if (upgrade_info->full_bitmap) {
 | 
						|
        os_mem_free(upgrade_info->full_bitmap);
 | 
						|
        upgrade_info->full_bitmap = NULL;
 | 
						|
    }
 | 
						|
    iot_printf("plc_upgrade:cco stop timer\n");
 | 
						|
}
 | 
						|
 | 
						|
/* query next broadcast block idx */
 | 
						|
static bool_t cli_remote_upgrade_next_block_idx(bool_t first)
 | 
						|
{
 | 
						|
    bool_t next = true;
 | 
						|
 | 
						|
    if (first) {
 | 
						|
        upgrade_info->block_idx = 0;
 | 
						|
        if (upgrade_info->pib_size) {
 | 
						|
            upgrade_info->current_file_type = UPGRADE_DATA_TYPE_PIB;
 | 
						|
        } else if (upgrade_info->fw_size) {
 | 
						|
            upgrade_info->current_file_type = UPGRADE_DATA_TYPE_FW;
 | 
						|
        } else if (upgrade_info->cus_size) {
 | 
						|
            upgrade_info->current_file_type = UPGRADE_DATA_TYPE_CUS;
 | 
						|
        } else {
 | 
						|
            next = false;
 | 
						|
        }
 | 
						|
    } else {
 | 
						|
        upgrade_info->block_idx++;
 | 
						|
        if ((UPGRADE_DATA_TYPE_PIB == upgrade_info->current_file_type) &&
 | 
						|
            (upgrade_info->pib_blocks == upgrade_info->block_idx)) {
 | 
						|
            upgrade_info->block_idx = 0;
 | 
						|
            if (upgrade_info->fw_size) {
 | 
						|
                upgrade_info->current_file_type = UPGRADE_DATA_TYPE_FW;
 | 
						|
            } else if (upgrade_info->cus_size) {
 | 
						|
                upgrade_info->current_file_type = UPGRADE_DATA_TYPE_CUS;
 | 
						|
            } else {
 | 
						|
                next = false;
 | 
						|
            }
 | 
						|
        } else if ((UPGRADE_DATA_TYPE_FW == upgrade_info->current_file_type) &&
 | 
						|
            (upgrade_info->fw_blocks == upgrade_info->block_idx)) {
 | 
						|
            if (upgrade_info->cus_size) {
 | 
						|
                upgrade_info->block_idx = 0;
 | 
						|
                upgrade_info->current_file_type = UPGRADE_DATA_TYPE_CUS;
 | 
						|
            } else {
 | 
						|
                next = false;
 | 
						|
            }
 | 
						|
        } else if ((UPGRADE_DATA_TYPE_CUS == upgrade_info->current_file_type) &&
 | 
						|
            (upgrade_info->cus_blocks == upgrade_info->block_idx)) {
 | 
						|
                next = false;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    return next;
 | 
						|
}
 | 
						|
 | 
						|
uint8_t cli_remote_upgrade_calculate_bcast_max_times()
 | 
						|
{
 | 
						|
    uint8_t max_times =
 | 
						|
        (uint8_t)upgrade_info->phase_one_broadcast_times;
 | 
						|
 | 
						|
    if (!max_times) {
 | 
						|
        max_times = IOT_PLC_UPGRADE_BCAST_TIMES_LEV1;
 | 
						|
        if (upgrade_info->dest_info.dst_total_num >
 | 
						|
            IOT_PLC_UPGRADE_BCAST_STA_THRESHOLD2) {
 | 
						|
            max_times = IOT_PLC_UPGRADE_BCAST_TIMES_LEV3;
 | 
						|
        } else if (upgrade_info->dest_info.dst_total_num >
 | 
						|
            IOT_PLC_UPGRADE_BCAST_STA_THRESHOLD) {
 | 
						|
            max_times = IOT_PLC_UPGRADE_BCAST_TIMES_LEV2;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    if (max_times > IOT_PLC_UPGRADE_BCAST_TIMES_LEV4) {
 | 
						|
        max_times = IOT_PLC_UPGRADE_BCAST_TIMES_LEV4;
 | 
						|
    }
 | 
						|
 | 
						|
    iot_printf("calculate bcast max times %d\n", max_times);
 | 
						|
 | 
						|
    return max_times;
 | 
						|
}
 | 
						|
 | 
						|
/* cco report broadcast progress to plc mgr */
 | 
						|
static void cli_remote_upgrade_report_broadcast_progress()
 | 
						|
{
 | 
						|
    uint8_t dest[IOT_MAC_ADDR_LEN] = { 0 };
 | 
						|
    uint16_t blocks = upgrade_info->block_idx + 1;
 | 
						|
    uint16_t total_blocks =
 | 
						|
        upgrade_info->pib_blocks + upgrade_info->fw_blocks;
 | 
						|
 | 
						|
    if (UPGRADE_DATA_TYPE_FW == upgrade_info->current_file_type) {
 | 
						|
        blocks += upgrade_info->pib_blocks;
 | 
						|
    }
 | 
						|
 | 
						|
    if ((blocks % IOT_PLC_UPGRADE_PROGRESS_BLOCKS_INTERVAL) == 0) {
 | 
						|
        uint8_t progress = (uint8_t)((blocks + total_blocks *
 | 
						|
            upgrade_info->broadcast_times) *
 | 
						|
            UPGRADE_BDCT_PROGRESS_IN_BCAST_PHASE / (total_blocks *
 | 
						|
                cli_remote_upgrade_calculate_bcast_max_times()));
 | 
						|
 | 
						|
        cli_remote_upgrade_send_upgrade_progress(progress, dest);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static uint32_t cli_remote_upgrade_calculate_broadcast_time()
 | 
						|
{
 | 
						|
    uint32_t base_interval_tm;
 | 
						|
 | 
						|
#if HW_PLATFORM == HW_PLATFORM_SIMU
 | 
						|
    base_interval_tm = IOT_PLC_UPGRADE_CCO_BCAST_TIME;
 | 
						|
#else
 | 
						|
    if (upgrade_info->dest_info.dst_total_num <=
 | 
						|
        IOT_PLC_UPGRADE_CCO_MIN_BCAST_NODE_CNT) {
 | 
						|
        base_interval_tm = IOT_PLC_UPGRADE_CCO_MIN_BCAST_TIME;
 | 
						|
    } else {
 | 
						|
        base_interval_tm = IOT_PLC_UPGRADE_CCO_SHORT_BCAST_TIME;
 | 
						|
    }
 | 
						|
#endif
 | 
						|
    base_interval_tm = (uint32_t)(base_interval_tm +
 | 
						|
        upgrade_info->dest_info.dst_total_num *
 | 
						|
        IOT_PLC_UPGRADE_STA_CNT_ADJ_VALUE + IOT_PLC_UPGRADE_PCO_ADJ_TIME *
 | 
						|
        upgrade_info->level_one_pco_count);
 | 
						|
    return base_interval_tm;
 | 
						|
}
 | 
						|
 | 
						|
void cli_remote_upgrade_bcast_tx_done()
 | 
						|
{
 | 
						|
    uint32_t interval = 0;
 | 
						|
    if (upgrade_info->bcast_wait_flag) {
 | 
						|
        upgrade_info->bcast_wait_flag = 0;
 | 
						|
        interval = cli_remote_upgrade_calculate_broadcast_time();
 | 
						|
        cli_upgrade_reset_timer(1, interval);
 | 
						|
    }
 | 
						|
}
 | 
						|
/* cco send broadcast data */
 | 
						|
void cli_remote_upgrade_cco_broadcast_data(bool_t first)
 | 
						|
{
 | 
						|
    uint8_t ctrl_type = UPGRADE_REMOTE_ALL_PHASE1_DATA;
 | 
						|
 | 
						|
    if (upgrade_info->upgrade_type == IOT_PLC_UPGRADE_STA_LIST) {
 | 
						|
        ctrl_type = UPGRADE_REMOTE_STA_LIST_DATA;
 | 
						|
    }
 | 
						|
 | 
						|
    if (cli_remote_upgrade_next_block_idx(first)) {
 | 
						|
        uint8_t dest[IOT_MAC_ADDR_LEN] = { 0 };
 | 
						|
        uint16_t idx[1];
 | 
						|
        idx[0] = upgrade_info->block_idx;
 | 
						|
 | 
						|
        cli_remote_upgrade_send_data(IOT_PLC_MSG_TYPE_BCAST,
 | 
						|
            upgrade_info->broadcast_retry_times, dest,
 | 
						|
            upgrade_info->upgrade_id, upgrade_info->current_file_type,
 | 
						|
            ctrl_type, upgrade_info->remote_block_size, idx, 1,
 | 
						|
            UPGRADE_DATA_FORWARD_INVALID,
 | 
						|
            cli_remote_upgrade_bcast_tx_done_callback);
 | 
						|
 | 
						|
        if (first) {
 | 
						|
            if (!os_is_timer_active(upgrade_info->upgrade_timer)) {
 | 
						|
                uint32_t broadcast_interval =
 | 
						|
                    cli_remote_upgrade_calculate_broadcast_time();
 | 
						|
                iot_printf("plc_upgrade: start broadcast data"
 | 
						|
                    " interval %d, retry times %d\n",
 | 
						|
                    broadcast_interval, upgrade_info->broadcast_retry_times);
 | 
						|
                os_start_timer(upgrade_info->upgrade_timer,
 | 
						|
                    broadcast_interval);
 | 
						|
            }
 | 
						|
        } else {
 | 
						|
            cli_remote_upgrade_report_broadcast_progress();
 | 
						|
        }
 | 
						|
    } else {
 | 
						|
        upgrade_info->broadcast_times++;
 | 
						|
        iot_printf("plc_upgrade:cco bcast time %d phase1\n",
 | 
						|
            upgrade_info->broadcast_times);
 | 
						|
        if (upgrade_info->broadcast_times <
 | 
						|
            cli_remote_upgrade_calculate_bcast_max_times()) {
 | 
						|
            cli_remote_upgrade_cco_broadcast_data(true);
 | 
						|
        } else {
 | 
						|
            cli_upgrade_reset_timer(0, 0);
 | 
						|
            iot_printf("plc_upgrade:coo stop broadcast\n");
 | 
						|
 | 
						|
            os_delay(5000);
 | 
						|
            iot_printf("plc_upgrade:phase 2\n");
 | 
						|
            upgrade_info->upgrade_state = IOT_PLC_UPGRADE_TRANSFERRED;
 | 
						|
 | 
						|
            iot_plc_query_neighbor_dev(host_config->app_handle,
 | 
						|
                IOT_PLC_API_REQ_ID_DEFAULT, 0, 1,
 | 
						|
                IOT_PLC_QUERY_TOPO_START_AS_TEI);
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void cli_remote_upgrade_prepare()
 | 
						|
{
 | 
						|
    upgrade_info->upgrade_state = IOT_PLC_UPGRADE_STARTING;
 | 
						|
    upgrade_info->fw_blocks = (uint16_t)iot_ceil(upgrade_info->fw_size,
 | 
						|
        upgrade_info->remote_block_size);
 | 
						|
    upgrade_info->pib_blocks = (uint16_t)iot_ceil(upgrade_info->pib_size,
 | 
						|
        upgrade_info->remote_block_size);
 | 
						|
    upgrade_info->cus_blocks = (uint16_t)iot_ceil(upgrade_info->cus_size,
 | 
						|
        upgrade_info->remote_block_size);
 | 
						|
 | 
						|
    iot_printf("cco prepare for upgrade pib blocks %d fw blocks %d"
 | 
						|
        "cus blocks %d\n", upgrade_info->pib_blocks, upgrade_info->fw_blocks,
 | 
						|
        upgrade_info->cus_blocks);
 | 
						|
    //create new upgrade id
 | 
						|
    upgrade_info->upgrade_id++;
 | 
						|
}
 | 
						|
 | 
						|
/* cco send upgrade broadcast start to sta list */
 | 
						|
uint32_t cli_remote_upgrade_broadcast_start_sta_list(bool_t first)
 | 
						|
{
 | 
						|
    uint32_t result = ERR_OK;
 | 
						|
 | 
						|
    if (first) {
 | 
						|
        upgrade_info->dest_info.upgrading_list_idx = 0;
 | 
						|
        cli_upgrade_reset_timer(1, upgrade_info->time_window);
 | 
						|
        iot_printf("upgrade start time window: %lu\n",
 | 
						|
            upgrade_info->time_window);
 | 
						|
    }
 | 
						|
    result = cli_remote_upgrade_multi_node_start_notify(IOT_PLC_MSG_TYPE_BCAST,
 | 
						|
        UPGRADE_START_UPGRADE_PHASE1);
 | 
						|
    if ((!first) && result == ERR_OK) {
 | 
						|
        upgrade_info->broadcast_times++;
 | 
						|
        iot_printf("plc_upgrade:cco bcast start cmd time %d phase1\n",
 | 
						|
            upgrade_info->broadcast_times);
 | 
						|
        if ((cli_remote_upgrade_find_init_dest_from_idx(0) != NULL) &&
 | 
						|
            (upgrade_info->broadcast_times <
 | 
						|
            IOT_PLC_UPGRADE_BROADCAST_TIMES_CNT)) {
 | 
						|
            cli_remote_upgrade_broadcast_start_sta_list(true);
 | 
						|
        } else {
 | 
						|
            iot_printf("plc_upgrade:coo stop broadcast start upgrade cmd\n");
 | 
						|
            cli_upgrade_reset_timer(0, 0);
 | 
						|
            upgrade_info->upgrade_state = IOT_PLC_UPGRADE_STARTED;
 | 
						|
            /*
 | 
						|
             * list node upgrade, begin broadcast upgrade data
 | 
						|
             * init broadcast upgrade file count
 | 
						|
             */
 | 
						|
            upgrade_info->broadcast_times = 0;
 | 
						|
            iot_printf("plc_upgrade:coo begin broadcast upgrade data\n");
 | 
						|
            cli_remote_upgrade_cco_broadcast_data(true);
 | 
						|
        }
 | 
						|
    }
 | 
						|
    return result;
 | 
						|
}
 | 
						|
 | 
						|
/* cco start sta list to start upgrade */
 | 
						|
void cli_remote_upgrade_sta_list_start()
 | 
						|
{
 | 
						|
    cli_remote_upgrade_prepare();
 | 
						|
 | 
						|
    cli_remote_upgrade_initialize_latest_block();
 | 
						|
    //init broadcast start upgrade count
 | 
						|
    upgrade_info->broadcast_times = 0;
 | 
						|
    upgrade_info->action_times = 0;
 | 
						|
    upgrade_info->last_timer_time = 0;
 | 
						|
    upgrade_info->time_window =
 | 
						|
        cli_remote_upgrade_calculate_time_window(upgrade_info->dst_list_idx);
 | 
						|
    iot_printf("plc_upgrade:coo start upgrade timer for broadcast data, "
 | 
						|
        "timewindow: %lu\n",
 | 
						|
        upgrade_info->time_window);
 | 
						|
    cli_remote_upgrade_broadcast_start_sta_list(true);
 | 
						|
}
 | 
						|
 | 
						|
/* cco start remote upgrade */
 | 
						|
void cli_remote_upgrade_all_sta_start()
 | 
						|
{
 | 
						|
    cli_remote_upgrade_prepare();
 | 
						|
 | 
						|
    //start broadcast
 | 
						|
    upgrade_info->broadcast_times = 0;
 | 
						|
    upgrade_info->upgrade_state = IOT_PLC_UPGRADE_STARTED;
 | 
						|
    cli_remote_upgrade_cco_broadcast_data(true);
 | 
						|
}
 | 
						|
 | 
						|
/* add status to list for report timer */
 | 
						|
void cli_remote_upgrade_add_report_status(
 | 
						|
    iot_plc_upgrade_dest_desc_t *status)
 | 
						|
{
 | 
						|
    if (status) {
 | 
						|
        if ((!status->updated) &&
 | 
						|
            (IOT_PLC_UPGRADE_LATEST_STATUS_MAX_CNT >
 | 
						|
                upgrade_info->dest_info.dest_idx))
 | 
						|
        {
 | 
						|
            status->updated = true;
 | 
						|
 | 
						|
            iot_printf("add status upgrade, %d, %d ",\
 | 
						|
                "mac: %02X:%02X:%02X:%02X:%02X:%02X\n",
 | 
						|
                status->percentage, status->error_code,
 | 
						|
                status->entry.addr[0], status->entry.addr[1],
 | 
						|
                status->entry.addr[2], status->entry.addr[3],
 | 
						|
                status->entry.addr[4], status->entry.addr[5]);
 | 
						|
 | 
						|
            upgrade_info->dest_info.latest_status_list[
 | 
						|
                upgrade_info->dest_info.dest_idx] = status;
 | 
						|
            upgrade_info->dest_info.dest_idx++;
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/* coo handle remote upgrade start ack from sta */
 | 
						|
void cli_remote_upgrade_start_ack(
 | 
						|
    uint8_t *buffer, uint32_t bufferlen, uint8_t *src_mac)
 | 
						|
{
 | 
						|
    (void)src_mac;
 | 
						|
    iot_plc_upgrade_dest_desc_t * dest = NULL;
 | 
						|
    iot_plc_upgrade_start_ul_t *ack;
 | 
						|
    ack = (iot_plc_upgrade_start_ul_t*)buffer;
 | 
						|
 | 
						|
    if (!ack){
 | 
						|
        IOT_ASSERT(ack);
 | 
						|
        return;
 | 
						|
    }
 | 
						|
    IOT_ASSERT(bufferlen >= sizeof(*ack));
 | 
						|
 | 
						|
    cli_upgrade_print_mac_info(ack->dst);
 | 
						|
 | 
						|
    dest = (iot_plc_upgrade_dest_desc_t *)
 | 
						|
        iot_addr_hash_table_find(upgrade_info->dest_info.table, ack->dst);
 | 
						|
    if (dest) {
 | 
						|
        if (UPGRADE_START_OK == ack->result) {
 | 
						|
            dest->status = IOT_PLC_UPGRADE_STARTED;
 | 
						|
        } else {
 | 
						|
            if ((dest->status != IOT_PLC_UPGRADE_TRANSFERRED) &&
 | 
						|
                (dest->status != IOT_PLC_UPGRADE_FAILED) &&
 | 
						|
                (dest->status != IOT_PLC_UPGRADE_START_FAIL)) {
 | 
						|
                iot_printf("upgrade result, mac: %02X:%02X:%02X:%02X:%02X:%02X,"
 | 
						|
                    " result %d\n",
 | 
						|
                    dest->entry.addr[0], dest->entry.addr[1],
 | 
						|
                    dest->entry.addr[2], dest->entry.addr[3],
 | 
						|
                    dest->entry.addr[4], dest->entry.addr[5],
 | 
						|
                    UPGRADE_START_END_SINCE_COMPLETED == ack->result);
 | 
						|
            }
 | 
						|
 | 
						|
            dest->status = IOT_PLC_UPGRADE_START_FAIL;
 | 
						|
            dest->error_code = UPGRADE_DATA_OTHER_ERROR;
 | 
						|
            if (UPGRADE_START_END_SINCE_COMPLETED == ack->result) {
 | 
						|
                if (dest->status != IOT_PLC_UPGRADE_TRANSFERRED) {
 | 
						|
                    upgrade_info->dest_info.dst_transferred_num++;
 | 
						|
                }
 | 
						|
                dest->status = IOT_PLC_UPGRADE_TRANSFERRED;
 | 
						|
                dest->error_code = UPGRADE_DATA_SUCCESS;
 | 
						|
            }
 | 
						|
 | 
						|
            cli_remote_upgrade_add_report_status(dest);
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/* cco check sta recv done */
 | 
						|
static uint8_t cli_remote_upgrade_check_sta_recv_done(uint8_t *bm, uint16_t cnt)
 | 
						|
{
 | 
						|
    uint8_t result = 1;
 | 
						|
    uint16_t byte_count = 0;
 | 
						|
    uint8_t over_bit = 0;
 | 
						|
 | 
						|
    byte_count = (cnt + 7) >> 3;
 | 
						|
    over_bit = (uint8_t)((byte_count << 3) - cnt);
 | 
						|
    /* last byte redundant bit set 1 */
 | 
						|
    bm[byte_count - 1] |= 0xff << (8 - over_bit);
 | 
						|
 | 
						|
    if (iot_bitmap_cbz(bm, byte_count) == 0) {
 | 
						|
        result = 1;
 | 
						|
    } else {
 | 
						|
        result = 0;
 | 
						|
    }
 | 
						|
 | 
						|
    return result;
 | 
						|
}
 | 
						|
/* cco handle sta info ack from sta */
 | 
						|
void cli_remote_upgrade_node_info_rsp(uint8_t *buffer, uint32_t bufferlen,
 | 
						|
    uint8_t *src_mac)
 | 
						|
{
 | 
						|
    (void)src_mac;
 | 
						|
    uint8_t err_code = 0;
 | 
						|
    uint16_t sta_written_block = 0;
 | 
						|
    uint16_t bm_size = 0;
 | 
						|
    iot_plc_upgrade_query_sta_info_ul_t *ack =
 | 
						|
        (iot_plc_upgrade_query_sta_info_ul_t *)buffer;
 | 
						|
    iot_plc_upgrade_dest_desc_t *dest;
 | 
						|
 | 
						|
    if (bufferlen < sizeof(*ack)) {
 | 
						|
        err_code = 1;
 | 
						|
        goto err;
 | 
						|
    }
 | 
						|
 | 
						|
    iot_printf("plc_upgrade:response node-%02X:%02X:%02X:%02X:%02X:%02X, "
 | 
						|
        "state:%d\n", ack->dst[0], ack->dst[1], ack->dst[2], ack->dst[3],
 | 
						|
        ack->dst[4], ack->dst[5], ack->state);
 | 
						|
    dest = (iot_plc_upgrade_dest_desc_t *)iot_addr_hash_table_find(
 | 
						|
        upgrade_info->dest_info.table, ack->dst);
 | 
						|
    if (dest == NULL) {
 | 
						|
        err_code = 2;
 | 
						|
        goto err;
 | 
						|
    }
 | 
						|
 | 
						|
    if (iot_mac_addr_cmp(ack->dst, upgrade_info->sta_mac) == 0) {
 | 
						|
        if (ack->state == IOT_PLC_UPGRADE_TRANSFERRED) {
 | 
						|
            dest->status = IOT_PLC_UPGRADE_TRANSFERRED;
 | 
						|
            dest->error_code = UPGRADE_DATA_SUCCESS;
 | 
						|
            dest->percentage = 100;
 | 
						|
        }
 | 
						|
 | 
						|
        err_code = 3;
 | 
						|
        goto err;
 | 
						|
    }
 | 
						|
 | 
						|
    if(upgrade_info->resend_data_state == CLI_SEND_DATA) {
 | 
						|
        err_code = 4;
 | 
						|
        goto err;
 | 
						|
    }
 | 
						|
 | 
						|
    upgrade_info->node_response_flag = 1;
 | 
						|
    if (ack->state == IOT_PLC_UPGRADE_INIT) {
 | 
						|
        /* the current node not started to upgrade, query the next node */
 | 
						|
        upgrade_info->resend_data_state = CLI_QUERY_NODE;
 | 
						|
        os_mem_set(upgrade_info->sta_mac, 0, IOT_MAC_ADDR_LEN);
 | 
						|
        cli_remote_upgrade_send_start_notify(IOT_PLC_MSG_TYPE_UNICAST,
 | 
						|
            dest->entry.addr, dest->entry.addr, UPGRADE_START_UPGRADE_PHASE1);
 | 
						|
        goto err;
 | 
						|
    }
 | 
						|
 | 
						|
    bm_size = (ack->cnt + 7) >> 3;
 | 
						|
    sta_written_block = (uint16_t)iot_bitmap_cbs(ack->bm, bm_size);
 | 
						|
    dest->percentage = (uint8_t)(sta_written_block * 100 /
 | 
						|
        (upgrade_info->pib_blocks + upgrade_info->fw_blocks));
 | 
						|
 | 
						|
    if (cli_remote_upgrade_check_sta_recv_done(ack->bm, ack->cnt) ||
 | 
						|
        ack->state == IOT_PLC_UPGRADE_TRANSFERRED) {
 | 
						|
        dest->status = IOT_PLC_UPGRADE_TRANSFERRED;
 | 
						|
        dest->error_code = UPGRADE_DATA_SUCCESS;
 | 
						|
        dest->percentage = 100;
 | 
						|
        upgrade_info->resend_data_state = CLI_QUERY_NODE;
 | 
						|
        os_mem_set(upgrade_info->sta_mac, 0, IOT_MAC_ADDR_LEN);
 | 
						|
        iot_printf("%02x:%02x:%02x:%02x:%02x:%02x: upgrade complete\n",
 | 
						|
            dest->entry.addr[0], dest->entry.addr[1], dest->entry.addr[2],
 | 
						|
            dest->entry.addr[3], dest->entry.addr[4], dest->entry.addr[5]);
 | 
						|
    } else {
 | 
						|
        os_mem_cpy(upgrade_info->full_bitmap, ack->bm, bm_size);
 | 
						|
        upgrade_info->resend_data_state = CLI_SEND_DATA;
 | 
						|
        dest->upgrade_type = CLI_UPGRADE_TYPE_V1;
 | 
						|
    }
 | 
						|
 | 
						|
err:
 | 
						|
    iot_printf("plc_upgrade: %s , resend state:%d err:%d \n", __FUNCTION__,
 | 
						|
        upgrade_info->resend_data_state, err_code);
 | 
						|
}
 | 
						|
 | 
						|
/* cco send upgrade result to plc manager */
 | 
						|
void cli_remote_upgrade_result(
 | 
						|
    uint8_t *buffer, uint32_t bufferlen, uint8_t *src_mac)
 | 
						|
{
 | 
						|
    (void)src_mac;
 | 
						|
    iot_plc_upgrade_dest_desc_t * dest = NULL;
 | 
						|
    iot_plc_upgrade_result_ul_t *result;
 | 
						|
    result = (iot_plc_upgrade_result_ul_t *)buffer;
 | 
						|
 | 
						|
    if ((!result) || (bufferlen < sizeof(*result))) {
 | 
						|
        iot_printf("%s param error", __FUNCTION__);
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    if (!upgrade_info->dest_info.table) {
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    dest = (iot_plc_upgrade_dest_desc_t *)iot_addr_hash_table_find(
 | 
						|
        upgrade_info->dest_info.table, result->dst);
 | 
						|
    if (dest) {
 | 
						|
        if ((dest->status != IOT_PLC_UPGRADE_TRANSFERRED) &&
 | 
						|
            (dest->status != IOT_PLC_UPGRADE_FAILED)) {
 | 
						|
            upgrade_info->sta_upgrade_active = 1;
 | 
						|
            iot_printf("upgrade result, mac: %02X:%02X:%02X:%02X:%02X:%02X,"
 | 
						|
                " result %d\n",
 | 
						|
                dest->entry.addr[0], dest->entry.addr[1],
 | 
						|
                dest->entry.addr[2], dest->entry.addr[3],
 | 
						|
                dest->entry.addr[4], dest->entry.addr[5],
 | 
						|
                result->error_code);
 | 
						|
        }
 | 
						|
 | 
						|
        if (UPGRADE_DATA_SUCCESS == result->error_code) {
 | 
						|
            if (dest->status != IOT_PLC_UPGRADE_TRANSFERRED) {
 | 
						|
                upgrade_info->dest_info.dst_transferred_num++;
 | 
						|
            }
 | 
						|
            cli_remote_upgrade_send_stop_rpt_notify(result->dst);
 | 
						|
            dest->status = IOT_PLC_UPGRADE_TRANSFERRED;
 | 
						|
            dest->error_code = result->error_code;
 | 
						|
            if (upgrade_info->control_upgrade_flag) {
 | 
						|
                 /* the current node upgrade complete, resend next node */
 | 
						|
                if (iot_mac_addr_cmp(upgrade_info->sta_mac, result->dst)) {
 | 
						|
                    os_mem_set(upgrade_info->sta_mac, 0, IOT_METER_ADDR_LEN);
 | 
						|
                    upgrade_info->node_response_flag = 1;
 | 
						|
                    upgrade_info->resend_data_state = CLI_QUERY_NODE;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        } else {
 | 
						|
            dest->status = IOT_PLC_UPGRADE_FAILED;
 | 
						|
            dest->error_code = result->error_code;
 | 
						|
        }
 | 
						|
 | 
						|
        cli_remote_upgrade_add_report_status(dest);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/* cco send upgrade progress to plc manager */
 | 
						|
void cli_remote_upgrade_progress(
 | 
						|
    uint8_t *buffer, uint32_t bufferlen, uint8_t *src_mac)
 | 
						|
{
 | 
						|
    (void)src_mac;
 | 
						|
    iot_plc_upgrade_dest_desc_t * dest = NULL;
 | 
						|
    iot_plc_upgrade_progress_ul_t *progress;
 | 
						|
    progress = (iot_plc_upgrade_progress_ul_t *)buffer;
 | 
						|
 | 
						|
    if ((!progress) || (bufferlen < sizeof(*progress))) {
 | 
						|
        iot_printf("%s param error", __FUNCTION__);
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    if (!upgrade_info->dest_info.table) {
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    upgrade_info->sta_upgrade_active = 1;
 | 
						|
 | 
						|
    dest = (iot_plc_upgrade_dest_desc_t *)iot_addr_hash_table_find(
 | 
						|
        upgrade_info->dest_info.table, progress->dst);
 | 
						|
    if (dest) {
 | 
						|
        dest->percentage = progress->progress;
 | 
						|
        dest->error_code = UPGRADE_DATA_STA_IN_PROGRESS;
 | 
						|
 | 
						|
        cli_remote_upgrade_add_report_status(dest);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/* initialize upgrading list */
 | 
						|
void cli_remote_upgrade_initialize_upgrading_list()
 | 
						|
{
 | 
						|
    uint16_t index = 0;
 | 
						|
    upgrade_info->dest_info.upgrading_list_idx = 0;
 | 
						|
    for (uint16_t i = 0; i < upgrade_info->dest_info.dst_total_num; i++) {
 | 
						|
        iot_plc_upgrade_dest_desc_t *desc =
 | 
						|
            upgrade_info->dest_info.entry_ptr[i];
 | 
						|
        // add uncompleted sta into
 | 
						|
        if (desc && (IOT_PLC_UPGRADE_TRANSFERRED != desc->status &&
 | 
						|
            (index < IOT_PLC_UPGRADE_PHASE_THREE_MAX_SAT_CNT))) {
 | 
						|
            upgrade_info->dest_info.upgrading_list[index] = desc;
 | 
						|
            index++;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    upgrade_info->dst_list_idx = index;
 | 
						|
    iot_printf("plc_upgrade:cco initialize upgrading"
 | 
						|
        " list for phase3 %lu\n", index);
 | 
						|
}
 | 
						|
 | 
						|
static uint8_t cli_remote_upgrade_conform_node_mode(
 | 
						|
    iot_plc_upgrade_dest_desc_t *dest, uint8_t mode)
 | 
						|
{
 | 
						|
    uint8_t result = 0;
 | 
						|
 | 
						|
    if (mode == CLI_FIND_START_NODE) {
 | 
						|
        if ((dest->upgrade_type == CLI_UPGRADE_TYPE_UNKNOWN) ||
 | 
						|
            (dest->upgrade_type == CLI_UPGRADE_TYPE_V0)) {
 | 
						|
            result = 1;
 | 
						|
        }
 | 
						|
    } else {
 | 
						|
        if ((dest->upgrade_type == CLI_UPGRADE_TYPE_UNKNOWN) ||
 | 
						|
            (dest->upgrade_type == CLI_UPGRADE_TYPE_V1)) {
 | 
						|
            result = 1;
 | 
						|
        }
 | 
						|
 | 
						|
    }
 | 
						|
    return result;
 | 
						|
}
 | 
						|
 | 
						|
static iot_plc_upgrade_dest_desc_t *
 | 
						|
cli_remote_upgrade_find_uncompleted_dest_from_idx(uint16_t start_idx,
 | 
						|
    uint8_t mode)
 | 
						|
{
 | 
						|
    iot_plc_upgrade_dest_desc_t *dest = NULL;
 | 
						|
    while ((start_idx < IOT_PLC_UPGRADE_PHASE_THREE_MAX_SAT_CNT) &&
 | 
						|
        upgrade_info->dest_info.upgrading_list[start_idx]) {
 | 
						|
        if (IOT_PLC_UPGRADE_TRANSFERRED !=
 | 
						|
            upgrade_info->dest_info.upgrading_list[start_idx]->status) {
 | 
						|
            if (cli_remote_upgrade_conform_node_mode(
 | 
						|
                upgrade_info->dest_info.upgrading_list[start_idx], mode)) {
 | 
						|
                dest = upgrade_info->dest_info.upgrading_list[start_idx];
 | 
						|
                upgrade_info->dest_info.upgrading_list_idx = start_idx + 1;
 | 
						|
                break;
 | 
						|
            }
 | 
						|
        }
 | 
						|
        start_idx++;
 | 
						|
    }
 | 
						|
    return dest;
 | 
						|
}
 | 
						|
 | 
						|
static iot_plc_upgrade_dest_desc_t *cli_remote_upgrade_find_uncompleted_dest(
 | 
						|
        uint8_t mode)
 | 
						|
{
 | 
						|
    iot_plc_upgrade_dest_desc_t *dest = NULL;
 | 
						|
    dest = cli_remote_upgrade_find_uncompleted_dest_from_idx(
 | 
						|
        upgrade_info->dest_info.upgrading_list_idx, mode);
 | 
						|
 | 
						|
    if (!dest) {
 | 
						|
        dest = cli_remote_upgrade_find_uncompleted_dest_from_idx(0, mode);
 | 
						|
    }
 | 
						|
 | 
						|
    return dest;
 | 
						|
}
 | 
						|
 | 
						|
/* get resend phase time window */
 | 
						|
uint16_t cli_remote_upgrade_get_resend_time_window(uint16_t node_cnt)
 | 
						|
{
 | 
						|
    uint16_t result = IOT_PLC_UPGRADE_CCO_SHORT_BCAST_TIME;
 | 
						|
 | 
						|
    if (node_cnt > 500) {
 | 
						|
        result += ((node_cnt - 200) + (node_cnt - 500) * 2);
 | 
						|
    } else if (node_cnt > 300) {
 | 
						|
         result += ((node_cnt - 100) + (node_cnt - 300) * 2);
 | 
						|
    } else if (node_cnt > 50) {
 | 
						|
        result += (node_cnt - 50) * 2;
 | 
						|
    }
 | 
						|
 | 
						|
    return result;
 | 
						|
}
 | 
						|
 | 
						|
static uint8_t cli_remote_upgrade_find_resend_dest()
 | 
						|
{
 | 
						|
    uint8_t query_cnt = 0;
 | 
						|
    iot_plc_upgrade_dest_desc_t *dest = NULL;
 | 
						|
 | 
						|
    dest = cli_remote_upgrade_find_uncompleted_dest(CLI_FIND_QUERY_NODE);
 | 
						|
    if (dest) {
 | 
						|
        iot_mac_addr_cpy(upgrade_info->sta_mac, dest->entry.addr);
 | 
						|
        query_cnt++;
 | 
						|
        iot_printf("plc_upgrade: find a resend node -"
 | 
						|
            "%02X:%02X:%02X:%02X:%02X:%02X\n", dest->entry.addr[0],
 | 
						|
            dest->entry.addr[1], dest->entry.addr[2], dest->entry.addr[3],
 | 
						|
            dest->entry.addr[4], dest->entry.addr[5]);
 | 
						|
    }
 | 
						|
 | 
						|
    return query_cnt;
 | 
						|
}
 | 
						|
 | 
						|
static void cli_remote_upgrade_query_node_bitmap(uint16_t start, uint16_t cnt)
 | 
						|
{
 | 
						|
    iot_plc_upgrade_query_sta_info_dl_t query_dl = {0};
 | 
						|
 | 
						|
    if (iot_mac_addr_valid(upgrade_info->sta_mac) == 0) {
 | 
						|
        iot_printf("plc_upgrade: %s dest mac invalid\n", __FUNCTION__);
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    query_dl.upgrade_id = upgrade_info->upgrade_id;
 | 
						|
    query_dl.start_idx = start;
 | 
						|
    query_dl.cnt = cnt;
 | 
						|
    iot_mac_addr_cpy(query_dl.dst, upgrade_info->sta_mac);
 | 
						|
 | 
						|
    iot_cli_module_send_data_with_retry(IOT_PLC_MSG_TYPE_UNICAST,
 | 
						|
        IOT_PLC_UPGRADE_PHASE_THREE_RETRY_TIMES,
 | 
						|
        CLI_MODULEID_HOSTINTERFACE,
 | 
						|
        CLI_MSGID_UPGRADE_NODE_INFO_QUERY, host_config->mac_addr,
 | 
						|
        upgrade_info->sta_mac, (uint8_t*)&query_dl, sizeof(query_dl));
 | 
						|
    iot_printf("plc_upgrade: cco send query node info cmd\n");
 | 
						|
}
 | 
						|
 | 
						|
static uint16_t cli_remote_upgrade_find_miss_block(uint8_t *file_type)
 | 
						|
{
 | 
						|
    uint16_t block_index = 0;
 | 
						|
    uint16_t bm_size = 0;
 | 
						|
    uint16_t fw_blocks = upgrade_info->fw_blocks;
 | 
						|
    uint16_t pib_blocks = upgrade_info->pib_blocks;
 | 
						|
 | 
						|
    bm_size = (pib_blocks + fw_blocks + 7) >> 3;
 | 
						|
    block_index =
 | 
						|
        (uint16_t)iot_bitmap_ffz_and_s(upgrade_info->full_bitmap, bm_size);
 | 
						|
 | 
						|
    if (block_index > 0) {
 | 
						|
        if (block_index <= pib_blocks) {
 | 
						|
            *file_type = UPGRADE_DATA_TYPE_PIB;
 | 
						|
            block_index -= 1;
 | 
						|
        } else if (block_index <= (fw_blocks + pib_blocks)) {
 | 
						|
            *file_type = UPGRADE_DATA_TYPE_FW;
 | 
						|
            block_index -= pib_blocks + 1;
 | 
						|
        }
 | 
						|
    } else {
 | 
						|
        if (upgrade_info->full_bitmap[0] & 0x01) {
 | 
						|
            /* if block index is 0,but bitmap bit0 is 1, return invalid index */
 | 
						|
            block_index = IOT_PLC_UPGRADE_INVALID_BLOCK_INDEX;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    return block_index;
 | 
						|
}
 | 
						|
 | 
						|
static uint8_t cli_remote_upgrade_send_miss_block()
 | 
						|
{
 | 
						|
    uint8_t file_type = UPGRADE_DATA_TYPE_PIB;
 | 
						|
    uint16_t idx[1];
 | 
						|
    uint16_t block_idx;
 | 
						|
    uint8_t i = 0;
 | 
						|
 | 
						|
    if (iot_mac_addr_valid(upgrade_info->sta_mac) == 0) {
 | 
						|
        iot_printf("plc_upgrade: %s dest mac invalid\n", __FUNCTION__);
 | 
						|
        return 0;
 | 
						|
    }
 | 
						|
 | 
						|
    for (i = 0; i < IOT_PLC_UPGRADE_SEND_BLOCK_CNT; ++i) {
 | 
						|
        block_idx = cli_remote_upgrade_find_miss_block(&file_type);
 | 
						|
        if (block_idx == IOT_PLC_UPGRADE_INVALID_BLOCK_INDEX) {
 | 
						|
            return 0;
 | 
						|
        }
 | 
						|
 | 
						|
        idx[0] = block_idx;
 | 
						|
 | 
						|
        cli_remote_upgrade_send_data(IOT_PLC_MSG_TYPE_UNICAST,
 | 
						|
            IOT_PLC_UPGRADE_MAX_START_RETRY_TIMES, upgrade_info->sta_mac,
 | 
						|
            upgrade_info->upgrade_id, file_type, UPGRADE_REMOTE_STA_LIST_DATA,
 | 
						|
            upgrade_info->remote_block_size, idx, 1,
 | 
						|
            UPGRADE_DATA_FORWARD_LOCAL_BCAST, NULL);
 | 
						|
    }
 | 
						|
 | 
						|
    return 1;
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
uint8_t cli_remote_upgrade_resend_phase()
 | 
						|
{
 | 
						|
    uint8_t node_cnt = 1;
 | 
						|
 | 
						|
    if (upgrade_info->node_response_flag) {
 | 
						|
        if (upgrade_info->resend_data_state == CLI_QUERY_NODE) {
 | 
						|
            if (iot_mac_addr_valid(upgrade_info->sta_mac) == 0) {
 | 
						|
                node_cnt = cli_remote_upgrade_find_resend_dest();
 | 
						|
                upgrade_info->query_node_retry_cnt = 0;
 | 
						|
            }
 | 
						|
            cli_remote_upgrade_query_node_bitmap(1, IOT_PLC_UPGRADE_QUERY_BM_ALL);
 | 
						|
            upgrade_info->dest_info.query_node_timeout_cnt = 0;
 | 
						|
            upgrade_info->node_response_flag = 0;
 | 
						|
            upgrade_info->query_node_retry_cnt++;
 | 
						|
            os_mem_set(upgrade_info->full_bitmap, 0,
 | 
						|
                IOT_PLC_UPGRADE_STA_BM_SIZE_MAX);
 | 
						|
 | 
						|
        } else if (upgrade_info->resend_data_state == CLI_SEND_DATA) {
 | 
						|
            if (cli_remote_upgrade_send_miss_block() == 0) {
 | 
						|
                upgrade_info->resend_data_state = CLI_QUERY_NODE;
 | 
						|
                os_mem_set(upgrade_info->full_bitmap, 0,
 | 
						|
                    IOT_PLC_UPGRADE_STA_BM_SIZE_MAX);
 | 
						|
 | 
						|
                if (upgrade_info->query_node_retry_cnt >
 | 
						|
                    IOT_PLC_UPGRADE_QUERY_RETRY_MAX) {
 | 
						|
                    os_mem_set(upgrade_info->sta_mac, 0, IOT_MAC_ADDR_LEN);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
    } else {
 | 
						|
        upgrade_info->dest_info.query_node_timeout_cnt++;
 | 
						|
        if (upgrade_info->dest_info.query_node_timeout_cnt >=
 | 
						|
            upgrade_info->dest_info.query_node_timeout) {
 | 
						|
            upgrade_info->node_response_flag = 1;
 | 
						|
            upgrade_info->resend_data_state = CLI_QUERY_NODE;
 | 
						|
            os_mem_set(upgrade_info->sta_mac, 0, IOT_MAC_ADDR_LEN);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    return node_cnt;
 | 
						|
}
 | 
						|
 | 
						|
void cli_remote_upgrade_complete()
 | 
						|
{
 | 
						|
    iot_printf("plc_upgrade: cli remote upgrade complete\n");
 | 
						|
    upgrade_info->upgrade_state = IOT_PLC_UPGRADE_STOPED;
 | 
						|
}
 | 
						|
 | 
						|
/* start phase three */
 | 
						|
uint8_t cli_remote_upgrade_start_phase_three()
 | 
						|
{
 | 
						|
    iot_plc_upgrade_dest_desc_t *dest = NULL;
 | 
						|
    iot_plc_upgrade_dest_desc_t *prev = NULL;
 | 
						|
    uint8_t phase_three_cnt = IOT_PLC_UPGRADE_PHASE_THREE_START_CNT;
 | 
						|
    uint8_t dec_mac[IOT_MAC_ADDR_LEN] = { 0 };
 | 
						|
    uint8_t total_send_cnt = 0;
 | 
						|
    iot_printf("plc_upgrade: cco start phase3\n");
 | 
						|
    for (uint8_t i = 0; i < phase_three_cnt; i++) {
 | 
						|
        //find next start sta
 | 
						|
        dest = cli_remote_upgrade_find_uncompleted_dest(CLI_FIND_START_NODE);
 | 
						|
 | 
						|
        if (!dest) {
 | 
						|
            break;
 | 
						|
        }
 | 
						|
 | 
						|
        if (prev && (prev == dest)) {
 | 
						|
            break;
 | 
						|
        } else {
 | 
						|
            prev = dest;
 | 
						|
        }
 | 
						|
        if (IOT_PLC_UPGRADE_STA_LIST == upgrade_info->upgrade_type) {
 | 
						|
            iot_mac_addr_cpy(dec_mac, dest->entry.addr);
 | 
						|
        }
 | 
						|
        cli_remote_upgrade_send_start_notify(IOT_PLC_MSG_TYPE_UNICAST,
 | 
						|
            dest->entry.addr, dec_mac, UPGRADE_START_UPGRADE_PHASE3);
 | 
						|
        total_send_cnt++;
 | 
						|
    }
 | 
						|
    return total_send_cnt;
 | 
						|
}
 | 
						|
 | 
						|
/* cco receive stop ack from sta */
 | 
						|
void cli_upgrade_stop_ack(
 | 
						|
    uint8_t *buffer, uint32_t bufferlen, uint8_t *src_mac)
 | 
						|
{
 | 
						|
    (void)src_mac;
 | 
						|
    iot_plc_upgrade_stop_ul_t *stop_ul;
 | 
						|
    stop_ul = (iot_plc_upgrade_stop_ul_t *)buffer;
 | 
						|
 | 
						|
    if ((!stop_ul) || (bufferlen < sizeof(*stop_ul))) {
 | 
						|
        iot_printf("%s param error", __FUNCTION__);
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    cli_upgrade_send_stop_ack(stop_ul->dst, stop_ul->error_code);
 | 
						|
 | 
						|
    if (upgrade_info->dest_info.table) {
 | 
						|
        iot_plc_upgrade_dest_desc_t * dest = (iot_plc_upgrade_dest_desc_t *)
 | 
						|
            iot_addr_hash_table_find(
 | 
						|
                upgrade_info->dest_info.table, stop_ul->dst);
 | 
						|
 | 
						|
        if (dest) {
 | 
						|
            dest->status = IOT_PLC_UPGRADE_STOPED;
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/* cco receive reset ack from sta */
 | 
						|
void cli_upgrade_reset_ack(
 | 
						|
    uint8_t *buffer, uint32_t bufferlen, uint8_t *src_mac)
 | 
						|
{
 | 
						|
    (void)src_mac;
 | 
						|
    iot_plc_upgrade_reset_ul_t *reset_ul;
 | 
						|
    reset_ul = (iot_plc_upgrade_reset_ul_t *)buffer;
 | 
						|
 | 
						|
    if ((!reset_ul) || (bufferlen < sizeof(*reset_ul))) {
 | 
						|
        iot_printf("%s param error", __FUNCTION__);
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    cli_upgrade_send_reset_ack(reset_ul->dst, reset_ul->error_code);
 | 
						|
}
 | 
						|
 | 
						|
/* cco handle sta join */
 | 
						|
void iot_cli_cco_handle_sta_join(uint8_t *mac)
 | 
						|
{
 | 
						|
    iot_plc_upgrade_dest_desc_t *dest = NULL;
 | 
						|
    iot_printf("plc_upgrade: sta join\n");
 | 
						|
    cli_upgrade_print_mac_info(mac);
 | 
						|
    dest = (iot_plc_upgrade_dest_desc_t *)iot_addr_hash_table_find(
 | 
						|
        upgrade_info->dest_info.table, mac);
 | 
						|
    if (!dest) {
 | 
						|
        cli_upgrade_add_dest_info(mac);
 | 
						|
        // add node to phase3
 | 
						|
        if (IOT_PLC_UPGRADE_ALL == upgrade_info->upgrade_type) {
 | 
						|
            if (upgrade_info->dst_list_idx) {
 | 
						|
                cli_upgrade_add_upgrade_list_dest_info(mac, 1, 0);
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/* cco handle sta leave */
 | 
						|
void iot_cli_cco_handle_sta_leave(iot_plc_sta_info_t *sta)
 | 
						|
{
 | 
						|
    iot_plc_upgrade_dest_desc_t *dest = NULL;
 | 
						|
 | 
						|
    iot_printf("plc_upgrade: sta leave\n");
 | 
						|
    cli_upgrade_print_mac_info(sta->mac_addr);
 | 
						|
 | 
						|
    if (!upgrade_info->dest_info.dst_total_num) {
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    dest = (iot_plc_upgrade_dest_desc_t *)
 | 
						|
        iot_addr_hash_table_find(upgrade_info->dest_info.table, sta->mac_addr);
 | 
						|
 | 
						|
    if (dest) {
 | 
						|
        dest->error_code = UPGRADE_DATA_STA_LEAVE;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void iot_cli_upgrade_app_register_handler(iot_cli_upgrade_app_handler handler)
 | 
						|
{
 | 
						|
    sg_upgrade_handler = handler;
 | 
						|
}
 | 
						|
 | 
						|
void cli_upgrade_cache_file_init(uint8_t *file_hdr)
 | 
						|
{
 | 
						|
    upgrade_info->cus_size = iot_get_file_cus_len(file_hdr);
 | 
						|
    upgrade_info->cus_data = NULL;
 | 
						|
 | 
						|
    upgrade_info->pib_size = 0;
 | 
						|
    upgrade_info->pib_data = NULL;
 | 
						|
 | 
						|
    upgrade_info->fw_size = (iot_get_file_len(file_hdr) +
 | 
						|
        iot_get_file_header_len(file_hdr)) - upgrade_info->cus_size;
 | 
						|
    upgrade_info->fw_data = NULL;
 | 
						|
 | 
						|
    cli_upgrade_write_data_to_flash_cache_init(upgrade_info->upgrade_id++,
 | 
						|
        upgrade_info->fw_size, upgrade_info->cus_size, upgrade_info->block_size);
 | 
						|
}
 | 
						|
 | 
						|
uint32_t iot_cli_upgrade_prepare(iot_cli_upgrade_completed_handler handler,
 | 
						|
    uint32_t file_size, uint8_t **data, uint8_t *file_hdr, uint16_t block_size,
 | 
						|
    uint8_t upgrade_type)
 | 
						|
{
 | 
						|
    uint32_t ret = ERR_OK;
 | 
						|
    uint32_t file_len = iot_get_file_len(file_hdr);
 | 
						|
 | 
						|
    /* if the file header is invalid, the file size is used */
 | 
						|
    if (file_len == 0) {
 | 
						|
        file_len = file_size;
 | 
						|
    } else {
 | 
						|
        file_len += iot_get_file_header_len(file_hdr);
 | 
						|
    }
 | 
						|
    if ((block_size != 100) && (block_size != 200) &&
 | 
						|
        (block_size != 300) && (block_size != 400)) {
 | 
						|
        iot_printf("%s block size %d is invalid\n", block_size);
 | 
						|
        ret = ERR_FAIL;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
 | 
						|
    if (file_size) {
 | 
						|
        cli_remote_upgrade_dest_info_reset();
 | 
						|
    } else {
 | 
						|
        ret = ERR_FAIL;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
 | 
						|
    if (handler) {
 | 
						|
        upgrade_info->completed_handler = handler;
 | 
						|
    }
 | 
						|
 | 
						|
    upgrade_info->block_size = block_size;
 | 
						|
#if IOT_CLI_UPGRADE_CACHE_TYPE
 | 
						|
    (void)file_hdr;
 | 
						|
    (void)upgrade_type;
 | 
						|
    if (file_len > IOT_CLI_UPGRADE_MAX_FILE_SIZE) {
 | 
						|
        ret = ERR_FAIL;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
#else
 | 
						|
    uint8_t part_num;
 | 
						|
    uint32_t part_size = 0;
 | 
						|
    if (upgrade_type == IOT_PLC_UPGRADE_LOCAL) {
 | 
						|
        ret = ERR_FAIL;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    dev_get_upgrade_fw_part_num(&part_num);
 | 
						|
    part_size = dev_get_part_size(part_num);
 | 
						|
    if (file_len > part_size) {
 | 
						|
        ret = ERR_FAIL;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    cli_upgrade_cache_file_init(file_hdr);
 | 
						|
    upgrade_info->fw_start = iot_get_file_fw_start(file_hdr);
 | 
						|
    upgrade_info->pib_start = iot_get_file_pib_start(file_hdr);
 | 
						|
    upgrade_info->cus_start = iot_get_file_cus_start(file_hdr);
 | 
						|
    upgrade_info->fw_size = iot_get_file_fw_len(file_hdr);
 | 
						|
    upgrade_info->pib_size = iot_get_file_pib_len(file_hdr);
 | 
						|
    upgrade_info->cus_size = iot_get_file_cus_len(file_hdr);
 | 
						|
#endif
 | 
						|
    *data = upgrade_info->file_data;
 | 
						|
out:
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
void iot_cli_translate_file()
 | 
						|
{
 | 
						|
    upgrade_info->fw_size = iot_get_file_fw_len(upgrade_info->file_data);
 | 
						|
    upgrade_info->pib_size = iot_get_file_pib_len(upgrade_info->file_data);
 | 
						|
    upgrade_info->cus_size = iot_get_file_cus_len(upgrade_info->file_data);
 | 
						|
 | 
						|
    upgrade_info->pib_data = upgrade_info->file_data +
 | 
						|
        iot_get_file_pib_start(upgrade_info->file_data);
 | 
						|
    upgrade_info->fw_data = upgrade_info->file_data +
 | 
						|
        iot_get_file_fw_start(upgrade_info->file_data);
 | 
						|
    upgrade_info->cus_data = upgrade_info->file_data +
 | 
						|
        iot_get_file_cus_start(upgrade_info->file_data);
 | 
						|
}
 | 
						|
 | 
						|
uint32_t iot_cli_upgrade_calc_file_crc(uint32_t file_size, uint32_t start_pos)
 | 
						|
{
 | 
						|
    uint32_t crc_tmp = 0xFFFFFFFF;
 | 
						|
 | 
						|
    uint32_t index = 0;
 | 
						|
    uint8_t *ptr;
 | 
						|
    uint32_t block_size = 2000;
 | 
						|
    uint32_t read_size = block_size;
 | 
						|
    iot_pkt_t *pkt = iot_pkt_alloc(block_size, IOT_CLI_MID);
 | 
						|
    IOT_ASSERT(pkt);
 | 
						|
 | 
						|
    ptr = iot_pkt_put(pkt, block_size);
 | 
						|
 | 
						|
    while (index < file_size) {
 | 
						|
        if ((index + block_size) > file_size) {
 | 
						|
            read_size = file_size - index;
 | 
						|
        }
 | 
						|
 | 
						|
        cli_upgrade_read_data_from_flash(UPGRADE_DATA_TYPE_FW,
 | 
						|
            start_pos + index, ptr, (uint16_t)read_size);
 | 
						|
 | 
						|
        crc_tmp = iot_getcrc32_update(crc_tmp, ptr, read_size);
 | 
						|
        index += block_size;
 | 
						|
    }
 | 
						|
 | 
						|
    iot_pkt_free(pkt);
 | 
						|
    return (crc_tmp ^ 0xFFFFFFFF);
 | 
						|
}
 | 
						|
 | 
						|
uint8_t  iot_cli_upgrade_external_start(uint8_t upgrade_type,
 | 
						|
    uint8_t control_flag)
 | 
						|
{
 | 
						|
 | 
						|
    if (upgrade_info->upgrade_state != IOT_PLC_UPGRADE_INIT) {
 | 
						|
        return UPGRADE_START_CCO_UPGRADING;
 | 
						|
    }
 | 
						|
    if ((IOT_PLC_UPGRADE_ALL != upgrade_type) &&
 | 
						|
        (IOT_PLC_UPGRADE_STA_LIST != upgrade_type)) {
 | 
						|
        iot_printf("cli upgrade not support upgrade type: %d\n", upgrade_type);
 | 
						|
        return UPGRADE_START_INVALID_TYPE;
 | 
						|
    }
 | 
						|
    iot_printf("cli upgrade start\n");
 | 
						|
 | 
						|
#if IOT_CLI_UPGRADE_CACHE_TYPE
 | 
						|
    iot_cli_translate_file();
 | 
						|
 | 
						|
    if (upgrade_info->fw_data && upgrade_info->fw_size) {
 | 
						|
        upgrade_info->fw_checksum =
 | 
						|
            iot_getcrc32(upgrade_info->fw_data, upgrade_info->fw_size);
 | 
						|
    }
 | 
						|
 | 
						|
    if (upgrade_info->pib_data && upgrade_info->pib_size) {
 | 
						|
        upgrade_info->pib_checksum =
 | 
						|
            iot_getcrc32(upgrade_info->pib_data, upgrade_info->pib_size);
 | 
						|
    }
 | 
						|
 | 
						|
    if (upgrade_info->cus_data && upgrade_info->cus_size) {
 | 
						|
        upgrade_info->cus_checksum =
 | 
						|
            iot_getcrc32(upgrade_info->cus_data, upgrade_info->cus_size);
 | 
						|
    }
 | 
						|
#else
 | 
						|
    //delay for share task write upgrade file.
 | 
						|
    os_delay(100);
 | 
						|
    if (upgrade_info->fw_size) {
 | 
						|
        upgrade_info->fw_checksum = iot_cli_upgrade_calc_file_crc(
 | 
						|
            upgrade_info->fw_size, upgrade_info->fw_start);
 | 
						|
    }
 | 
						|
 | 
						|
    if (upgrade_info->pib_size) {
 | 
						|
        upgrade_info->pib_checksum = iot_cli_upgrade_calc_file_crc(
 | 
						|
            upgrade_info->pib_size, upgrade_info->pib_start);
 | 
						|
    }
 | 
						|
 | 
						|
    if (upgrade_info->cus_size) {
 | 
						|
        upgrade_info->cus_checksum = iot_cli_upgrade_calc_file_crc(
 | 
						|
            upgrade_info->cus_size, upgrade_info->cus_start);
 | 
						|
    }
 | 
						|
#endif
 | 
						|
 | 
						|
    cli_remote_upgrade_sta_initialize(upgrade_type,
 | 
						|
        UPGRADE_DEFAULT_BLOCK_SIZE, UPGRADE_DEFAULT_BLOCK_SIZE,
 | 
						|
        upgrade_info->fw_size, upgrade_info->pib_size, upgrade_info->cus_size,
 | 
						|
        upgrade_info->fw_checksum, upgrade_info->pib_checksum,
 | 
						|
        upgrade_info->cus_checksum, IOT_PLC_UPGRADE_DEFAULT_TIMER,
 | 
						|
        IOT_PLC_UPGRADE_DEFAULT_REMOTE_BLOCK_CNT);
 | 
						|
 | 
						|
    upgrade_info->control_upgrade_flag = !!control_flag;
 | 
						|
    upgrade_info->level_one_pco_count = IOT_PLC_UPGRADE_PCO_DEFAULT_ADJ_COUNT;
 | 
						|
    upgrade_info->broadcast_retry_times =
 | 
						|
        IOT_PLC_UPGRADE_CCO_BCAST_MIN_RETRY_CNT;
 | 
						|
    //start sg upgrade
 | 
						|
    cli_remote_upgrade_prepare();
 | 
						|
    if (IOT_PLC_UPGRADE_STA_LIST == upgrade_type) {
 | 
						|
        cli_remote_upgrade_sta_list_start();
 | 
						|
    } else {
 | 
						|
        /* init upgrade list */
 | 
						|
        cli_upgrade_add_upgrade_list_dest_info(NULL, 0, 1);
 | 
						|
        upgrade_info->upgrade_state = IOT_PLC_UPGRADE_STARTED;
 | 
						|
        cli_remote_upgrade_cco_broadcast_data(true);
 | 
						|
    }
 | 
						|
    return UPGRADE_START_OK;
 | 
						|
}
 | 
						|
 | 
						|
/* sg cli upgrade start */
 | 
						|
uint8_t iot_cli_upgrade_start(uint8_t upgrade_type, uint8_t control_flag)
 | 
						|
{
 | 
						|
    return iot_cli_upgrade_external_start(upgrade_type, control_flag);
 | 
						|
}
 | 
						|
 | 
						|
/* sg cli upgrade stop */
 | 
						|
void iot_cli_upgrade_stop()
 | 
						|
{
 | 
						|
    iot_printf("cli upgrade stop\n");
 | 
						|
    upgrade_info->completed_handler = NULL;
 | 
						|
    if ((IOT_PLC_UPGRADE_STARTING == upgrade_info->upgrade_state) ||
 | 
						|
        (IOT_PLC_UPGRADE_STARTED == upgrade_info->upgrade_state) ||
 | 
						|
        (IOT_PLC_UPGRADE_TRANSFERRED == upgrade_info->upgrade_state)) {
 | 
						|
        upgrade_info->upgrade_state = IOT_PLC_UPGRADE_STOPED;
 | 
						|
        upgrade_info->action_times = 0;
 | 
						|
        cli_upgrade_reset_timer(1, IOT_PLC_UPGRADE_CCO_MIN_BCAST_TIME);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/* write pib or fw data to flash !! */
 | 
						|
void iot_cli_upgrade_write_file_to_flash(uint8_t file_type,
 | 
						|
    uint16_t interval)
 | 
						|
{
 | 
						|
    uint32_t written_size   = 0;
 | 
						|
    uint16_t block_index    = 0;
 | 
						|
    uint32_t src_block_size = upgrade_info->pib_size;
 | 
						|
    uint8_t  *src_data      = upgrade_info->pib_data;
 | 
						|
    uint16_t block_size     = upgrade_info->block_size;
 | 
						|
 | 
						|
    if (UPGRADE_DATA_TYPE_PIB != file_type) {
 | 
						|
        src_block_size = upgrade_info->fw_size;
 | 
						|
        src_data = upgrade_info->fw_data;
 | 
						|
    }
 | 
						|
 | 
						|
    while (written_size < src_block_size) {
 | 
						|
        if ((written_size + block_size) >
 | 
						|
            src_block_size) {
 | 
						|
            block_size = (uint16_t)(src_block_size - written_size);
 | 
						|
        }
 | 
						|
        cli_upgrade_write_data_to_flash(file_type, 1,
 | 
						|
                &block_index, &block_size,
 | 
						|
                src_data + written_size);
 | 
						|
        written_size += block_size;
 | 
						|
        block_index++;
 | 
						|
        os_delay(interval);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/* cco handle destination list from app */
 | 
						|
uint8_t iot_cli_upgrade_set_dst_list(iot_plc_upgrade_dst_list_t *data,
 | 
						|
    uint8_t is_renew)
 | 
						|
{
 | 
						|
    uint8_t error_code;
 | 
						|
    uint16_t tmp_dst_list_idx = upgrade_info->dst_list_idx;
 | 
						|
    if (is_renew) {
 | 
						|
        upgrade_info->dst_list_idx = 0;
 | 
						|
    }
 | 
						|
    error_code = cli_upgrade_dst_list_check(data);
 | 
						|
    upgrade_info->dst_list_idx = tmp_dst_list_idx;
 | 
						|
    if (UPGRADE_DST_LIST_SUCCESS != error_code) {
 | 
						|
        goto err_exit;
 | 
						|
    }
 | 
						|
    cli_upgrade_add_upgrade_list_dest_info(data->dst_list, data->dst_num,
 | 
						|
        is_renew);
 | 
						|
    upgrade_info->dest_info.upgrading_list_idx = 0;
 | 
						|
 | 
						|
    error_code = UPGRADE_DST_LIST_SUCCESS;
 | 
						|
 | 
						|
err_exit:
 | 
						|
    return error_code;
 | 
						|
}
 | 
						|
 | 
						|
void iot_cli_upgrade_qr_dst_status_list(uint16_t start_idx,
 | 
						|
    uint8_t count, iot_plc_upgrade_dst_status_list *status_list)
 | 
						|
{
 | 
						|
    uint8_t progress = 0;
 | 
						|
    iot_plc_upgrade_dst_status_list tmp_status_list;
 | 
						|
    uint8_t i = 0;
 | 
						|
    uint8_t weight_value = UPGRADE_BDCT_PROGRESS_WEIGHT_FOR_LIST;
 | 
						|
 | 
						|
    if ((upgrade_info->upgrade_type == IOT_PLC_UPGRADE_ALL) &&
 | 
						|
        (upgrade_info->dest_info.dst_total_num >
 | 
						|
         UPGRADE_PROGRESS_THRESHOLD_VALUE_STA_CNT)) {
 | 
						|
        weight_value = UPGRADE_BDCT_PROGRESS_WEIGHT_FOR_ALL;
 | 
						|
    }
 | 
						|
 | 
						|
    cli_upgrade_set_dst_status_list(start_idx, count, &tmp_status_list);
 | 
						|
    switch (upgrade_info->upgrade_state) {
 | 
						|
    case IOT_PLC_UPGRADE_STARTING:
 | 
						|
    case IOT_PLC_UPGRADE_STARTED:
 | 
						|
        if ((upgrade_info->current_file_type == UPGRADE_DATA_TYPE_PIB) &&
 | 
						|
            upgrade_info->pib_blocks) {
 | 
						|
            progress = (uint8_t)((weight_value *
 | 
						|
                upgrade_info->block_idx) /
 | 
						|
                (upgrade_info->pib_blocks + upgrade_info->fw_blocks));
 | 
						|
        } else {
 | 
						|
            progress = (uint8_t)((weight_value *
 | 
						|
                (upgrade_info->block_idx + upgrade_info->pib_blocks)) /
 | 
						|
                (upgrade_info->pib_blocks + upgrade_info->fw_blocks));
 | 
						|
        }
 | 
						|
 | 
						|
        status_list->end = 1;
 | 
						|
        if (count > UPGRADE_REMOTE_DST_STATUS_ONCE_MAX_NUM) {
 | 
						|
            count = UPGRADE_REMOTE_DST_STATUS_ONCE_MAX_NUM;
 | 
						|
            status_list->end = 0;
 | 
						|
        }
 | 
						|
        status_list->dst_num = tmp_status_list.dst_num;
 | 
						|
        status_list->dst_status_list_idx = tmp_status_list.dst_status_list_idx;
 | 
						|
 | 
						|
        for (i = 0; i < status_list->dst_num; i++) {
 | 
						|
            os_mem_cpy(status_list->dst_status_list[i].dst,
 | 
						|
                tmp_status_list.dst_status_list[i].dst, IOT_MAC_ADDR_LEN);
 | 
						|
            status_list->dst_status_list[i].error_code =
 | 
						|
                UPGRADE_DATA_STA_IN_PROGRESS;
 | 
						|
            status_list->dst_status_list[i].percentage = progress;
 | 
						|
        }
 | 
						|
        break;
 | 
						|
    case IOT_PLC_UPGRADE_TRANSFERRED:
 | 
						|
    {
 | 
						|
        status_list->dst_num = tmp_status_list.dst_num;
 | 
						|
        status_list->dst_status_list_idx = tmp_status_list.dst_status_list_idx;
 | 
						|
        status_list->end = tmp_status_list.end;
 | 
						|
        for (i = 0; i < tmp_status_list.dst_num; i++) {
 | 
						|
            os_mem_cpy(status_list->dst_status_list[i].dst,
 | 
						|
                tmp_status_list.dst_status_list[i].dst,
 | 
						|
                IOT_MAC_ADDR_LEN);
 | 
						|
            status_list->dst_status_list[i].error_code =
 | 
						|
                tmp_status_list.dst_status_list[i].error_code;
 | 
						|
            if ((IOT_PLC_UPGRADE_INIT ==
 | 
						|
                tmp_status_list.dst_status_list[i].status) ||
 | 
						|
                (IOT_PLC_UPGRADE_STARTED ==
 | 
						|
                tmp_status_list.dst_status_list[i].status) ||
 | 
						|
                (IOT_PLC_UPGRADE_LISTEN ==
 | 
						|
                tmp_status_list.dst_status_list[i].status)) {
 | 
						|
                status_list->dst_status_list[i].error_code =
 | 
						|
                    UPGRADE_DATA_STA_IN_PROGRESS;
 | 
						|
            }
 | 
						|
            if (UPGRADE_DATA_SUCCESS ==
 | 
						|
                status_list->dst_status_list[i].error_code) {
 | 
						|
                status_list->dst_status_list[i].percentage = 100;
 | 
						|
            } else {
 | 
						|
                status_list->dst_status_list[i].percentage =
 | 
						|
                    (weight_value +
 | 
						|
                    (tmp_status_list.dst_status_list[i].percentage *
 | 
						|
                    (100 - weight_value)));
 | 
						|
            }
 | 
						|
        }
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case IOT_PLC_UPGRADE_STOPED:
 | 
						|
    case IOT_PLC_UPGRADE_RESET:
 | 
						|
    case IOT_PLC_UPGRADE_INIT:
 | 
						|
    default:
 | 
						|
        break;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void iot_cli_upgrade_qr_dst_status(iot_plc_upgrade_dst_status_query *query)
 | 
						|
{
 | 
						|
    cli_upgrade_set_dst_status_ack(query);
 | 
						|
}
 | 
						|
 | 
						|
#if (!IOT_SMART_GRID_ENABLE)
 | 
						|
uint16_t iot_cli_upgrade_set_renew_nodelist(uint8_t *dstlist, uint16_t cnt)
 | 
						|
{
 | 
						|
    uint16_t tmp_cnt = 0;
 | 
						|
 | 
						|
    if (cnt > IOT_PLC_UPGRADE_PHASE_THREE_MAX_SAT_CNT) {
 | 
						|
        cnt = IOT_PLC_UPGRADE_PHASE_THREE_MAX_SAT_CNT;
 | 
						|
    }
 | 
						|
 | 
						|
    tmp_cnt = cli_upgrade_add_upgrade_list_dest_info(dstlist, cnt, 1);
 | 
						|
    upgrade_info->dest_info.upgrading_list_idx = 0;
 | 
						|
    if (tmp_cnt) {
 | 
						|
        cli_remote_upgrade_start_phase3();
 | 
						|
    }
 | 
						|
    return tmp_cnt;
 | 
						|
}
 | 
						|
 | 
						|
#endif /* end !IOT_SMART_GRID_ENABLE */
 | 
						|
 | 
						|
#else /* IOT_CLI_UPGRADE_ENABLE */
 | 
						|
 | 
						|
/* cco handle sta join */
 | 
						|
void iot_cli_cco_handle_sta_join(uint8_t *mac)
 | 
						|
{
 | 
						|
    iot_printf("plc_upgrade: sta join: %02x:%02x:%02x:%02x:%02x:%02x\n",
 | 
						|
        mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
 | 
						|
}
 | 
						|
 | 
						|
/* cco handle sta leave */
 | 
						|
void iot_cli_cco_handle_sta_leave(iot_plc_sta_info_t *sta)
 | 
						|
{
 | 
						|
    iot_printf("plc_upgrade: sta leave: %02x:%02x:%02x:%02x:%02x:%02x\n",
 | 
						|
        sta->mac_addr[0], sta->mac_addr[1], sta->mac_addr[2],
 | 
						|
        sta->mac_addr[3], sta->mac_addr[4], sta->mac_addr[5]);
 | 
						|
}
 | 
						|
 | 
						|
/* sg cli upgrade stop */
 | 
						|
void iot_cli_upgrade_stop()
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
uint32_t iot_cli_upgrade_prepare(iot_cli_upgrade_completed_handler handler,
 | 
						|
    uint32_t file_size, uint8_t **data, uint8_t *file_hdr, uint16_t block_size,
 | 
						|
    uint8_t upgrade_type)
 | 
						|
{
 | 
						|
    (void)handler;
 | 
						|
    uint32_t ret = ERR_OK;
 | 
						|
    uint32_t file_len = iot_get_file_len(file_hdr);
 | 
						|
 | 
						|
    /* if the file header is invalid, the file size is used */
 | 
						|
    if (file_len == 0) {
 | 
						|
        file_len = file_size;
 | 
						|
    }
 | 
						|
 | 
						|
    if ((block_size != 100) && (block_size != 200) &&
 | 
						|
        (block_size != 300) && (block_size != 400)) {
 | 
						|
        iot_printf("%s block size %d is invalid\n", block_size);
 | 
						|
        ret = ERR_FAIL;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
 | 
						|
    upgrade_info->block_size = block_size;
 | 
						|
#if IOT_CLI_UPGRADE_CACHE_TYPE
 | 
						|
    (void)file_hdr;
 | 
						|
    (void)upgrade_type;
 | 
						|
    if (file_len > IOT_CLI_UPGRADE_MAX_FILE_SIZE) {
 | 
						|
        ret = ERR_FAIL;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
#else
 | 
						|
    uint8_t part_num;
 | 
						|
    uint32_t part_size = 0;
 | 
						|
    if (upgrade_type == IOT_PLC_UPGRADE_LOCAL) {
 | 
						|
        ret = ERR_FAIL;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    dev_get_upgrade_fw_part_num(&part_num);
 | 
						|
    part_size = dev_get_part_size(part_num);
 | 
						|
    if (file_len > part_size) {
 | 
						|
        ret = ERR_FAIL;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    cli_upgrade_cache_file_init(file_hdr);
 | 
						|
#endif
 | 
						|
    *data = upgrade_info->file_data;
 | 
						|
out:
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
static void cli_upgrade_dst_status_query_internal(uint8_t *src_mac)
 | 
						|
{
 | 
						|
    (void)src_mac;
 | 
						|
}
 | 
						|
 | 
						|
void cli_upgrade_dst_status_list_internal(uint16_t start_index,
 | 
						|
    uint8_t dst_num, uint8_t *src_mac)
 | 
						|
{
 | 
						|
    (void)start_index;
 | 
						|
    (void)dst_num;
 | 
						|
    (void)src_mac;
 | 
						|
}
 | 
						|
 | 
						|
/* sg cli upgrade start */
 | 
						|
uint8_t iot_cli_upgrade_start(uint8_t upgrade_type, uint8_t control_flag)
 | 
						|
{
 | 
						|
    (void)upgrade_type;
 | 
						|
    (void)control_flag;
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
void iot_cli_upgrade_app_register_handler(iot_cli_upgrade_app_handler handler)
 | 
						|
{
 | 
						|
    sg_upgrade_handler = handler;
 | 
						|
}
 | 
						|
 | 
						|
void cli_remote_upgrade_bcast_tx_done()
 | 
						|
{
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
#endif /* IOT_CLI_UPGRADE_ENABLE */
 | 
						|
 | 
						|
void cli_upgrade_dst_status_query(uint8_t *buffer, uint32_t bufferlen,
 | 
						|
    uint8_t *src_mac)
 | 
						|
{
 | 
						|
    (void)buffer;
 | 
						|
    (void)bufferlen;
 | 
						|
 | 
						|
    if (host_config->cli_upgrade_enabled) {
 | 
						|
        cli_upgrade_dst_status_query_internal(src_mac);
 | 
						|
    } else {
 | 
						|
        cli_upgrade_dst_status_sg_query(add_addr_to_mapping_table(src_mac));
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void cli_upgrade_dst_status_list(
 | 
						|
    uint8_t *buffer, uint32_t bufferlen, uint8_t *src_mac)
 | 
						|
{
 | 
						|
    iot_plc_upgrade_dst_status_list_dl *list_dl;
 | 
						|
    list_dl = (iot_plc_upgrade_dst_status_list_dl *)buffer;
 | 
						|
 | 
						|
    if ((!list_dl) || (bufferlen < sizeof(*list_dl))) {
 | 
						|
        iot_printf("%s param error", __FUNCTION__);
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    if (host_config->cli_upgrade_enabled) {
 | 
						|
        cli_upgrade_dst_status_list_internal(list_dl->dst_status_list_idx,
 | 
						|
            list_dl->dst_num, src_mac);
 | 
						|
    } else {
 | 
						|
        cli_upgrade_dst_status_sg_list(list_dl->dst_status_list_idx,
 | 
						|
            list_dl->dst_num, add_addr_to_mapping_table(src_mac));
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/* sg upgrade data ack */
 | 
						|
void cli_sg_upgrade_data_ack(uint8_t result_code, uint16_t seg_index)
 | 
						|
{
 | 
						|
    iot_plc_sg_upgrade_data_ack_ul_t ack_ul;
 | 
						|
    ack_ul.error_code = result_code;
 | 
						|
    ack_ul.seg_index = seg_index;
 | 
						|
 | 
						|
    iot_printf("sg upgrade data ack, seg_index %lu result code %lu\n",
 | 
						|
        seg_index, result_code);
 | 
						|
 | 
						|
    iot_cli_send_to_host(CLI_MSGID_SG_UPGRADE_DATA_ACK,
 | 
						|
        (uint8_t*)&ack_ul, sizeof(ack_ul), NULL);
 | 
						|
}
 | 
						|
 | 
						|
/* sg upgrade stop */
 | 
						|
void cli_sg_upgrade_stop()
 | 
						|
{
 | 
						|
    iot_printf("cli set sg upgrade stop\n");
 | 
						|
    if (sg_upgrade_handler) {
 | 
						|
        sg_upgrade_handler(UPGRADE_CLI_UPGRADE_STOP_CMD, NULL, 0);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/* sg upgrade data */
 | 
						|
void cli_sg_upgrade_data(
 | 
						|
    uint8_t *buffer, uint32_t bufferlen, uint8_t *src_mac)
 | 
						|
{
 | 
						|
    iot_plc_sg_upgrade_data_dl_t *data =
 | 
						|
        (iot_plc_sg_upgrade_data_dl_t *)buffer;
 | 
						|
    (void)src_mac;
 | 
						|
    uint8_t result_code = UPGRADE_DATA_SUCCESS;
 | 
						|
 | 
						|
    BUILD_BUG_ON(sizeof(iot_plc_sg_upgrade_data_dl_t) ==
 | 
						|
        sizeof(iot_plc_app_upgrade_data_t));
 | 
						|
 | 
						|
    if ((!data) || (bufferlen < sizeof(*data))) {
 | 
						|
        iot_printf("%s param error", __FUNCTION__);
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    if ((data->seg_index == 0) && host_config->cli_upgrade_enabled) {
 | 
						|
        host_config->cli_upgrade_enabled = 0;
 | 
						|
    }
 | 
						|
 | 
						|
    iot_printf("sg upgrade data, seg_index %lu,"
 | 
						|
        " total seg cnt %lu, data len %lu\n",
 | 
						|
        data->seg_index, data->total_seg_count, data->data_len);
 | 
						|
 | 
						|
    if (sg_upgrade_handler) {
 | 
						|
       if (ERR_OK != sg_upgrade_handler(UPGRADE_CLI_UPGRADE_DATA, buffer,
 | 
						|
            bufferlen)) {
 | 
						|
            result_code = UPGRADE_DATA_OTHER_ERROR;
 | 
						|
       }
 | 
						|
    }
 | 
						|
 | 
						|
    if ((data->total_seg_count - 1) == data->seg_index) {
 | 
						|
        iot_printf("sg upgrade data recv done\n");
 | 
						|
    }
 | 
						|
    cli_sg_upgrade_data_ack(result_code, data->seg_index);
 | 
						|
}
 | 
						|
 | 
						|
uint32_t iot_cli_upgrade_read(uint32_t offset, uint8_t *buf,
 | 
						|
    uint16_t buf_len)
 | 
						|
{
 | 
						|
    uint8_t result = UPGRADE_DATA_SUCCESS;
 | 
						|
 | 
						|
#if IOT_CLI_UPGRADE_CACHE_TYPE
 | 
						|
    result = cli_upgrade_read_data_from_buffer(UPGRADE_DATA_TYPE_PKG, offset,
 | 
						|
      buf, buf_len);
 | 
						|
#else
 | 
						|
    result = cli_upgrade_read_data_from_flash(UPGRADE_DATA_TYPE_FW, offset,
 | 
						|
        buf, buf_len);
 | 
						|
#endif
 | 
						|
 | 
						|
    return result;
 | 
						|
}
 | 
						|
 | 
						|
uint32_t iot_cli_upgrade_write(uint32_t offset, uint8_t *buf,
 | 
						|
    uint16_t buf_len)
 | 
						|
{
 | 
						|
    uint8_t result = UPGRADE_DATA_SUCCESS;
 | 
						|
    uint16_t block_idx = (uint16_t)(offset / upgrade_info->block_size);
 | 
						|
 | 
						|
    if (offset % upgrade_info->block_size != 0) {
 | 
						|
        result = UPGRADE_DATA_INVALID_DATA;
 | 
						|
        iot_printf(" %s invalid offset.\n");
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
 | 
						|
#if IOT_CLI_UPGRADE_CACHE_TYPE
 | 
						|
    result = cli_upgrade_write_data_to_buffer(UPGRADE_DATA_TYPE_PKG, 1,
 | 
						|
        &block_idx, &buf_len, buf);
 | 
						|
#else
 | 
						|
    result = cli_upgrade_write_data_to_flash(UPGRADE_DATA_TYPE_FW, 1,
 | 
						|
        &block_idx, &buf_len, buf);
 | 
						|
#endif
 | 
						|
 | 
						|
out:
 | 
						|
    return result;
 | 
						|
}
 | 
						|
 | 
						|
uint32_t iot_cli_upgrade_get_file_limit(uint8_t local_upgrade,
 | 
						|
    uint8_t *file_hdr)
 | 
						|
{
 | 
						|
    uint32_t size = 0;
 | 
						|
    uint8_t part_num;
 | 
						|
 | 
						|
    if (local_upgrade) {
 | 
						|
        if (file_hdr == NULL) {
 | 
						|
            return 0;
 | 
						|
        }
 | 
						|
 | 
						|
        if (iot_get_file_fw_len(file_hdr)) {
 | 
						|
            dev_get_upgrade_fw_part_num(&part_num);
 | 
						|
            size += dev_get_part_size(part_num);
 | 
						|
        }
 | 
						|
 | 
						|
        if (iot_get_file_pib_len(file_hdr)) {
 | 
						|
            dev_get_upgrade_pib_part_num(&part_num);
 | 
						|
            size += dev_get_part_size(part_num);
 | 
						|
        }
 | 
						|
 | 
						|
        if (iot_get_file_cus_len(file_hdr)) {
 | 
						|
            dev_get_upgrade_cus_part_num(&part_num);
 | 
						|
            size += dev_get_part_size(part_num);
 | 
						|
        }
 | 
						|
    } else {
 | 
						|
        if (IOT_CLI_UPGRADE_MAX_FILE_SIZE) {
 | 
						|
            size = IOT_CLI_UPGRADE_MAX_FILE_SIZE;
 | 
						|
        } else {
 | 
						|
            dev_get_upgrade_fw_part_num(&part_num);
 | 
						|
            size = dev_get_part_size(part_num);
 | 
						|
        }
 | 
						|
    }
 | 
						|
    return size;
 | 
						|
}
 | 
						|
 | 
						|
#endif /* PLC_SUPPORT_CCO_ROLE */ |