Files
kunlun/cli/host_interface/plc/iot_cli_plc_nw.c
2024-09-28 14:24:04 +08:00

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*)&notify, 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
}