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 */ |