1078 lines
		
	
	
		
			38 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1078 lines
		
	
	
		
			38 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_io.h"
 | |
| #include "iot_app.h"
 | |
| #include "iot_mtd.h"
 | |
| #include "iot_system.h"
 | |
| #include "iot_plc_msg_api.h"
 | |
| 
 | |
| #include "iot_cli_common.h"
 | |
| #include "iot_cli_host_interface.h"
 | |
| #include "iot_cli_plc_module.h"
 | |
| #include "iot_cli_plc_tx_rx.h"
 | |
| 
 | |
| #include "iot_cli_plc_nw.h"
 | |
| #include "iot_cli_upgrade.h"
 | |
| #include "iot_cli_host_upgrade.h"
 | |
| #include "iot_cli_set_info.h"
 | |
| #include "iot_cli_plc_mgr_alive.h"
 | |
| #include "iot_cli_discovery.h"
 | |
| #include "iot_plc_led_api.h"
 | |
| 
 | |
| extern iot_plc_host_config_t *host_config;
 | |
| extern iot_cli_host_info_t *host_info;
 | |
| extern iot_cli_t cli;
 | |
| 
 | |
| #if PLC_SUPPORT_CCO_ROLE
 | |
| 
 | |
| static uint8_t cli_topo_changed_to_plc_ver(uint8_t cli_topo_ver)
 | |
| {
 | |
|     return (cli_topo_ver == IOT_CLI_CCO_TOPO_VER1) ? \
 | |
|         IOT_PLC_CCO_TOPO_REQ_DATA_VER_V7 : IOT_PLC_CCO_TOPO_REQ_DATA_VER_V0;
 | |
| }
 | |
| 
 | |
| static uint8_t cli_topo_changed_from_plc_ver(uint8_t plc_topo_ver)
 | |
| {
 | |
|     return (plc_topo_ver == IOT_PLC_CCO_TOPO_REQ_DATA_VER_V7) ? \
 | |
|         IOT_CLI_CCO_TOPO_VER1 : IOT_CLI_CCO_TOPO_VER0;
 | |
| }
 | |
| 
 | |
| static iot_pkt_t *cli_topo_data_malloc(iot_plc_nw_topo_rpt_t *topo_rpt,
 | |
|     uint32_t node_size, uint16_t topo_size)
 | |
| {
 | |
|     iot_pkt_t *topo_data = NULL;
 | |
|     cli_host_topo_info_t *cli_topo_info = NULL;
 | |
| 
 | |
|     if (topo_size < sizeof(cli_host_topo_info_t)) {
 | |
|         goto out;
 | |
|     }
 | |
|     iot_printf("topo info size %lu notification size %lu\n",
 | |
|         sizeof(cli_host_topo_info_t), topo_size);
 | |
| 
 | |
|     topo_data = iot_pkt_alloc(topo_size, IOT_CLI_MID);
 | |
|     if (!topo_data) {
 | |
|         iot_printf("topo info notify, alloc failed\n");
 | |
|         goto out;
 | |
|     }
 | |
| 
 | |
|     cli_topo_info = (cli_host_topo_info_t *)iot_pkt_data(topo_data);
 | |
|     cli_topo_info->node_len = (uint8_t)node_size;
 | |
|     cli_topo_info->count = topo_rpt->count;
 | |
|     cli_topo_info->done = topo_rpt->done;
 | |
|     cli_topo_info->err_code = topo_rpt->err_code;
 | |
|     cli_topo_info->compatibility_check = 1;
 | |
|     cli_topo_info->reserved = topo_rpt->reserved;
 | |
|     cli_topo_info->total_count = topo_rpt->total_count;
 | |
|     cli_topo_info->ver = cli_topo_changed_from_plc_ver(topo_rpt->version);
 | |
|     iot_pkt_put(topo_data, topo_size);
 | |
| out:
 | |
|     return topo_data;
 | |
| }
 | |
| 
 | |
| /* notify topo info to plc mgr */
 | |
| static uint16_t cli_topo_info_notify(
 | |
|     iot_plc_nw_topo_rpt_t *topo_rpt, uint8_t* cli_src_mac)
 | |
| {
 | |
|     uint16_t notification_size = 0;
 | |
|     iot_pkt_t *topo_data = NULL;
 | |
|     cli_host_topo_info_t *cli_topo_info = NULL;
 | |
| 
 | |
|     if (!topo_rpt) {
 | |
|         iot_printf("topo info notify, invalid data\n");
 | |
|         return 0;
 | |
|     }
 | |
|     switch (topo_rpt->version) {
 | |
|     case IOT_PLC_CCO_TOPO_REQ_DATA_VER_V0:
 | |
|     {
 | |
|         iot_plc_node_info_v0_t *node = NULL;
 | |
|         cli_host_node_info_t *cli_node = NULL;
 | |
|         notification_size = sizeof(cli_host_topo_info_t) +
 | |
|             topo_rpt->count * sizeof(cli_host_node_info_t);
 | |
| 
 | |
|         iot_printf("topo info size %lu notification size %lu\n",
 | |
|             sizeof(cli_host_topo_info_t), notification_size);
 | |
| 
 | |
|         topo_data = cli_topo_data_malloc(topo_rpt, sizeof(cli_host_node_info_t),
 | |
|             notification_size);
 | |
|         if (!topo_data) {
 | |
|             return 0;
 | |
|         }
 | |
|         cli_topo_info = (cli_host_topo_info_t *)iot_pkt_data(topo_data);
 | |
|         node = (iot_plc_node_info_v0_t *)topo_rpt->data;
 | |
|         cli_node = (cli_host_node_info_t *)cli_topo_info->data;
 | |
|         for (uint16_t i = 0; i < topo_rpt->count; i++) {
 | |
|             cli_node[i].sta_tei = node[i].sta_tei;
 | |
|             cli_node[i].proxy_tei = node[i].proxy_tei;
 | |
|             cli_node[i].level = (uint8_t)node[i].level;
 | |
|             cli_node[i].role = (uint8_t)node[i].role;
 | |
|             cli_node[i].ul_tf_sr = node[i].ul_tf_sr;
 | |
|             cli_node[i].dl_tf_sr = node[i].dl_tf_sr;
 | |
|             cli_node[i].ul_snr = node[i].ul_snr;
 | |
|             cli_node[i].dl_snr = node[i].dl_snr;
 | |
|             iot_mac_addr_cpy(cli_node[i].addr, node[i].addr);
 | |
|             cli_node[i].dev_type = node[i].dev_type;
 | |
|             cli_node[i].logic_phase1 = node[i].logic_phase1;
 | |
|             cli_node[i].logic_phase2 = node[i].logic_phase2;
 | |
|             cli_node[i].logic_phase3 = node[i].logic_phase3;
 | |
|             cli_node[i].comm_type = node[i].comm_type;
 | |
|             cli_node[i].pco_link_rf = node[i].pco_link_rf;
 | |
|             cli_node[i].phy_phase1 = node[i].phy_phase1;
 | |
|             cli_node[i].phy_phase2 = node[i].phy_phase2;
 | |
|             cli_node[i].phy_phase3 = node[i].phy_phase3;
 | |
|             cli_node[i].opposite_phase = node[i].opposite_phase;
 | |
|             cli_node[i].opposite_3p = node[i].opposite_3p;
 | |
|             cli_node[i].opposite_3p_pos = node[i].opposite_3p_pos;
 | |
|             cli_node[i].boot_reason = node[i].boot_reason;
 | |
|             cli_node[i].build_ver = node[i].build_ver;
 | |
|             cli_node[i].sw_ver = node[i].sw_ver;
 | |
|             iot_printf("topo tei %lu, topo sw_ver %x\n",
 | |
|                 cli_node[i].sta_tei, cli_node[i].sw_ver);
 | |
|             cli_node[i].vendor = node[i].vendor;
 | |
|             cli_node[i].assoc_rx_cnt = node[i].assoc_rx_cnt;
 | |
|             cli_node[i].proxy_chg_accept_cnt = node[i].proxy_chg_accept_cnt;
 | |
|             cli_node[i].proxy_chg_rx_cnt = node[i].proxy_chg_rx_cnt;
 | |
|             cli_node[i].in_network_time = node[i].in_network_time;
 | |
|             cli_node[i].last_assoc_rx_time = node[i].last_assoc_rx_time;
 | |
|             cli_node[i].last_proxy_chg_time = node[i].last_proxy_chg_time;
 | |
|             cli_node[i].inactive_time = node[i].inactive_time;
 | |
|             cli_node[i].mtd_type = node[i].mtd_type;
 | |
|             cli_node[i].psram = node[i].psram;
 | |
|             cli_node[i].ver_type = node[i].ver_type;
 | |
| 
 | |
|             cli_node[i].chip_id.hd1 = node[i].chip_id.hd1;
 | |
|             cli_node[i].chip_id.hd2 = node[i].chip_id.hd2;
 | |
|             cli_node[i].chip_id.hd3 = node[i].chip_id.hd3;
 | |
|             cli_node[i].chip_id.hd4_1 = node[i].chip_id.hd4_1;
 | |
|             cli_node[i].chip_id.hd4_2 = node[i].chip_id.hd4_2;
 | |
|             cli_node[i].chip_id.hd4_3 = node[i].chip_id.hd4_3;
 | |
|             cli_node[i].chip_id.dev_type = node[i].chip_id.dev_type;
 | |
|             cli_node[i].chip_id.vendor = node[i].chip_id.vendor;
 | |
|             cli_node[i].chip_id.chip_mode = node[i].chip_id.chip_mode;
 | |
|             os_mem_cpy(cli_node[i].chip_id.dev_code,
 | |
|                 node[i].chip_id.dev_code,
 | |
|                 IOT_PLC_CHIP_ID_SERIAL_NUM_LEN);
 | |
|             os_mem_cpy(cli_node[i].chip_id.check_code,
 | |
|                 node[i].chip_id.check_code,
 | |
|                 IOT_PLC_CHIP_ID_CRC_LEN);
 | |
| 
 | |
|             cli_node[i].addr_type = node[i].addr_type;
 | |
|         }
 | |
|         break;
 | |
|     }
 | |
|     case IOT_PLC_CCO_TOPO_REQ_DATA_VER_V7:
 | |
|     {
 | |
|         iot_plc_node_info_v7_t *node7 = NULL;
 | |
|         cli_host_node_info_v7_t *cli_node7 = NULL;
 | |
|         notification_size = sizeof(cli_host_topo_info_t) +
 | |
|             topo_rpt->count * sizeof(cli_host_node_info_v7_t);
 | |
|         topo_data = cli_topo_data_malloc(topo_rpt,
 | |
|             sizeof(cli_host_node_info_v7_t), notification_size);
 | |
|         if (!topo_data) {
 | |
|             return 0;
 | |
|         }
 | |
|         cli_topo_info = (cli_host_topo_info_t *)iot_pkt_data(topo_data);
 | |
|         node7 = (iot_plc_node_info_v7_t *)topo_rpt->data;
 | |
|         cli_node7 = (cli_host_node_info_v7_t *)cli_topo_info->data;
 | |
|         for (uint16_t i = 0; i < topo_rpt->count; i++) {
 | |
|             cli_node7[i].sta_tei = node7[i].sta_tei;
 | |
|             cli_node7[i].proxy_tei = node7[i].proxy_tei;
 | |
|             cli_node7[i].level = node7[i].level;
 | |
|             cli_node7[i].role = node7[i].role;
 | |
|             cli_node7[i].dev_type = node7[i].dev_type;
 | |
|             iot_mac_addr_cpy(cli_node7[i].addr, node7[i].addr);
 | |
|             cli_node7[i].sw_ver = node7[i].sw_ver;
 | |
|             cli_node7[i].build_time_y = node7[i].build_time_y;
 | |
|             cli_node7[i].build_time_m = node7[i].build_time_m;
 | |
|             cli_node7[i].build_time_d = node7[i].build_time_d;
 | |
|             cli_node7[i].vendor_id = node7[i].vendor_id;
 | |
|             cli_node7[i].chip_code = node7[i].chip_code;
 | |
|             cli_node7[i].build_ver = node7[i].build_ver;
 | |
|         }
 | |
|         break;
 | |
|     }
 | |
|     default:
 | |
|         break;
 | |
|     }
 | |
| 
 | |
|     if (topo_data) {
 | |
|         iot_cli_send_to_host(CLI_MSGID_GET_TOPO_RESP, (uint8_t*)cli_topo_info,
 | |
|             notification_size, cli_src_mac);
 | |
|         iot_pkt_free(topo_data);
 | |
|     }
 | |
| 
 | |
|     return notification_size;
 | |
| }
 | |
| 
 | |
| static void cli_cco_nw_status_notify(uint8_t* cli_src_mac)
 | |
| {
 | |
|     cli_host_cco_nw_status cco_nw_status;
 | |
|     cco_nw_status.proto = host_config->proto;
 | |
|     cco_nw_status.nw_fmt_done =
 | |
|         host_config->nw_fmt_done;
 | |
|     cco_nw_status.route_learn_done =
 | |
|         host_config->route_learn_done;
 | |
|     cco_nw_status.nid =
 | |
|         host_config->nid;
 | |
|     iot_printf("cli_cco_nw_status_notify proto %d,"
 | |
|         " nw_fmt_done %lu, route_learn_done %lu, nid %lu\n",
 | |
|         host_config->proto, host_config->nw_fmt_done,
 | |
|         host_config->route_learn_done, host_config->nid);
 | |
| 
 | |
|     cli_ul_send_with_retry(CLI_MSGID_CCO_NW_STATUS,
 | |
|         (uint8_t*)&cco_nw_status,
 | |
|         sizeof(cco_nw_status), cli_src_mac);
 | |
| }
 | |
| 
 | |
| static uint16_t cli_get_plc_version_last_tei(iot_plc_nw_topo_rpt_t *topo_data)
 | |
| {
 | |
|     uint16_t tei = 0;
 | |
| 
 | |
|     if (topo_data->done) {
 | |
|         return tei;
 | |
|     }
 | |
|     switch (topo_data->version) {
 | |
|     case IOT_PLC_CCO_TOPO_REQ_DATA_VER_V0:
 | |
|     {
 | |
|         iot_plc_node_info_v0_t *node0 =
 | |
|             (iot_plc_node_info_v0_t *)topo_data->data;
 | |
|         tei = node0[topo_data->count - 1].sta_tei;
 | |
|         break;
 | |
|     }
 | |
|     case IOT_PLC_CCO_TOPO_REQ_DATA_VER_V7:
 | |
|     {
 | |
|         iot_plc_node_info_v7_t *node7 =
 | |
|             (iot_plc_node_info_v7_t *)topo_data->data;
 | |
|         tei = node7[topo_data->count - 1].sta_tei;
 | |
|         break;
 | |
|     }
 | |
|     default:
 | |
|         break;
 | |
|     }
 | |
|     return tei;
 | |
| }
 | |
| 
 | |
| #endif
 | |
| 
 | |
| static void cli_neighbor_info_notify(
 | |
|     iot_plc_neighbor_dev_rpt_t *neighbor_rpt, uint8_t* mac)
 | |
| {
 | |
|     uint16_t notification_size = 0;
 | |
|     iot_pkt_t *neighbor_data = NULL;
 | |
|     cli_neighbor_info_t *neighbor_info = NULL;
 | |
| 
 | |
|     if (!neighbor_rpt) {
 | |
|         iot_printf("neighbor info notify, invalid data\n");
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     notification_size = sizeof(cli_neighbor_info_t) +
 | |
|         neighbor_rpt->cnt * sizeof(cli_neighbor_node_info_t);
 | |
| 
 | |
|     neighbor_data = iot_pkt_alloc(notification_size, IOT_CLI_MID);
 | |
|     if (!neighbor_data) {
 | |
|         iot_printf("neighbor info notify, alloc failed\n");
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     neighbor_info = (cli_neighbor_info_t *)iot_pkt_data(neighbor_data);
 | |
|     iot_mac_addr_cpy(neighbor_info->sta_addr, host_config->mac_addr);
 | |
|     neighbor_info->total_d_sub_sta_cnt = neighbor_rpt->total_d_sub_sta_cnt;
 | |
|     neighbor_info->total_cnt = neighbor_rpt->total_cnt;
 | |
|     neighbor_info->cnt = neighbor_rpt->cnt;
 | |
|     neighbor_info->done = neighbor_rpt->done;
 | |
| 
 | |
|     for (uint16_t i = 0; i < neighbor_info->cnt; i++) {
 | |
|         neighbor_info->node[i].tei = (uint16_t)neighbor_rpt->node[i].tei;
 | |
|         neighbor_info->node[i].level = (uint8_t)neighbor_rpt->node[i].level;
 | |
|         neighbor_info->node[i].role = (uint8_t)neighbor_rpt->node[i].role;
 | |
|         neighbor_info->node[i].ul_tf_sr = neighbor_rpt->node[i].ul_tf_sr;
 | |
|         neighbor_info->node[i].dl_tf_sr = neighbor_rpt->node[i].dl_tf_sr;
 | |
|         neighbor_info->node[i].phase1 = neighbor_rpt->node[i].phase1;
 | |
|         neighbor_info->node[i].phase2 = neighbor_rpt->node[i].phase2;
 | |
|         neighbor_info->node[i].phase3 = neighbor_rpt->node[i].phase3;
 | |
|         neighbor_info->node[i].d_sub_sta = neighbor_rpt->node[i].d_sub_sta;
 | |
|         neighbor_info->node[i].proxy = neighbor_rpt->node[i].proxy;
 | |
|         neighbor_info->node[i].addr_valid = neighbor_rpt->node[i].addr_valid;
 | |
|         neighbor_info->node[i].reserved = neighbor_rpt->node[i].reserved;
 | |
|         neighbor_info->node[i].snr = neighbor_rpt->node[i].snr;
 | |
|         iot_mac_addr_cpy(neighbor_info->node[i].addr,
 | |
|             neighbor_rpt->node[i].addr);
 | |
|     }
 | |
| 
 | |
|     iot_pkt_put(neighbor_data, notification_size);
 | |
|     iot_cli_send_to_host(CLI_MSGID_NEIGHBOR_INFO_RESP,
 | |
|         (uint8_t*)neighbor_info,
 | |
|         notification_size, mac);
 | |
| 
 | |
|     iot_pkt_free(neighbor_data);
 | |
| }
 | |
| 
 | |
| static void cli_neighbor_nw_info_notify(
 | |
|     iot_plc_nb_nw_rpt_t *nb_nw_rpt, uint8_t* mac)
 | |
| {
 | |
|     uint16_t notification_size = 0;
 | |
|     iot_pkt_t *neighbor_nw_data = NULL;
 | |
|     cli_neighbor_nw_rpt *neighbor_nw_rpt = NULL;
 | |
| 
 | |
|     if (!nb_nw_rpt) {
 | |
|         iot_printf("neighbor nw notify, invalid data\n");
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     notification_size = sizeof(cli_neighbor_nw_rpt) +
 | |
|         nb_nw_rpt->count * sizeof(cli_neighbor_nw_info);
 | |
| 
 | |
|     neighbor_nw_data = iot_pkt_alloc(notification_size, IOT_CLI_MID);
 | |
|     if (!neighbor_nw_data) {
 | |
|         iot_printf("neighbor nw notify, alloc failed\n");
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     neighbor_nw_rpt =
 | |
|         (cli_neighbor_nw_rpt *)iot_pkt_data(neighbor_nw_data);
 | |
|     neighbor_nw_rpt->count = nb_nw_rpt->count;
 | |
|     for (uint16_t i = 0; i < neighbor_nw_rpt->count; i++) {
 | |
|         neighbor_nw_rpt->nb_info[i].nid =
 | |
|             nb_nw_rpt->nb_info[i].nid;
 | |
|         neighbor_nw_rpt->nb_info[i].bandwidth =
 | |
|             nb_nw_rpt->nb_info[i].bandwidth;
 | |
|         iot_mac_addr_cpy(
 | |
|             neighbor_nw_rpt->nb_info[i].addr,
 | |
|             nb_nw_rpt->nb_info[i].addr);
 | |
|         os_mem_cpy(
 | |
|             neighbor_nw_rpt->nb_info[i].bc_data,
 | |
|             nb_nw_rpt->nb_info[i].bc_data,
 | |
|             IOT_PLC_BEACON_DATA_MAX);
 | |
|         os_mem_cpy(
 | |
|             neighbor_nw_rpt->nb_info[i].snr,
 | |
|             nb_nw_rpt->nb_info[i].snr,
 | |
|             IOT_PLC_PHASE_CNT);
 | |
| 
 | |
|         iot_printf("neighbor nw %lu, %02X:%02X:%02X:%02X:%02X:%02X\n",
 | |
|             nb_nw_rpt->nb_info[i].nid,
 | |
|             nb_nw_rpt->nb_info[i].addr[0],
 | |
|             nb_nw_rpt->nb_info[i].addr[1],
 | |
|             nb_nw_rpt->nb_info[i].addr[2],
 | |
|             nb_nw_rpt->nb_info[i].addr[3],
 | |
|             nb_nw_rpt->nb_info[i].addr[4],
 | |
|             nb_nw_rpt->nb_info[i].addr[5]);
 | |
|     }
 | |
| 
 | |
|     iot_pkt_put(neighbor_nw_data, notification_size);
 | |
|     iot_cli_send_to_host(CLI_MSGID_NEIGHBOR_NW_RESP,
 | |
|         (uint8_t*)neighbor_nw_rpt,
 | |
|         notification_size, mac);
 | |
| 
 | |
|     iot_pkt_free(neighbor_nw_data);
 | |
| }
 | |
| 
 | |
| void cli_handle_plc_msg(iot_pkt_t *pkt)
 | |
| {
 | |
|     iot_plc_msg_header_t *hdr =
 | |
|         (iot_plc_msg_header_t*)iot_pkt_block_ptr(pkt, IOT_PKT_BLOCK_DATA);
 | |
| 
 | |
|     if (hdr->app_id != IOT_PLC_APP_HOST_INTERFACE &&
 | |
|         hdr->app_id != IOT_PLC_APP_ID_BCAST) {
 | |
|         // corrupted message
 | |
|         iot_pkt_free(pkt);
 | |
|         return;
 | |
|     }
 | |
|     uint8_t *cli_src_mac = NULL;
 | |
| #if PLC_SUPPORT_CCO_ROLE
 | |
|     if (hdr->req_id) {
 | |
|         cli_app_cmd_mapping_item* cmd =
 | |
|             get_cmd_from_mapping_table(hdr->req_id);
 | |
|         if (cmd) {
 | |
|             cli_src_mac = &cmd->mac[0];
 | |
|             iot_printf("plc_host_handle_mac_mapping msg=%d, index=%d\n", \
 | |
|                 hdr->msg_id, hdr->req_id);
 | |
|         }
 | |
|     }
 | |
| #endif
 | |
|     switch (hdr->msg_id) {
 | |
|     case IOT_PLC_MSG_APP_REG_CONF: {
 | |
|         iot_plc_app_reg_conf_t* rpt = (iot_plc_app_reg_conf_t*)(hdr + 1);
 | |
|         if (rpt->result == IOT_PLC_SUCCESS ||
 | |
|             rpt->result == IOT_PLC_SUCCESS_MODIFIED) {
 | |
|             host_config->app_registered = 1;
 | |
|             iot_plc_query_dev_info(host_config->app_handle,
 | |
|                 CLI_HOST_USE_API_BY_PLCM);
 | |
|             iot_cli_upgrade_init();
 | |
|         }
 | |
|     }
 | |
|     break;
 | |
|     case IOT_PLC_MSG_DEV_INFO_RPT: {
 | |
|         iot_plc_dev_info_rpt_t* rpt = (iot_plc_dev_info_rpt_t*)(hdr + 1);
 | |
|         uint8_t prev_role = host_config->dev_role;
 | |
|         iot_printf("%s: get the dev info, prev role %lu,"
 | |
|             " cur role %lu dev type %lu\n",
 | |
|             __FUNCTION__, prev_role, rpt->dev_role, rpt->dev_type);
 | |
|         host_config->dev_role = rpt->dev_role;
 | |
|         host_config->dev_type = rpt->dev_type;
 | |
|         iot_mac_addr_cpy(host_config->mac_addr, rpt->local_mac);
 | |
|         iot_mac_addr_cpy(host_info->mac_addr, rpt->local_mac);
 | |
| 
 | |
|         if (host_config->dev_role != IOT_PLC_DEV_ROLE_CCO) {
 | |
|             iot_cli_role_change(prev_role, host_config->dev_role);
 | |
|         }
 | |
|     }
 | |
|     break;
 | |
|     case IOT_PLC_MSG_DEV_STATE_CHANGE_RPT: {
 | |
|         iot_plc_dev_state_change_rpt_t* rpt =
 | |
|             (iot_plc_dev_state_change_rpt_t*)(hdr + 1);
 | |
| #if PLC_SUPPORT_CCO_ROLE
 | |
|         if ((host_config->dev_role == IOT_PLC_DEV_ROLE_CCO) &&
 | |
|             ((host_config->route_learn_done != rpt->route_learn_done) ||
 | |
|             (host_config->nw_fmt_done != rpt->nw_fmt_done) ||
 | |
|                 (host_config->nid != rpt->nid))) {
 | |
|             host_config->route_learn_done = rpt->route_learn_done;
 | |
|             host_config->nw_fmt_done = rpt->nw_fmt_done;
 | |
|             host_config->nid = rpt->nid;
 | |
|             cli_cco_nw_status_notify(cli_src_mac);
 | |
|         }
 | |
| #endif
 | |
|         /* sync local mac and cco mac with cvg */
 | |
|         iot_mac_addr_cpy(host_config->mac_addr, rpt->local_mac);
 | |
|         iot_mac_addr_cpy(host_info->mac_addr, rpt->local_mac);
 | |
|         iot_mac_addr_cpy(host_config->cco_mac, rpt->cco_mac);
 | |
|         if (!iot_cli_host_is_join_connected() && rpt->is_ready) {
 | |
|             uint8_t prev_network_sn = host_config->network_sn;
 | |
|             iot_plc_query_dev_info(host_config->app_handle,
 | |
|                 IOT_PLC_API_REQ_ID_DEFAULT);
 | |
|             /* dev becomes available to serve app request */
 | |
|             iot_printf("%s: MAC layer is ready!\n", __FUNCTION__);
 | |
|             iot_dbglog_input(IOT_CLI_HOST, DBGLOG_INFO_LVL_2,
 | |
|                 IOT_CLI_HOST_INTERFACE_MAC_LAYER_READY_INFO, 0);
 | |
|             host_config->dev_role = rpt->dev_role;
 | |
|             host_config->dev_tei = rpt->dev_tei;
 | |
|             host_config->network_sn = rpt->nework_sn;
 | |
|             iot_cli_host_set_join_connected(1);
 | |
|             iot_cli_sta_state_change(prev_network_sn, rpt->nework_sn);
 | |
|         } else if (iot_cli_host_is_join_connected() && (!rpt->is_ready)) {
 | |
|             /* dev becomes unavailable. It cannot serve app request */
 | |
|             iot_printf("%s: MAC layer is NOT ready!\n", __FUNCTION__);
 | |
|             iot_cli_host_set_join_connected(0);
 | |
|             iot_dbglog_input(IOT_CLI_HOST, DBGLOG_INFO_LVL_2,
 | |
|                 IOT_CLI_HOST_INTERFACE_MAC_LAYER_NOT_READY_INFO, 0);
 | |
|             iot_cli_sta_leave();
 | |
|             iot_cli_user_ver_change_reset();
 | |
|         } else if (iot_cli_host_is_join_connected() && rpt->is_ready) {
 | |
|             uint8_t prev_role = host_config->dev_role;
 | |
|             /* dev role has changed */
 | |
|             if (host_config->dev_role != rpt->dev_role) {
 | |
|                 host_config->dev_role = rpt->dev_role;
 | |
|                 iot_printf("%s: role change, prev role %lu cur role %lu\n",
 | |
|                     __FUNCTION__, prev_role, rpt->dev_role);
 | |
|                 iot_cli_role_change(prev_role, host_config->dev_role);
 | |
|             }
 | |
|         }
 | |
|     }
 | |
|     break;
 | |
| #if PLC_SUPPORT_CCO_ROLE
 | |
|     case IOT_PLC_MSG_STA_PHASE_UPDATED: {
 | |
|         iot_plc_sta_phase_update_t *rpt;
 | |
|         cli_host_oppsite_phase_notify notify;
 | |
|         rpt = (iot_plc_sta_phase_update_t *)(hdr + 1);
 | |
|         notify.oppsite_phase = rpt->sta[0].opposite_phase;
 | |
|         iot_mac_addr_cpy(notify.sta, rpt->sta[0].addr);
 | |
| 
 | |
|         cli_ul_send_with_retry(CLI_MSGID_OPPSITE_PHASE_NOTIFY,
 | |
|             (uint8_t*)¬ify, sizeof(notify), cli_src_mac);
 | |
|     }
 | |
|     break;
 | |
|     case IOT_PLC_MSG_TX_POWER_CAP_SET_RPT: {
 | |
|         iot_plc_tx_power_cap_set_rpt_t* rpt = \
 | |
|             (iot_plc_tx_power_cap_set_rpt_t*)(hdr + 1);
 | |
|         iot_cli_send_to_host(CLI_MSGID_SET_TX_POWER_RESP, (uint8_t*)rpt,
 | |
|             sizeof(iot_plc_tx_power_cap_set_rpt_t), cli_src_mac);
 | |
|     }
 | |
|     break;
 | |
|     case IOT_PLC_MSG_NW_TOPO_RPT: {
 | |
|         uint16_t topo_size = 0;
 | |
|         iot_plc_nw_topo_rpt_t* rpt = (iot_plc_nw_topo_rpt_t*)(hdr + 1);
 | |
|         uint16_t query_start_tei = cli_get_plc_version_last_tei(rpt);
 | |
|         uint16_t query_interval = 500;
 | |
| 
 | |
|         iot_printf("%s, topo rpt cnt:%d, reply end = %d next query tei: %d\n",
 | |
|             __FUNCTION__, rpt->count, rpt->done, query_start_tei);
 | |
| 
 | |
|         if (host_config->dev_role == IOT_PLC_DEV_ROLE_CCO) {
 | |
|             topo_size = cli_topo_info_notify(rpt, cli_src_mac);
 | |
|         }
 | |
| 
 | |
|         /* reset continue query start index */
 | |
|         host_config->topo_query_start_index = query_start_tei + 1;
 | |
| 
 | |
|         /* uart plc mgr query topo */
 | |
|         if (cli.enable_commu) {
 | |
|             /* uart plc mgr query all topo data */
 | |
|             if (host_config->continue_query && (rpt->done == 0)) {
 | |
|                 query_interval =
 | |
|                     (uint16_t)((topo_size * 1000) /
 | |
|                     (IOT_UART_BANDRATE_DEFAULT >>3));
 | |
|                 if (query_interval == 0) {
 | |
|                     query_interval = 50;
 | |
|                 }
 | |
|             } else {
 | |
|                 host_config->continue_query = 0;
 | |
|                 break;
 | |
|             }
 | |
|         /* ckb query topo */
 | |
|         } else if (host_config->query_miss_topo == 1) {
 | |
|             host_config->query_miss_topo = 0;
 | |
|             if (host_config->continue_query == 0) {
 | |
|                 break;
 | |
|             }
 | |
|         } else if (rpt->done) {
 | |
|             /* query all topo data done */
 | |
|             host_config->continue_query = 0;
 | |
|             break;
 | |
|         }
 | |
|         /* continue query all topo data */
 | |
|         os_start_timer(host_config->topo_data_timer, query_interval);
 | |
|         iot_printf("continue to query topo, start from tei:%d, cnt:%d\n",
 | |
|             query_start_tei + 1, host_config->topo_count_in_packet);
 | |
|     }
 | |
|     break;
 | |
| #endif
 | |
|     case IOT_PLC_MSG_NW_WL_RPT: {
 | |
|         iot_plc_wl_rpt_t* rpt = (iot_plc_wl_rpt_t*)(hdr + 1);
 | |
|         for (uint32_t i = 0; i < rpt->count; ++i) {
 | |
|             iot_printf("%s: mac=[%02X:%02X:%02X:%02X:%02X:%02X], \
 | |
|                             \n", __FUNCTION__,
 | |
|                 rpt->mac_addr[i][0], rpt->mac_addr[i][1],
 | |
|                 rpt->mac_addr[i][2], rpt->mac_addr[i][3],
 | |
|                 rpt->mac_addr[i][4], rpt->mac_addr[i][5]);
 | |
|         }
 | |
| 
 | |
|         if (host_config->dev_role == IOT_PLC_DEV_ROLE_CCO) {
 | |
|             iot_cli_send_to_host(CLI_MSGID_GETWHITELIST_RESP, (uint8_t*)rpt,
 | |
|                 sizeof(iot_plc_wl_rpt_t) +
 | |
|                 (IOT_MAC_ADDR_LEN * rpt->count), cli_src_mac);
 | |
|         }
 | |
| 
 | |
|         iot_printf("%s: whitelist reply end = %d------------------\n",
 | |
|             __FUNCTION__, rpt->done);
 | |
|     }
 | |
|     break;
 | |
|     case IOT_PLC_MSG_NW_BL_RPT: {
 | |
|         iot_plc_bl_rpt_t* rpt = (iot_plc_bl_rpt_t*)(hdr + 1);
 | |
|         for (uint32_t i = 0; i < rpt->count; ++i) {
 | |
|             iot_printf("%s: mac=[%02X:%02X:%02X:%02X:%02X:%02X], \
 | |
|                         \n", __FUNCTION__,
 | |
|                 rpt->mac_addr[i][0], rpt->mac_addr[i][1],
 | |
|                 rpt->mac_addr[i][2], rpt->mac_addr[i][3],
 | |
|                 rpt->mac_addr[i][4], rpt->mac_addr[i][5]);
 | |
|         }
 | |
| 
 | |
|         if (host_config->dev_role == IOT_PLC_DEV_ROLE_CCO) {
 | |
|             iot_cli_send_to_host(CLI_MSGID_GETBLACKLIST_RESP, (uint8_t*)rpt,
 | |
|                 sizeof(iot_plc_bl_rpt_t) +
 | |
|                 (IOT_MAC_ADDR_LEN * rpt->count), cli_src_mac);
 | |
|         }
 | |
| 
 | |
|         iot_printf("%s: blacklist reply end = %d------------------\n",
 | |
|             __FUNCTION__, rpt->done);
 | |
| 
 | |
|     }
 | |
|     break;
 | |
|     case IOT_PLC_MSG_CTRL_PROTO_RECV:
 | |
|     case IOT_PLC_MSG_MSDU_RECV: {
 | |
|         iot_plc_msdu_recv_t *msdu = (iot_plc_msdu_recv_t*)(hdr + 1);
 | |
|         if (msdu && msdu->len >= sizeof(cli_msg_hdr_t)) {
 | |
|             iot_cli_queue_data(msdu->data, msdu->len);
 | |
|         }
 | |
|     }
 | |
|     break;
 | |
| #if PLC_SUPPORT_CCO_ROLE
 | |
|     case IOT_PLC_MSG_STA_JOIN_INFO: {
 | |
|         iot_plc_sta_join_info_t *join_node =
 | |
|             (iot_plc_sta_join_info_t*)(hdr + 1);
 | |
|         iot_cli_cco_handle_sta_join(join_node->sta_info.addr);
 | |
|         if ((join_node->sta_info.dev_type == IOT_PLC_DEV_TYPE_METER_CONTROLLER)
 | |
|             && iot_cli_host_is_ctrl_connected()) {
 | |
|             iot_cli_host_set_ctrl_connected(0);
 | |
|         }
 | |
|     }
 | |
|     break;
 | |
|     case IOT_PLC_MSG_STA_LEAVE_INFO: {
 | |
|         iot_plc_sta_leave_info_t *leave_info =
 | |
|             (iot_plc_sta_leave_info_t*)(hdr + 1);
 | |
|         for (uint32_t i = 0; i < leave_info->sta_count; ++i) {
 | |
|             iot_cli_cco_handle_sta_leave(&leave_info->sta[i]);
 | |
|             remove_addr_from_mapping_table(leave_info->sta[i].mac_addr);
 | |
|         }
 | |
|         if ((0 == cli.enable_commu) &&
 | |
|             (get_first_ckb_addr_from_mapping_table() == NULL)) {
 | |
|             /* enable cli uart when pre ckb is not used */
 | |
|             cli.enable_commu = 1;
 | |
|         }
 | |
|     }
 | |
|     break;
 | |
| #endif
 | |
| #if (PLC_SUPPORT_CCO_ROLE || (IOT_STA_CONTROL_MODE == IOT_STA_CONTROL_TYPE_STA))
 | |
|     case IOT_PLC_MSG_BAND_INFO_QUERY_RPT: {
 | |
|         iot_plc_freq_band_info_query_rpt_t *rpt =
 | |
|             (iot_plc_freq_band_info_query_rpt_t*)(hdr + 1);
 | |
|         iot_printf("cli_get_band_id (%d)\n", rpt->freq_band);
 | |
|         iot_cli_send_to_host(CLI_MSGID_GET_BAND_ID_RESP, (uint8_t*)rpt,
 | |
|             sizeof(iot_plc_freq_band_info_query_rpt_t), cli_src_mac);
 | |
|     }
 | |
|     break;
 | |
|     case IOT_PLC_MSG_FREQ_BAND_SET_RPT: {
 | |
|         iot_plc_freq_band_set_rpt_t* rpt = \
 | |
|             (iot_plc_freq_band_set_rpt_t*)(hdr + 1);
 | |
|         iot_cli_send_to_host(CLI_MSGID_SET_BAND_ID_RESP, (uint8_t*)rpt,
 | |
|             sizeof(iot_plc_freq_band_set_rpt_t), cli_src_mac);
 | |
|     }
 | |
|     break;
 | |
|     case IOT_PLC_MSG_RF_CHANNEL_SET_RPT: {
 | |
|         iot_plc_set_rf_channel_rpt_t* rpt =
 | |
|             (iot_plc_set_rf_channel_rpt_t*)(hdr + 1);
 | |
|         iot_cli_send_to_host(CLI_MSGID_SET_RF_CHANNEL_RSP, (uint8_t*)rpt,
 | |
|             sizeof(iot_plc_set_rf_channel_rpt_t), cli_src_mac);
 | |
|     }
 | |
|     break;
 | |
| #endif
 | |
|     case IOT_PLC_MSG_NEIGHBOR_DEV_RPT: {
 | |
|         iot_plc_neighbor_dev_rpt_t *neighbor_info =
 | |
|             (iot_plc_neighbor_dev_rpt_t*)(hdr + 1);
 | |
|         iot_printf("plc_upgrade:neighbor info, sub sta count %lu,"
 | |
|             " cnt %lu, total cnt %lu done %lu\n",
 | |
|             neighbor_info->total_d_sub_sta_cnt,
 | |
|             neighbor_info->cnt,
 | |
|             neighbor_info->total_cnt,
 | |
|             neighbor_info->done);
 | |
| 
 | |
|         if (hdr->req_id == IOT_PLC_API_REQ_ID_DEFAULT) {
 | |
|             cli_remote_upgrade_start_phase2(
 | |
|                 neighbor_info->total_d_sub_sta_cnt);
 | |
|         } else {
 | |
|             cli_neighbor_info_notify(neighbor_info, host_config->cco_mac);
 | |
|         }
 | |
|     }
 | |
|     break;
 | |
| #if (IOT_STA_CONTROL_MODE == IOT_STA_CONTROL_TYPE_STA)
 | |
|     case IOT_PLC_MSG_ENABLE_DISCOVERY_RPT: {
 | |
|         iot_plc_enable_discovery_rpt_t *rpt =
 | |
|             (iot_plc_enable_discovery_rpt_t *)(hdr + 1);
 | |
|         cli_enable_discovery_mode_ack ack;
 | |
|         iot_printf("discovery enable rpt %lu %lu\n",
 | |
|             rpt->result, rpt->err_no);
 | |
|         ack.result = rpt->result;
 | |
|         iot_cli_send_to_host(
 | |
|             CLI_MSGID_ENABLE_DISCOVERY_MODE_ACK,
 | |
|             (uint8_t *)&ack, sizeof(ack), cli_src_mac);
 | |
|     }
 | |
|     break;
 | |
|     case IOT_PLC_MSG_DISCOVERY_NODE_RPT: {
 | |
|         iot_plc_discovery_node_rpt_t *rpt =
 | |
|             (iot_plc_discovery_node_rpt_t *)(hdr + 1);
 | |
|         iot_printf(
 | |
|             "discovery node %lu mac=[%02X:%02X:%02X:%02X:%02X:%02X] band %lu\n",
 | |
|             rpt->role, rpt->addr[0], rpt->addr[1],
 | |
|             rpt->addr[2], rpt->addr[3], rpt->addr[4], rpt->addr[5], rpt->band_id);
 | |
|         cli_discovery_node_notify(rpt);
 | |
|     }
 | |
|     break;
 | |
| #endif
 | |
|     case IOT_PLC_MSG_CTRL_PROTO_STATUS_RPT: {
 | |
|         iot_plc_ctrl_proto_state_rpt_t *rpt =
 | |
|             (iot_plc_ctrl_proto_state_rpt_t *)(hdr + 1);
 | |
|         if (rpt->state == IOT_PLC_CTRL_PROTO_STATE_CONNECTED) {
 | |
|             iot_cli_host_set_ctrl_connected(1);
 | |
|         } else if (rpt->state == IOT_PLC_CTRL_PROTO_STATE_DISCONNECTED) {
 | |
|             iot_cli_host_set_ctrl_connected(0);
 | |
|         }
 | |
|         iot_printf("is_ready :  %lu \n", host_info->is_ready);
 | |
|     }
 | |
|     break;
 | |
|     case IOT_PLC_MSG_NW_NEIGHBOR_RPT: {
 | |
|         iot_plc_nb_nw_rpt_t *rpt =
 | |
|             (iot_plc_nb_nw_rpt_t *)(hdr + 1);
 | |
|         iot_printf("nw neighbor rpt count %lu\n", rpt->count);
 | |
|         cli_neighbor_nw_info_notify(rpt, cli_src_mac);
 | |
|     }
 | |
|     break;
 | |
|     default:
 | |
|         break;
 | |
|     }
 | |
| 
 | |
|     iot_pkt_free(pkt);
 | |
| }
 | |
| 
 | |
| 
 | |
| #if PLC_SUPPORT_CCO_ROLE
 | |
| void cli_chang_host_role(uint8_t *src_mac)
 | |
| {
 | |
|     host_config->continue_query = 0;
 | |
|     host_config->topo_count_in_packet = 0;
 | |
|     host_config->topo_query_start_index = 0;
 | |
|     host_config->query_miss_topo = 0;
 | |
|     host_config->cli_request_id = add_addr_to_mapping_table(src_mac);
 | |
| }
 | |
| 
 | |
| void ci_nw_status_query(
 | |
|     uint8_t *buffer, uint32_t bufferlen, uint8_t *src_mac)
 | |
| {
 | |
|     cli_nw_status_query_dl *query =
 | |
|         (cli_nw_status_query_dl *)buffer;
 | |
| 
 | |
|     if ((!query) || (bufferlen < sizeof(*query))) {
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     iot_printf("cli nw status query\n");
 | |
| 
 | |
|     cli_cco_nw_status_notify(src_mac);
 | |
| }
 | |
| 
 | |
| void cli_set_pco_snr_config(
 | |
|     uint8_t *buffer, uint32_t bufferlen, uint8_t *src_mac)
 | |
| {
 | |
|     iot_plc_cfg_set_req_t cfg;
 | |
|     cli_host_set_dl_snr *set = (cli_host_set_dl_snr *)buffer;
 | |
|     cli_host_set_dl_snr_ack ack;
 | |
| 
 | |
|     if ((!set) || (bufferlen < sizeof(*set))) {
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     os_mem_set(&cfg, 0, sizeof(cfg));
 | |
|     cfg.pco_snr_rpt_valid = 1;
 | |
|     cfg.pco_snr_rpt = set->on;
 | |
| 
 | |
|     ack.result = 0;
 | |
|     iot_cli_send_to_host(CLI_MSGID_SET_PCO_SNR_CFG_ACK,
 | |
|         (uint8_t *)&ack, sizeof(ack), src_mac);
 | |
| 
 | |
|     iot_printf("cli_set_pco_snr_config(%d)\n", cfg.pco_snr_rpt);
 | |
| 
 | |
|     iot_plc_set_cfg(host_config->app_handle,
 | |
|         add_addr_to_mapping_table(src_mac), &cfg);
 | |
| }
 | |
| 
 | |
| void cli_set_nid(
 | |
|     uint8_t *buffer, uint32_t bufferlen, uint8_t *src_mac)
 | |
| {
 | |
|     (void)src_mac;
 | |
|     cli_host_set_nid *cmd =
 | |
|         (cli_host_set_nid *)buffer;
 | |
|     cli_host_set_nid_ack ack;
 | |
| 
 | |
|     if ((!cmd) || (bufferlen < sizeof(*cmd))) {
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     ack.result = 0;
 | |
|     iot_cli_send_to_host(CLI_MSGID_SET_NID_ACK,
 | |
|         (uint8_t *)&ack, sizeof(ack), src_mac);
 | |
| 
 | |
|     iot_plc_set_nid(host_config->app_handle,
 | |
|         add_addr_to_mapping_table(src_mac), cmd->nid);
 | |
| }
 | |
| 
 | |
| void cli_neighbor_nw_query(
 | |
|     uint8_t *buffer, uint32_t bufferlen, uint8_t *src_mac)
 | |
| {
 | |
|     cli_neighbor_nw_query_dl *query =
 | |
|         (cli_neighbor_nw_query_dl *)buffer;
 | |
| 
 | |
|     if ((!query) || (bufferlen < sizeof(*query))) {
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     iot_printf("cli neighbor nw query\n");
 | |
| 
 | |
|     iot_plc_query_nb_nw_info(host_config->app_handle,
 | |
|         add_addr_to_mapping_table(src_mac));
 | |
| }
 | |
| 
 | |
| void cli_neighbor_info_response(
 | |
|     uint8_t *buffer, uint32_t bufferlen, uint8_t *src_mac)
 | |
| {
 | |
|     (void)src_mac;
 | |
|     iot_printf("cco forward neighbor info\n");
 | |
|     iot_cli_send_to_host(CLI_MSGID_NEIGHBOR_INFO_RESP,
 | |
|         buffer, bufferlen, host_config->cmd_src_addr);
 | |
| }
 | |
| 
 | |
| void cli_set_tx_power(uint8_t *buffer, uint32_t bufferlen, uint8_t *src_mac)
 | |
| {
 | |
|     cli_host_tx_power_set_t *cmd = (cli_host_tx_power_set_t *)buffer;
 | |
|     uint8_t *p_hplc = NULL;
 | |
|     int8_t *p_rf = NULL;
 | |
| 
 | |
|     if ((!cmd) || (bufferlen < sizeof(*cmd))) {
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     iot_printf("cli_set_tx_power hplc:%lu %lu, rf: %lu %d\n",
 | |
|         cmd->hplc_valid, cmd->hplc_power, cmd->rf_valid, cmd->rf_power);
 | |
|     if (!cmd->hplc_valid && !cmd->rf_valid) {
 | |
|         return;
 | |
|     }
 | |
|     if (cmd->hplc_valid) {
 | |
|         p_hplc = &cmd->hplc_power;
 | |
|     }
 | |
|     if (cmd->rf_valid) {
 | |
|         p_rf = &cmd->rf_power;
 | |
|     }
 | |
|     iot_plc_set_tx_power_cap(host_config->app_handle,
 | |
|         add_addr_to_mapping_table(src_mac), p_hplc, p_rf);
 | |
| }
 | |
| 
 | |
| void cli_set_cli_upgrade_enabled(
 | |
|     uint8_t *buffer, uint32_t bufferlen, uint8_t *src_mac)
 | |
| {
 | |
|     (void)src_mac;
 | |
|     cli_host_set_cli_upgrade_enabled *cmd =
 | |
|         (cli_host_set_cli_upgrade_enabled *)buffer;
 | |
|     cli_host_set_cli_upgrade_enabled_ack ack;
 | |
| 
 | |
|     if ((!cmd) || (bufferlen < sizeof(*cmd))) {
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     host_config->cli_upgrade_enabled = cmd->enabled;
 | |
|     iot_printf("cli upgrade host_config->cli_upgrade_enabled %lu\n",
 | |
|         host_config->cli_upgrade_enabled);
 | |
| 
 | |
|     ack.result = 0;
 | |
|     iot_cli_send_to_host(CLI_MSGID_SET_CLI_UPGRADE_ENABLED_ACK,
 | |
|         (uint8_t *)&ack, sizeof(ack), src_mac);
 | |
| }
 | |
| #endif
 | |
| 
 | |
| #if (PLC_SUPPORT_CCO_ROLE || (IOT_STA_CONTROL_MODE == IOT_STA_CONTROL_TYPE_STA))
 | |
| void cli_get_band_id(uint8_t *buffer, uint32_t bufferlen, uint8_t *src_mac)
 | |
| {
 | |
|     (void)buffer;
 | |
|     (void)bufferlen;
 | |
|     (void)src_mac;
 | |
| 
 | |
| #if PLC_SUPPORT_CCO_ROLE
 | |
|     iot_plc_query_band_info(host_config->app_handle,
 | |
|         add_addr_to_mapping_table(src_mac));
 | |
| #else
 | |
|     iot_plc_query_band_info(host_config->app_handle,
 | |
|         CLI_HOST_USE_API_BY_PLCM);
 | |
| #endif
 | |
| }
 | |
| 
 | |
| void cli_set_band_id(uint8_t *buffer, uint32_t bufferlen, uint8_t *src_mac)
 | |
| {
 | |
|     (void)src_mac;
 | |
| 
 | |
|     if ((!buffer) || (bufferlen < sizeof(uint8_t))) {
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     iot_printf("cli_set_band_id(%d)\n", *buffer);
 | |
| #if PLC_SUPPORT_CCO_ROLE
 | |
|     iot_plc_set_freq_band(host_config->app_handle,
 | |
|         add_addr_to_mapping_table(src_mac), *buffer);
 | |
| #else
 | |
|     iot_plc_set_freq_band(host_config->app_handle,
 | |
|         CLI_HOST_USE_API_BY_PLCM, *buffer);
 | |
| #endif
 | |
| }
 | |
| 
 | |
| void cli_set_rf_channel(uint8_t *buffer, uint32_t bufferlen,
 | |
|     uint8_t *src_mac)
 | |
| {
 | |
|     (void)src_mac;
 | |
|     cli_set_rf_channel_dl_t *cmd = (cli_set_rf_channel_dl_t *)buffer;
 | |
| 
 | |
|     if ((!cmd) || (bufferlen < sizeof(*cmd))) {
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     iot_printf("cli_set_rf, option:%lu, channel:%lu, enable:%lu\n", cmd->option,
 | |
|         cmd->channel, cmd->rf_cod_enable);
 | |
| 
 | |
| #if PLC_SUPPORT_CCO_ROLE
 | |
|     iot_plc_set_rf_channel(host_config->app_handle,
 | |
|         add_addr_to_mapping_table(src_mac), cmd->option, cmd->channel,
 | |
|         cmd->rf_cod_enable);
 | |
| #else
 | |
|     iot_plc_set_rf_channel(host_config->app_handle, CLI_HOST_USE_API_BY_PLCM,
 | |
|         cmd->option, cmd->channel, cmd->rf_cod_enable);
 | |
| #endif
 | |
| }
 | |
| #endif
 | |
| 
 | |
| void cli_get_topo(uint8_t *buffer, uint32_t bufferlen, uint8_t *src_mac)
 | |
| {
 | |
|     (void)src_mac;
 | |
|     if (IOT_PLC_DEV_ROLE_CCO != host_config->dev_role) {
 | |
|         // sta control tsf get topo msg to cco
 | |
|         iot_cli_module_send_data_with_retry(
 | |
|             IOT_PLC_MSG_TYPE_UNICAST, 0,
 | |
|             MODULEID_HOSTINTERFACE, CLI_MSGID_GET_TOPO, NULL,
 | |
|             host_config->cco_mac, buffer, bufferlen);
 | |
|     }
 | |
| #if PLC_SUPPORT_CCO_ROLE
 | |
|     else {
 | |
|         cli_host_nw_topo_query *query = (cli_host_nw_topo_query*)buffer;
 | |
| 
 | |
|         if ((!query) || (bufferlen < sizeof(*query))) {
 | |
|             return;
 | |
|         }
 | |
| 
 | |
|         if (query->auto_rpt == 0) {
 | |
|             host_config->continue_query = 1;
 | |
|             host_config->topo_count_in_packet = query->count;
 | |
|         } else if (!cli.enable_commu) {
 | |
|             /* disable ckb plc mgr retry query topo data */
 | |
|             if (host_config->query_miss_topo) {
 | |
|                 return;
 | |
|             }
 | |
|             host_config->query_miss_topo = 1;
 | |
|             if (host_config->continue_query) {
 | |
|                 /* stop query topo data timer, rsp miss topo data */
 | |
|                 os_stop_timer(host_config->topo_data_timer);
 | |
|                 iot_task_clean_msg(cli.cli_task_h, IOT_CLI_QUEUE_TIMER,
 | |
|                     IOT_CLI_RPT_TOPO_TIMER);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         host_config->topo_ver = cli_topo_changed_to_plc_ver(query->ver);
 | |
|         iot_printf("start to query topo start:%d, cnt:%d, \
 | |
|             auto rpt: %d\n", query->start, query->count, query->auto_rpt);
 | |
|         iot_plc_query_nw_topo(host_config->app_handle,
 | |
|             host_config->cli_request_id, host_config->topo_ver,
 | |
|             IOT_PLC_QUERY_TOPO_START_AS_TEI, query->start, query->count);
 | |
|     }
 | |
| #endif
 | |
| }
 | |
| 
 | |
| void cli_neighbor_info_query(
 | |
|     uint8_t *buffer, uint32_t bufferlen, uint8_t *src_mac)
 | |
| {
 | |
|     (void)src_mac;
 | |
|     cli_neighbor_info_query_dl *query =
 | |
|         (cli_neighbor_info_query_dl *)buffer;
 | |
| 
 | |
|     if ((!query) || (bufferlen < sizeof(*query))) {
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     if (host_config->dev_role != IOT_PLC_DEV_ROLE_CCO) {
 | |
|         iot_plc_query_neighbor_dev(
 | |
|             host_config->app_handle,
 | |
|             CLI_HOST_USE_API_BY_PLCM,
 | |
|             query->start, query->cnt, IOT_PLC_QUERY_TOPO_START_AS_TEI);
 | |
|     }
 | |
| #if PLC_SUPPORT_CCO_ROLE
 | |
|     else {
 | |
|         iot_mac_addr_cpy(host_config->cmd_src_addr, src_mac);
 | |
|         // cco forward neighbor info to sta
 | |
|         iot_cli_host_send_data_plc(IOT_PLC_MSG_TYPE_UNICAST,
 | |
|             CLI_MSGID_NEIGHBOR_INFO_QUERY, query->sta_addr,
 | |
|             (uint8_t*)query, sizeof(*query));
 | |
|     }
 | |
| #endif
 | |
| }
 | |
| 
 | |
| void cli_online_handler(uint8_t *buffer, uint32_t bufferlen, uint8_t *src_mac)
 | |
| {
 | |
|     (void)buffer;
 | |
|     (void)bufferlen;
 | |
|     cli_host_online_response_t response;
 | |
| 
 | |
|     response.cco = 0;
 | |
|     if (IOT_PLC_DEV_ROLE_CCO == host_config->dev_role) {
 | |
|         response.cco = 1;
 | |
|     }
 | |
| 
 | |
|     response.mt = 0;
 | |
|     if (iot_chip_id_check() == IOT_CHIP_ID_MT) {
 | |
|         response.mt = 1;
 | |
|     }
 | |
| 
 | |
| #if PLC_SUPPORT_CCO_ROLE
 | |
|     if (response.cco) {
 | |
|         response.cco_nw_status.proto =
 | |
|             host_config->proto;
 | |
|         response.cco_nw_status.nw_fmt_done =
 | |
|             host_config->nw_fmt_done;
 | |
|         response.cco_nw_status.route_learn_done =
 | |
|             host_config->route_learn_done;
 | |
|         response.cco_nw_status.nid =
 | |
|             host_config->nid;
 | |
|         iot_printf("proto %d, nw_fmt_done %lu,"
 | |
|             " route_learn_done %lu\n",
 | |
|             host_config->proto,
 | |
|             host_config->nw_fmt_done,
 | |
|             host_config->route_learn_done);
 | |
|     }
 | |
|     cli_set_plc_mgr_state(1);
 | |
| #elif (IOT_STA_CONTROL_MODE == IOT_STA_CONTROL_TYPE_STA)
 | |
|     cli_disable_discovery_mode();
 | |
|     response.sw_ver = iot_version_hex();
 | |
| #endif
 | |
| 
 | |
|     iot_cli_send_to_host(CLI_MSGID_ONLINE_RESP,
 | |
|         (uint8_t *)&response, sizeof(response), src_mac);
 | |
| }
 | |
| 
 | |
| void cli_switch_boot_part(
 | |
|     uint8_t *buffer, uint32_t bufferlen, uint8_t *src_mac)
 | |
| {
 | |
|     (void)src_mac;
 | |
|     cli_host_switch_boot_part *boot_info =
 | |
|         (cli_host_switch_boot_part *)buffer;
 | |
| 
 | |
|     if ((!boot_info) || (bufferlen < sizeof(*boot_info))) {
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     if (IOT_PLC_DEV_TYPE_METER_CONTROLLER == host_config->dev_type) {
 | |
|         return;
 | |
|     } else if ((host_config->dev_role != IOT_PLC_DEV_ROLE_CCO) &&
 | |
|         (0 == host_config->switch_flag)) {
 | |
|         iot_printf("sta switch boot part\n");
 | |
|         iot_dbglog_input(IOT_CLI_HOST, DBGLOG_ERR,
 | |
|             IOT_CLI_HOST_SWITCH_BOOT_PART_INFO, 0);
 | |
|         host_config->switch_flag = 1;
 | |
|         dev_switch_part_flag(DEV_SWITCH_PART_CAUSE_OTHER);
 | |
|         /* set LED to show upgrading state */
 | |
|         iot_plc_led_request(IOT_PLC_LED_UPGRADE_ON);
 | |
|     }
 | |
| #if PLC_SUPPORT_CCO_ROLE
 | |
|     else {
 | |
|         // send ack to plc mfr
 | |
|         iot_cli_send_to_host(CLI_MSGID_SWITCH_BOOT_PART_ACK, NULL, 0, src_mac);
 | |
| 
 | |
|         // check if the dst is cco
 | |
|         if (iot_mac_addr_cmp(boot_info->dst, host_config->mac_addr)) {
 | |
|             iot_printf("cco switch boot part\n");
 | |
|             iot_dbglog_input(IOT_CLI_HOST, DBGLOG_ERR,
 | |
|                 IOT_CLI_HOST_SWITCH_BOOT_PART_INFO, 0);
 | |
|             dev_switch_part_flag(DEV_SWITCH_PART_CAUSE_OTHER);
 | |
|         } else {
 | |
|             uint8_t send_type = IOT_PLC_MSG_TYPE_UNICAST;
 | |
|             // check if broadcast
 | |
|             if (iot_mac_is_bcast(boot_info->dst)) {
 | |
|                 send_type = IOT_PLC_MSG_TYPE_BCAST;
 | |
|             }
 | |
|             iot_cli_host_send_data_plc(send_type, CLI_MSGID_SWITCH_BOOT_PART,
 | |
|                 boot_info->dst, buffer, bufferlen);
 | |
|         }
 | |
|     }
 | |
| #endif
 | |
| } |