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