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
 | 
						|
} |