6014 lines
205 KiB
C
Executable File
6014 lines
205 KiB
C
Executable File
/****************************************************************************
|
|
|
|
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.
|
|
|
|
****************************************************************************/
|
|
/* os_ship header files */
|
|
#include "os_task_api.h"
|
|
#include "os_event_api.h"
|
|
#include "os_timer_api.h"
|
|
#include "os_utils_api.h"
|
|
|
|
/* iot common header files */
|
|
#include "iot_plc_cco_api.h"
|
|
#include "iot_module_api.h"
|
|
#include "iot_queue_api.h"
|
|
#include "iot_mem_pool_api.h"
|
|
#include "iot_config_api.h"
|
|
#include "iot_app_api.h"
|
|
#include "iot_errno_api.h"
|
|
#include "iot_io_api.h"
|
|
#include "iot_dbglog_api.h"
|
|
#include "iot_uart_api.h"
|
|
#include "iot_task_api.h"
|
|
#include "iot_flash_api.h"
|
|
#include "iot_system_api.h"
|
|
#include "iot_version_api.h"
|
|
#include "iot_oem_api.h"
|
|
#include "iot_plc_msg_api.h"
|
|
|
|
#include "iot_grapp.h"
|
|
#include "iot_plctxrx.h"
|
|
#include "iot_proto_ge.h"
|
|
#include "iot_gr_upgrade.h"
|
|
|
|
#include "iot_board_api.h"
|
|
#include "iot_gpio_api.h"
|
|
#include "iot_flashinfo.h"
|
|
#include "iot_proto_dl645.h"
|
|
|
|
#if IOT_GR_APP_ENABLE
|
|
|
|
static uint16_t overflow_index = CCO_RX_TIME + 1;
|
|
|
|
#define IOT_PROTO_INVALID_GPIO_INDEX 0xFF
|
|
|
|
void iot_proto_node_info_report(uint8_t *data, uint16_t dlen,
|
|
uint16_t total_cnt, uint16_t cur_cnt, uint8_t type, uint8_t done);
|
|
|
|
void iot_proto_nw_info_report(uint8_t max_level, uint8_t *data, uint8_t length);
|
|
extern void iot_common_bin_dump(uint8_t *data, uint32_t dlen);
|
|
extern void iot_proto_set_local_mac(void);
|
|
|
|
#if HW_PLATFORM == HW_PLATFORM_SIMU
|
|
|
|
extern uint8_t g_ucMACAddress[IOT_MAC_ADDR_LEN];
|
|
|
|
bool_t iot_proto_cache_data_for_window_rpt(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
uint32_t wind_tmr = 0;
|
|
uint16_t saved_len = 0;
|
|
bool_t ret = false;
|
|
ge_extend_fn_hdr_t *frm_hdr = (ge_extend_fn_hdr_t *)data;
|
|
ge_frame_data_send_set_subfn160_t *frm = NULL;
|
|
iot_pkt_t *send_pkt = NULL;
|
|
uint8_t *pkt_ptr = NULL;
|
|
|
|
if (CMD_REMOTE_UP_LINK != dir) {
|
|
return ret;
|
|
}
|
|
if (frm_hdr->subfn == PROTO_GE_DATA_CMD) {
|
|
frm = (ge_frame_data_send_set_subfn160_t *)data;
|
|
if (mac_addr_is_bcast_addr(frm->dest_mac)) {
|
|
saved_len = prototask_contxt.rpt_cache.data_len;
|
|
if (saved_len + len > PROTO_WIN_CACHE_LEN) {
|
|
if (saved_len != 0) {
|
|
send_pkt = iot_pkt_alloc(saved_len, IOT_GREE_APP_MID);
|
|
if (send_pkt == NULL) {
|
|
iot_cus_printf("[grpr]NO memery, sending cached pkt "
|
|
"failed\n");
|
|
return false;
|
|
}
|
|
pkt_ptr = iot_pkt_data(send_pkt);
|
|
iot_pkt_put(send_pkt, len);
|
|
os_mem_cpy(pkt_ptr, prototask_contxt.rpt_cache.data,
|
|
saved_len);
|
|
|
|
iot_proto_send_to_mainboard(send_pkt);
|
|
os_mem_set(&prototask_contxt.rpt_cache, 0,
|
|
sizeof(proto_rpt_cache_t));
|
|
}
|
|
/* if the cache buffer is full, send the cached data immediately */
|
|
if (os_is_timer_active(prototask_contxt.rpt_window_tmr)) {
|
|
os_stop_timer(prototask_contxt.rpt_window_tmr);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
os_mem_cpy(&prototask_contxt.rpt_cache.data[saved_len],
|
|
data, len);
|
|
prototask_contxt.rpt_cache.data_len += len;
|
|
|
|
if (!os_is_timer_active(prototask_contxt.rpt_window_tmr)) {
|
|
wind_tmr = os_rand() % PROTO_RTP_WINDOW_DEFAULT_SPAN;
|
|
os_start_timer(prototask_contxt.rpt_window_tmr, wind_tmr);
|
|
iot_cus_printf("[grpr]window timer started, act_window %d"
|
|
" ms\n", wind_tmr);
|
|
}
|
|
ret = true;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
#else /* HW_PLATFORM == HW_PLATFORM_SIMU */
|
|
bool_t iot_proto_cache_data_for_window_rpt(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
(void)data;
|
|
(void)len;
|
|
(void)dir;
|
|
return false;
|
|
}
|
|
|
|
#endif
|
|
|
|
/**
|
|
* @brief iot_delay_timer_get() - get a delay time (ntb)
|
|
* @param data input data to get the time
|
|
* @param time_type witch time to get
|
|
* @param set_time the time to set if need
|
|
*/
|
|
void iot_delay_timer_get(uint32_t *data, uint8_t time_type,
|
|
uint32_t set_time)
|
|
{
|
|
uint32_t cur_time;
|
|
|
|
if (set_time == 0) {
|
|
cur_time = iot_plc_get_ntb(greeapp->app_handle);
|
|
} else {
|
|
cur_time = set_time;
|
|
}
|
|
|
|
if (time_type > CCO_RX_TIME) {
|
|
iot_cus_printf("[ERR] %s get type error\n", __FUNCTION__);
|
|
return;
|
|
}
|
|
|
|
os_mem_cpy(data + time_type, &cur_time, sizeof(uint32_t));
|
|
}
|
|
|
|
void iot_proto_query_mcu_mac()
|
|
{
|
|
/* Query MCU for mac addr assigned */
|
|
proto_cmd_hdl_state_t *sm = iot_proto_cmd_handle_state_get();
|
|
#if PLC_SUPPORT_STA_ROLE
|
|
/* send 645 read address */
|
|
iot_pkt_t *pkt = iot_pkt_alloc(sizeof(proto_645_header_t) +
|
|
sizeof(proto_645_tailer_t), IOT_GREE_APP_MID);
|
|
IOT_ASSERT(pkt);
|
|
iot_pkt_put(pkt, sizeof(proto_645_header_t) + sizeof(proto_645_tailer_t));
|
|
iot_proto_dl645_read_addr(iot_pkt_data(pkt));
|
|
#else
|
|
iot_pkt_t *pkt =
|
|
iot_pkt_alloc(sizeof(ge_frame_local_mac_query_subfn1_t), IOT_GREE_APP_MID);
|
|
IOT_ASSERT(pkt);
|
|
ge_frame_local_mac_query_subfn1_t *cmd =
|
|
(ge_frame_local_mac_query_subfn1_t *)iot_pkt_data(pkt);
|
|
iot_pkt_put(pkt, sizeof(*cmd));
|
|
os_mem_set(cmd, 0, sizeof(*cmd));
|
|
/*
|
|
Hint, normall, we shuld add seq, but, since this is repeat cmd, so, skip
|
|
increase seq currently.
|
|
*/
|
|
|
|
EXT_FN_FRM_PREPARE(cmd, PROTO_GE_PLC_QUERY_CMD, PROTO_LOCAL_MAC_QUERY_CMD);
|
|
|
|
cmd->dir = DIR_UP_TO_MCU;
|
|
cmd->nw_role = prototask_contxt.local_dev.nw_role;
|
|
cmd->tail.check_sum = ge_frm_checksum_calc((uint8_t *)cmd,
|
|
sizeof(*cmd)-sizeof(ge_frm_tail_t));
|
|
#endif
|
|
/* send to MCU */
|
|
if (prototask_contxt.proto_sendto_mainboard_fn) {
|
|
if (PROTO_CMD_IDLE == sm->state ||
|
|
PROTO_CMD_WAIT_MAC_RESP == sm->state) {
|
|
iot_proto_send_to_mainboard(pkt);
|
|
/* set state to wait for mac response */
|
|
sm->dir = CMD_LOCAL_DOWN_LINK;
|
|
sm->state = PROTO_CMD_WAIT_MAC_RESP;
|
|
}
|
|
} else {
|
|
iot_pkt_free(pkt);
|
|
}
|
|
}
|
|
|
|
#if PLC_SUPPORT_CCO_ROLE
|
|
void iot_proto_cco_groupnet_cfm_send(uint8_t seq,
|
|
uint8_t dir, uint8_t sub_fn, uint8_t result, uint8_t reason)
|
|
{
|
|
iot_pkt_t *cfm_pkt = iot_pkt_alloc(sizeof(ge_frame_cmd_cfm_set_subfn20_t),
|
|
IOT_GREE_APP_MID);
|
|
IOT_ASSERT(cfm_pkt);
|
|
iot_pkt_put(cfm_pkt, sizeof(ge_frame_cmd_cfm_set_subfn20_t));
|
|
os_mem_set(iot_pkt_data(cfm_pkt), 0, sizeof(ge_frame_cmd_cfm_set_subfn20_t));
|
|
iot_proto_cfm_cmd_group(iot_pkt_data(cfm_pkt),
|
|
sub_fn, result, reason, seq);
|
|
if (CMD_LOCAL_DOWN_LINK == dir) {
|
|
/* send start group net confirm cmd to MCU */
|
|
iot_proto_send_to_mainboard(cfm_pkt);
|
|
} else {
|
|
iot_pkt_free(cfm_pkt);
|
|
}
|
|
}
|
|
|
|
static void iot_update_proxy_info(uint8_t *pco_mac)
|
|
{
|
|
uint16_t i;
|
|
|
|
if (iot_mac_addr_cmp(prototask_contxt.local_dev.mac, pco_mac)) {
|
|
/* if proxy is cco, not update */
|
|
return;
|
|
}
|
|
for (i = 0; i < STA_DEV_MAX; i++) {
|
|
if (iot_mac_addr_cmp(prototask_contxt.dev_lst.dev[i].mac, pco_mac)) {
|
|
if (prototask_contxt.dev_lst.dev[i].dev_role !=
|
|
IOT_PLC_DEV_ROLE_PCO) {
|
|
/* update pco role */
|
|
iot_cus_printf("update pco role mac:%02X%02X%02X%02X%02X%02X\n",
|
|
pco_mac[0], pco_mac[1], pco_mac[2],
|
|
pco_mac[3], pco_mac[4], pco_mac[5]);
|
|
prototask_contxt.dev_lst.dev[i].dev_role = IOT_PLC_DEV_ROLE_PCO;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
void iot_proto_cco_groupnet_sm(uint8_t *data, uint8_t subfn,
|
|
transmit_direction_e_t dir, void *info)
|
|
{
|
|
uint8_t state = prototask_contxt.groupnet_state.state;
|
|
proto_dev_list_t *dev_lst= &prototask_contxt.dev_lst;
|
|
uint16_t i, j;
|
|
ge_app_pib_info_t *p_flash = &prototask_contxt.flashinfo;
|
|
uint8_t tmp_mac[IOT_MAC_ADDR_LEN] = { 0 };
|
|
|
|
switch (state) {
|
|
case CCO_STATE_GROUPNET_IDLE:
|
|
{
|
|
switch (subfn) {
|
|
case PROTO_CONN_IND_RPT_CMD:
|
|
{
|
|
plctxrx_cmd_joined_network_t *join_info =
|
|
(plctxrx_cmd_joined_network_t *)info;
|
|
/* here device list must not be empty, we just need
|
|
* to change the device's network flag.whitelist must
|
|
* be enable.
|
|
*/
|
|
|
|
/* first check if STA is in the device list */
|
|
for (i = 0; i < STA_DEV_MAX; i++) {
|
|
if (iot_mac_addr_cmp(join_info->mac, dev_lst->dev[i].mac)) {
|
|
iot_update_proxy_info(join_info->pco_mac);
|
|
/* save device role */
|
|
dev_lst->dev[i].dev_role = join_info->role;
|
|
iot_mac_addr_cpy(dev_lst->dev_pco[i], join_info->pco_mac);
|
|
if (dev_lst->online_flag[i] == false) {
|
|
prototask_contxt.dev_lst.online_dev_cnt++;
|
|
/* save device join state */
|
|
dev_lst->online_flag[i] = true;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
if (i == STA_DEV_MAX) {
|
|
iot_cus_printf("[glpr][err]cco_groupnet_sm idle:"
|
|
"STA is not in dev list!!!mac[0]=0x%x,"
|
|
"mac[1]=0x%x,mac[2]=0x%x\n", join_info->mac[0],
|
|
join_info->mac[1],join_info->mac[2]);
|
|
return;
|
|
}
|
|
|
|
break;
|
|
}
|
|
case PROTO_DISCONN_IND_RPT_CMD:
|
|
{
|
|
plctxrx_cmd_leave_net_t *leave_info =
|
|
(plctxrx_cmd_leave_net_t *)info;
|
|
for (i = 0; i < leave_info->cnt; i++) {
|
|
/* first check if the sta is in nw sta list */
|
|
for (j = 0; j < STA_DEV_MAX; j++) {
|
|
if (iot_mac_addr_cmp(leave_info->mac[i],
|
|
dev_lst->dev[j].mac)) {
|
|
os_mem_set(dev_lst->dev_pco[j], 0, IOT_MAC_ADDR_LEN);
|
|
if (dev_lst->online_flag[j] == true) {
|
|
if (prototask_contxt.dev_lst.online_dev_cnt > 0)
|
|
prototask_contxt.dev_lst.online_dev_cnt--;
|
|
/* clean online flag */
|
|
dev_lst->online_flag[j] = false;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (j == STA_DEV_MAX) {
|
|
iot_cus_printf("[glpr][war]not find\n");
|
|
}
|
|
/* report disconn event to MCU */
|
|
iot_proto_report_disconn_event2mcu(leave_info->mac[i]);
|
|
}
|
|
break;
|
|
}
|
|
case PROTO_CCO_START_GROUP_NET_CMD:
|
|
{
|
|
ge_frame_start_group_set_subfn13_t *src_cmd =
|
|
(ge_frame_start_group_set_subfn13_t *)data;
|
|
dev_lst->valid_dev_tmp_cnt = dev_lst->valid_dev_cnt;
|
|
os_mem_cpy(dev_lst->dev_tmp, dev_lst->dev,
|
|
sizeof(proto_dev_t) * STA_DEV_MAX);
|
|
/* 1st: empty whitelist in CVG */
|
|
iot_proto_whitelist_add_remove(GE_PROTO_ACTION_DEL, NULL, false);
|
|
iot_proto_whitelist_state_init();
|
|
/* 2nd: empty whitelist in device list */
|
|
os_mem_set(dev_lst->dev, 0, sizeof(proto_dev_t) * STA_DEV_MAX);
|
|
/* 3rd: clean online flag */
|
|
os_mem_set(dev_lst->online_flag, 0, sizeof(bool_t) * STA_DEV_MAX);
|
|
dev_lst->valid_dev_cnt = 0;
|
|
/* 4ur: empty whitelist in flash */
|
|
p_flash->public.pub.dev_cnt = 0;
|
|
os_mem_set(p_flash->public.pub.dev_tbl, 0,
|
|
STA_DEV_MAX * sizeof(proto_dev_t));
|
|
(void)iot_proto_flashsave(p_flash);
|
|
/**
|
|
* disable whitelist, do not need to handle cmd confirm,
|
|
* so do not record wait_cmd_cfm state, just drop cmd cfm
|
|
* when recv it from PLCTXRX.
|
|
*
|
|
*/
|
|
iot_proto_whitelist_en_disable(GE_PROTO_WL_DISABLE, false);
|
|
/* confirm response */
|
|
iot_proto_cco_groupnet_cfm_send(src_cmd->seq,
|
|
dir, PROTO_CCO_START_GROUP_NET_CMD, 0, 0);
|
|
/* set vendor info */
|
|
prototask_contxt.net_start_flag = 1;
|
|
|
|
/* next state */
|
|
prototask_contxt.groupnet_state.state = CCO_STATE_GROUPNETING;
|
|
|
|
break;
|
|
}
|
|
case PROTO_CCO_END_GROUP_NET_CMD:
|
|
{
|
|
/**
|
|
* when recv start groupnet cmd in groupneting state,
|
|
* we should response a groupnet start cfm to MCU.
|
|
*/
|
|
ge_frame_end_group_set_subfn14_t *src_cmd =
|
|
(ge_frame_end_group_set_subfn14_t *)data;
|
|
/* confirm response */
|
|
iot_proto_cco_groupnet_cfm_send(src_cmd->seq,
|
|
dir, PROTO_CCO_END_GROUP_NET_CMD, 1,
|
|
PROTO_REASON_CCO_GROUPNETING_IDLE);
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case CCO_STATE_GROUPNETING:
|
|
{
|
|
switch (subfn) {
|
|
case PROTO_CONN_IND_RPT_CMD:
|
|
{
|
|
plctxrx_cmd_joined_network_t *join_info =
|
|
(plctxrx_cmd_joined_network_t *)info;
|
|
|
|
/* check if there is duplicated sta in sta list */
|
|
for (i = 0; i < STA_DEV_MAX; i++) {
|
|
if (iot_mac_addr_cmp(join_info->mac, dev_lst->dev[i].mac)) {
|
|
dev_lst->dev[i].dev_role = join_info->role;
|
|
iot_cus_printf("[glpr][war]cco_groupnet_sm grouping:"
|
|
"duplicate sta\n");
|
|
return;
|
|
}
|
|
}
|
|
/* not find duplicated sta,then find a free place to record it */
|
|
for (i = 0; i < STA_DEV_MAX; i++) {
|
|
if (iot_mac_addr_cmp(tmp_mac, dev_lst->dev[i].mac)) {
|
|
/* record new sta in sta list */
|
|
iot_mac_addr_cpy(dev_lst->dev[i].mac, join_info->mac);
|
|
dev_lst->dev[i].dev_role = join_info->role;
|
|
if (dev_lst->online_flag[i] == false) {
|
|
prototask_contxt.dev_lst.online_dev_cnt++;
|
|
/* save device join state */
|
|
dev_lst->online_flag[i] = true;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
/* check if dev cnt is over range */
|
|
if (STA_DEV_MAX == i) {
|
|
iot_cus_printf("[glpr][war]cco_groupnet_sm:"
|
|
"sta cnt over-range\n");
|
|
return;
|
|
}
|
|
break;
|
|
}
|
|
case PROTO_DISCONN_IND_RPT_CMD:
|
|
{
|
|
plctxrx_cmd_leave_net_t *leave_info =
|
|
(plctxrx_cmd_leave_net_t *)info;
|
|
for (i = 0; i < leave_info->cnt; i++) {
|
|
/* first check if the sta is in nw sta list */
|
|
for (j = 0; j < STA_DEV_MAX; j++) {
|
|
if (iot_mac_addr_cmp(leave_info->mac[i],
|
|
dev_lst->dev[j].mac)) {
|
|
if (dev_lst->online_flag[j] == true) {
|
|
if (prototask_contxt.dev_lst.online_dev_cnt > 0)
|
|
prototask_contxt.dev_lst.online_dev_cnt--;
|
|
/* clean online flag */
|
|
dev_lst->online_flag[j] = false;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
if (j == STA_DEV_MAX) {
|
|
/* not find the sta in nw sta list */
|
|
iot_cus_printf("[glpr][war]cco_groupnet_sm grouping:"
|
|
"not find leave sta in sta list\n");
|
|
continue;
|
|
}
|
|
/* report disconn event to MCU */
|
|
iot_proto_report_disconn_event2mcu(leave_info->mac[i]);
|
|
/* del leave sta in nw sta list */
|
|
os_mem_set(&dev_lst->dev[j], 0, sizeof(proto_dev_t));
|
|
}
|
|
break;
|
|
}
|
|
case PROTO_CCO_END_GROUP_NET_CMD:
|
|
{
|
|
/**
|
|
* disable whitelist, do not need to handle cmd confirm,
|
|
* so do not record wait_cmd_cfm state, just drop cmd cfm
|
|
* when recv from PLCTXRX.
|
|
*
|
|
*/
|
|
ge_frame_end_group_set_subfn14_t *src_cmd =
|
|
(ge_frame_end_group_set_subfn14_t *)data;
|
|
/* confirm response */
|
|
iot_proto_cco_groupnet_cfm_send(src_cmd->seq,
|
|
dir, PROTO_CCO_END_GROUP_NET_CMD, 0, 0);
|
|
/* update whitelist to flash */
|
|
os_mem_set(p_flash->public.pub.dev_tbl, 0,
|
|
STA_DEV_MAX*sizeof(proto_dev_t));
|
|
for (i = 0, j = 0; i < STA_DEV_MAX; i++) {
|
|
if (!iot_mac_addr_cmp(tmp_mac,
|
|
prototask_contxt.dev_lst.dev[i].mac)) {
|
|
os_mem_cpy(&p_flash->public.pub.dev_tbl[j++],
|
|
&prototask_contxt.dev_lst.dev[i], sizeof(proto_dev_t));
|
|
}
|
|
}
|
|
prototask_contxt.dev_lst.valid_dev_cnt = j;
|
|
p_flash->public.pub.dev_cnt = j;
|
|
iot_cus_printf("[glpr][info]group end :valid dev cnt=%d\n",
|
|
p_flash->public.pub.dev_cnt);
|
|
/* sync dev list and flash dev list */
|
|
os_mem_set(prototask_contxt.dev_lst.dev,
|
|
0, STA_DEV_MAX*sizeof(proto_dev_t));
|
|
os_mem_cpy(prototask_contxt.dev_lst.dev,
|
|
p_flash->public.pub.dev_tbl,
|
|
p_flash->public.pub.dev_cnt * sizeof(proto_dev_t));
|
|
|
|
dev_lst->valid_dev_tmp_cnt = dev_lst->valid_dev_cnt;
|
|
os_mem_cpy(dev_lst->dev_tmp, dev_lst->dev,
|
|
sizeof(proto_dev_t) * STA_DEV_MAX);
|
|
/* save whitelist to flash */
|
|
(void)iot_proto_flashsave(p_flash);
|
|
/* add whitelist to CVG */
|
|
iot_proto_whitelist_add_remove(GE_PROTO_ACTION_ADD, NULL, false);
|
|
/* enable whitelist in CVG */
|
|
iot_proto_whitelist_en_disable(GE_PROTO_WL_ENABLE, false);
|
|
/* set vendor info */
|
|
prototask_contxt.net_start_flag = 0;
|
|
|
|
/* next state */
|
|
prototask_contxt.groupnet_state.state = CCO_STATE_GROUPNET_IDLE;
|
|
|
|
break;
|
|
}
|
|
case PROTO_CCO_START_GROUP_NET_CMD:
|
|
{
|
|
/**
|
|
* when recv start groupnet cmd in groupneting state,
|
|
* we should response a groupnet start cfm to MCU.
|
|
*/
|
|
ge_frame_start_group_set_subfn13_t *src_cmd =
|
|
(ge_frame_start_group_set_subfn13_t *)data;
|
|
/* confirm response */
|
|
iot_proto_cco_groupnet_cfm_send(src_cmd->seq,
|
|
dir, PROTO_CCO_START_GROUP_NET_CMD, 1,
|
|
PROTO_REASON_CCO_GROUPNETING);
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return;
|
|
}
|
|
#else
|
|
void iot_proto_cco_groupnet_sm(uint8_t *data, uint8_t subfn,
|
|
transmit_direction_e_t dir, void *info)
|
|
{
|
|
(void)data;
|
|
(void)subfn;
|
|
(void)dir;
|
|
(void)info;
|
|
}
|
|
#endif
|
|
|
|
bool_t iot_proto_set_local_mac_subfn_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
bool_t rpt2mcu = false;
|
|
ge_frame_local_mac_set_subfn1_t *frm = (ge_frame_local_mac_set_subfn1_t *)data;
|
|
proto_cmd_hdl_state_t* sm = iot_proto_cmd_handle_state_get();
|
|
uint8_t mac_addr[IOT_MAC_ADDR_LEN] = { 0 };
|
|
uint32_t reason = 0;
|
|
|
|
if (len != sizeof(ge_frame_local_mac_set_subfn1_t)) {
|
|
reason = PROTO_REASON_LEN_MISSMATCH;
|
|
} else if (iot_mac_addr_cmp(frm->mac, mac_addr)) {
|
|
reason = PROTO_REASON_MAC_ADDR_ZERO;
|
|
} else if (iot_mac_addr_cmp(prototask_contxt.local_dev.mac, frm->mac)) {
|
|
reason = PROTO_REASON_DUP_SETTING;
|
|
}
|
|
|
|
if (0 != reason) {
|
|
iot_proto_resp_cfm_frame(reason, dir, PROTO_LOCAL_MAC_SET_CMD,
|
|
frm->seq, NULL);
|
|
iot_cus_printf("[glpr][err]set_local_mac failed, "
|
|
"reason--%d\n", reason);
|
|
return rpt2mcu;
|
|
}
|
|
|
|
/* Set cmd handle state */
|
|
sm->dir = CMD_LOCAL_UP_LINK;
|
|
sm->cur_subfn = frm->hdr.subfn;
|
|
sm->seq = frm->seq;
|
|
sm->state = PROTO_CMD_WAIT_CMD_CFM;
|
|
/* set mac and type to CVG layer */
|
|
iot_proto_set_mac(frm->mac, 0, true);
|
|
|
|
return rpt2mcu;
|
|
}
|
|
|
|
bool_t iot_proto_local_mac_resp_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
bool_t rpt2mcu = false;
|
|
IOT_ASSERT(CMD_LOCAL_DOWN_LINK == dir);
|
|
sta_dev_t *local_dev = &prototask_contxt.local_dev;
|
|
uint8_t tmp_mac[IOT_MAC_ADDR_LEN] = { 0 };
|
|
ge_frame_local_mac_resp_subfn1_t *cmd =
|
|
(ge_frame_local_mac_resp_subfn1_t *)data;
|
|
|
|
if (len != sizeof(ge_frame_local_mac_resp_subfn1_t)) {
|
|
iot_cus_printf("[glpr][err]%s cmd len mismatch\n", "mac resp");
|
|
return rpt2mcu;
|
|
}
|
|
|
|
iot_cus_printf("[glpr]local_mac_resp_handler:mac:%x:%x:%x:%x:%x:%x\n",
|
|
cmd->mac[0], cmd->mac[1], cmd->mac[2],
|
|
cmd->mac[3], cmd->mac[4], cmd->mac[5]);
|
|
|
|
/* check if mac addr is valid */
|
|
if (iot_mac_addr_cmp(tmp_mac, cmd->mac)) {
|
|
iot_cus_printf("[glpr][err]mac addr is not valid\n");
|
|
return rpt2mcu;
|
|
}
|
|
|
|
/* check if set the same mac and dev type */
|
|
if (iot_mac_addr_cmp(local_dev->mac, cmd->mac)) {
|
|
iot_cus_printf("[glpr]set the same mac and type\n");
|
|
return rpt2mcu;
|
|
}
|
|
|
|
/* set mac and type to CVG layer */
|
|
iot_proto_set_mac(cmd->mac, 0, false);
|
|
|
|
return rpt2mcu;
|
|
}
|
|
|
|
bool_t iot_proto_query_local_mac_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
(void)dir;
|
|
bool_t rpt2mcu = false;
|
|
ge_frame_local_mac_resp_subfn1_t *resp_cmd;
|
|
ge_frame_local_mac_query_subfn1_t *query_cmd =
|
|
(ge_frame_local_mac_query_subfn1_t *)data;
|
|
|
|
iot_pkt_t *pkt = iot_pkt_alloc(sizeof(*resp_cmd), IOT_GREE_APP_MID);
|
|
if (pkt == NULL) {
|
|
iot_cus_printf("[glpr][err]No Mem!\n");
|
|
return rpt2mcu;
|
|
}
|
|
resp_cmd = (ge_frame_local_mac_resp_subfn1_t *)iot_pkt_data(pkt);
|
|
iot_pkt_put(pkt, sizeof(*resp_cmd));
|
|
|
|
os_mem_set(resp_cmd, 0, sizeof(*resp_cmd));
|
|
EXT_FN_FRM_PREPARE(resp_cmd,
|
|
PROTO_GE_PLC_RESP_CMD, PROTO_LOCAL_MAC_RESP_CMD);
|
|
if (len == sizeof(ge_frame_local_mac_query_subfn1_t)) {
|
|
resp_cmd->seq = query_cmd->seq;
|
|
iot_mac_addr_cpy(resp_cmd->mac, prototask_contxt.local_dev.mac);
|
|
resp_cmd->dir = DIR_UP_TO_MCU;
|
|
resp_cmd->nw_role = prototask_contxt.local_dev.nw_role;
|
|
} else {
|
|
iot_cus_printf("[glpr][err]%s cmd len mismatch\n", "qurey local mac");
|
|
}
|
|
resp_cmd->tail.check_sum =
|
|
ge_frm_checksum_calc((uint8_t *)resp_cmd,
|
|
sizeof(*resp_cmd)-sizeof(ge_frm_tail_t));
|
|
|
|
/* send to MCU */
|
|
iot_proto_send_to_mainboard(pkt);
|
|
|
|
return rpt2mcu;
|
|
}
|
|
|
|
bool_t iot_proto_conn_ind_subfn_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
(void)len;
|
|
sta_dev_t *local_dev = &prototask_contxt.local_dev;
|
|
proto_dev_list_t *dev_lst= &prototask_contxt.dev_lst;
|
|
bool_t rpt2mcu = false;
|
|
plctxrx_cmd_resp_t *cmd = (plctxrx_cmd_resp_t *)data;
|
|
plctxrx_cmd_joined_network_t *info;
|
|
iot_pkt_t *pkt;
|
|
ge_frame_conn_ind_rpt_set_subfn9_t *ind_frm;
|
|
uint8_t need_save_flash = 0;
|
|
ge_app_pib_info_t *p_flash = &prototask_contxt.flashinfo;
|
|
|
|
info = (plctxrx_cmd_joined_network_t *)cmd->data;
|
|
|
|
if (IOT_PLC_DEV_ROLE_CCO != local_dev->nw_role) {
|
|
iot_mac_addr_cpy(prototask_contxt.cco_dev.mac, info->mac);
|
|
local_dev->nw_role = info->role;
|
|
local_dev->nid = info->nid;
|
|
local_dev->dev_ready = true;
|
|
if (!iot_mac_addr_cmp(p_flash->public.pub.cco_mac, info->mac)) {
|
|
iot_mac_addr_cpy(p_flash->public.pub.cco_mac, info->mac);
|
|
need_save_flash = 1;
|
|
}
|
|
|
|
if (need_save_flash) {
|
|
iot_proto_flashsave(p_flash);
|
|
}
|
|
} else {
|
|
iot_cus_printf("join: role=%d pco_mac=%02X:%02X:%02X:%02X:%02X:%02X\n",
|
|
info->role, info->pco_mac[0], info->pco_mac[1], info->pco_mac[2],
|
|
info->pco_mac[3], info->pco_mac[4], info->pco_mac[5]);
|
|
iot_proto_cco_groupnet_sm(NULL, PROTO_CONN_IND_RPT_CMD, dir, info);
|
|
}
|
|
|
|
/* report connect event to MCU */
|
|
pkt = iot_pkt_alloc(sizeof(ge_frame_conn_ind_rpt_set_subfn9_t), IOT_GREE_APP_MID);
|
|
IOT_ASSERT(pkt);
|
|
|
|
iot_pkt_put(pkt, sizeof(ge_frame_conn_ind_rpt_set_subfn9_t));
|
|
ind_frm = (ge_frame_conn_ind_rpt_set_subfn9_t *)iot_pkt_data(pkt);
|
|
/* fill connect indication frame field */
|
|
os_mem_set(ind_frm, 0 , sizeof(*ind_frm));
|
|
EXT_FN_FRM_PREPARE(ind_frm,
|
|
PROTO_GE_PLC_SET_CMD, PROTO_CONN_IND_RPT_CMD);
|
|
/* nid will be recorded when MCU set it - TODO */
|
|
ind_frm->nid = local_dev->nid;
|
|
iot_mac_addr_cpy(ind_frm->mac, info->mac);
|
|
ind_frm->rssi = 0;
|
|
ind_frm->snr = 0;
|
|
ind_frm->seq = local_dev->ind_seq++;
|
|
ind_frm->tail.check_sum =
|
|
ge_frm_checksum_calc((uint8_t *)ind_frm,
|
|
sizeof(*ind_frm)-sizeof(ge_frm_tail_t));
|
|
/* report connected indication event to MCU */
|
|
iot_proto_send_to_mainboard(pkt);
|
|
iot_cus_printf("[glpr]connect ind,valid_cnt=%d,online_cnt=%d\n",
|
|
dev_lst->valid_dev_cnt, dev_lst->online_dev_cnt);
|
|
return rpt2mcu;
|
|
}
|
|
|
|
void iot_proto_report_disconn_event2mcu(uint8_t *mac)
|
|
{
|
|
iot_pkt_t *pkt;
|
|
ge_frame_disc_ind_rpt_set_subfn10_t *ind_frm;
|
|
pkt = iot_pkt_alloc(sizeof(ge_frame_disc_ind_rpt_set_subfn10_t), IOT_GREE_APP_MID);
|
|
IOT_ASSERT(pkt);
|
|
iot_pkt_put(pkt, sizeof(ge_frame_disc_ind_rpt_set_subfn10_t));
|
|
ind_frm = (ge_frame_disc_ind_rpt_set_subfn10_t *)iot_pkt_data(pkt);
|
|
/* fill connect indication frame field */
|
|
os_mem_set(ind_frm, 0 , sizeof(*ind_frm));
|
|
EXT_FN_FRM_PREPARE(ind_frm,
|
|
PROTO_GE_PLC_SET_CMD, PROTO_DISCONN_IND_RPT_CMD);
|
|
ind_frm->nid = prototask_contxt.local_dev.nid;
|
|
iot_mac_addr_cpy(ind_frm->mac, mac);
|
|
/* TODO */
|
|
ind_frm->reason = 0;
|
|
ind_frm->seq = prototask_contxt.local_dev.ind_seq++;
|
|
ind_frm->tail.check_sum =
|
|
ge_frm_checksum_calc((uint8_t *)ind_frm,
|
|
sizeof(*ind_frm)-sizeof(ge_frm_tail_t));
|
|
/* report sta leave network event to MCU */
|
|
iot_proto_send_to_mainboard(pkt);
|
|
}
|
|
|
|
bool_t iot_proto_set_nid_subfn_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
bool_t rpt2mcu = false;
|
|
uint8_t reason = PROTO_REASON_OK;
|
|
iot_pkt_t *cmd_pkt;
|
|
ge_frame_cco_nid_set_subfn17_t *frm = (ge_frame_cco_nid_set_subfn17_t *)data;
|
|
plctxrx_cmd_arg_t cmd = { 0 };
|
|
plctxrx_cmd_nid_t set_nid = { 0 };
|
|
proto_cmd_hdl_state_t *sm = iot_proto_cmd_handle_state_get();
|
|
sta_dev_t *local_dev = &prototask_contxt.local_dev;
|
|
|
|
if (len != sizeof(ge_frame_cco_nid_set_subfn17_t)) {
|
|
reason = PROTO_REASON_LEN_MISSMATCH;
|
|
} else if (!iot_mac_addr_cmp(local_dev->mac, frm->mac)) {
|
|
reason = PROTO_REASON_MAC_MISSMATCH;
|
|
} else if (local_dev->nid == frm->nid) {
|
|
reason = PROTO_REASON_NID_DUP;
|
|
} else if (0 == frm->nid || 99 < frm->nid) {
|
|
reason = PROTO_REASON_NID_MISSMATCH;
|
|
}
|
|
|
|
if (reason != PROTO_REASON_OK) {
|
|
iot_cus_printf("[glpr]set_nid error reason%d!\n", reason);
|
|
iot_proto_resp_cfm_frame(reason, dir,
|
|
PROTO_CCO_NID_SET_CMD, frm->seq, NULL);
|
|
return rpt2mcu;
|
|
}
|
|
|
|
cmd.cid.cid = PLCTXRX_CID_NID;
|
|
cmd.cid.opcode = PLCTXRX_OP_CONFIG;
|
|
cmd.prio = 0;
|
|
cmd.need_ack = true;
|
|
cmd.dlen = sizeof(plctxrx_cmd_nid_t);
|
|
/* alloc packet for sending cmd */
|
|
cmd_pkt = iot_pkt_alloc(sizeof(cmd) + cmd.dlen, IOT_GREE_APP_MID);
|
|
IOT_ASSERT(cmd_pkt);
|
|
set_nid.nid = frm->nid;
|
|
|
|
iot_pkt_put(cmd_pkt, sizeof(cmd) + cmd.dlen);
|
|
/* copy plctxrx_cmd_arg_t */
|
|
os_mem_cpy(iot_pkt_data(cmd_pkt), &cmd, sizeof(cmd));
|
|
os_mem_cpy(iot_pkt_data(cmd_pkt) + sizeof(cmd), &set_nid, cmd.dlen);
|
|
|
|
sm->state = PROTO_CMD_WAIT_CMD_CFM;
|
|
sm->dir = CMD_LOCAL_UP_LINK;
|
|
sm->seq = frm->seq;
|
|
sm->cur_subfn = frm->hdr.subfn;
|
|
|
|
/* send cmd to plctxrx layer */
|
|
iot_proto_cmd_send_to_plctxrx(cmd_pkt);
|
|
/* save nid to local */
|
|
local_dev->nid = frm->nid;
|
|
|
|
iot_cus_printf("[glpr]set nid succ!\n");
|
|
|
|
return rpt2mcu;
|
|
}
|
|
|
|
bool_t iot_proto_set_sta_leave_handler
|
|
(uint8_t *data, uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
ge_frame_leave_nw_set_subfn4_t *p_frame = (ge_frame_leave_nw_set_subfn4_t *)data;
|
|
uint8_t reason = PROTO_REASON_OK;
|
|
protpkt_tx_info_t txinfo = { 0 };
|
|
ge_frame_sta_leave_ind_set_subfn154_t ind_frm = {0};
|
|
uint8_t *local_mac = prototask_contxt.local_dev.mac;
|
|
|
|
if (len != sizeof(ge_frame_leave_nw_set_subfn4_t)) {
|
|
reason = PROTO_REASON_LEN_MISSMATCH;
|
|
} else if ((CMD_LOCAL_DOWN_LINK != dir) && (DATA_DOWN_LINK != dir)) {
|
|
reason = PROTO_REASON_CMD_DIR_ERR;
|
|
} else if (IOT_PLC_DEV_ROLE_CCO == prototask_contxt.local_dev.nw_role) {
|
|
reason = PROTO_REASON_ROLE_MISMATCH;
|
|
} else if (!prototask_contxt.local_dev.dev_ready) {
|
|
reason = PROTO_REASON_NOT_READY;
|
|
} else if (p_frame->nid != prototask_contxt.local_dev.nid) {
|
|
reason = PROTO_REASON_NID_MISSMATCH;
|
|
}
|
|
iot_cus_printf("[glpr]set_sta_leave:myrole=%d,ready=%d,nid=%d\n",
|
|
prototask_contxt.local_dev.nw_role,
|
|
prototask_contxt.local_dev.dev_ready,
|
|
prototask_contxt.local_dev.nid);
|
|
|
|
if (reason == PROTO_REASON_OK) {
|
|
iot_mac_addr_cpy(ind_frm.mac, local_mac);
|
|
ind_frm.seq = p_frame->seq;
|
|
EXT_FN_FRM_PREPARE((&ind_frm),
|
|
PROTO_GE_PLC_SET_CMD, PROTO_STA_LEAVE_IND);
|
|
ind_frm.tail.check_sum =
|
|
ge_frm_checksum_calc((uint8_t *)(&ind_frm),
|
|
sizeof(ind_frm)-sizeof(ge_frm_tail_t));
|
|
|
|
iot_proto_fill_txinfo(&txinfo, true, PLCTXRX_UNICAST, 3, 200, 1,
|
|
local_mac, NULL);
|
|
iot_proto_remote_cmd_send_to_plctxrx((uint8_t *)(&ind_frm),
|
|
sizeof(ge_frame_sta_leave_ind_set_subfn154_t), &txinfo);
|
|
|
|
iot_cus_printf("[glpr]sta will leave netowork in 5 sec\n");
|
|
os_start_timer(prototask_contxt.leave_tmr,
|
|
PROTO_TIMER_LEAVE_DELAY_INTVL);
|
|
} else {
|
|
iot_cus_printf("[glpr]leave error, reason%d!\n",reason);
|
|
}
|
|
|
|
iot_proto_resp_cfm_frame(reason, dir, PROTO_LEAVE_NW_SET_CMD,
|
|
p_frame->seq, NULL);
|
|
|
|
return 0;
|
|
}
|
|
|
|
bool_t iot_proto_grapp_reg_conf_ind_subfn_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
(void)dir;
|
|
(void)len;
|
|
(void)data;
|
|
|
|
ge_app_pib_info_t *p_flash = &prototask_contxt.flashinfo;
|
|
|
|
iot_cus_printf("[glpr]load_local_dev=%d, mac-%x:%x:%x:%x:%x:%x\n",
|
|
p_flash->public.pub.local_type,
|
|
p_flash->public.pub.local_mac[0], p_flash->public.pub.local_mac[1],
|
|
p_flash->public.pub.local_mac[2], p_flash->public.pub.local_mac[3],
|
|
p_flash->public.pub.local_mac[4], p_flash->public.pub.local_mac[5]);
|
|
|
|
/* set tx power */
|
|
iot_proto_set_tx_power(DEFAULT_TX_POWER, false);
|
|
if (IOT_PLC_DEV_ROLE_CCO == prototask_contxt.local_dev.nw_role) {
|
|
/* cco enable whitelist as default */
|
|
iot_proto_whitelist_en_disable(GE_PROTO_WL_ENABLE, false);
|
|
iot_proto_whitelist_add_remove(GE_PROTO_ACTION_ADD, NULL, false);
|
|
} else {
|
|
/* sta set whitelist state from flash */
|
|
if (p_flash->public.pub.wl_state == 1) {
|
|
iot_proto_whitelist_en_disable(GE_PROTO_WL_ENABLE, false);
|
|
} else {
|
|
iot_proto_whitelist_en_disable(GE_PROTO_WL_DISABLE, false);
|
|
}
|
|
if (iot_mac_addr_valid(p_flash->public.pub.cco_mac)) {
|
|
iot_proto_whitelist_add_remove(GE_PROTO_ACTION_ADD,
|
|
p_flash->public.pub.cco_mac, false);
|
|
}
|
|
}
|
|
|
|
if (prototask_contxt.local_dev.nw_role != IOT_PLC_DEV_ROLE_CCO &&
|
|
!iot_hwver_is_ledc_v3_0_jy()) {
|
|
/* 启动探测mac */
|
|
os_start_timer(prototask_contxt.detect_timer, 0);
|
|
} else {
|
|
/* 设置mac */
|
|
iot_proto_set_local_mac();
|
|
}
|
|
|
|
/* if STA role, set scan bitmap saved in app pib or default value */
|
|
#if PLC_SUPPORT_STA_ROLE
|
|
iot_proto_set_fb_bitmap(NULL, false);
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
|
|
bool_t iot_proto_reboot_sta_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
bool_t rpt2mcu = false;
|
|
bool_t rpt_cfm = false;
|
|
ge_frame_reboot_sta_set_subfn18_t *frm =
|
|
(ge_frame_reboot_sta_set_subfn18_t *)data;
|
|
proto_cmd_hdl_state_t *sm = iot_proto_cmd_handle_state_get();
|
|
uint8_t dst_mac[IOT_MAC_ADDR_LEN] = { 0 };
|
|
uint8_t *local_mac = prototask_contxt.local_dev.mac;
|
|
protpkt_tx_info_t txinfo = { 0 };
|
|
uint8_t reason = PROTO_REASON_OK;
|
|
|
|
if (len != sizeof(ge_frame_reboot_sta_set_subfn18_t)) {
|
|
reason = PROTO_REASON_LEN_MISSMATCH;
|
|
iot_cus_printf("[glpr][err]%s cmd len mismatch\n", "set reboot");
|
|
rpt_cfm = true;
|
|
goto cfm;
|
|
}
|
|
|
|
iot_mac_addr_cpy(dst_mac, frm->dst_mac);
|
|
|
|
switch (dir) {
|
|
case CMD_LOCAL_DOWN_LINK:
|
|
{
|
|
if (iot_mac_addr_cmp(dst_mac, local_mac)) {
|
|
reason = PROTO_REASON_OK;
|
|
} else if (frm->nid != prototask_contxt.local_dev.nid) {
|
|
reason = PROTO_REASON_NID_MISSMATCH;
|
|
} else {
|
|
iot_proto_fill_txinfo(&txinfo, true, PLCTXRX_UNICAST, 3, 200, 1,
|
|
local_mac, dst_mac);
|
|
iot_cus_printf("[glpr]reboot[%2x:%2x:%2x:"
|
|
"%2x:%2x:%2x]cmd forward, dir:%d\n",
|
|
dst_mac[0],dst_mac[1],dst_mac[2],dst_mac[3],dst_mac[4],
|
|
dst_mac[5], dir);
|
|
iot_proto_remote_cmd_send_to_plctxrx(data,
|
|
sizeof(ge_frame_reboot_sta_set_subfn18_t), &txinfo);
|
|
sm->dir = CMD_REMOTE_UP_LINK;
|
|
sm->state = PROTO_CMD_WAIT_CMD_CFM;
|
|
sm->seq = frm->seq;
|
|
sm->cur_subfn = frm->hdr.subfn;
|
|
return rpt2mcu;
|
|
}
|
|
rpt_cfm = true;
|
|
goto cfm;
|
|
}
|
|
case CMD_REMOTE_UP_LINK:
|
|
{
|
|
iot_cus_printf("[glpr]remote reboot cmd excuted\n");
|
|
|
|
if (frm->nid != prototask_contxt.local_dev.nid) {
|
|
reason = PROTO_REASON_NID_MISSMATCH;
|
|
} else if (!iot_mac_addr_cmp(dst_mac, local_mac)) {
|
|
reason = PROTO_REASON_MAC_MISSMATCH;
|
|
}
|
|
iot_cus_printf("[glpr]send remote reboot cfm to[%2x:%2x:%2x:%2x"
|
|
"%2x:%2x] result:%d\n", frm->src_mac[0],frm->src_mac[1],
|
|
frm->src_mac[2], frm->src_mac[3], frm->src_mac[4],
|
|
frm->src_mac[5], reason);
|
|
rpt_cfm = true;
|
|
goto cfm;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
|
|
cfm:
|
|
if (rpt_cfm) {
|
|
iot_proto_resp_cfm_frame(reason, dir, PROTO_REBOOT_STA_CMD,
|
|
frm->seq, frm->src_mac);
|
|
}
|
|
if (reason == PROTO_REASON_OK) {
|
|
prototask_contxt.reboot_reason = frm->reboot_type;
|
|
|
|
iot_cus_printf("[glpr]reboot after %dsec reason=%d\n",
|
|
PROTO_TIMER_REBOOT_DELAY_INTVL,
|
|
prototask_contxt.reboot_reason);
|
|
os_start_timer(prototask_contxt.reboot_tmr,
|
|
PROTO_TIMER_REBOOT_DELAY_INTVL);
|
|
}
|
|
|
|
return rpt2mcu;
|
|
}
|
|
|
|
bool_t iot_proto_set_uart_param_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
(void)dir;
|
|
bool_t rpt2mcu = false;
|
|
uint8_t reason = 0;
|
|
uint32_t baud_val[] = PROTO_GE_UART_BAUD_VALUE;
|
|
iot_pkt_t *pkt;
|
|
ge_app_pib_info_t *p_flash = &prototask_contxt.flashinfo;
|
|
ge_frame_cmd_cfm_set_subfn20_t *cfm_cmd;
|
|
ge_frame_uart_param_set_subfn161_t *set_cmd =
|
|
(ge_frame_uart_param_set_subfn161_t *)data;
|
|
|
|
/* check param */
|
|
if (len == sizeof(*set_cmd)) {
|
|
if ((iot_proto_uart_param_check(set_cmd->baudrate, set_cmd->parity,
|
|
set_cmd->data_bit, set_cmd->stop_bit) == false) ||
|
|
(p_flash->public.pub.baudidx >= PROTO_GE_UART_BAUD_IDX_MAX)) {
|
|
reason = PROTO_REASON_UART_PARAM_ERR;
|
|
} else if ((baud_val[p_flash->public.pub.baudidx] == set_cmd->baudrate) &&
|
|
(p_flash->public.pub.parity == set_cmd->parity) &&
|
|
(p_flash->public.pub.data == set_cmd->data_bit) &&
|
|
(p_flash->public.pub.stop == set_cmd->stop_bit)) {
|
|
reason = PROTO_REASON_DUP_SETTING;
|
|
}
|
|
} else {
|
|
reason = PROTO_REASON_LEN_MISSMATCH;
|
|
}
|
|
|
|
if (reason == 0) {
|
|
/* save uart param to flash */
|
|
p_flash->public.pub.baudidx = uart_baud_find_index(set_cmd->baudrate);
|
|
p_flash->public.pub.parity = set_cmd->parity;
|
|
p_flash->public.pub.data = set_cmd->data_bit;
|
|
p_flash->public.pub.stop = set_cmd->stop_bit;
|
|
iot_proto_flashsave(p_flash);
|
|
}
|
|
|
|
/* send set confirm cmd to HOST */
|
|
pkt = iot_pkt_alloc(sizeof(*cfm_cmd), IOT_GREE_APP_MID);
|
|
IOT_ASSERT(pkt);
|
|
|
|
cfm_cmd = (ge_frame_cmd_cfm_set_subfn20_t *)iot_pkt_data(pkt);
|
|
os_mem_set(cfm_cmd, 0, sizeof(*cfm_cmd));
|
|
iot_pkt_put(pkt, sizeof(*cfm_cmd));
|
|
|
|
cfm_cmd->seq = set_cmd->seq;
|
|
cfm_cmd->cmd = set_cmd->hdr.subfn;
|
|
cfm_cmd->reason = reason;
|
|
if (reason) {
|
|
cfm_cmd->result = 1;
|
|
} else {
|
|
cfm_cmd->result = 0;
|
|
}
|
|
EXT_FN_FRM_PREPARE(cfm_cmd, PROTO_GE_PLC_SET_CMD, PROTO_CMD_CFM_CMD);
|
|
cfm_cmd->tail.check_sum = ge_frm_checksum_calc((uint8_t *)cfm_cmd,
|
|
sizeof(*cfm_cmd) - sizeof(ge_frm_tail_t));
|
|
|
|
iot_proto_send_to_mainboard(pkt);
|
|
|
|
return rpt2mcu;
|
|
}
|
|
|
|
void iot_proto_send_bc_data_as_internal_data(uint8_t *data)
|
|
{
|
|
ge_frm_tail_t *tail;
|
|
ge_frame_data_send_set_subfn160_t *bc_data;
|
|
iot_pkt_t *p_pkt;
|
|
uint8_t bc_data_len = GE_FRM_MIN_LEN + IOT_MAC_ADDR_LEN +
|
|
IOT_PLC_BEACON_DATA_MAX ;
|
|
|
|
p_pkt = iot_pkt_alloc(bc_data_len, IOT_GREE_APP_MID);
|
|
if (NULL == p_pkt) {
|
|
iot_cus_printf("[glpr][err]send_bc_data No Mem!\n");
|
|
return;
|
|
}
|
|
bc_data = (ge_frame_data_send_set_subfn160_t *)iot_pkt_put(p_pkt,
|
|
bc_data_len);
|
|
|
|
bc_data->hdr.hdr.preamble = GE_FRM_PREAMBLE_CODE;
|
|
bc_data->hdr.hdr.data_len = bc_data_len - GE_FRM_MIN_LEN;
|
|
bc_data->hdr.hdr.fn = PROTO_GE_PLC_SET_CMD;
|
|
bc_data->hdr.subfn = PROTO_GE_DATA_CMD;
|
|
bc_data->force_tx_connless = 0x1;
|
|
bc_data->resv = 0;
|
|
bc_data->force_noaggr = 0x1;
|
|
bc_data->data_type = GE_INTERNAL_BCN_DATA_TYPE;
|
|
iot_mac_addr_cpy(bc_data->dest_mac, ge_bcast_addr);
|
|
os_mem_cpy(bc_data->data, data, IOT_PLC_BEACON_DATA_MAX);
|
|
tail = (ge_frm_tail_t *)(bc_data->data + IOT_PLC_BEACON_DATA_MAX);
|
|
tail->check_sum = ge_frm_checksum_calc((uint8_t *)bc_data,
|
|
bc_data_len - sizeof(ge_frm_tail_t));
|
|
tail->tail = GE_FRM_TAIL_CODE;
|
|
|
|
iot_proto_data_handler((uint8_t*)bc_data, bc_data_len, CMD_LOCAL_DOWN_LINK);
|
|
iot_pkt_free(p_pkt);
|
|
}
|
|
|
|
bool_t iot_proto_bc_data_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
bool_t rpt2mcu = false;
|
|
uint32_t reason = 0;
|
|
plctxrx_cmd_arg_t cmd = { 0 };
|
|
iot_pkt_t *cmd_pkt;
|
|
ge_frame_bc_data_send_subfn162_t *frm =
|
|
(ge_frame_bc_data_send_subfn162_t *)data;
|
|
proto_cmd_hdl_state_t *sm = iot_proto_cmd_handle_state_get();
|
|
|
|
if (len != sizeof(ge_frame_bc_data_send_subfn162_t)) {
|
|
reason = PROTO_REASON_LEN_MISSMATCH;
|
|
} else if (prototask_contxt.local_dev.nw_role != IOT_PLC_DEV_ROLE_CCO) {
|
|
reason = PROTO_REASON_NO_AUTHORITY;
|
|
}
|
|
|
|
if (0 != reason) {
|
|
iot_proto_resp_cfm_frame(reason, dir, PROTO_GE_BC_DATA_CMD,
|
|
0, NULL);
|
|
iot_cus_printf("[glpr][err]send bc data err:%d\n", reason);
|
|
return rpt2mcu;
|
|
}
|
|
|
|
/* Broadcast beacon data as connless pkt at the same time in case that
|
|
* off-line STAs can not report beacon data up to app layer
|
|
*/
|
|
iot_proto_send_bc_data_as_internal_data(frm->data);
|
|
|
|
sm->dir = CMD_LOCAL_UP_LINK;
|
|
sm->state = PROTO_CMD_WAIT_CMD_CFM;
|
|
sm->seq = frm->seq;
|
|
sm->cur_subfn = frm->hdr.subfn;
|
|
|
|
cmd.cid.cid = PLCTXRX_CID_VENDOR_DATA;
|
|
cmd.cid.opcode = PLCTXRX_OP_EXECUTE;
|
|
cmd.prio = 0;
|
|
cmd.need_ack = 1;
|
|
cmd.dlen = IOT_PLC_BEACON_DATA_MAX;
|
|
/* alloc packet for sending cmd */
|
|
cmd_pkt = iot_pkt_alloc(sizeof(cmd) + cmd.dlen, IOT_GREE_APP_MID);
|
|
IOT_ASSERT(cmd_pkt);
|
|
iot_pkt_put(cmd_pkt, sizeof(cmd) + cmd.dlen);
|
|
/* copy plctxrx_cmd_arg_t */
|
|
os_mem_cpy(iot_pkt_data(cmd_pkt), &cmd, sizeof(cmd));
|
|
os_mem_cpy(iot_pkt_data(cmd_pkt) + sizeof(cmd), frm->data,
|
|
IOT_PLC_BEACON_DATA_MAX);
|
|
|
|
iot_cus_printf("[glpr]send bc data\n");
|
|
|
|
/* send cmd to plctxrx layer */
|
|
iot_proto_cmd_send_to_plctxrx(cmd_pkt);
|
|
|
|
return rpt2mcu;
|
|
}
|
|
|
|
bool_t iot_proto_set_fb_bitmap_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
bool_t rpt2mcu = false;
|
|
uint32_t reason = 0;
|
|
ge_frame_fb_scan_bitmap_set_subfn30_t *frm =
|
|
(ge_frame_fb_scan_bitmap_set_subfn30_t *)data;
|
|
proto_cmd_hdl_state_t *sm = iot_proto_cmd_handle_state_get();
|
|
|
|
if (len != sizeof(ge_frame_fb_scan_bitmap_set_subfn30_t)) {
|
|
reason = PROTO_REASON_LEN_MISSMATCH;
|
|
} else if (prototask_contxt.local_dev.nw_role == IOT_PLC_DEV_ROLE_CCO) {
|
|
reason = PROTO_REASON_NO_AUTHORITY;
|
|
}
|
|
|
|
if (0 != reason) {
|
|
iot_proto_resp_cfm_frame(reason, dir, PROTO_SET_FB_BITMAP_CMD,
|
|
0, NULL);
|
|
iot_cus_printf("[glpr][err]set band bitmap err:%d\n", reason);
|
|
return rpt2mcu;
|
|
}
|
|
sm->dir = CMD_LOCAL_UP_LINK;
|
|
sm->state = PROTO_CMD_WAIT_CMD_CFM;
|
|
sm->seq = frm->seq;
|
|
sm->cur_subfn = frm->hdr.subfn;
|
|
|
|
iot_proto_set_fb_bitmap(&frm->fb_scan_bitmap, true);
|
|
|
|
iot_cus_printf("[glpr]set band bitmap\n");
|
|
|
|
return rpt2mcu;
|
|
}
|
|
|
|
bool_t iot_proto_set_fix_rate_mode_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
bool_t rpt2mcu = false;
|
|
iot_pkt_t *p_pkt;
|
|
plctxrx_cmd_fix_rate_t p_fix_rate = { 0 };
|
|
plctxrx_cmd_arg_t *p_arg;
|
|
ge_frame_fix_rate_set_subfn31_t *frm =
|
|
(ge_frame_fix_rate_set_subfn31_t *)data;
|
|
proto_cmd_hdl_state_t *sm = iot_proto_cmd_handle_state_get();
|
|
|
|
if (len != sizeof(ge_frame_fix_rate_set_subfn31_t)) {
|
|
iot_proto_resp_cfm_frame(PROTO_REASON_LEN_MISSMATCH, dir,
|
|
PROTO_SET_FIX_RATE_MODE_CMD, 0, NULL);
|
|
iot_cus_printf("[glpr][err]set fixed rate err\n");
|
|
return rpt2mcu;
|
|
}
|
|
|
|
sm->dir = CMD_LOCAL_UP_LINK;
|
|
sm->state = PROTO_CMD_WAIT_CMD_CFM;
|
|
sm->seq = frm->seq;
|
|
sm->cur_subfn = frm->hdr.subfn;
|
|
|
|
p_fix_rate.fix_rate_mode = frm->enable;
|
|
|
|
p_pkt = iot_pkt_alloc(sizeof(*p_arg) + sizeof(p_fix_rate),
|
|
IOT_GREE_APP_MID);
|
|
IOT_ASSERT(p_pkt);
|
|
iot_pkt_put(p_pkt, sizeof(*p_arg) + sizeof(p_fix_rate));
|
|
p_arg = (plctxrx_cmd_arg_t *)iot_pkt_data(p_pkt);
|
|
p_arg->cid.cid = PLCTXRX_CID_FIXED_RATE;
|
|
p_arg->cid.opcode = PLCTXRX_OP_CONFIG;
|
|
p_arg->need_ack = true;
|
|
p_arg->dlen = sizeof(p_fix_rate);
|
|
|
|
/* copy plctxrx_cmd_arg_t */
|
|
os_mem_cpy(iot_pkt_data(p_pkt), p_arg, sizeof(*p_arg));
|
|
os_mem_cpy(iot_pkt_data(p_pkt) + sizeof(*p_arg), &p_fix_rate, p_arg->dlen);
|
|
|
|
iot_proto_cmd_send_to_plctxrx(p_pkt);
|
|
|
|
iot_cus_printf("[glpr]set fixed rate\n");
|
|
|
|
return rpt2mcu;
|
|
}
|
|
|
|
bool_t iot_proto_sta_paging_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
bool_t rpt2mcu = false;
|
|
uint32_t reason = 0;
|
|
uint8_t i = 0;
|
|
ge_frame_sta_paging_subfn32_t *frm =
|
|
(ge_frame_sta_paging_subfn32_t *)data;
|
|
uint8_t frm_len = sizeof(*frm) + frm->count * IOT_MAC_ADDR_LEN +
|
|
GE_FRM_CHECKSUM_FIELD_LEN + GE_FRM_TAIL_FILED_LEN;
|
|
|
|
if (dir != CMD_REMOTE_UP_LINK) {
|
|
reason = PROTO_REASON_CMD_DIR_ERR;
|
|
} else if (IOT_PLC_DEV_ROLE_CCO == prototask_contxt.local_dev.nw_role) {
|
|
reason = PROTO_REASON_NO_AUTHORITY;
|
|
} else if (len != frm_len) {
|
|
reason = PROTO_REASON_LEN_MISSMATCH;
|
|
} else if (prototask_contxt.local_dev.dev_ready) {
|
|
reason = PROTO_REASON_JOINED;
|
|
} else if (iot_mac_addr_cmp(prototask_contxt.paging_cco_mac, frm->cco_mac)) {
|
|
reason = PROTO_REASON_DUP_SETTING;
|
|
}
|
|
iot_cus_printf("[glpr]recv sta paging mac\n");
|
|
|
|
if (0 != reason) {
|
|
iot_cus_printf("err:%d\n", reason);
|
|
return rpt2mcu;
|
|
}
|
|
iot_cus_printf("count:%d\n", frm->count);
|
|
/* check paging mac */
|
|
for (i = 0; i < frm->count; i++) {
|
|
if (iot_mac_addr_cmp(frm->sta_mac[i], prototask_contxt.local_dev.mac)) {
|
|
iot_mac_addr_cpy(prototask_contxt.paging_cco_mac, frm->cco_mac);
|
|
if (prototask_contxt.update_cco_mac) {
|
|
iot_cus_printf("[glpr]post cco mac:%02X,%02X,%02X,%02X,%02X,"
|
|
"%02X to custom app\n", frm->cco_mac[0], frm->cco_mac[1],
|
|
frm->cco_mac[2], frm->cco_mac[3],
|
|
frm->cco_mac[4], frm->cco_mac[5]);
|
|
prototask_contxt.update_cco_mac(frm->cco_mac);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return rpt2mcu;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_proto_switch_boot_part_ind_handler(): switch boot part ind handler
|
|
* @param dst_mac: the dest mac decide command direction,
|
|
* if dest mac is local mac, will send to uart,
|
|
* otherwise send to remote address.
|
|
* @param reason: the reason of the switch boot part
|
|
*/
|
|
static void iot_proto_switch_boot_part_ind_handler(uint8_t *dst_mac,
|
|
uint8_t reason)
|
|
{
|
|
|
|
iot_pkt_t *pkt;
|
|
protpkt_tx_info_t txinfo = { 0 };
|
|
ge_frame_sw_bt_part_ind_subfn95_t *ind_frm;
|
|
|
|
if (dst_mac == NULL || !iot_mac_addr_valid(dst_mac) ||
|
|
iot_mac_is_bcast(dst_mac)) {
|
|
iot_cus_printf("[glpr]switch_boot_part_ind dst mac invalid\n");
|
|
return;
|
|
}
|
|
|
|
pkt = iot_pkt_alloc(sizeof(*ind_frm), IOT_GREE_APP_MID);
|
|
if (pkt == NULL) {
|
|
iot_cus_printf("[glpr] alloc pkt err\n");
|
|
return;
|
|
}
|
|
iot_pkt_put(pkt, sizeof(*ind_frm));
|
|
ind_frm = (ge_frame_sw_bt_part_ind_subfn95_t *)iot_pkt_data(pkt);
|
|
/* fill indication frame field */
|
|
os_mem_set(ind_frm, 0 , sizeof(*ind_frm));
|
|
EXT_FN_FRM_PREPARE(ind_frm, PROTO_GE_PLC_SET_CMD,
|
|
PROTO_SWITCH_BOOT_PART_IND_CMD);
|
|
iot_mac_addr_cpy(ind_frm->mac, prototask_contxt.local_dev.mac);
|
|
ind_frm->reason = reason;
|
|
ind_frm->seq = prototask_contxt.local_dev.ind_seq++;
|
|
ind_frm->tail.check_sum = ge_frm_checksum_calc((uint8_t *)ind_frm,
|
|
sizeof(*ind_frm) - sizeof(ge_frm_tail_t));
|
|
|
|
/* if dest mac is local mac, will send to uart,
|
|
* otherwise send to remote address.*/
|
|
if (iot_mac_addr_cmp(prototask_contxt.local_dev.mac, dst_mac)) {
|
|
iot_proto_send_to_mainboard(pkt);
|
|
} else {
|
|
iot_cus_printf("[glpr]send remote sw bootpart ind to[%2x:%2x:%2x:%2x"
|
|
"%2x:%2x] result:%d\n", dst_mac[0], dst_mac[1], dst_mac[2],
|
|
dst_mac[3], dst_mac[4], dst_mac[5], reason);
|
|
iot_proto_fill_txinfo(&txinfo, true, PLCTXRX_UNICAST, 0,
|
|
PROTO_UNICAST_RETRY_DEFAULT_INTVL, 1,
|
|
prototask_contxt.local_dev.mac, dst_mac);
|
|
/* set to remote dst mac */
|
|
iot_proto_remote_cmd_send_to_plctxrx((uint8_t*)ind_frm,
|
|
sizeof(*ind_frm), &txinfo);
|
|
iot_pkt_free(pkt);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief iot_proto_switch_boot_part_handler(): switch boot part handler,
|
|
* support local and remote command.
|
|
* @param data: switch boot part command frame
|
|
* @param len: the data length
|
|
* @param dir: the direction of command come from.
|
|
*/
|
|
bool_t iot_proto_switch_boot_part_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
bool_t rpt2mcu = false;
|
|
ge_frame_sw_bt_part_subfn34_t *frm = (ge_frame_sw_bt_part_subfn34_t *)data;
|
|
uint8_t dst_mac[IOT_MAC_ADDR_LEN] = { 0 };
|
|
uint8_t *local_mac = prototask_contxt.local_dev.mac;
|
|
protpkt_tx_info_t txinfo = { 0 };
|
|
uint8_t reason = PROTO_REASON_OK;
|
|
|
|
if (len != sizeof(*frm)) {
|
|
reason = PROTO_REASON_LEN_MISSMATCH;
|
|
iot_cus_printf("[glpr][err]%s cmd len mismatch\n", "sw boot part");
|
|
goto cfm;
|
|
}
|
|
iot_mac_addr_cpy(dst_mac, frm->dst_mac);
|
|
|
|
if (!iot_mac_addr_valid(dst_mac)) {
|
|
reason = PROTO_REASON_MAC_MISSMATCH;
|
|
iot_cus_printf("[glpr][err]%s mac is mismatch\n", "sw boot part");
|
|
goto cfm;
|
|
}
|
|
|
|
switch (dir) {
|
|
case CMD_LOCAL_DOWN_LINK:
|
|
{
|
|
if (iot_mac_is_bcast(dst_mac)) {
|
|
/* not support broadcast switch boot part */
|
|
reason = PROTO_REASON_NOT_SUPPORT;
|
|
} else if (!iot_mac_addr_cmp(dst_mac, local_mac)) {
|
|
iot_proto_fill_txinfo(&txinfo, true, PLCTXRX_UNICAST, 0,
|
|
PROTO_UNICAST_RETRY_DEFAULT_INTVL, 1,
|
|
local_mac, dst_mac);
|
|
iot_cus_printf("[glpr]sw bt part[%2x:%2x:%2x:"
|
|
"%2x:%2x:%2x]cmd forward, dir:%d\n",
|
|
dst_mac[0],dst_mac[1],dst_mac[2],dst_mac[3],dst_mac[4],
|
|
dst_mac[5], dir);
|
|
iot_proto_remote_cmd_send_to_plctxrx(data, len, &txinfo);
|
|
}
|
|
break;
|
|
}
|
|
case CMD_REMOTE_UP_LINK:
|
|
{
|
|
iot_cus_printf("[glpr]remote sw boot part cmd excuted\n");
|
|
|
|
if (!iot_mac_addr_cmp(dst_mac, local_mac)) {
|
|
reason = PROTO_REASON_MAC_MISSMATCH;
|
|
/* dest mac is not equal to local mac will drop */
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
reason = PROTO_REASON_NOT_SUPPORT;
|
|
break;
|
|
}
|
|
|
|
cfm:
|
|
/* only report confirm when received command from uart */
|
|
if (CMD_LOCAL_DOWN_LINK == dir) {
|
|
iot_proto_resp_cfm_frame(reason, dir, PROTO_SET_SWITCH_BOOT_PART_CMD,
|
|
frm->seq, NULL);
|
|
}
|
|
|
|
/* only report indication if command dest mac is equal to local mac */
|
|
if (iot_mac_addr_cmp(dst_mac, local_mac)) {
|
|
iot_proto_switch_boot_part_ind_handler(frm->src_mac, reason);
|
|
|
|
/* only reason is ok need to switch boot part */
|
|
if (reason == PROTO_REASON_OK) {
|
|
iot_switch_boot_part();
|
|
/* after swicth boot part need to reboot */
|
|
os_start_timer(prototask_contxt.reboot_tmr,
|
|
PROTO_TIMER_REBOOT_DELAY_INTVL);
|
|
}
|
|
}
|
|
return rpt2mcu;
|
|
}
|
|
|
|
bool_t iot_proto_set_local_ip4_subfn_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
(void)dir;
|
|
bool_t rpt2mcu = false;
|
|
uint8_t ip_addr[IOT_IP4_ADDR_LEN] = { 0 };
|
|
uint8_t ip_mask[IOT_IP4_ADDR_LEN] = { 0 };
|
|
uint32_t reason = 0;
|
|
ge_frame_local_ip4_set_subfn35_t *frm = (
|
|
ge_frame_local_ip4_set_subfn35_t *)data;
|
|
|
|
iot_oem_get_local_ip4_addr(ip_addr);
|
|
iot_oem_get_local_ip4_netmask(ip_mask);
|
|
|
|
if (len != sizeof(ge_frame_local_ip4_set_subfn35_t)) {
|
|
reason = PROTO_REASON_LEN_MISSMATCH;
|
|
} else if ((IOT_OEM_IP4_IS_INVALID == iot_oem_ip4_addr_is_valid(
|
|
frm->ip4_addr)) ||
|
|
(IOT_OEM_IP4_MASK_IS_INVALID == iot_oem_ip4_netmask_is_valid(
|
|
frm->ip4_mask))) {
|
|
reason = PROTO_REASON_IP4_IS_INVALID;
|
|
} else if (iot_ip4_addr_cmp(ip_addr, frm->ip4_addr) &&
|
|
iot_ip4_addr_cmp(ip_mask, frm->ip4_mask)) {
|
|
reason = PROTO_REASON_DUP_SETTING;
|
|
} else if (ERR_OK != iot_oem_set_local_ip4_info(frm->ip4_addr,
|
|
frm->ip4_mask)) {
|
|
reason = PROTO_REASON_NO_IP4_SETTED;
|
|
}
|
|
|
|
iot_proto_resp_cfm_frame(reason, dir, PROTO_LOCAL_IP4_INFO_SET_CMD,
|
|
frm->seq, NULL);
|
|
|
|
if (0 != reason) {
|
|
iot_cus_printf("[glpr][err]set_local_ip4 failed, "
|
|
"reason--%d\n", reason);
|
|
}
|
|
return rpt2mcu;
|
|
}
|
|
|
|
/* Get operable gpio index */
|
|
static uint8_t iot_proto_get_gpio_index(uint8_t gpio)
|
|
{
|
|
uint8_t index = 0, gpio_max = 0;
|
|
uint8_t board_id = iot_board_get_board_id();
|
|
|
|
if ((CUS_BOARD_ID_LEDCSTA01 == board_id) ||
|
|
(CUS_BOARD_ID_LEDCCCO01 == board_id)) {
|
|
gpio_max = IOT_GE_LEDC01_VALID_GPIO_MAX;
|
|
}
|
|
for (; index < gpio_max; index++) {
|
|
if (gpio == iot_ge_gpio_g[index].gpio_num) {
|
|
return index;
|
|
}
|
|
}
|
|
return IOT_PROTO_INVALID_GPIO_INDEX;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_proto_config_gpio_handler(): config gpio handler.
|
|
* @param data: config gpio command frame
|
|
* @param len: the data length
|
|
* @param dir: the direction of command come from.
|
|
*/
|
|
bool_t iot_proto_config_gpio_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
(void)dir;
|
|
bool_t rpt2mcu = false;
|
|
bool_t rpt_cfm = false;
|
|
ge_frame_gpio_config_subfn164_t *frm =
|
|
(ge_frame_gpio_config_subfn164_t *)data;
|
|
proto_cmd_hdl_state_t *sm = iot_proto_cmd_handle_state_get();
|
|
uint8_t dst_mac[IOT_MAC_ADDR_LEN] = { 0 };
|
|
uint8_t *local_mac = prototask_contxt.local_dev.mac;
|
|
protpkt_tx_info_t txinfo = { 0 };
|
|
uint8_t reason = PROTO_REASON_OK;
|
|
transmit_direction_e_t tmp_dir = 0;
|
|
uint8_t gpio_index = 0;
|
|
|
|
if (len != sizeof(ge_frame_gpio_config_subfn164_t)) {
|
|
reason = PROTO_REASON_LEN_MISSMATCH;
|
|
iot_cus_printf("[glpr][err]%s cmd len mismatch\n", "config gpio");
|
|
rpt_cfm = true;
|
|
goto cfm;
|
|
} else if (iot_mac_addr_cmp(frm->dest_mac, dst_mac)) {
|
|
reason = PROTO_REASON_MAC_ADDR_ZERO;
|
|
iot_cus_printf("[glpr][err]%s cmd dest mac addr is zero\n", "config gpio");
|
|
rpt_cfm = true;
|
|
goto cfm;
|
|
} else if (IOT_PROTO_INVALID_GPIO_INDEX ==
|
|
(gpio_index = iot_proto_get_gpio_index(frm->gpio_num))) {
|
|
reason = PROTO_REASON_NOT_SUPPORT;
|
|
iot_cus_printf("[glpr][err]%s cmd gpio num is invalid\n", "config gpio");
|
|
rpt_cfm = true;
|
|
goto cfm;
|
|
} else if ((IOT_GE_GPIO_DIR_OUTPUT != frm->dir_mode) &&
|
|
(IOT_GE_GPIO_DIR_INPUT != frm->dir_mode)) {
|
|
reason = PROTO_REASON_PARAME_ERR;
|
|
iot_cus_printf("[glpr][err]%s cmd dir mode is invalid\n", "config gpio");
|
|
rpt_cfm = true;
|
|
goto cfm;
|
|
|
|
} else if ((IOT_GE_GPIO_PULL_NONE != frm->pull_mode) &&
|
|
(IOT_GE_GPIO_PULL_UP != frm->pull_mode) &&
|
|
(IOT_GE_GPIO_PULL_DOWN != frm->pull_mode)) {
|
|
reason = PROTO_REASON_PARAME_ERR;
|
|
iot_cus_printf("[glpr][err]%s cmd pull mode is invalid\n", "config gpio");
|
|
rpt_cfm = true;
|
|
goto cfm;
|
|
}
|
|
|
|
iot_mac_addr_cpy(dst_mac, frm->dest_mac);
|
|
if (iot_mac_addr_cmp(dst_mac, local_mac)) {
|
|
tmp_dir = CMD_LOCAL_DOWN_LINK;
|
|
} else {
|
|
tmp_dir = CMD_REMOTE_DOWN_LINK;
|
|
}
|
|
|
|
switch (tmp_dir) {
|
|
case CMD_LOCAL_DOWN_LINK:
|
|
{
|
|
if (iot_ge_gpio_g[gpio_index].dir_mode != frm->dir_mode) {
|
|
if (IOT_GE_GPIO_DIR_OUTPUT == frm->dir_mode) {
|
|
if (ERR_OK != iot_gpio_switch_io_mode_dynamic(frm->gpio_num,
|
|
GPIO_OUTPUT))
|
|
{
|
|
iot_cus_printf("[glpr][err] open gpio as output err, gpio num:%d\n",
|
|
frm->gpio_num);
|
|
goto not_ready;
|
|
}
|
|
} else if (IOT_GE_GPIO_DIR_INPUT == frm->dir_mode) {
|
|
if (ERR_OK != iot_gpio_switch_io_mode_dynamic(frm->gpio_num,
|
|
GPIO_INPUT))
|
|
{
|
|
iot_cus_printf("[glpr][err] open gpio as input err, gpio num:%d\n",
|
|
frm->gpio_num);
|
|
goto not_ready;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (iot_ge_gpio_g[gpio_index].pull_mode != frm->pull_mode) {
|
|
if (IOT_GE_GPIO_PULL_UP == frm->pull_mode) {
|
|
if (ERR_OK != iot_gpio_set_pull_mode(frm->gpio_num, GPIO_PULL_UP))
|
|
{
|
|
iot_cus_printf("[glpr][err] pull up gpio err, gpio num:%d\n",
|
|
frm->gpio_num);
|
|
goto not_ready;
|
|
}
|
|
} else if (IOT_GE_GPIO_PULL_DOWN == frm->pull_mode) {
|
|
if (ERR_OK != iot_gpio_set_pull_mode(frm->gpio_num, GPIO_PULL_DOWN))
|
|
{
|
|
iot_cus_printf("[glpr][err] pull down gpio err, gpio num:%d\n",
|
|
frm->gpio_num);
|
|
goto not_ready;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (IOT_GE_GPIO_DIR_OUTPUT == frm->dir_mode) {
|
|
iot_gpio_value_set(frm->gpio_num, frm->output_value? 1:0);
|
|
}
|
|
|
|
iot_ge_gpio_g[gpio_index].gpio_num = frm->gpio_num;
|
|
iot_ge_gpio_g[gpio_index].dir_mode = frm->dir_mode;
|
|
iot_ge_gpio_g[gpio_index].pull_mode = frm->pull_mode;
|
|
iot_ge_gpio_g[gpio_index].gpio_state = IOT_GE_GPIO_OPEN;
|
|
reason = PROTO_REASON_OK;
|
|
rpt_cfm = true;
|
|
goto cfm;
|
|
}
|
|
case CMD_REMOTE_DOWN_LINK:
|
|
{
|
|
iot_proto_fill_txinfo(&txinfo, true,
|
|
PLCTXRX_UNICAST, PROTO_UNICAST_RETRY_DEFAULT_CNT,
|
|
PROTO_UNICAST_RETRY_DEFAULT_INTVL, 1, local_mac, dst_mac);
|
|
|
|
iot_proto_remote_cmd_send_to_plctxrx(data,
|
|
sizeof(ge_frame_gpio_config_subfn164_t), &txinfo);
|
|
sm->dir = CMD_REMOTE_UP_LINK;
|
|
sm->state = PROTO_CMD_WAIT_CMD_CFM;
|
|
sm->seq = frm->seq;
|
|
sm->cur_subfn = frm->hdr.subfn;
|
|
return rpt2mcu;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
|
|
not_ready:
|
|
reason = PROTO_REASON_NOT_READY;
|
|
rpt_cfm = true;
|
|
cfm:
|
|
if (rpt_cfm) {
|
|
iot_proto_resp_cfm_frame(reason, dir, PROTO_GE_GPIO_CONFIG_CMD,
|
|
frm->seq, frm->src_mac);
|
|
}
|
|
|
|
return rpt2mcu;
|
|
}
|
|
|
|
bool_t iot_proto_set_gpio_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
bool_t rpt2mcu = false;
|
|
bool_t rpt_cfm = false;
|
|
ge_frame_gpio_set_subfn165_t *frm =
|
|
(ge_frame_gpio_set_subfn165_t *)data;
|
|
proto_cmd_hdl_state_t *sm = iot_proto_cmd_handle_state_get();
|
|
uint8_t dst_mac[IOT_MAC_ADDR_LEN] = { 0 };
|
|
uint8_t *local_mac = prototask_contxt.local_dev.mac;
|
|
protpkt_tx_info_t txinfo = { 0 };
|
|
uint8_t reason = PROTO_REASON_OK;
|
|
transmit_direction_e_t tmp_dir = 0;
|
|
uint8_t gpio_index = 0;
|
|
|
|
if (len != sizeof(ge_frame_gpio_set_subfn165_t)) {
|
|
reason = PROTO_REASON_LEN_MISSMATCH;
|
|
iot_cus_printf("[glpr][err]%s cmd len mismatch\n", "set gpio");
|
|
rpt_cfm = true;
|
|
goto cfm;
|
|
} else if (iot_mac_addr_cmp(frm->dest_mac, dst_mac)) {
|
|
reason = PROTO_REASON_MAC_ADDR_ZERO;
|
|
iot_cus_printf("[glpr][err]%s cmd dest mac addr is zero\n", "set gpio");
|
|
rpt_cfm = true;
|
|
goto cfm;
|
|
} else if (IOT_PROTO_INVALID_GPIO_INDEX ==
|
|
(gpio_index = iot_proto_get_gpio_index(frm->gpio_num))) {
|
|
reason = PROTO_REASON_NOT_SUPPORT;
|
|
iot_cus_printf("[glpr][err]%s cmd gpio num is invalid\n", "set gpio");
|
|
rpt_cfm = true;
|
|
goto cfm;
|
|
}
|
|
|
|
iot_mac_addr_cpy(dst_mac, frm->dest_mac);
|
|
if (iot_mac_addr_cmp(dst_mac, local_mac)) {
|
|
tmp_dir = CMD_LOCAL_DOWN_LINK;
|
|
} else {
|
|
tmp_dir = CMD_REMOTE_DOWN_LINK;
|
|
}
|
|
|
|
switch (tmp_dir) {
|
|
case CMD_LOCAL_DOWN_LINK:
|
|
{
|
|
|
|
if ((IOT_GE_GPIO_OPEN != iot_ge_gpio_g[gpio_index].gpio_state) ||
|
|
(IOT_GE_GPIO_DIR_OUTPUT != iot_ge_gpio_g[gpio_index].dir_mode)) {
|
|
reason = PROTO_REASON_NOT_READY;
|
|
iot_cus_printf("[glpr][err]%s need to config the gpio before\n",
|
|
"set gpio");
|
|
rpt_cfm = true;
|
|
goto cfm;
|
|
}
|
|
|
|
iot_gpio_value_set(frm->gpio_num, frm->value);
|
|
reason = PROTO_REASON_OK;
|
|
rpt_cfm = true;
|
|
goto cfm;
|
|
}
|
|
case CMD_REMOTE_DOWN_LINK:
|
|
{
|
|
iot_proto_fill_txinfo(&txinfo, true,
|
|
PLCTXRX_UNICAST, PROTO_UNICAST_RETRY_DEFAULT_CNT,
|
|
PROTO_UNICAST_RETRY_DEFAULT_INTVL, 1, local_mac, dst_mac);
|
|
|
|
iot_proto_remote_cmd_send_to_plctxrx(data,
|
|
sizeof(ge_frame_gpio_set_subfn165_t), &txinfo);
|
|
sm->dir = CMD_REMOTE_UP_LINK;
|
|
sm->state = PROTO_CMD_WAIT_CMD_CFM;
|
|
sm->seq = frm->seq;
|
|
sm->cur_subfn = frm->hdr.subfn;
|
|
return rpt2mcu;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
|
|
cfm:
|
|
if (rpt_cfm) {
|
|
iot_proto_resp_cfm_frame(reason, dir, PROTO_GE_GPIO_SET_CMD,
|
|
frm->seq, frm->src_mac);
|
|
}
|
|
|
|
return rpt2mcu;
|
|
}
|
|
|
|
/* only for cco */
|
|
void iot_proto_sta_paging_mac()
|
|
{
|
|
uint32_t index;
|
|
iot_pkt_t *p_pkt;
|
|
ge_frame_sta_paging_subfn32_t *frame ;
|
|
ge_frm_tail_t *tail;
|
|
protpkt_tx_info_t txinfo = { 0 };
|
|
uint8_t frm_len;
|
|
uint8_t cnt = 0;
|
|
|
|
if (IOT_PLC_DEV_ROLE_CCO != prototask_contxt.local_dev.nw_role) {
|
|
iot_cus_printf("[glpr]paging only support cco\n");
|
|
return ;
|
|
}
|
|
|
|
frm_len = sizeof(*frame) + PROTO_STA_PAGING_MAX_CNT * IOT_MAC_ADDR_LEN +
|
|
GE_FRM_CHECKSUM_FIELD_LEN + GE_FRM_TAIL_FILED_LEN;
|
|
p_pkt = iot_pkt_alloc(frm_len, IOT_GREE_APP_MID);
|
|
if (NULL == p_pkt) {
|
|
iot_cus_printf("[glpr][err]sta_paging_mac No Mem!\n");
|
|
return;
|
|
}
|
|
|
|
frame = (ge_frame_sta_paging_subfn32_t *)iot_pkt_data(p_pkt);
|
|
index = prototask_contxt.paging_index;
|
|
/* check disconnect sta mac */
|
|
for (; index < STA_DEV_MAX; index++) {
|
|
if (iot_mac_addr_valid(prototask_contxt.dev_lst.dev[index].mac)) {
|
|
if (false == prototask_contxt.dev_lst.online_flag[index]) {
|
|
iot_mac_addr_cpy((uint8_t *)frame->sta_mac[cnt],
|
|
prototask_contxt.dev_lst.dev[index].mac);
|
|
cnt++;
|
|
/* send paging message one time can include max mac count */
|
|
if (cnt >= PROTO_STA_PAGING_MAX_CNT) {
|
|
index++;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (index >= STA_DEV_MAX) {
|
|
index = 0;
|
|
}
|
|
|
|
prototask_contxt.paging_index = index;
|
|
|
|
if (cnt > 0) {
|
|
frm_len = sizeof(*frame) + cnt * IOT_MAC_ADDR_LEN +
|
|
GE_FRM_CHECKSUM_FIELD_LEN + GE_FRM_TAIL_FILED_LEN;
|
|
iot_mac_addr_cpy(frame->cco_mac, prototask_contxt.local_dev.mac);
|
|
frame->hdr.hdr.preamble = GE_FRM_PREAMBLE_CODE;
|
|
frame->hdr.hdr.data_len = frm_len - GE_FRM_MIN_LEN;
|
|
frame->hdr.hdr.fn = PROTO_GE_PLC_SET_CMD;
|
|
frame->hdr.subfn = PROTO_SEND_STA_PAGING_CMD;
|
|
frame->count = cnt;
|
|
tail = (ge_frm_tail_t *)(frame->sta_mac + cnt);
|
|
tail->check_sum = ge_frm_checksum_calc((uint8_t *)frame,
|
|
sizeof(*frame) + cnt * IOT_MAC_ADDR_LEN);
|
|
tail->tail = GE_FRM_TAIL_CODE;
|
|
|
|
iot_pkt_put(p_pkt, frm_len);
|
|
|
|
iot_proto_fill_txinfo(&txinfo, false,
|
|
PLCTXRX_BORADCAST, PROTO_BROADCAST_RETRY_DEFAULT_CNT,
|
|
PROTO_BROADCAST_RETRY_DEFAULT_INTVL, 0,
|
|
prototask_contxt.local_dev.mac, NULL);
|
|
|
|
txinfo.force_noaggr = true;
|
|
txinfo.force_tx_connless = true;
|
|
txinfo.need_ack = false;
|
|
txinfo.retry_cnt = 0;
|
|
iot_proto_remote_cmd_send_to_plctxrx((uint8_t*)frame, frm_len, &txinfo);
|
|
}
|
|
iot_pkt_free(p_pkt);
|
|
}
|
|
|
|
#if IOT_GE_AES_ENABLE
|
|
bool_t iot_proto_set_aes_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
bool_t rpt2mcu = false;
|
|
uint32_t reason = 0;
|
|
ge_frame_aes_set_subfn163_t *hdr = (ge_frame_aes_set_subfn163_t *)data;
|
|
if (dir != CMD_LOCAL_DOWN_LINK) {
|
|
reason = PROTO_REASON_CMD_DIR_ERR;
|
|
goto out;
|
|
} else if (os_mem_cmp(hdr->dest_mac,
|
|
prototask_contxt.local_dev.mac, IOT_MAC_ADDR_LEN)) {
|
|
reason = PROTO_REASON_MAC_MISSMATCH;
|
|
goto out;
|
|
} else if (len != sizeof(ge_frame_aes_set_subfn163_t)) {
|
|
reason = PROTO_REASON_LEN_MISSMATCH;
|
|
goto out;
|
|
} else {
|
|
reason = PROTO_REASON_OK;
|
|
}
|
|
if (hdr->aes.enable) {
|
|
greeapp->aes.enable = 1;
|
|
} else {
|
|
greeapp->aes.enable = 0;
|
|
}
|
|
|
|
out:
|
|
iot_proto_resp_cfm_frame(reason, dir, PROTO_AES_SET_CMD, hdr->seq, NULL);
|
|
return rpt2mcu;
|
|
}
|
|
|
|
bool_t iot_proto_resp_aes_frame(uint8_t seq)
|
|
{
|
|
bool_t rpt2mcu = false;
|
|
ge_frame_aes_resp_subfn26_t *resp_cmd;
|
|
iot_pkt_t *pkt = iot_pkt_alloc(sizeof(*resp_cmd), IOT_GREE_APP_MID);
|
|
if (pkt == NULL) {
|
|
iot_cus_printf("[glpr][err]No Mem!\n");
|
|
return rpt2mcu;
|
|
}
|
|
resp_cmd = (ge_frame_aes_resp_subfn26_t *)iot_pkt_data(pkt);
|
|
iot_pkt_put(pkt, sizeof(*resp_cmd));
|
|
os_mem_set(resp_cmd, 0, sizeof(*resp_cmd));
|
|
EXT_FN_FRM_PREPARE(resp_cmd,
|
|
PROTO_GE_PLC_RESP_CMD, PROTO_AES_RESP_CMD);
|
|
resp_cmd->seq = seq;
|
|
os_mem_cpy(&resp_cmd->aes, &greeapp->aes, sizeof(ge_aes_contxt_t));
|
|
resp_cmd->tail.check_sum = ge_frm_checksum_calc((uint8_t *)resp_cmd,
|
|
sizeof(*resp_cmd) - sizeof(ge_frm_tail_t));
|
|
/* send to MCU */
|
|
iot_proto_send_to_mainboard(pkt);
|
|
|
|
return rpt2mcu;
|
|
}
|
|
|
|
bool_t iot_proto_resp_aes_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
bool_t rpt2mcu = false;
|
|
|
|
return rpt2mcu;
|
|
}
|
|
|
|
bool_t iot_proto_query_aes_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
(void)dir;
|
|
(void)len;
|
|
bool_t rpt2mcu = false;
|
|
ge_frame_aes_query_subfn26_t *hdr = (ge_frame_aes_query_subfn26_t *)data;
|
|
rpt2mcu = iot_proto_resp_aes_frame(hdr->seq);
|
|
|
|
return rpt2mcu;
|
|
}
|
|
|
|
#else
|
|
bool_t iot_proto_set_aes_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
(void)data;
|
|
(void)len;
|
|
(void)dir;
|
|
return false;
|
|
}
|
|
|
|
bool_t iot_proto_resp_aes_frame(uint8_t seq)
|
|
{
|
|
(void)seq;
|
|
return false;
|
|
}
|
|
|
|
bool_t iot_proto_query_aes_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
(void)data;
|
|
(void)len;
|
|
(void)dir;
|
|
return false;
|
|
}
|
|
|
|
bool_t iot_proto_resp_aes_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
(void)data;
|
|
(void)len;
|
|
(void)dir;
|
|
return false;
|
|
}
|
|
|
|
#endif
|
|
|
|
bool_t iot_proto_data_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
bool_t rpt2mcu = false;
|
|
uint8_t role = prototask_contxt.local_dev.nw_role, retry_cnt;
|
|
transmit_direction_e_t tmp_dir;
|
|
ge_frame_data_send_set_subfn160_t *hdr =
|
|
(ge_frame_data_send_set_subfn160_t *)data;
|
|
protpkt_tx_info_t txinfo = { 0 };
|
|
uint8_t dest_mac[IOT_MAC_ADDR_LEN];
|
|
|
|
if (CMD_LOCAL_DOWN_LINK == dir) {
|
|
if (iot_mac_addr_cmp(hdr->dest_mac, prototask_contxt.local_dev.mac)) {
|
|
if ((IOT_PLC_DEV_ROLE_STA == role) &&
|
|
(prototask_contxt.local_dev.dev_ready)) {
|
|
iot_mac_addr_cpy(dest_mac, prototask_contxt.cco_dev.mac);
|
|
} else {
|
|
return rpt2mcu;
|
|
}
|
|
} else {
|
|
iot_mac_addr_cpy(dest_mac, hdr->dest_mac);
|
|
}
|
|
tmp_dir = DATA_DOWN_LINK;
|
|
} else {
|
|
tmp_dir = DATA_UP_LINK;
|
|
}
|
|
|
|
switch (tmp_dir) {
|
|
case DATA_DOWN_LINK:
|
|
{
|
|
if(hdr->retr_cnt == 0) {
|
|
retry_cnt = PROTO_UNICAST_RETRY_DEFAULT_CNT;
|
|
} else {
|
|
retry_cnt = hdr->retr_cnt;
|
|
}
|
|
if (IOT_PLC_DEV_ROLE_CCO == role) {
|
|
if (mac_addr_is_bcast_addr(hdr->dest_mac)) {
|
|
iot_proto_fill_txinfo(&txinfo, false,
|
|
PLCTXRX_BORADCAST, PROTO_BROADCAST_RETRY_DEFAULT_CNT,
|
|
PROTO_BROADCAST_RETRY_DEFAULT_INTVL, 0,
|
|
prototask_contxt.local_dev.mac, NULL);
|
|
} else {
|
|
iot_proto_fill_txinfo(&txinfo, true,
|
|
PLCTXRX_UNICAST, retry_cnt,
|
|
PROTO_UNICAST_RETRY_DEFAULT_INTVL, 1,
|
|
prototask_contxt.local_dev.mac, dest_mac);
|
|
}
|
|
} else {
|
|
if (mac_addr_is_bcast_addr(hdr->dest_mac)) {
|
|
iot_proto_fill_txinfo(&txinfo, true,
|
|
PLCTXRX_UNICAST, retry_cnt,
|
|
PROTO_UNICAST_RETRY_DEFAULT_INTVL, 1,
|
|
prototask_contxt.local_dev.mac, NULL);
|
|
} else {
|
|
iot_proto_fill_txinfo(&txinfo, true,
|
|
PLCTXRX_UNICAST, retry_cnt,
|
|
PROTO_UNICAST_RETRY_DEFAULT_INTVL, 1,
|
|
prototask_contxt.local_dev.mac, dest_mac);
|
|
}
|
|
}
|
|
|
|
txinfo.force_noaggr = hdr->force_noaggr;
|
|
txinfo.force_tx_connless = hdr->force_tx_connless;
|
|
/* connless or not need ack pkt need no ack */
|
|
if (hdr->force_tx_connless == 1) {
|
|
txinfo.need_ack = false;
|
|
txinfo.retry_cnt = 0;
|
|
}
|
|
if (hdr->not_need_ack == 1) {
|
|
txinfo.need_ack = false;
|
|
txinfo.retry_cnt = hdr->retr_cnt;
|
|
txinfo.retry_intvl = PROTO_UNICAST_RETRY_NOACK_INTVL;
|
|
}
|
|
iot_proto_data_send_to_plctxrx(data, len, &txinfo);
|
|
break;
|
|
}
|
|
case DATA_UP_LINK:
|
|
{
|
|
if (GE_INTERNAL_BCN_DATA_TYPE == hdr->data_type) {
|
|
iot_pkt_t *pkt;
|
|
proto_vendor_info_t *vendr_info;
|
|
|
|
pkt = iot_pkt_alloc(sizeof(proto_vendor_info_t), IOT_GREE_APP_MID);
|
|
IOT_ASSERT(pkt);
|
|
|
|
vendr_info = (proto_vendor_info_t *)iot_pkt_data(pkt);
|
|
os_mem_cpy(vendr_info->data, hdr->data,
|
|
sizeof(proto_vendor_info_t));
|
|
iot_pkt_put(pkt, sizeof(proto_vendor_info_t));
|
|
iot_proto_update_vendr(pkt);
|
|
rpt2mcu = false;
|
|
} else {
|
|
rpt2mcu = true;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
IOT_ASSERT(0);
|
|
break;
|
|
}
|
|
|
|
return rpt2mcu;
|
|
}
|
|
|
|
bool_t iot_proto_query_topo_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
bool_t rpt2mcu = false;
|
|
uint8_t dev_role = prototask_contxt.local_dev.nw_role;
|
|
proto_cmd_hdl_state_t *sm = iot_proto_cmd_handle_state_get();
|
|
iot_pkt_t *cmd_pkt;
|
|
ge_frame_topo_query_subfn5_t *query_cmd =
|
|
(ge_frame_topo_query_subfn5_t *)data;
|
|
ge_frame_topo_resp_subfn5_t *resp_frm;
|
|
uint16_t resp_len = 0;
|
|
uint16_t topo_info_len = 0;
|
|
uint16_t txrx_cmd_len;
|
|
ge_frm_tail_t *tail;
|
|
plctxrx_cmd_arg_t *cmd;
|
|
plctxrx_cmd_query_topo_t *topo_cmd;
|
|
|
|
switch (query_cmd->type) {
|
|
case TOPO_INFO_TYPE_V0:
|
|
topo_info_len = sizeof(topo_info_v0_t);
|
|
break;
|
|
case TOPO_INFO_TYPE_V1:
|
|
topo_info_len = sizeof(topo_info_v1_t);
|
|
break;
|
|
default:
|
|
iot_cus_printf("[glpr][err]topo info quary error with type[%d]\n",
|
|
query_cmd->type);
|
|
return rpt2mcu;
|
|
}
|
|
|
|
resp_len = sizeof(ge_frame_topo_resp_subfn5_t) + topo_info_len +
|
|
sizeof(ge_frm_tail_t);
|
|
|
|
if (len != sizeof(ge_frame_topo_query_subfn5_t)) {
|
|
iot_pkt_t *pkt = iot_pkt_alloc(resp_len, IOT_GREE_APP_MID);
|
|
if (pkt == NULL) {
|
|
iot_cus_printf("[glpr][err]No Mem!\n");
|
|
return rpt2mcu;
|
|
}
|
|
resp_frm = (ge_frame_topo_resp_subfn5_t *)iot_pkt_data(pkt);
|
|
iot_pkt_put(pkt, resp_len);
|
|
os_mem_set(resp_frm, 0, resp_len);
|
|
resp_frm->type = query_cmd->type;
|
|
GE_FRM_HDR_PREPARE(resp_frm,
|
|
PROTO_GE_PLC_RESP_CMD, PROTO_TOPO_RESP_CMD, resp_len);
|
|
tail = (ge_frm_tail_t *)(resp_frm->info + topo_info_len);
|
|
tail->check_sum = ge_frm_checksum_calc((uint8_t *)resp_frm,
|
|
resp_len - sizeof(ge_frm_tail_t));
|
|
tail->tail = GE_FRM_TAIL_CODE;
|
|
/* send to MCU */
|
|
iot_proto_send_to_mainboard(pkt);
|
|
|
|
iot_cus_printf("[glpr][err]%s cmd len mismatch\n", "qurey topo");
|
|
return rpt2mcu;
|
|
}
|
|
|
|
prototask_contxt.topo_info_type = query_cmd->type;
|
|
|
|
txrx_cmd_len = sizeof(plctxrx_cmd_arg_t) + sizeof(plctxrx_cmd_query_topo_t);
|
|
|
|
/* alloc packet for sending cmd */
|
|
cmd_pkt = iot_pkt_alloc(txrx_cmd_len, IOT_GREE_APP_MID);
|
|
if (cmd_pkt == NULL) {
|
|
iot_cus_printf("[glpr][err]pkt alloc fail\n");
|
|
return rpt2mcu;
|
|
}
|
|
cmd = (plctxrx_cmd_arg_t*)iot_pkt_put(cmd_pkt, txrx_cmd_len);
|
|
cmd->cid.cid = PLCTXRX_CID_TOPO;
|
|
cmd->cid.opcode = PLCTXRX_OP_QUERY;
|
|
cmd->need_ack = true;
|
|
cmd->prio = 0;
|
|
cmd->dlen = sizeof(plctxrx_cmd_query_topo_t);
|
|
topo_cmd = (plctxrx_cmd_query_topo_t*)cmd->arg;
|
|
topo_cmd->ver = IOT_PLC_CCO_TOPO_REQ_DATA_VER_V1;
|
|
topo_cmd->start = 1;
|
|
topo_cmd->cnt = STA_DEV_MAX;
|
|
|
|
/* judge local device role */
|
|
switch (dir) {
|
|
case CMD_LOCAL_DOWN_LINK:
|
|
{
|
|
/* if device is not ready. */
|
|
if (!prototask_contxt.local_dev.dev_ready) {
|
|
ge_frame_topo_resp_subfn5_t *frame;
|
|
iot_pkt_t *data_pkt = iot_pkt_alloc(resp_len, IOT_GREE_APP_MID);
|
|
IOT_ASSERT(data_pkt);
|
|
|
|
frame = (ge_frame_topo_resp_subfn5_t *)iot_pkt_data(data_pkt);
|
|
iot_pkt_put(data_pkt, resp_len);
|
|
/* if txrx return zero sta cnt */
|
|
os_mem_set(frame, 0, resp_len);
|
|
frame->type = query_cmd->type;
|
|
frame->total_cnt = 1;
|
|
frame->cur_cnt = 1;
|
|
frame->seq = query_cmd->seq;
|
|
switch (query_cmd->type) {
|
|
case TOPO_INFO_TYPE_V0:
|
|
{
|
|
topo_info_v0_t *topo_info_v0 = (topo_info_v0_t *)frame->info;
|
|
iot_mac_addr_cpy(topo_info_v0->mac,
|
|
prototask_contxt.local_dev.mac);
|
|
break;
|
|
}
|
|
case TOPO_INFO_TYPE_V1:
|
|
{
|
|
topo_info_v1_t *topo_info_v1 = (topo_info_v1_t *)frame->info;
|
|
os_mem_set(topo_info_v1, 0, sizeof(topo_info_v1));
|
|
iot_mac_addr_cpy(topo_info_v1->mac,
|
|
prototask_contxt.local_dev.mac);
|
|
break;
|
|
}
|
|
default:
|
|
iot_pkt_free(data_pkt);
|
|
return rpt2mcu;
|
|
}
|
|
|
|
GE_FRM_HDR_PREPARE(frame, PROTO_GE_PLC_RESP_CMD, PROTO_TOPO_RESP_CMD,
|
|
resp_len);
|
|
tail = (ge_frm_tail_t *)(frame->info + topo_info_len);
|
|
tail->check_sum = ge_frm_checksum_calc((uint8_t *)frame,
|
|
resp_len - sizeof(ge_frm_tail_t));
|
|
tail->tail = GE_FRM_TAIL_CODE;
|
|
/* report topo to MCU */
|
|
iot_proto_send_to_mainboard(data_pkt);
|
|
iot_cus_printf("[glpr]topo cmd send error,"\
|
|
" device is not ready!\n");
|
|
return rpt2mcu;
|
|
}
|
|
|
|
if (IOT_PLC_DEV_ROLE_CCO == dev_role) {
|
|
/* if async cmd, we need to set a state for response cmd.
|
|
*/
|
|
sm->state = PROTO_CMD_WAIT_TOPO_RESP;
|
|
sm->dir = CMD_LOCAL_UP_LINK;
|
|
sm->seq = query_cmd->seq;
|
|
/* send cmd to plctxrx layer */
|
|
iot_proto_cmd_send_to_plctxrx(cmd_pkt);
|
|
} else {
|
|
/* send cmd to CCO */
|
|
protpkt_tx_info_t txinfo = { 0 };
|
|
iot_proto_fill_txinfo(&txinfo, true, PLCTXRX_UNICAST, 3, 500, 1,
|
|
prototask_contxt.local_dev.mac,
|
|
prototask_contxt.cco_dev.mac);
|
|
/* if async cmd, we need to set a state for response cmd.
|
|
*/
|
|
sm->state = PROTO_CMD_WAIT_TOPO_RESP;
|
|
sm->dir = CMD_REMOTE_UP_LINK;
|
|
sm->seq = query_cmd->seq;
|
|
iot_proto_remote_cmd_send_to_plctxrx(data, len, &txinfo);
|
|
}
|
|
break;
|
|
}
|
|
case CMD_REMOTE_UP_LINK:
|
|
{
|
|
/* if async cmd, we need to set a state for response cmd.
|
|
*/
|
|
sm->state = PROTO_CMD_WAIT_TOPO_RESP;
|
|
sm->dir = CMD_REMOTE_DOWN_LINK;
|
|
sm->seq = query_cmd->seq;
|
|
iot_mac_addr_cpy(sm->dev.mac, prototask_contxt.rx_info.mac);
|
|
/* send cmd to plctxrx layer */
|
|
iot_proto_cmd_send_to_plctxrx(cmd_pkt);
|
|
break;
|
|
}
|
|
default:
|
|
iot_cus_printf("[glpr][err]query topo:dir=%d\n", dir);
|
|
IOT_ASSERT(0);
|
|
break;
|
|
}
|
|
|
|
return rpt2mcu;
|
|
}
|
|
|
|
bool_t iot_proto_query_nw_detailinfo_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
(void)data;
|
|
(void)len;
|
|
(void)dir;
|
|
|
|
return false;
|
|
}
|
|
|
|
bool_t iot_proto_query_uart_param_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
(void)dir;
|
|
(void)len;
|
|
bool_t rpt2mcu = false;
|
|
uint32_t baud_val[] = PROTO_GE_UART_BAUD_VALUE;
|
|
ge_frame_uart_param_query_subfn14_t *query_cmd =
|
|
(ge_frame_uart_param_query_subfn14_t *)data;
|
|
ge_frame_uart_param_resp_subfn14_t *resp_cmd;
|
|
iot_pkt_t *pkt;
|
|
ge_app_pib_info_t *p_flash = &prototask_contxt.flashinfo;
|
|
|
|
pkt = iot_pkt_alloc(sizeof(*resp_cmd), IOT_GREE_APP_MID);
|
|
IOT_ASSERT(pkt);
|
|
|
|
resp_cmd = (ge_frame_uart_param_resp_subfn14_t *)iot_pkt_data(pkt);
|
|
iot_pkt_put(pkt, sizeof(*resp_cmd));
|
|
os_mem_set(resp_cmd, 0, sizeof(*resp_cmd));
|
|
|
|
if (p_flash->public.pub.baudidx >= PROTO_GE_UART_BAUD_IDX_MAX) {
|
|
p_flash->public.pub.baudidx = 0;
|
|
}
|
|
resp_cmd->baudrate = baud_val[p_flash->public.pub.baudidx];
|
|
resp_cmd->parity = p_flash->public.pub.parity;
|
|
resp_cmd->data_bit = p_flash->public.pub.data;
|
|
resp_cmd->stop_bit = p_flash->public.pub.stop;
|
|
resp_cmd->seq = query_cmd->seq;
|
|
EXT_FN_FRM_PREPARE(resp_cmd,
|
|
PROTO_GE_PLC_RESP_CMD, PROTO_GE_UART_PARAM_RESP_CMD);
|
|
resp_cmd->tail.check_sum = ge_frm_checksum_calc((uint8_t *)resp_cmd,
|
|
sizeof(*resp_cmd) - sizeof(ge_frm_tail_t));
|
|
|
|
iot_proto_send_to_mainboard(pkt);
|
|
|
|
return rpt2mcu;
|
|
}
|
|
|
|
bool_t iot_proto_ext_query_wl_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
(void)dir;
|
|
(void)len;
|
|
bool_t rpt2mcu = false;
|
|
ge_frame_ext_wl_query_subfn15_t *query_cmd =
|
|
(ge_frame_ext_wl_query_subfn15_t *)data;
|
|
ge_frame_ext_wl_resp_subfn15_t *resp_cmd;
|
|
proto_dev_list_t *p_devlist = &prototask_contxt.dev_lst;
|
|
uint16_t total_cnt = p_devlist->valid_dev_cnt;
|
|
uint16_t rpt_cnt = 0;
|
|
iot_pkt_t *pkt;
|
|
uint16_t rpt_size = 0;
|
|
uint16_t i;
|
|
uint16_t index = 0;
|
|
uint16_t start_index = 0;
|
|
uint16_t req_sta_cnt = query_cmd->sta_cnt;
|
|
ge_frm_tail_t *resp_tail;
|
|
|
|
if (len != sizeof(ge_frame_ext_wl_query_subfn15_t)) {
|
|
iot_cus_printf("[gepr][err]%s cmd len mismatch\n", " query_ext_wl");
|
|
rpt_cnt = 0;
|
|
} else if (query_cmd->index == 0 || query_cmd->index > total_cnt) {
|
|
iot_cus_printf("[gepr][err]%s cmd err!\n", " query_ext_wl");
|
|
rpt_cnt = 0;
|
|
} else {
|
|
start_index = query_cmd->index - 1;
|
|
rpt_cnt = total_cnt - start_index;
|
|
if (req_sta_cnt > WL_QUERY_REQ_MAX_STA_CNT) {
|
|
req_sta_cnt = WL_QUERY_REQ_MAX_STA_CNT;
|
|
}
|
|
if (rpt_cnt > req_sta_cnt) {
|
|
rpt_cnt = req_sta_cnt;
|
|
}
|
|
}
|
|
|
|
rpt_size = sizeof(ge_frame_ext_wl_resp_subfn15_t) +
|
|
rpt_cnt * IOT_MAC_ADDR_LEN + sizeof(ge_frm_tail_t);
|
|
pkt = iot_pkt_alloc(rpt_size, IOT_GREE_APP_MID);
|
|
IOT_ASSERT(pkt);
|
|
|
|
resp_cmd = (ge_frame_ext_wl_resp_subfn15_t *)iot_pkt_data(pkt);
|
|
iot_pkt_put(pkt, rpt_size);
|
|
|
|
os_mem_set(resp_cmd, 0, rpt_size);
|
|
|
|
resp_cmd->hdr.hdr.preamble = GE_FRM_PREAMBLE_CODE;
|
|
resp_cmd->hdr.hdr.data_len =
|
|
(uint8_t)(rpt_size - GE_FRM_MIN_LEN + GE_FRM_PLD_MIN_LEN);
|
|
resp_cmd->hdr.hdr.fn = PROTO_GE_PLC_RESP_CMD;
|
|
resp_cmd->hdr.subfn = PROTO_GE_EXT_WL_RESP_CMD;
|
|
|
|
resp_cmd->resv[0] = 0;
|
|
resp_cmd->resv[1] = 0;
|
|
|
|
resp_cmd->total = total_cnt;
|
|
resp_cmd->rpt_cnt = rpt_cnt;
|
|
resp_cmd->seq = query_cmd->seq;
|
|
|
|
if (rpt_cnt > 0) {
|
|
/* fill mac */
|
|
for (i = 0; i < STA_DEV_MAX; i++) {
|
|
if (mac_addr_is_valid_addr(p_devlist->dev[i].mac)) {
|
|
if (index >= start_index) {
|
|
if (index - start_index <= rpt_cnt) {
|
|
iot_mac_addr_cpy(resp_cmd->mac[index - start_index],
|
|
p_devlist->dev[i].mac);
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
index++;
|
|
}
|
|
}
|
|
}
|
|
|
|
resp_tail = (ge_frm_tail_t *)(resp_cmd->mac + rpt_cnt);
|
|
resp_tail->check_sum = ge_frm_checksum_calc((uint8_t *)resp_cmd,
|
|
rpt_size - sizeof(ge_frm_tail_t));
|
|
resp_tail->tail = GE_FRM_TAIL_CODE;
|
|
/* response result */
|
|
iot_proto_send_to_mainboard(pkt);
|
|
|
|
return rpt2mcu;
|
|
}
|
|
|
|
bool_t iot_proto_query_nid_handler(uint8_t *data, uint16_t len,
|
|
transmit_direction_e_t dir)
|
|
{
|
|
(void)len;
|
|
(void)dir;
|
|
bool_t rpt2mcu = false;
|
|
ge_frame_nid_query_subfn16_t *query_cmd = (ge_frame_nid_query_subfn16_t *)data;
|
|
ge_frame_nid_resp_subfn16_t *resp_cmd;
|
|
iot_pkt_t *pkt;
|
|
|
|
pkt = iot_pkt_alloc(sizeof(*resp_cmd), IOT_GREE_APP_MID);
|
|
IOT_ASSERT(pkt);
|
|
|
|
resp_cmd = (ge_frame_nid_resp_subfn16_t *)iot_pkt_data(pkt);
|
|
iot_pkt_put(pkt, sizeof(*resp_cmd));
|
|
os_mem_set(resp_cmd, 0, sizeof(*resp_cmd));
|
|
|
|
resp_cmd->seq = query_cmd->seq;
|
|
resp_cmd->nid = prototask_contxt.local_dev.nid;
|
|
|
|
EXT_FN_FRM_PREPARE(resp_cmd, PROTO_GE_PLC_RESP_CMD, PROTO_NID_RESP_CMD);
|
|
resp_cmd->tail.check_sum =
|
|
ge_frm_checksum_calc((uint8_t *)resp_cmd,
|
|
sizeof(*resp_cmd)-sizeof(ge_frm_tail_t));
|
|
|
|
iot_proto_send_to_mainboard(pkt);
|
|
|
|
return rpt2mcu;
|
|
}
|
|
|
|
bool_t iot_proto_query_wl_state_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
(void)dir;
|
|
bool_t rpt2mcu = false;
|
|
ge_app_pib_info_t *p_flash = &prototask_contxt.flashinfo;
|
|
iot_pkt_t *pkt;
|
|
ge_frame_wl_state_query_subfn17_t *query_cmd =
|
|
(ge_frame_wl_state_query_subfn17_t *)data;
|
|
ge_frame_wl_state_resp_subfn17_t *resp_frm;
|
|
|
|
pkt = iot_pkt_alloc(sizeof(*resp_frm), IOT_GREE_APP_MID);
|
|
if (pkt == NULL) {
|
|
iot_cus_printf("[glpr][err]No Mem!\n");
|
|
return rpt2mcu;
|
|
}
|
|
|
|
resp_frm = (ge_frame_wl_state_resp_subfn17_t *)iot_pkt_data(pkt);
|
|
iot_pkt_put(pkt, sizeof(*resp_frm));
|
|
|
|
os_mem_set(resp_frm, 0, sizeof(*resp_frm));
|
|
EXT_FN_FRM_PREPARE(resp_frm, PROTO_GE_PLC_RESP_CMD,
|
|
PROTO_WHITELIST_STATE_RESP_CMD);
|
|
|
|
//check cmd length
|
|
if (len != sizeof(ge_frame_wl_state_query_subfn17_t)) {
|
|
iot_cus_printf("[glpr][err]%s cmd len mismatch\n", " query_wl_state");
|
|
} else {
|
|
resp_frm->seq = query_cmd->seq;
|
|
resp_frm->state = p_flash->public.pub.wl_state;
|
|
iot_cus_printf("[gepr]query_wl_state %d\n", resp_frm->state);
|
|
}
|
|
|
|
resp_frm->tail.check_sum = ge_frm_checksum_calc((uint8_t *)resp_frm,
|
|
sizeof(*resp_frm) - sizeof(ge_frm_tail_t));
|
|
|
|
/* send to MCU */
|
|
iot_proto_send_to_mainboard(pkt);
|
|
|
|
return rpt2mcu;
|
|
}
|
|
|
|
bool_t iot_proto_query_module_info_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
(void)dir;
|
|
bool_t rpt2mcu = false;
|
|
ge_app_pib_info_t *p_flash = &prototask_contxt.flashinfo;
|
|
ge_frame_module_info_query_subfn18_t *query_cmd =
|
|
(ge_frame_module_info_query_subfn18_t *)data;
|
|
ge_frame_module_info_resp_subfn18_t *resp_frm;
|
|
iot_pkt_t *pkt = iot_pkt_alloc(sizeof(ge_frame_module_info_resp_subfn18_t),
|
|
IOT_GREE_APP_MID);
|
|
if (pkt == NULL) {
|
|
iot_cus_printf("[glpr][err]No Mem!\n");
|
|
return rpt2mcu;
|
|
}
|
|
resp_frm = (ge_frame_module_info_resp_subfn18_t *)iot_pkt_data(pkt);
|
|
iot_pkt_put(pkt, sizeof(*resp_frm));
|
|
|
|
os_mem_set(resp_frm, 0, sizeof(*resp_frm));
|
|
EXT_FN_FRM_PREPARE(resp_frm, PROTO_GE_PLC_RESP_CMD,
|
|
PROTO_MODULE_INFO_RESP_CMD);
|
|
|
|
if (len != sizeof(ge_frame_module_info_query_subfn18_t) ) {
|
|
iot_cus_printf("[glpr][err]%s cmd len mismatch\n", "query_module_info");
|
|
} else {
|
|
resp_frm->seq = query_cmd->seq;
|
|
resp_frm->role = prototask_contxt.local_dev.nw_role;
|
|
os_mem_cpy(resp_frm->mac, prototask_contxt.local_dev.mac,
|
|
IOT_MAC_ADDR_LEN);
|
|
os_mem_cpy(resp_frm->cco_mac, prototask_contxt.cco_dev.mac,
|
|
IOT_MAC_ADDR_LEN);
|
|
resp_frm->nid = prototask_contxt.local_dev.nid;
|
|
resp_frm->state = prototask_contxt.local_dev.dev_ready;
|
|
resp_frm->wl_state = p_flash->public.pub.wl_state;
|
|
resp_frm->swver = iot_version_hex();
|
|
iot_cus_printf("[gepr]query_module_info\n");
|
|
}
|
|
|
|
resp_frm->tail.check_sum = ge_frm_checksum_calc((uint8_t *)resp_frm,
|
|
sizeof(*resp_frm) - sizeof(ge_frm_tail_t));
|
|
/* send to MCU */
|
|
iot_proto_send_to_mainboard(pkt);
|
|
return rpt2mcu;
|
|
}
|
|
|
|
bool_t iot_proto_query_ntb_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
(void)dir;
|
|
bool_t rpt2mcu = false;
|
|
proto_cmd_hdl_state_t *sm;
|
|
iot_pkt_t *cmd_pkt;
|
|
ge_frame_ntb_query_subfn19_t *query_cmd =
|
|
(ge_frame_ntb_query_subfn19_t *)data;
|
|
plctxrx_cmd_arg_t cmd = { 0 };
|
|
ge_frame_ntb_resp_subfn19_t *resp_frm;
|
|
|
|
if (len != sizeof(ge_frame_ntb_query_subfn19_t)) {
|
|
iot_pkt_t *pkt =
|
|
iot_pkt_alloc(sizeof(*resp_frm), IOT_GREE_APP_MID);
|
|
if (pkt == NULL) {
|
|
iot_cus_printf("[glpr][err]No Mem!\n");
|
|
return rpt2mcu;
|
|
}
|
|
resp_frm = (ge_frame_ntb_resp_subfn19_t *)iot_pkt_data(pkt);
|
|
iot_pkt_put(pkt, sizeof(*resp_frm));
|
|
|
|
os_mem_set(resp_frm, 0, sizeof(*resp_frm));
|
|
EXT_FN_FRM_PREPARE(resp_frm, PROTO_GE_PLC_RESP_CMD, PROTO_NTB_RESP_CMD);
|
|
resp_frm->tail.check_sum = ge_frm_checksum_calc((uint8_t *)resp_frm,
|
|
sizeof(*resp_frm) - sizeof(ge_frm_tail_t));
|
|
|
|
/* send to MCU */
|
|
iot_proto_send_to_mainboard(pkt);
|
|
|
|
iot_cus_printf("[glpr][err]%s cmd len mismatch\n",
|
|
"qurey ntb");
|
|
return rpt2mcu;
|
|
}
|
|
|
|
cmd.cid.cid = PLCTXRX_CID_NTB;
|
|
cmd.cid.opcode = PLCTXRX_OP_QUERY;
|
|
cmd.need_ack = true;
|
|
cmd.prio = 0;
|
|
cmd.dlen = 0;
|
|
/* alloc packet for sending cmd */
|
|
cmd_pkt = iot_pkt_alloc(sizeof(cmd)+cmd.dlen, IOT_GREE_APP_MID);
|
|
IOT_ASSERT(cmd_pkt);
|
|
iot_pkt_put(cmd_pkt, sizeof(cmd)+cmd.dlen);
|
|
/* copy plctxrx_cmd_arg_t */
|
|
os_mem_cpy(iot_pkt_data(cmd_pkt), &cmd, sizeof(cmd));
|
|
/* if async cmd, we need to set a state for response */
|
|
sm = iot_proto_cmd_handle_state_get();
|
|
sm->state = PROTO_CMD_WAIT_NTB_RESP;
|
|
sm->dir = CMD_LOCAL_UP_LINK;
|
|
sm->seq = query_cmd->seq;
|
|
/* send cmd to plctxrx layer */
|
|
iot_proto_cmd_send_to_plctxrx(cmd_pkt);
|
|
|
|
return rpt2mcu;
|
|
}
|
|
|
|
bool_t iot_proto_query_fb_bitmap_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
(void)dir;
|
|
bool_t rpt2mcu = false;
|
|
proto_cmd_hdl_state_t *sm;
|
|
iot_pkt_t *cmd_pkt;
|
|
ge_frame_fb_bitmap_query_subfn20_t *query_cmd =
|
|
(ge_frame_fb_bitmap_query_subfn20_t *)data;
|
|
plctxrx_cmd_arg_t cmd = { 0 };
|
|
ge_frame_fb_bitmap_resp_subfn20_t *resp_frm;
|
|
|
|
if (len != sizeof(ge_frame_fb_bitmap_query_subfn20_t)) {
|
|
iot_pkt_t *pkt =
|
|
iot_pkt_alloc(sizeof(*resp_frm), IOT_GREE_APP_MID);
|
|
IOT_ASSERT(pkt);
|
|
resp_frm = (ge_frame_fb_bitmap_resp_subfn20_t *)iot_pkt_data(pkt);
|
|
iot_pkt_put(pkt, sizeof(*resp_frm));
|
|
|
|
os_mem_set(resp_frm, 0, sizeof(*resp_frm));
|
|
EXT_FN_FRM_PREPARE(resp_frm, PROTO_GE_PLC_RESP_CMD,
|
|
PROTO_FB_BITMAP_RESP_CMD);
|
|
resp_frm->tail.check_sum = ge_frm_checksum_calc((uint8_t *)resp_frm,
|
|
sizeof(*resp_frm) - sizeof(ge_frm_tail_t));
|
|
|
|
/* send to MCU */
|
|
iot_proto_send_to_mainboard(pkt);
|
|
|
|
iot_cus_printf("[glpr][err]%s cmd len mismatch\n",
|
|
"qurey fb bitmap");
|
|
return rpt2mcu;
|
|
}
|
|
|
|
cmd.cid.cid = PLCTXRX_CID_FB_BITMAP;
|
|
cmd.cid.opcode = PLCTXRX_OP_QUERY;
|
|
cmd.need_ack = true;
|
|
cmd.prio = 0;
|
|
cmd.dlen = sizeof(query_cmd->is_scan_bitmap);
|
|
/* alloc packet for sending cmd */
|
|
cmd_pkt = iot_pkt_alloc(sizeof(cmd)+cmd.dlen, IOT_GREE_APP_MID);
|
|
IOT_ASSERT(cmd_pkt);
|
|
iot_pkt_put(cmd_pkt, sizeof(cmd)+cmd.dlen);
|
|
/* copy plctxrx_cmd_arg_t */
|
|
os_mem_cpy(iot_pkt_data(cmd_pkt), &cmd, sizeof(cmd));
|
|
/* copy query_cmd->is_scan_bitmap */
|
|
os_mem_cpy(iot_pkt_data(cmd_pkt)+sizeof(cmd), &query_cmd->is_scan_bitmap,
|
|
sizeof(query_cmd->is_scan_bitmap));
|
|
/* if async cmd, we need to set a state for response */
|
|
sm = iot_proto_cmd_handle_state_get();
|
|
sm->state = PROTO_CMD_WAIT_FB_BITMAP_RESP;
|
|
sm->dir = CMD_LOCAL_UP_LINK;
|
|
sm->seq = query_cmd->seq;
|
|
/* send cmd to plctxrx layer */
|
|
iot_proto_cmd_send_to_plctxrx(cmd_pkt);
|
|
|
|
return rpt2mcu;
|
|
}
|
|
|
|
bool_t iot_proto_query_fix_rate_mode_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
(void)dir;
|
|
bool_t rpt2mcu = false;
|
|
proto_cmd_hdl_state_t *sm;
|
|
iot_pkt_t *cmd_pkt;
|
|
ge_frame_fix_rate_query_subfn21_t *query_cmd =
|
|
(ge_frame_fix_rate_query_subfn21_t *)data;
|
|
plctxrx_cmd_arg_t cmd = { 0 };
|
|
ge_frame_fix_rate_mode_resp_subfn21_t *resp_frm;
|
|
|
|
if (len != sizeof(ge_frame_fix_rate_query_subfn21_t)) {
|
|
iot_pkt_t *pkt =
|
|
iot_pkt_alloc(sizeof(*resp_frm), IOT_GREE_APP_MID);
|
|
IOT_ASSERT(pkt);
|
|
resp_frm = (ge_frame_fix_rate_mode_resp_subfn21_t *)iot_pkt_data(pkt);
|
|
iot_pkt_put(pkt, sizeof(*resp_frm));
|
|
|
|
os_mem_set(resp_frm, 0, sizeof(*resp_frm));
|
|
EXT_FN_FRM_PREPARE(resp_frm, PROTO_GE_PLC_RESP_CMD,
|
|
PROTO_FIX_RATE_MODE_RESP_CMD);
|
|
resp_frm->tail.check_sum = ge_frm_checksum_calc((uint8_t *)resp_frm,
|
|
sizeof(*resp_frm) - sizeof(ge_frm_tail_t));
|
|
|
|
/* send to MCU */
|
|
iot_proto_send_to_mainboard(pkt);
|
|
|
|
iot_cus_printf("[glpr][err]%s cmd len mismatch\n",
|
|
"qurey fix rate mode");
|
|
return rpt2mcu;
|
|
}
|
|
|
|
cmd.cid.cid = PLCTXRX_CID_FIXED_RATE;
|
|
cmd.cid.opcode = PLCTXRX_OP_QUERY;
|
|
cmd.need_ack = true;
|
|
cmd.prio = 0;
|
|
cmd.dlen = 0;
|
|
/* alloc packet for sending cmd */
|
|
cmd_pkt = iot_pkt_alloc(sizeof(cmd)+cmd.dlen, IOT_GREE_APP_MID);
|
|
IOT_ASSERT(cmd_pkt);
|
|
iot_pkt_put(cmd_pkt, sizeof(cmd)+cmd.dlen);
|
|
/* copy plctxrx_cmd_arg_t */
|
|
os_mem_cpy(iot_pkt_data(cmd_pkt), &cmd, sizeof(cmd));
|
|
/* if async cmd, we need to set a state for response */
|
|
sm = iot_proto_cmd_handle_state_get();
|
|
sm->state = PROTO_CMD_WAIT_FIX_RATE_MODE_RESP;
|
|
sm->dir = CMD_LOCAL_UP_LINK;
|
|
sm->seq = query_cmd->seq;
|
|
/* send cmd to plctxrx layer */
|
|
iot_proto_cmd_send_to_plctxrx(cmd_pkt);
|
|
|
|
return rpt2mcu;
|
|
}
|
|
|
|
bool_t iot_proto_query_work_band_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
(void)dir;
|
|
bool_t rpt2mcu = false;
|
|
proto_cmd_hdl_state_t *sm;
|
|
iot_pkt_t *cmd_pkt;
|
|
ge_frame_work_band_query_subfn22_t *query_cmd =
|
|
(ge_frame_work_band_query_subfn22_t *)data;
|
|
plctxrx_cmd_arg_t cmd = { 0 };
|
|
ge_frame_work_band_resp_subfn22_t *resp_frm;
|
|
|
|
if (len != sizeof(ge_frame_work_band_query_subfn22_t)) {
|
|
iot_pkt_t *pkt =
|
|
iot_pkt_alloc(sizeof(*resp_frm), IOT_GREE_APP_MID);
|
|
IOT_ASSERT(pkt);
|
|
resp_frm = (ge_frame_work_band_resp_subfn22_t *)iot_pkt_data(pkt);
|
|
iot_pkt_put(pkt, sizeof(*resp_frm));
|
|
|
|
os_mem_set(resp_frm, 0, sizeof(*resp_frm));
|
|
EXT_FN_FRM_PREPARE(resp_frm, PROTO_GE_PLC_RESP_CMD,
|
|
PROTO_WORK_BAND_RESP_CMD);
|
|
resp_frm->tail.check_sum = ge_frm_checksum_calc((uint8_t *)resp_frm,
|
|
sizeof(*resp_frm) - sizeof(ge_frm_tail_t));
|
|
|
|
/* send to MCU */
|
|
iot_proto_send_to_mainboard(pkt);
|
|
|
|
iot_cus_printf("[glpr][err]%s cmd len mismatch\n",
|
|
"qurey work band");
|
|
return rpt2mcu;
|
|
}
|
|
|
|
cmd.cid.cid = PLCTXRX_CID_BAND_ID;
|
|
cmd.cid.opcode = PLCTXRX_OP_QUERY;
|
|
cmd.need_ack = true;
|
|
cmd.prio = 0;
|
|
cmd.dlen = 0;
|
|
/* alloc packet for sending cmd */
|
|
cmd_pkt = iot_pkt_alloc(sizeof(cmd)+cmd.dlen, IOT_GREE_APP_MID);
|
|
IOT_ASSERT(cmd_pkt);
|
|
iot_pkt_put(cmd_pkt, sizeof(cmd)+cmd.dlen);
|
|
/* copy plctxrx_cmd_arg_t */
|
|
os_mem_cpy(iot_pkt_data(cmd_pkt), &cmd, sizeof(cmd));
|
|
/* if async cmd, we need to set a state for response */
|
|
sm = iot_proto_cmd_handle_state_get();
|
|
sm->state = PROTO_CMD_WAIT_WORK_BAND_RESP;
|
|
sm->dir = CMD_LOCAL_UP_LINK;
|
|
sm->seq = query_cmd->seq;
|
|
/* send cmd to plctxrx layer */
|
|
iot_proto_cmd_send_to_plctxrx(cmd_pkt);
|
|
|
|
return rpt2mcu;
|
|
}
|
|
|
|
/* handle wl set from local or remote mcu */
|
|
bool_t iot_proto_whitelist_set_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
proto_dev_list_t *p_table = &prototask_contxt.dev_lst;
|
|
proto_cmd_hdl_state_t *sm = iot_proto_cmd_handle_state_get();
|
|
proto_dev_t wlist;
|
|
uint32_t reason = 0;
|
|
uint16_t i;
|
|
bool_t need_ack = false;
|
|
ge_frame_op_wl_set_subfn5_t *p_frame = (ge_frame_op_wl_set_subfn5_t *)data;
|
|
|
|
if (len != sizeof(ge_frame_op_wl_set_subfn5_t)) {
|
|
/* check command length */
|
|
reason = PROTO_REASON_LEN_MISSMATCH;
|
|
goto check;
|
|
} else if ((p_frame->action == GE_PROTO_ACTION_ADD ||
|
|
p_frame->action == GE_PROTO_ACTION_DEL ||
|
|
p_frame->action == GE_PROTO_ACTION_DEL_ALL) &&
|
|
!prototask_contxt.local_dev.dev_ready) {
|
|
/* add and delete whitelist condition:
|
|
* 1.CCO state is started,
|
|
* 2.STA is already in network,
|
|
*/
|
|
reason = PROTO_REASON_NOT_READY;
|
|
goto check;
|
|
} else if (p_frame->action == GE_PROTO_ACTION_DEL_ALL &&
|
|
IOT_PLC_DEV_ROLE_CCO != prototask_contxt.local_dev.nw_role) {
|
|
/* only cco support clear whitelist */
|
|
reason = PROTO_REASON_WL_CLR_NOTSUPPORT;
|
|
goto check;
|
|
}
|
|
|
|
sm->seq = p_frame->seq;
|
|
#if (WHITELIST_PAIR_DEBUG == 1)
|
|
iot_cus_printf("[glpr]whitelist_set_handler-"
|
|
"%02x:%02x:%02x:%02x:%02x:%02x, action %d, dir=%d!\n",
|
|
p_frame->mac[0], p_frame->mac[1], p_frame->mac[2], p_frame->mac[3],
|
|
p_frame->mac[4], p_frame->mac[5], p_frame->action, dir);
|
|
#endif
|
|
if (GE_PROTO_ACTION_DEL == p_frame->action ||
|
|
GE_PROTO_ACTION_ADD == p_frame->action) {
|
|
if ((0 == p_frame->total_frame) || (0 == p_frame->cur_frame)) {
|
|
/* when add/delete whitelist, total_frame & cur_frame can not be 0 */
|
|
reason = PROTO_REASON_PARAME_ERR;
|
|
} else if (!iot_mac_addr_valid(p_frame->mac)) {
|
|
/* when add/delete whitelist, make sure the mac is valid */
|
|
reason = PROTO_REASON_MAC_ADDR_ZERO;
|
|
}
|
|
}
|
|
|
|
check:
|
|
if (0 != reason) {
|
|
iot_proto_resp_cfm_frame(reason, dir, p_frame->hdr.subfn, p_frame->seq,
|
|
prototask_contxt.rx_info.mac);
|
|
iot_proto_whitelist_state_init();
|
|
iot_proto_cmd_handle_state_init();
|
|
return false;
|
|
}
|
|
|
|
/* Set when every single frame received. */
|
|
sm->state = PROTO_CMD_WAIT_WHITE_LIST_SET;
|
|
sm->cur_subfn = PROTO_OP_WHITELIST_SET_CMD;
|
|
os_mem_set(&wlist, 0x00, sizeof(wlist));
|
|
iot_mac_addr_cpy(wlist.mac, p_frame->mac);
|
|
|
|
if (IOT_PLC_DEV_ROLE_CCO != prototask_contxt.local_dev.nw_role) {
|
|
if (p_frame->action == GE_PROTO_WL_DISABLE ||
|
|
p_frame->action == GE_PROTO_WL_ENABLE) {
|
|
/* STA can enable and disable whitelist */
|
|
sm->dir = CMD_LOCAL_UP_LINK;
|
|
iot_proto_whitelist_en_disable(p_frame->action, true);
|
|
return false;
|
|
} else {
|
|
/* STA does not have "ADD", "DEL" operation, so send it to CCO
|
|
* So we set sm->dir = CMD_LOCAL_UP_LINK;
|
|
*/
|
|
sm->dir = CMD_REMOTE_UP_LINK;
|
|
return iot_proto_wl_or_pt_remote_set_or_query_to_cco(data, len,
|
|
dir, PROTO_CMD_WAIT_RMT_WHITELIST_CFM);
|
|
}
|
|
}
|
|
/**
|
|
* CCO role could set local whitelist and allow remote STA to set,
|
|
* so,we should judge where current cmd comes from.
|
|
* when TO,in state PROTO_CMD_WAIT_WHITE_LIST_SET,
|
|
* we should send TO cfm or response to dir device.
|
|
*/
|
|
if (CMD_LOCAL_DOWN_LINK == dir) {
|
|
sm->dir = CMD_LOCAL_UP_LINK;
|
|
} else if (CMD_REMOTE_UP_LINK == dir) {
|
|
sm->dir = CMD_REMOTE_DOWN_LINK;
|
|
iot_mac_addr_cpy(sm->dev.mac, prototask_contxt.rx_info.mac);
|
|
}
|
|
|
|
/* clear tmp dev list for current completed recving */
|
|
if (FIRST_WL_FRAME == p_frame->cur_frame)
|
|
iot_proto_whitelist_state_init();
|
|
|
|
p_table->wl_ccofrag_cnt++;
|
|
if (GE_PROTO_ACTION_ADD == p_frame->action) {
|
|
if (iot_proto_check_mac_exists(p_frame->mac, p_table->dev,
|
|
p_table->valid_dev_cnt) >= 0) {
|
|
iot_cus_printf("[glpr]Mac exist, frame dropped!\n");
|
|
} else {
|
|
if (iot_proto_check_mac_exists(p_frame->mac,
|
|
p_table->dev_tmp, p_table->valid_dev_tmp_cnt) < 0) {
|
|
iot_proto_add_wl_to_tmp(&wlist);
|
|
} else {
|
|
iot_cus_printf("[glpr]Mac exist, frame dropped!\n");
|
|
}
|
|
}
|
|
|
|
/* cur_frame = total_frame means this is the last frame in this
|
|
opration. */
|
|
if (p_frame->cur_frame == p_frame->total_frame) {
|
|
/* dev_frame_cnt = total_frame means we received all the frames. */
|
|
if (p_table->wl_ccofrag_cnt == p_frame->total_frame) {
|
|
iot_cus_printf("[glpr]whitelist completed!\n");
|
|
if (p_table->valid_dev_tmp_cnt > 0) {
|
|
sm->state = PROTO_CMD_WAIT_CMD_CFM;
|
|
iot_proto_add_wl_tmp2formal();
|
|
/* sync whitelist to cvg */
|
|
iot_proto_whitelist_add_remove(GE_PROTO_ACTION_ADD,
|
|
NULL, true);
|
|
iot_proto_wl_save2flash();
|
|
} else {
|
|
/* Nothing to be set so response OK here. */
|
|
iot_proto_resp_cfm_frame(PROTO_REASON_OK, dir,
|
|
p_frame->hdr.subfn, p_frame->seq,
|
|
prototask_contxt.rx_info.mac);
|
|
iot_proto_cmd_handle_state_init();
|
|
}
|
|
} else {
|
|
iot_cus_printf("[glpr]frame lost!\n");
|
|
iot_proto_resp_cfm_frame(PROTO_REASON_WL_LOST_FRM, dir,
|
|
p_frame->hdr.subfn, p_frame->seq,
|
|
prototask_contxt.rx_info.mac);
|
|
iot_proto_cmd_handle_state_init();
|
|
}
|
|
|
|
iot_proto_whitelist_state_init();
|
|
}
|
|
} else if (GE_PROTO_ACTION_DEL == p_frame->action) {
|
|
|
|
if (iot_proto_check_mac_exists(p_frame->mac,
|
|
p_table->dev, p_table->valid_dev_cnt) < 0) {
|
|
iot_cus_printf("[glpr]frame repeated!\n");
|
|
} else {
|
|
/* record MAC(s) to tmp dev list that we need to delete. */
|
|
if (iot_proto_check_mac_exists(p_frame->mac,
|
|
p_table->dev_tmp, p_table->valid_dev_tmp_cnt) < 0) {
|
|
iot_proto_add_wl_to_tmp(&wlist);
|
|
} else {
|
|
iot_cus_printf("[glpr]frame repeated!\n");
|
|
}
|
|
}
|
|
|
|
/* cur_frame = total_frame means this
|
|
* is the last frame in this opration.
|
|
*/
|
|
if (p_frame->cur_frame == p_frame->total_frame) {
|
|
/* dev_frame_cnt = total_frame means we received all the frames. */
|
|
if (p_table->wl_ccofrag_cnt == p_frame->total_frame) {
|
|
iot_cus_printf("[glpr]whitelist completed!\n");
|
|
if (p_table->valid_dev_tmp_cnt > 0) {
|
|
sm->state = PROTO_CMD_WAIT_CMD_CFM;
|
|
/* remove del whitelist in CVG one by one,
|
|
* if the last whitelist,then need ack.
|
|
*/
|
|
for (i = 0; i < p_table->valid_dev_tmp_cnt; i++) {
|
|
if (i == (p_table->valid_dev_tmp_cnt - 1)) {
|
|
need_ack = true;
|
|
}
|
|
iot_proto_whitelist_add_remove(GE_PROTO_ACTION_DEL,
|
|
p_table->dev_tmp[i].mac, need_ack);
|
|
}
|
|
iot_proto_del_wl_from_formal();
|
|
iot_proto_wl_save2flash();
|
|
} else {
|
|
/* Nothing to be set so response OK here. */
|
|
iot_proto_resp_cfm_frame(PROTO_REASON_OK, dir,
|
|
p_frame->hdr.subfn, p_frame->seq,
|
|
prototask_contxt.rx_info.mac);
|
|
iot_proto_cmd_handle_state_init();
|
|
}
|
|
} else {
|
|
iot_cus_printf("[glpr]frame lost!\n");
|
|
iot_proto_resp_cfm_frame(PROTO_REASON_WL_LOST_FRM, dir,
|
|
p_frame->hdr.subfn, p_frame->seq,
|
|
prototask_contxt.rx_info.mac);
|
|
iot_proto_cmd_handle_state_init();
|
|
}
|
|
iot_proto_whitelist_state_init();
|
|
}
|
|
} else if (GE_PROTO_ACTION_DEL_ALL == p_frame->action) {
|
|
if (p_table->valid_dev_cnt > 0) {
|
|
p_table->valid_dev_cnt = 0;
|
|
os_mem_set(p_table->dev, 0, sizeof(proto_dev_t) * STA_DEV_MAX);
|
|
iot_proto_wl_save2flash();
|
|
iot_proto_whitelist_remove_all(true);
|
|
iot_cus_printf("[glpr]clear whitelist!\n");
|
|
} else {
|
|
/* whitelist already clear, so response OK here. */
|
|
iot_proto_resp_cfm_frame(PROTO_REASON_OK, dir, p_frame->hdr.subfn,
|
|
p_frame->seq, prototask_contxt.rx_info.mac);
|
|
iot_proto_cmd_handle_state_init();
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool_t iot_proto_query_whitelist_handler
|
|
(uint8_t *data, uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
uint16_t i, total;
|
|
uint8_t cco_flag, *p_buf = NULL;
|
|
proto_dev_list_t *p_table = &prototask_contxt.dev_lst;
|
|
protpkt_tx_info_t info = { 0 };
|
|
iot_pkt_t *resp_pkt = NULL, *p_pkt_buf = NULL;
|
|
uint32_t buf_index = 0, buf_len = TXRX_AGGR_PKT_LEN;
|
|
ge_frame_wl_resp_subfn7_t *frame;
|
|
ge_frame_wl_query_subfn7_t *query_cmd =
|
|
(ge_frame_wl_query_subfn7_t *)data;
|
|
proto_cmd_hdl_state_t *sm = iot_proto_cmd_handle_state_get();
|
|
|
|
/* alloc packet for response frame */
|
|
resp_pkt = iot_pkt_alloc(sizeof(*frame), IOT_GREE_APP_MID);
|
|
IOT_ASSERT(resp_pkt);
|
|
iot_pkt_put(resp_pkt, sizeof(*frame));
|
|
os_mem_set(iot_pkt_data(resp_pkt), 0, sizeof(*frame));
|
|
frame = (ge_frame_wl_resp_subfn7_t *)iot_pkt_data(resp_pkt);
|
|
|
|
/* check parameter */
|
|
if (len != sizeof(ge_frame_wl_query_subfn7_t)) {
|
|
EXT_FN_FRM_PREPARE(frame,
|
|
PROTO_GE_PLC_RESP_CMD, PROTO_WHITELIST_RESP_CMD);
|
|
frame->tail.check_sum = ge_frm_checksum_calc((uint8_t *)frame,
|
|
sizeof(*frame) - sizeof(ge_frm_tail_t));
|
|
/* send to MCU */
|
|
iot_proto_send_to_mainboard(resp_pkt);
|
|
return 0;
|
|
}
|
|
|
|
cco_flag = query_cmd->cco_flag? 1 : 0;
|
|
sm->seq = query_cmd->seq; /* SEQ byte is 7th */
|
|
if (cco_flag &&
|
|
IOT_PLC_DEV_ROLE_CCO != prototask_contxt.local_dev.nw_role) {
|
|
/* if CCO_FLAG set and this dev is not cco, forward this frame to cco */
|
|
iot_proto_wl_or_pt_remote_set_or_query_to_cco
|
|
(data, len, dir, PROTO_CMD_WAIT_RMT_WHITELIST_RESP);
|
|
|
|
return 0;
|
|
}
|
|
|
|
#if (WHITELIST_PAIR_DEBUG == 1)
|
|
iot_cus_printf("[glpr]Query whitelist! " \
|
|
"dir=%d, mac=%02x:%02x:%02x:%02x:%02x:%02x.\n", dir,
|
|
prototask_contxt.rx_info.mac[0], prototask_contxt.rx_info.mac[1],
|
|
prototask_contxt.rx_info.mac[2], prototask_contxt.rx_info.mac[3],
|
|
prototask_contxt.rx_info.mac[4], prototask_contxt.rx_info.mac[5]);
|
|
#endif
|
|
/* fill tx info to prepare for remote sending */
|
|
iot_proto_fill_txinfo(&info, 1, PLCTXRX_UNICAST, 2, 200, 1,
|
|
prototask_contxt.local_dev.mac,
|
|
prototask_contxt.rx_info.mac);
|
|
|
|
EXT_FN_FRM_PREPARE(frame,
|
|
PROTO_GE_PLC_RESP_CMD, PROTO_WHITELIST_RESP_CMD);
|
|
frame->cco_flag = cco_flag;
|
|
frame->total_cnt = p_table->valid_dev_cnt;
|
|
total = p_table->valid_dev_cnt;
|
|
frame->seq = sm->seq;
|
|
if (CMD_REMOTE_UP_LINK == dir) {
|
|
p_pkt_buf = iot_pkt_alloc(buf_len, IOT_GREE_APP_MID);
|
|
if (NULL == p_pkt_buf) {
|
|
iot_cus_printf("[glpr][err]No Mem!\n");
|
|
frame->cur_cnt = 0;
|
|
frame->total_cnt = 0;
|
|
frame->tail.check_sum = ge_frm_checksum_calc((uint8_t *)frame,
|
|
sizeof(*frame) - sizeof(ge_frm_tail_t));
|
|
iot_proto_remote_cmd_send_to_plctxrx
|
|
((uint8_t*)frame, sizeof(*frame), &info);
|
|
|
|
return 0;
|
|
}
|
|
p_buf = iot_pkt_data(p_pkt_buf);
|
|
}
|
|
|
|
if (CMD_REMOTE_UP_LINK == dir) {
|
|
i = 0;
|
|
do {
|
|
if (total > 0) {
|
|
frame->cur_cnt = i + 1;
|
|
iot_mac_addr_cpy(frame->mac, p_table->dev[i].mac);
|
|
} else {
|
|
frame->cur_cnt = 0;
|
|
os_mem_set(frame->mac, 0, IOT_MAC_ADDR_LEN);
|
|
}
|
|
|
|
frame->tail.check_sum = ge_frm_checksum_calc((uint8_t *)frame,
|
|
sizeof(*frame) - sizeof(ge_frm_tail_t));
|
|
os_mem_cpy(p_buf + buf_index, frame, sizeof(*frame));
|
|
buf_index += sizeof(*frame);
|
|
if (buf_index + sizeof(*frame) > buf_len) {
|
|
iot_proto_remote_cmd_send_to_plctxrx(p_buf, buf_index, &info);
|
|
buf_index = 0;
|
|
}
|
|
i++;
|
|
} while (i < total);
|
|
} else {
|
|
if (total > 0) {
|
|
#define PROTO_WL_RPT_FRAG_CNT 30
|
|
uint16_t frag_cnt = 0, loop_cnt = 0, m, j;
|
|
iot_pkt_t *frag_pkt = NULL;
|
|
uint8_t *data_t = NULL;
|
|
loop_cnt = (total <= PROTO_WL_RPT_FRAG_CNT)?
|
|
1:(total/PROTO_WL_RPT_FRAG_CNT
|
|
+ (((total%PROTO_WL_RPT_FRAG_CNT) == 0)?0:1));
|
|
for (m = 1; m <= loop_cnt; m++) {
|
|
if (m*PROTO_WL_RPT_FRAG_CNT > total) {
|
|
frag_cnt = total - (m - 1)*PROTO_WL_RPT_FRAG_CNT;
|
|
} else {
|
|
frag_cnt = PROTO_WL_RPT_FRAG_CNT;
|
|
}
|
|
frag_pkt = iot_pkt_alloc(sizeof(*frame)*frag_cnt,
|
|
IOT_GREE_APP_MID);
|
|
IOT_ASSERT(frag_pkt);
|
|
data_t = iot_pkt_data(frag_pkt);
|
|
iot_pkt_put(frag_pkt, sizeof(*frame)*frag_cnt);
|
|
for (j = 0; j < frag_cnt; j++) {
|
|
frame->cur_cnt = (m-1)*PROTO_WL_RPT_FRAG_CNT + j + 1;
|
|
iot_mac_addr_cpy(frame->mac,
|
|
p_table->dev[(m-1)*PROTO_WL_RPT_FRAG_CNT + j].mac);
|
|
frame->tail.check_sum =
|
|
ge_frm_checksum_calc((uint8_t *)frame,
|
|
sizeof(*frame) - sizeof(ge_frm_tail_t));
|
|
os_mem_cpy(data_t+j*sizeof(*frame), frame, sizeof(*frame));
|
|
}
|
|
iot_proto_send_to_mainboard(frag_pkt);
|
|
}
|
|
} else {
|
|
/* whitelist is empty, report all 0 frame to MCU. */
|
|
iot_pkt_t *rpt_pkt = NULL;
|
|
uint8_t *buf_pkt = NULL;
|
|
frame->cur_cnt = 0;
|
|
os_mem_set(frame->mac, 0, IOT_MAC_ADDR_LEN);
|
|
rpt_pkt = iot_pkt_alloc(sizeof(*frame), IOT_GREE_APP_MID);
|
|
IOT_ASSERT(rpt_pkt);
|
|
buf_pkt = iot_pkt_data(rpt_pkt);
|
|
iot_pkt_put(rpt_pkt, sizeof(*frame));
|
|
frame->tail.check_sum =
|
|
ge_frm_checksum_calc((uint8_t *)frame,
|
|
sizeof(*frame) - sizeof(ge_frm_tail_t));
|
|
os_mem_cpy(buf_pkt, frame, sizeof(*frame));
|
|
iot_proto_send_to_mainboard(rpt_pkt);
|
|
}
|
|
}
|
|
/* Only CMD_REMOTE_UP_LINK == dir will lead buf_index > 0 */
|
|
if (buf_index > 0) {
|
|
iot_proto_remote_cmd_send_to_plctxrx(p_buf, buf_index, &info);
|
|
}
|
|
|
|
if (p_pkt_buf) {
|
|
iot_pkt_free(p_pkt_buf);
|
|
}
|
|
|
|
if (resp_pkt) {
|
|
iot_pkt_free(resp_pkt);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
bool_t iot_proto_whitelist_resp_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
(void)len;
|
|
(void)dir;
|
|
/* Response and indicate have the same frame type with set. */
|
|
ge_frame_wl_resp_subfn7_t *p_frame = (ge_frame_wl_resp_subfn7_t *)data;
|
|
proto_dev_list_t *p_table = &prototask_contxt.dev_lst;
|
|
iot_pkt_t *p_pkt;
|
|
uint8_t cco_flag;
|
|
uint32_t pkt_len, frame_index;
|
|
proto_dev_t wlist;
|
|
|
|
proto_cmd_hdl_state_t *sm = iot_proto_cmd_handle_state_get();
|
|
|
|
sm->seq = p_frame->seq;
|
|
|
|
cco_flag = p_frame->cco_flag ? 1 : 0;
|
|
|
|
#if (WHITELIST_PAIR_DEBUG == 1)
|
|
iot_cus_printf("\n[glpr]whitelist_resp_handler," \
|
|
" dir=%d, seq=%d, cur=%d, total=%d, "
|
|
"mac=%02x:%02x:%02x:%02x:%02x:%02x, cco_flag=%d!\n",
|
|
dir, p_frame->seq, p_frame->cur_cnt, p_frame->total_cnt,
|
|
p_frame->mac[0], p_frame->mac[1], p_frame->mac[2],
|
|
p_frame->mac[3], p_frame->mac[4], p_frame->mac[5],
|
|
p_frame->cco_flag);
|
|
#endif
|
|
|
|
if ((0 == p_frame->total_cnt) && (0 == p_frame->cur_cnt)) {
|
|
iot_proto_cmd_handle_state_init();
|
|
/* It is queried by mcu, so forword this frame to MCU. */
|
|
if (cco_flag)
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
if (FIRST_WL_FRAME == p_frame->cur_cnt)
|
|
iot_proto_whitelist_state_init();
|
|
|
|
p_table->wl_ccofrag_cnt++;
|
|
os_mem_set(&wlist, 0x00, sizeof(wlist));
|
|
iot_mac_addr_cpy(wlist.mac, p_frame->mac);
|
|
|
|
if (iot_proto_check_mac_exists(p_frame->mac,
|
|
p_table->dev_tmp, p_table->valid_dev_tmp_cnt) < 0) {
|
|
iot_proto_add_wl_to_tmp(&wlist);
|
|
}
|
|
|
|
if (p_frame->cur_cnt == p_frame->total_cnt) {
|
|
if (p_table->wl_ccofrag_cnt == p_frame->total_cnt) {
|
|
iot_cus_printf("[glpr]whitelist completed, toltal=%d, valid=%d!\n",
|
|
p_frame->total_cnt, p_table->valid_dev_tmp_cnt);
|
|
if (cco_flag) {
|
|
/* It is queried by mcu, so send all those frame to MCU. */
|
|
pkt_len = sizeof(*p_frame) * p_table->valid_dev_tmp_cnt;
|
|
p_pkt = iot_pkt_alloc(pkt_len, IOT_GREE_APP_MID);
|
|
if (p_pkt) {
|
|
p_frame =
|
|
(ge_frame_wl_resp_subfn7_t*)iot_pkt_put(p_pkt, pkt_len);
|
|
/* A big packet of frames to MCU. */
|
|
for (frame_index = 0;
|
|
frame_index < p_table->valid_dev_tmp_cnt;
|
|
frame_index++) {
|
|
os_mem_cpy(p_frame, data, sizeof(*p_frame));
|
|
p_frame->cur_cnt = (uint16_t)(frame_index + 1);
|
|
p_frame->cco_flag = 1;
|
|
p_frame->total_cnt = p_table->valid_dev_tmp_cnt;
|
|
iot_mac_addr_cpy(p_frame->mac,
|
|
p_table->dev_tmp[frame_index].mac);
|
|
p_frame->tail.check_sum =
|
|
ge_frm_checksum_calc((uint8_t *)p_frame,
|
|
sizeof(*p_frame) - sizeof(ge_frm_tail_t));
|
|
|
|
p_frame++;
|
|
|
|
}
|
|
|
|
iot_proto_send_to_mainboard(p_pkt);
|
|
} else {
|
|
/* TODO : Every single frame to MCU */
|
|
IOT_ASSERT(0);
|
|
}
|
|
}
|
|
} else {
|
|
iot_cus_printf("[glpr]frame lost!\n");
|
|
}
|
|
iot_proto_whitelist_state_init();
|
|
iot_proto_cmd_handle_state_init();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
bool_t iot_proto_topo_resp_subfn_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
(void)len;
|
|
(void)dir;
|
|
bool_t rpt2mcu = false;
|
|
proto_cmd_hdl_state_t *sm = iot_proto_cmd_handle_state_get();
|
|
plctxrx_cmd_resp_t *cmd = (plctxrx_cmd_resp_t *)data;
|
|
plctxrx_handle_topo_t *topo_info = (plctxrx_handle_topo_t *)cmd->data;
|
|
uint8_t type = prototask_contxt.topo_info_type;
|
|
uint16_t frm_len = 0;
|
|
uint16_t topo_info_len = 0;
|
|
ge_frm_tail_t *tail = NULL;
|
|
|
|
if (sm->state == PROTO_CMD_DL645_WAIT_TOPO_INFO_RESP) {
|
|
/* for cctt send dl645 query topo */
|
|
iot_proto_cctt_dl645_topo_resp(data, len, dir);
|
|
return rpt2mcu;
|
|
}
|
|
|
|
switch (type) {
|
|
case TOPO_INFO_TYPE_V0:
|
|
topo_info_len = sizeof(topo_info_v0_t);
|
|
break;
|
|
case TOPO_INFO_TYPE_V1:
|
|
topo_info_len = sizeof(topo_info_v1_t);
|
|
break;
|
|
default:
|
|
iot_cus_printf("[glpr][err]topo info resp error with type[%d]\n", type);
|
|
return rpt2mcu;
|
|
}
|
|
|
|
frm_len = sizeof(ge_frame_topo_resp_subfn5_t) + topo_info_len +
|
|
sizeof(ge_frm_tail_t);
|
|
|
|
switch (sm->dir) {
|
|
/* report to MCU */
|
|
case CMD_LOCAL_UP_LINK:
|
|
{
|
|
ge_frame_topo_resp_subfn5_t *frame;
|
|
uint16_t i;
|
|
iot_pkt_t *data_pkt;
|
|
uint8_t *data_p;
|
|
|
|
uint16_t size = frm_len * topo_info->cnt;
|
|
|
|
if (size == 0)
|
|
size = frm_len;
|
|
|
|
data_pkt = iot_pkt_alloc(size, IOT_GREE_APP_MID);
|
|
|
|
if (!data_pkt) {
|
|
iot_cus_printf("[glpr][err]alloc pkt err\n");
|
|
return rpt2mcu;
|
|
}
|
|
|
|
data_p = iot_pkt_data(data_pkt);
|
|
iot_pkt_put(data_pkt, size);
|
|
os_mem_set(data_p, 0, size);
|
|
|
|
if (topo_info->cnt > 0) {
|
|
for (i = 0; i < topo_info->cnt; i++) {
|
|
frame = (ge_frame_topo_resp_subfn5_t *)(data_p + i * frm_len);
|
|
frame->type = type;
|
|
frame->total_cnt = cmd->index.total;
|
|
frame->cur_cnt = prototask_contxt.topo_resp_index + i + 1;
|
|
frame->seq = sm->seq;
|
|
|
|
switch (type) {
|
|
case TOPO_INFO_TYPE_V0:
|
|
{
|
|
topo_info_v0_t *topo_info_v0 = (topo_info_v0_t *)frame->info;
|
|
topo_info_v0->level = topo_info->topo[i].level;
|
|
iot_mac_addr_cpy(topo_info_v0->mac, topo_info->topo[i].mac);
|
|
break;
|
|
}
|
|
case TOPO_INFO_TYPE_V1:
|
|
{
|
|
topo_info_v1_t *topo_info_v1 = (topo_info_v1_t *)frame->info;
|
|
topo_info_v1->level = topo_info->topo[i].level;
|
|
topo_info_v1->logic_phase = topo_info->topo[i].logic_phase;
|
|
topo_info_v1->phy_phase = topo_info->topo[i].phy_phase;
|
|
iot_mac_addr_cpy(topo_info_v1->mac, topo_info->topo[i].mac);
|
|
break;
|
|
}
|
|
default:
|
|
iot_pkt_free(data_pkt);
|
|
return rpt2mcu;
|
|
}
|
|
|
|
GE_FRM_HDR_PREPARE(frame, PROTO_GE_PLC_RESP_CMD,
|
|
PROTO_TOPO_RESP_CMD, frm_len);
|
|
tail = (ge_frm_tail_t *)(frame->info + topo_info_len);
|
|
tail->check_sum = ge_frm_checksum_calc((uint8_t *)frame,
|
|
frm_len - sizeof(ge_frm_tail_t));
|
|
tail->tail = GE_FRM_TAIL_CODE;
|
|
}
|
|
prototask_contxt.topo_resp_index += topo_info->cnt;
|
|
}
|
|
else
|
|
{
|
|
/* if txrx return zero sta cnt */
|
|
frame = (ge_frame_topo_resp_subfn5_t *)data_p;
|
|
frame->type = type;
|
|
frame->total_cnt = topo_info->cnt;
|
|
frame->cur_cnt = topo_info->cnt;
|
|
frame->seq = sm->seq;
|
|
GE_FRM_HDR_PREPARE(frame, PROTO_GE_PLC_RESP_CMD, PROTO_TOPO_RESP_CMD,
|
|
frm_len);
|
|
tail = (ge_frm_tail_t *)(frame->info + topo_info_len);
|
|
tail->check_sum = ge_frm_checksum_calc((uint8_t *)frame,
|
|
frm_len - sizeof(ge_frm_tail_t));
|
|
tail->tail = GE_FRM_TAIL_CODE;
|
|
}
|
|
if (cmd->index.current == cmd->index.total) {
|
|
/* switch cmd handle state to idle state */
|
|
prototask_contxt.topo_resp_index = 0;
|
|
iot_proto_cmd_handle_state_init();
|
|
}
|
|
/* report topo to MCU */
|
|
iot_proto_send_to_mainboard(data_pkt);
|
|
break;
|
|
}
|
|
/* go data down link path */
|
|
case CMD_REMOTE_DOWN_LINK:
|
|
{
|
|
ge_frame_topo_resp_subfn5_t *frame;
|
|
uint16_t i;
|
|
iot_pkt_t *resp_pkt = NULL;
|
|
protpkt_tx_info_t txinfo = { 0 };
|
|
iot_proto_fill_txinfo(&txinfo, true, PLCTXRX_UNICAST, 3, 500, 1,
|
|
prototask_contxt.local_dev.mac, sm->dev.mac);
|
|
|
|
/* alloc packet for response frame */
|
|
resp_pkt = iot_pkt_alloc(frm_len, IOT_GREE_APP_MID);
|
|
IOT_ASSERT(resp_pkt);
|
|
iot_pkt_put(resp_pkt, frm_len);
|
|
frame = (ge_frame_topo_resp_subfn5_t *)iot_pkt_data(resp_pkt);
|
|
|
|
if (topo_info->cnt > 0) {
|
|
for (i = 0; i < topo_info->cnt; i++) {
|
|
os_mem_set(frame, 0, frm_len);
|
|
frame->type = type;
|
|
frame->seq = sm->seq;
|
|
frame->total_cnt = (uint8_t)cmd->index.total;
|
|
frame->cur_cnt = prototask_contxt.topo_resp_index + i + 1;
|
|
|
|
switch (type) {
|
|
case TOPO_INFO_TYPE_V0:
|
|
{
|
|
topo_info_v0_t *topo_info_v0 = (topo_info_v0_t *)frame->info;
|
|
topo_info_v0->level = topo_info->topo[i].level;
|
|
iot_mac_addr_cpy(topo_info_v0->mac, topo_info->topo[i].mac);
|
|
break;
|
|
}
|
|
case TOPO_INFO_TYPE_V1:
|
|
{
|
|
topo_info_v1_t *topo_info_v1 = (topo_info_v1_t *)frame->info;
|
|
topo_info_v1->level = topo_info->topo[i].level;
|
|
topo_info_v1->logic_phase = topo_info->topo[i].logic_phase;
|
|
topo_info_v1->phy_phase = topo_info->topo[i].phy_phase;
|
|
iot_mac_addr_cpy(topo_info_v1->mac, topo_info->topo[i].mac);
|
|
break;
|
|
}
|
|
default:
|
|
iot_pkt_free(resp_pkt);
|
|
return rpt2mcu;
|
|
}
|
|
|
|
GE_FRM_HDR_PREPARE(frame, PROTO_GE_PLC_RESP_CMD,
|
|
PROTO_TOPO_RESP_CMD, frm_len);
|
|
tail = (ge_frm_tail_t *)(frame->info + topo_info_len);
|
|
tail->check_sum = ge_frm_checksum_calc((uint8_t *)frame,
|
|
frm_len - sizeof(ge_frm_tail_t));
|
|
tail->tail = GE_FRM_TAIL_CODE;
|
|
/* send to remote */
|
|
iot_proto_remote_cmd_send_to_plctxrx((uint8_t *)frame,
|
|
frm_len, &txinfo);
|
|
}
|
|
prototask_contxt.topo_resp_index += topo_info->cnt;
|
|
} else {
|
|
os_mem_set(frame, 0, frm_len);
|
|
frame->type = type;
|
|
frame->seq = sm->seq;
|
|
frame->total_cnt = topo_info->cnt;
|
|
frame->cur_cnt = topo_info->cnt;
|
|
GE_FRM_HDR_PREPARE(frame, PROTO_GE_PLC_RESP_CMD, PROTO_TOPO_RESP_CMD,
|
|
frm_len);
|
|
tail = (ge_frm_tail_t *)(frame->info + topo_info_len);
|
|
tail->check_sum = ge_frm_checksum_calc((uint8_t *)frame,
|
|
frm_len - sizeof(ge_frm_tail_t));
|
|
tail->tail = GE_FRM_TAIL_CODE;
|
|
/* switch cmd handle state to idle state */
|
|
iot_proto_cmd_handle_state_init();
|
|
/* send to remote */
|
|
iot_proto_remote_cmd_send_to_plctxrx((uint8_t *)frame, frm_len,
|
|
&txinfo);
|
|
}
|
|
if (cmd->index.current == cmd->index.total) {
|
|
/* switch cmd handle state to idle state */
|
|
prototask_contxt.topo_resp_index = 0;
|
|
iot_proto_cmd_handle_state_init();
|
|
}
|
|
|
|
if (resp_pkt) {
|
|
iot_pkt_free(resp_pkt);
|
|
}
|
|
|
|
break;
|
|
}
|
|
/* report to MCU */
|
|
case CMD_REMOTE_UP_LINK:
|
|
{
|
|
ge_frame_topo_resp_subfn5_t *frm = (ge_frame_topo_resp_subfn5_t*)data;
|
|
/* check have respon over */
|
|
if (sm->state == PROTO_CMD_WAIT_TOPO_RESP &&
|
|
frm->total_cnt == frm->cur_cnt)
|
|
sm->state = PROTO_CMD_IDLE;
|
|
rpt2mcu = true;
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return rpt2mcu;
|
|
}
|
|
|
|
bool_t iot_proto_query_net_sts_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
(void)dir;
|
|
bool_t rpt2mcu = false;
|
|
|
|
uint8_t mac[IOT_MAC_ADDR_LEN] = { 0 };
|
|
ge_frame_net_stat_query_subfn6_t *query_cmd =
|
|
(ge_frame_net_stat_query_subfn6_t *)data;
|
|
|
|
ge_frame_net_stat_resp_subfn6_t *resp_frm;
|
|
|
|
if (len != sizeof(ge_frame_net_stat_query_subfn6_t)) {
|
|
iot_pkt_t *pkt =
|
|
iot_pkt_alloc(sizeof(ge_frame_net_stat_resp_subfn6_t), IOT_GREE_APP_MID);
|
|
IOT_ASSERT(pkt);
|
|
resp_frm = (ge_frame_net_stat_resp_subfn6_t *)iot_pkt_data(pkt);
|
|
iot_pkt_put(pkt, sizeof(*resp_frm));
|
|
|
|
os_mem_set(resp_frm, 0, sizeof(*resp_frm));
|
|
EXT_FN_FRM_PREPARE(resp_frm,
|
|
PROTO_GE_PLC_RESP_CMD, PROTO_NET_STS_RESP_CMD);
|
|
resp_frm->tail.check_sum =
|
|
ge_frm_checksum_calc((uint8_t *)resp_frm,
|
|
sizeof(*resp_frm) - sizeof(ge_frm_tail_t));
|
|
|
|
/* send to MCU */
|
|
iot_proto_send_to_mainboard(pkt);
|
|
|
|
return rpt2mcu;
|
|
}
|
|
|
|
iot_mac_addr_cpy(mac, query_cmd->mac);
|
|
proto_cmd_hdl_state_t *sm = iot_proto_cmd_handle_state_get();
|
|
iot_pkt_t *cmd_pkt;
|
|
plctxrx_cmd_arg_t cmd = { 0 };
|
|
cmd.cid.cid = PLCTXRX_CID_NET_STS;
|
|
cmd.cid.opcode = PLCTXRX_OP_QUERY;
|
|
cmd.need_ack = true;
|
|
cmd.prio = 0;
|
|
cmd.dlen = sizeof(mac);
|
|
/* alloc packet for sending cmd */
|
|
cmd_pkt = iot_pkt_alloc(sizeof(cmd) + cmd.dlen, IOT_GREE_APP_MID);
|
|
IOT_ASSERT(cmd_pkt);
|
|
/* copy plctxrx_cmd_arg_t */
|
|
os_mem_cpy(iot_pkt_data(cmd_pkt), &cmd, sizeof(cmd));
|
|
os_mem_cpy(iot_pkt_data(cmd_pkt) + sizeof(cmd), mac, sizeof(mac));
|
|
iot_pkt_put(cmd_pkt, sizeof(cmd) + cmd.dlen);
|
|
/* if async cmd, we need to set a state for response */
|
|
sm->state = PROTO_CMD_WAIT_NET_STS_RESP;
|
|
sm->dir = CMD_LOCAL_UP_LINK;
|
|
sm->seq = query_cmd->seq;
|
|
/* send cmd to plctxrx layer */
|
|
iot_proto_cmd_send_to_plctxrx(cmd_pkt);
|
|
|
|
return rpt2mcu;
|
|
}
|
|
|
|
bool_t iot_proto_net_sts_resp_subfn_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
(void)len;
|
|
(void)dir;
|
|
bool_t rpt2mcu = false;
|
|
proto_cmd_hdl_state_t *sm = iot_proto_cmd_handle_state_get();
|
|
plctxrx_cmd_resp_t *cmd = (plctxrx_cmd_resp_t *)data;
|
|
iot_pkt_t *data_pkt = NULL;
|
|
uint16_t i;
|
|
|
|
iot_cus_printf("[glpr]resp net states to mcu\n");
|
|
ge_frame_net_stat_resp_subfn6_t *frame;
|
|
uint16_t size;
|
|
plctxrx_net_sts_data_info_t *net_sts =
|
|
(plctxrx_net_sts_data_info_t*)cmd->data;
|
|
if (cmd->resp == PLCTXRX_RESP_ERROR || net_sts == NULL) {
|
|
size = sizeof(ge_frame_net_stat_resp_subfn6_t);
|
|
data_pkt = iot_pkt_alloc(size, IOT_GREE_APP_MID);
|
|
IOT_ASSERT(data_pkt);
|
|
|
|
frame = (ge_frame_net_stat_resp_subfn6_t *)iot_pkt_data(data_pkt);
|
|
iot_pkt_put(data_pkt, size);
|
|
os_mem_set(frame, 0, size);
|
|
frame->seq = sm->seq;
|
|
EXT_FN_FRM_PREPARE((frame),
|
|
PROTO_GE_PLC_RESP_CMD, PROTO_NET_STS_RESP_CMD);
|
|
frame->tail.check_sum = ge_frm_checksum_calc((uint8_t *)(frame),
|
|
sizeof(*frame) - sizeof(ge_frm_tail_t));
|
|
} else {
|
|
size = sizeof(ge_frame_net_stat_resp_subfn6_t)*net_sts->count;
|
|
data_pkt = iot_pkt_alloc(size, IOT_GREE_APP_MID);
|
|
IOT_ASSERT(data_pkt);
|
|
|
|
frame = (ge_frame_net_stat_resp_subfn6_t *)iot_pkt_data(data_pkt);
|
|
iot_pkt_put(data_pkt,size);
|
|
|
|
for (i = 0; i < net_sts->count; i++) {
|
|
os_mem_set(frame + i, 0, sizeof(*frame));
|
|
(frame + i)->total_cnt = net_sts->count;
|
|
(frame + i)->cur_cnt = i + 1;
|
|
(frame + i)->snr = net_sts->net_sts_data[i].snr;
|
|
(frame + i)->nf = net_sts->net_sts_data[i].nf;
|
|
(frame + i)->tsf = net_sts->net_sts_data[i].dl_tf_sr;
|
|
(frame + i)->rsf = net_sts->net_sts_data[i].ul_tf_sr;
|
|
iot_mac_addr_cpy((frame + i)->mac, net_sts->net_sts_data[i].mac);
|
|
(frame + i)->seq = sm->seq;
|
|
EXT_FN_FRM_PREPARE((frame+i),
|
|
PROTO_GE_PLC_RESP_CMD, PROTO_NET_STS_RESP_CMD);
|
|
(frame + i)->tail.check_sum =
|
|
ge_frm_checksum_calc((uint8_t *)(frame + i),
|
|
sizeof(*(frame + i)) - sizeof(ge_frm_tail_t));
|
|
}
|
|
}
|
|
|
|
/* clean state */
|
|
iot_proto_cmd_handle_state_init();
|
|
/* report net states to MCU */
|
|
iot_proto_send_to_mainboard(data_pkt);
|
|
return rpt2mcu;
|
|
}
|
|
|
|
bool_t iot_proto_query_node_info_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
(void)dir;
|
|
bool_t rpt2mcu = false;
|
|
iot_pkt_t *cmd_pkt;
|
|
uint16_t pkt_len;
|
|
plctxrx_cmd_arg_t *cmd;
|
|
plctxrx_cmd_query_node_info_t *node_info;
|
|
|
|
ge_frame_node_info_query_subfn23_t *query_cmd =
|
|
(ge_frame_node_info_query_subfn23_t *)data;
|
|
|
|
pkt_len = sizeof(plctxrx_cmd_arg_t) + sizeof(plctxrx_cmd_query_node_info_t);
|
|
|
|
if (len != sizeof(ge_frame_node_info_query_subfn23_t)) {
|
|
iot_cus_printf("query_node_info cmd length mismatch\n");
|
|
iot_proto_node_info_report(NULL, 0, 0, 0, query_cmd->type, 1);
|
|
return rpt2mcu;
|
|
}
|
|
|
|
proto_cmd_hdl_state_t *sm = iot_proto_cmd_handle_state_get();
|
|
/* alloc packet for sending cmd */
|
|
cmd_pkt = iot_pkt_alloc(pkt_len, IOT_GREE_APP_MID);
|
|
if (NULL == cmd_pkt) {
|
|
iot_cus_printf("[glpr]query_node_info alloc pkt error\n");
|
|
return rpt2mcu;
|
|
}
|
|
cmd = (plctxrx_cmd_arg_t *)iot_pkt_put(cmd_pkt, pkt_len);
|
|
cmd->cid.cid = PLCTXRX_CID_NODE_INFO;
|
|
cmd->cid.opcode = PLCTXRX_OP_QUERY;
|
|
cmd->need_ack = true;
|
|
cmd->prio = 0;
|
|
cmd->dlen = sizeof(plctxrx_cmd_query_node_info_t);
|
|
node_info = (plctxrx_cmd_query_node_info_t *)cmd->arg;
|
|
iot_mac_addr_cpy(node_info->mac, query_cmd->mac);
|
|
node_info->type = query_cmd->type;
|
|
|
|
/* if async cmd, we need to set a state for response */
|
|
sm->state = PROTO_CMD_WAIT_NODE_INFO_RESP;
|
|
sm->dir = CMD_LOCAL_UP_LINK;
|
|
sm->seq = query_cmd->seq;
|
|
/* send cmd to plctxrx layer */
|
|
iot_proto_cmd_send_to_plctxrx(cmd_pkt);
|
|
|
|
return rpt2mcu;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_proto_query_nw_info_handler() - query network information handler
|
|
* @param data query network command data frame data.
|
|
* @param len the data length.
|
|
* @param dir the direction of command command from.
|
|
* @retval: whether need report to mcu.
|
|
*/
|
|
bool_t iot_proto_query_nw_info_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
(void)dir;
|
|
bool_t rpt2mcu = false;
|
|
iot_pkt_t *cmd_pkt;
|
|
plctxrx_cmd_arg_t *cmd;
|
|
|
|
ge_frame_nw_info_query_subfn24_t *query_cmd =
|
|
(ge_frame_nw_info_query_subfn24_t *)data;
|
|
|
|
if (len != sizeof(ge_frame_nw_info_query_subfn24_t)) {
|
|
iot_proto_nw_info_report(0, NULL, 0);
|
|
return rpt2mcu;
|
|
}
|
|
|
|
proto_cmd_hdl_state_t *sm = iot_proto_cmd_handle_state_get();
|
|
/* alloc packet for sending cmd */
|
|
cmd_pkt = iot_pkt_alloc(sizeof(plctxrx_cmd_arg_t), IOT_GREE_APP_MID);
|
|
if (NULL == cmd_pkt) {
|
|
iot_cus_printf("[glpr]query_nw_info alloc pkt error\n");
|
|
return rpt2mcu;
|
|
}
|
|
cmd = (plctxrx_cmd_arg_t *)iot_pkt_put(cmd_pkt, sizeof(plctxrx_cmd_arg_t));
|
|
cmd->cid.cid = PLCTXRX_CID_NW_INFO;
|
|
cmd->cid.opcode = PLCTXRX_OP_QUERY;
|
|
cmd->need_ack = true;
|
|
cmd->prio = 0;
|
|
cmd->dlen = 0;
|
|
|
|
/* if async cmd, we need to set a state for response */
|
|
sm->state = PROTO_CMD_WAIT_NW_INFO_RESP;
|
|
sm->dir = CMD_LOCAL_UP_LINK;
|
|
sm->seq = query_cmd->seq;
|
|
/* send cmd to plctxrx layer */
|
|
iot_proto_cmd_send_to_plctxrx(cmd_pkt);
|
|
|
|
return rpt2mcu;
|
|
}
|
|
|
|
bool_t iot_proto_query_local_ip4_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
(void)dir;
|
|
bool_t rpt2mcu = false;
|
|
iot_pkt_t *pkt = NULL;
|
|
ge_frame_local_ip4_resp_subfn25_t *resp_cmd;
|
|
ge_frame_local_ip4_query_subfn25_t *query_cmd =
|
|
(ge_frame_local_ip4_query_subfn25_t *)data;
|
|
uint8_t ip4_addr[IOT_IP4_ADDR_LEN] = {0};
|
|
uint8_t ip4_mask[IOT_IP4_ADDR_LEN] = {0};
|
|
|
|
if (len != sizeof(ge_frame_local_ip4_query_subfn25_t)) {
|
|
iot_cus_printf("[glpr][err]qurey local ip4 info cmd len mismatch\n");
|
|
return rpt2mcu;
|
|
}
|
|
|
|
pkt = iot_pkt_alloc(sizeof(*resp_cmd), IOT_GREE_APP_MID);
|
|
if (pkt == NULL) {
|
|
iot_cus_printf("[glpr][err]No Mem!\n");
|
|
return rpt2mcu;
|
|
}
|
|
resp_cmd = (ge_frame_local_ip4_resp_subfn25_t *)iot_pkt_data(pkt);
|
|
iot_pkt_put(pkt, sizeof(*resp_cmd));
|
|
|
|
os_mem_set(resp_cmd, 0, sizeof(*resp_cmd));
|
|
EXT_FN_FRM_PREPARE(resp_cmd,
|
|
PROTO_GE_PLC_RESP_CMD, PROTO_LOCAL_IP4_INFO_RESP_CMD);
|
|
resp_cmd->seq = query_cmd->seq;
|
|
iot_oem_get_local_ip4_addr(ip4_addr);
|
|
iot_oem_get_local_ip4_netmask(ip4_mask);
|
|
os_mem_cpy(resp_cmd->ip4_addr, ip4_addr, IOT_IP4_ADDR_LEN);
|
|
os_mem_cpy(resp_cmd->ip4_mask, ip4_mask, IOT_IP4_ADDR_LEN);
|
|
resp_cmd->tail.check_sum =
|
|
ge_frm_checksum_calc((uint8_t *)resp_cmd,
|
|
sizeof(*resp_cmd)-sizeof(ge_frm_tail_t));
|
|
|
|
/* send to MCU */
|
|
iot_proto_send_to_mainboard(pkt);
|
|
|
|
return rpt2mcu;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_proto_gpio_resp() - response gpio info.
|
|
* @param data_pkt data which need to resp
|
|
*/
|
|
void iot_proto_gpio_resp(iot_pkt_t *data_pkt)
|
|
{
|
|
ge_frame_query_gpio_resp_subfn27_t *frame =
|
|
(ge_frame_query_gpio_resp_subfn27_t *)iot_pkt_data(data_pkt);
|
|
|
|
if (iot_mac_addr_cmp(frame->dest_mac, prototask_contxt.local_dev.mac)) {
|
|
/* report topo to MCU */
|
|
iot_proto_send_to_mainboard(data_pkt);
|
|
iot_proto_cmd_handle_state_init();
|
|
return;
|
|
}
|
|
|
|
protpkt_tx_info_t txinfo = { 0 };
|
|
iot_proto_fill_txinfo(&txinfo, true,
|
|
PLCTXRX_UNICAST, PROTO_UNICAST_RETRY_DEFAULT_CNT,
|
|
PROTO_UNICAST_RETRY_DEFAULT_INTVL, 1, frame->src_mac, frame->dest_mac);
|
|
|
|
iot_proto_remote_cmd_send_to_plctxrx(iot_pkt_data(data_pkt),
|
|
iot_pkt_data_len(data_pkt), &txinfo);
|
|
iot_pkt_free(data_pkt);
|
|
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* @brief iot_proto_delay_time_send() - send delay time info.
|
|
* @param data_pkt data which need to send
|
|
* @param src_mac source mac
|
|
* @param dst_mac dst mac
|
|
*/
|
|
void iot_proto_delay_time_send(iot_pkt_t *data_pkt, uint8_t *src_mac, uint8_t *dst_mac)
|
|
{
|
|
uint8_t *data;
|
|
uint8_t len;
|
|
protpkt_tx_info_t txinfo = { 0 };
|
|
|
|
iot_proto_fill_txinfo(&txinfo, false, PLCTXRX_UNICAST, 0,
|
|
PROTO_UNICAST_RETRY_DEFAULT_INTVL, 1, src_mac, dst_mac);
|
|
txinfo.force_noaggr = true;
|
|
data = iot_pkt_data(data_pkt);
|
|
len = (uint8_t)iot_pkt_data_len(data_pkt);
|
|
|
|
iot_common_bin_dump(data, len);
|
|
iot_proto_data_send_to_plctxrx(data, len, &txinfo);
|
|
|
|
iot_pkt_free(data_pkt);
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_proto_query_gpio_handler() - query gpio handler
|
|
* @param data query gpio frame data.
|
|
* @param len the data length.
|
|
* @param dir the direction of command command from.
|
|
* @retval: whether need report to mcu.
|
|
*/
|
|
bool_t iot_proto_query_gpio_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
(void)dir;
|
|
bool_t rpt2mcu = false;
|
|
bool_t rpt_cfm = false;
|
|
ge_frame_gpio_query_subfn27_t *frm =
|
|
(ge_frame_gpio_query_subfn27_t *)data;
|
|
proto_cmd_hdl_state_t *sm = iot_proto_cmd_handle_state_get();
|
|
uint8_t dst_mac[IOT_MAC_ADDR_LEN] = { 0 };
|
|
uint8_t *local_mac = prototask_contxt.local_dev.mac;
|
|
protpkt_tx_info_t txinfo = { 0 };
|
|
uint8_t reason = PROTO_REASON_OK;
|
|
transmit_direction_e_t tmp_dir = 0;
|
|
uint8_t gpio_index = 0;
|
|
uint32_t gpio_value = 0;
|
|
|
|
if (len != sizeof(ge_frame_gpio_query_subfn27_t)) {
|
|
reason = PROTO_REASON_LEN_MISSMATCH;
|
|
iot_cus_printf("[glpr][err]%s cmd len mismatch\n", "query gpio");
|
|
rpt_cfm = true;
|
|
goto cfm;
|
|
} else if (iot_mac_addr_cmp(frm->dest_mac, dst_mac)) {
|
|
reason = PROTO_REASON_MAC_ADDR_ZERO;
|
|
iot_cus_printf("[glpr][err]%s cmd len mismatch\n", "query gpio");
|
|
rpt_cfm = true;
|
|
goto cfm;
|
|
} else if (IOT_PROTO_INVALID_GPIO_INDEX ==
|
|
(gpio_index = iot_proto_get_gpio_index(frm->gpio_num))) {
|
|
reason = PROTO_REASON_NOT_SUPPORT;
|
|
iot_cus_printf("[glpr][err]%s cmd gpio num is invalid\n", "config gpio");
|
|
rpt_cfm = true;
|
|
goto cfm;
|
|
}
|
|
|
|
iot_mac_addr_cpy(dst_mac, frm->dest_mac);
|
|
|
|
if (iot_mac_addr_cmp(dst_mac, local_mac)) {
|
|
tmp_dir = CMD_LOCAL_DOWN_LINK;
|
|
} else {
|
|
tmp_dir = CMD_REMOTE_DOWN_LINK;
|
|
}
|
|
|
|
switch (tmp_dir) {
|
|
case CMD_LOCAL_DOWN_LINK:
|
|
{
|
|
ge_frame_query_gpio_resp_subfn27_t *resp_frame = NULL;
|
|
iot_pkt_t *data_pkt = NULL;
|
|
uint16_t frame_len = sizeof(ge_frame_query_gpio_resp_subfn27_t);
|
|
|
|
if (IOT_GE_GPIO_OPEN != iot_ge_gpio_g[gpio_index].gpio_state) {
|
|
reason = PROTO_REASON_NOT_READY;
|
|
iot_cus_printf("[glpr][err]%s need to config the gpio before\n",
|
|
"query gpio");
|
|
rpt_cfm = true;
|
|
goto cfm;
|
|
}
|
|
|
|
if (IOT_GE_GPIO_DIR_INPUT == iot_ge_gpio_g[gpio_index].dir_mode) {
|
|
gpio_value = iot_gpio_value_get(frm->gpio_num);
|
|
} else if (IOT_GE_GPIO_DIR_OUTPUT == iot_ge_gpio_g[gpio_index].dir_mode) {
|
|
iot_gpio_output_value_get(frm->gpio_num, (int *)&gpio_value);
|
|
}
|
|
gpio_value = gpio_value? 1:0;
|
|
iot_cus_printf("%s gpio num = %d, value = %d\n", __FUNCTION__, frm->gpio_num, gpio_value);
|
|
|
|
data_pkt = iot_pkt_alloc(frame_len, IOT_GREE_APP_MID);
|
|
resp_frame = (ge_frame_query_gpio_resp_subfn27_t*)iot_pkt_put(data_pkt,
|
|
frame_len);
|
|
os_mem_set(resp_frame, 0, frame_len);
|
|
iot_mac_addr_cpy(resp_frame->dest_mac, frm->src_mac);
|
|
iot_mac_addr_cpy(resp_frame->src_mac, frm->dest_mac);
|
|
resp_frame->seq = frm->seq;
|
|
resp_frame->gpio_num = frm->gpio_num;
|
|
resp_frame->gpio_dir = iot_ge_gpio_g[gpio_index].dir_mode;
|
|
resp_frame->pull_mode = iot_ge_gpio_g[gpio_index].pull_mode;
|
|
resp_frame->value = (uint8_t)gpio_value;
|
|
EXT_FN_FRM_PREPARE(resp_frame,
|
|
PROTO_GE_PLC_RESP_CMD, PROTO_QUERY_GPIO_RESP_CMD);
|
|
resp_frame->tail.check_sum =
|
|
ge_frm_checksum_calc((uint8_t *)resp_frame,
|
|
frame_len - sizeof(ge_frm_tail_t));
|
|
|
|
iot_proto_gpio_resp(data_pkt);
|
|
reason = PROTO_REASON_OK;
|
|
return rpt2mcu;
|
|
}
|
|
case CMD_REMOTE_DOWN_LINK:
|
|
{
|
|
iot_proto_fill_txinfo(&txinfo, true,
|
|
PLCTXRX_UNICAST, PROTO_UNICAST_RETRY_DEFAULT_CNT,
|
|
PROTO_UNICAST_RETRY_DEFAULT_INTVL, 1, local_mac, dst_mac);
|
|
|
|
iot_proto_remote_cmd_send_to_plctxrx(data,
|
|
sizeof(ge_frame_gpio_query_subfn27_t), &txinfo);
|
|
sm->dir = CMD_REMOTE_UP_LINK;
|
|
sm->state = PROTO_CMD_WAIT_CMD_CFM;
|
|
sm->seq = frm->seq;
|
|
sm->cur_subfn = frm->hdr.subfn;
|
|
return rpt2mcu;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
|
|
cfm:
|
|
if (rpt_cfm) {
|
|
iot_proto_resp_cfm_frame(reason, dir, PROTO_GE_GPIO_QUERY_CMD,
|
|
frm->seq, frm->src_mac);
|
|
}
|
|
|
|
return rpt2mcu;
|
|
}
|
|
|
|
/*
|
|
* @brief iot_ntb_to_us() transform one value form ntb to us.
|
|
* @param ntb the ntb value which need to transform to us.
|
|
* @param current_type the current date type.
|
|
* @retval:data_us the us value witch transformed form ntb value.
|
|
*/
|
|
uint32_t iot_ntb_to_us(uint32_t ntb, uint8_t current_type)
|
|
{
|
|
uint32_t data_us;
|
|
|
|
/* current_type is not smaller than overflow_index means value is
|
|
* overflow, the value should add a (0xFFFFFFFF / 25)
|
|
*/
|
|
if (overflow_index <= current_type) {
|
|
data_us = (ntb + 0xFFFFFFFF % 25) / 25 + 0xFFFFFFFF / 25;
|
|
} else {
|
|
data_us = ntb / 25;
|
|
}
|
|
|
|
return data_us;
|
|
}
|
|
|
|
/*
|
|
* @brief iot_delay_time_ntb_to_us() - change ntb to us
|
|
* @param data addr of value need to change.
|
|
*/
|
|
void iot_delay_time_ntb_to_us(ge_delay_tm_test_t *data)
|
|
{
|
|
if (data->cco_tx_time > data->sta_rx_time) {
|
|
overflow_index = STA_RX_TIME;
|
|
} else if (data->sta_rx_time > data->sta_tx_time) {
|
|
overflow_index = STA_TX_TIME;
|
|
} else if (data->sta_tx_time > data->cco_rx_time) {
|
|
overflow_index = CCO_RX_TIME;
|
|
}
|
|
|
|
data->cco_tx_time = iot_ntb_to_us(data->cco_tx_time, CCO_TX_TIME);
|
|
data->sta_rx_time = iot_ntb_to_us(data->sta_rx_time, STA_RX_TIME);
|
|
data->sta_tx_time = iot_ntb_to_us(data->sta_tx_time, STA_TX_TIME);
|
|
data->cco_rx_time = iot_ntb_to_us(data->cco_rx_time, CCO_RX_TIME);
|
|
/* clear the value of overflow_index to initialization value*/
|
|
overflow_index = CCO_RX_TIME + 1;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_proto_delay_time_handler() - test time delay
|
|
* @param data test delay time frame data.
|
|
* @param len the data length.
|
|
* @param dir the direction of command command from.
|
|
* @retval: whether need report to mcu.
|
|
*/
|
|
#if PLC_SUPPORT_STA_ROLE
|
|
bool_t iot_proto_delay_time_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
bool_t rpt2mcu = false;
|
|
ge_frame_delay_time_subfn166_t *frm =
|
|
(ge_frame_delay_time_subfn166_t *)data;
|
|
uint8_t dst_mac[IOT_MAC_ADDR_LEN] = { 0 };
|
|
uint8_t reason = PROTO_REASON_OK;
|
|
uint16_t rsv_data_len = frm->tm_test.datalen;
|
|
ge_frame_delay_time_subfn166_t *resp_frame = NULL;
|
|
ge_frm_tail_t *tail_data;
|
|
iot_pkt_t *data_pkt = NULL;
|
|
|
|
if (iot_mac_addr_cmp(frm->dest_mac, dst_mac)) {
|
|
reason = PROTO_REASON_MAC_MISSMATCH;
|
|
iot_cus_printf("[glpr][err]%s dst_mac missmatch\n", "test delay time");
|
|
goto cfm;
|
|
}
|
|
|
|
/* sta don't support FE A6 from uart,we need response the unsupported reason
|
|
included in the FE 14 frame */
|
|
if (dir != CMD_REMOTE_UP_LINK) {
|
|
reason = PROTO_REASON_CMD_DIR_ERR;
|
|
iot_cus_printf("[glpr][err]%s sta direction error\n", "test delay time");
|
|
goto cfm;
|
|
}
|
|
/* add fill data,need to alloc new pkt */
|
|
data_pkt = iot_pkt_alloc(len, IOT_GREE_APP_MID);
|
|
if (data_pkt == NULL) {
|
|
reason = PROTO_REASON_ALLOC_MEM_ERR;
|
|
iot_cus_printf("[err]%s pkt alloc fail\n", __FUNCTION__);
|
|
goto cfm;
|
|
}
|
|
|
|
resp_frame = (ge_frame_delay_time_subfn166_t *)iot_pkt_put(data_pkt, len);
|
|
tail_data = (ge_frm_tail_t *)(iot_pkt_data(data_pkt) +
|
|
sizeof(ge_frame_delay_time_subfn166_t) + rsv_data_len);
|
|
os_mem_set(resp_frame, 0, len);
|
|
resp_frame->seq = frm->seq;
|
|
resp_frame->resv = frm->resv;
|
|
iot_mac_addr_cpy(resp_frame->dest_mac, frm->dest_mac);
|
|
os_mem_cpy((uint8_t *)&resp_frame->tm_test, (uint8_t *)&frm->tm_test,
|
|
sizeof(frm->tm_test) + rsv_data_len);
|
|
iot_common_bin_dump((uint8_t *)resp_frame, len);
|
|
iot_delay_timer_get(&resp_frame->tm_test.mcu_tx_time, STA_RX_TIME, 0);
|
|
iot_delay_timer_get(&resp_frame->tm_test.mcu_tx_time, STA_TX_TIME, 0);
|
|
EXT_FN_TWO_PART_FRM_PREPARE(resp_frame, tail_data, rsv_data_len,
|
|
PROTO_GE_PLC_SET_CMD, PROTO_GE_DELAY_TM_CMD);
|
|
tail_data->check_sum =
|
|
ge_frm_checksum_calc((uint8_t *)resp_frame, len - sizeof(ge_frm_tail_t));
|
|
|
|
iot_proto_delay_time_send(data_pkt, resp_frame->dest_mac,
|
|
prototask_contxt.cco_dev.mac);
|
|
return rpt2mcu;
|
|
|
|
cfm:
|
|
iot_proto_resp_cfm_frame(reason, dir, PROTO_GE_DELAY_TM_CMD,
|
|
frm->seq, frm->dest_mac);
|
|
return rpt2mcu;
|
|
}
|
|
|
|
#else /* PLC_SUPPORT_STA_ROLE */
|
|
|
|
/**
|
|
* @brief iot_proto_delay_time_recv_subfn_handler() - compute cco recv time stamp.
|
|
* @param data data which need to recv
|
|
* @param len the data length
|
|
* @param dir the data received direction
|
|
* @retval: whether need report to mcu.
|
|
*/
|
|
static bool_t iot_proto_delay_time_recv_subfn_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
ge_frm_tail_t *tail_frm;
|
|
(void)dir;
|
|
|
|
ge_frame_delay_time_subfn166_t *frame =
|
|
(ge_frame_delay_time_subfn166_t *)data;
|
|
|
|
iot_delay_timer_get(&frame->tm_test.mcu_tx_time, CCO_RX_TIME, 0);
|
|
iot_delay_time_ntb_to_us(&frame->tm_test);
|
|
|
|
tail_frm = (ge_frm_tail_t *)(data + sizeof(ge_frame_delay_time_subfn166_t)
|
|
+ frame->tm_test.datalen);
|
|
tail_frm->check_sum = ge_frm_checksum_calc(data, len - sizeof(ge_frm_tail_t));
|
|
tail_frm->tail = GE_FRM_TAIL_CODE;
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_proto_delay_time_send_subfn_handler() - cco send time stamp.
|
|
* @param data data which need to send
|
|
* @param len the data length
|
|
* @param dir the data received direction
|
|
* @retval: whether need report to mcu.
|
|
*/
|
|
static bool_t iot_proto_delay_time_send_subfn_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
uint16_t pkt_len;
|
|
bool_t rpt2mcu = false;
|
|
ge_frame_delay_time_subfn166_t *frm =
|
|
(ge_frame_delay_time_subfn166_t *)data;
|
|
uint8_t reason = PROTO_REASON_OK;
|
|
uint8_t dst_mac[IOT_MAC_ADDR_LEN] = { 0 };
|
|
iot_pkt_t *data_pkt = NULL;
|
|
uint8_t *local_mac = prototask_contxt.local_dev.mac;
|
|
ge_delay_tm_test_t *time_data = &frm->tm_test;
|
|
uint8_t *pkt_data;
|
|
|
|
if (iot_mac_addr_cmp(frm->dest_mac, dst_mac)) {
|
|
reason = PROTO_REASON_MAC_ADDR_ZERO;
|
|
iot_cus_printf("[glpr][err]%s dst_mac is ivalid\n", "test delay time");
|
|
goto cfm;
|
|
}
|
|
|
|
iot_mac_addr_cpy(dst_mac, frm->dest_mac);
|
|
if (iot_mac_addr_cmp(dst_mac, local_mac)) {
|
|
reason = PROTO_REASON_MAC_ADDR_ZERO;
|
|
iot_cus_printf("[glpr][err]%s the mac is local\n", "test delay time");
|
|
goto cfm;
|
|
}
|
|
|
|
pkt_len = len + time_data->datalen;
|
|
if (pkt_len > 255) {
|
|
reason = PROTO_REASON_PARAME_ERR;
|
|
iot_cus_printf("[glpr][err]%s the fill data is too much\n",
|
|
"test delay time");
|
|
goto cfm;
|
|
}
|
|
data_pkt = iot_pkt_alloc(pkt_len, IOT_GREE_APP_MID);
|
|
if (data_pkt == NULL) {
|
|
reason = PROTO_REASON_ALLOC_MEM_ERR;
|
|
iot_cus_printf("[err]%s pkt alloc fail\n", __FUNCTION__);
|
|
goto cfm;
|
|
}
|
|
|
|
iot_common_bin_dump(data, len);
|
|
frm->hdr.hdr.data_len = frm->hdr.hdr.data_len + time_data->datalen;
|
|
frm->resv = GE_TYPE;
|
|
pkt_data = iot_pkt_put(data_pkt, pkt_len);
|
|
|
|
frm->tm_test.level = iot_plctxrx_get_node_level(frm->dest_mac);
|
|
if (frm->tm_test.level == -1) {
|
|
iot_cus_printf("[glpr][err] query level failed\n");
|
|
}
|
|
iot_delay_timer_get(&frm->tm_test.mcu_tx_time, CCO_TX_TIME, 0);
|
|
os_mem_cpy(pkt_data, data, sizeof(ge_frame_delay_time_subfn166_t));
|
|
os_mem_cpy(pkt_data + sizeof(ge_frame_delay_time_subfn166_t) +
|
|
time_data->datalen, data + sizeof(ge_frame_delay_time_subfn166_t),
|
|
sizeof(ge_frm_tail_t));
|
|
iot_cus_printf("delaytime with fill pkt_len = %d\n", pkt_len);
|
|
iot_proto_delay_time_send(data_pkt, local_mac, dst_mac);
|
|
return rpt2mcu;
|
|
|
|
cfm:
|
|
iot_proto_resp_cfm_frame(reason, dir, PROTO_GE_DELAY_TM_CMD,
|
|
frm->seq, frm->dest_mac);
|
|
return rpt2mcu;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_proto_delay_time_handler() - test delay time.
|
|
* @param data data which need to test
|
|
* @param len the data length
|
|
* @param dir the data received direction
|
|
* @retval: whether need report to mcu.
|
|
*/
|
|
bool_t iot_proto_delay_time_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
bool_t rpt2mcu = false;
|
|
|
|
if (CMD_LOCAL_DOWN_LINK == dir) {
|
|
rpt2mcu = iot_proto_delay_time_send_subfn_handler(data, len, dir);
|
|
} else {
|
|
rpt2mcu = iot_proto_delay_time_recv_subfn_handler(data, len, dir);
|
|
}
|
|
|
|
return rpt2mcu;
|
|
}
|
|
|
|
#endif /* end PLC_SUPPORT_STA_ROLE */
|
|
|
|
void iot_proto_cfm_cmd_group(void *buf, uint8_t cmd,
|
|
uint8_t result, uint8_t reason, uint8_t seq)
|
|
{
|
|
IOT_ASSERT(buf);
|
|
ge_frame_cmd_cfm_set_subfn20_t *cfm = (ge_frame_cmd_cfm_set_subfn20_t *)buf;
|
|
os_mem_set(cfm, 0, sizeof(*cfm));
|
|
cfm->cmd = cmd;
|
|
cfm->reason = reason;
|
|
cfm->result = result;
|
|
cfm->seq = seq;
|
|
|
|
EXT_FN_FRM_PREPARE(cfm, PROTO_GE_PLC_SET_CMD,
|
|
PROTO_CMD_CFM_CMD);
|
|
cfm->tail.check_sum =
|
|
ge_frm_checksum_calc((uint8_t *)cfm,
|
|
sizeof(*cfm) - sizeof(ge_frm_tail_t));
|
|
|
|
return;
|
|
}
|
|
|
|
bool_t iot_proto_cmd_cfm_subfn_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
bool_t rpt2mcu =false;
|
|
proto_cmd_hdl_state_t *sm = iot_proto_cmd_handle_state_get();
|
|
|
|
(void)dir;
|
|
(void)len;
|
|
ge_app_pib_info_t *p_flash = &prototask_contxt.flashinfo;
|
|
uint8_t need_save_flash = 0;
|
|
iot_cus_printf("[glpr] cmd_cfm: dir=%d, sm->dir=%d\n", dir, sm->dir);
|
|
|
|
switch (sm->dir) {
|
|
case CMD_LOCAL_UP_LINK:
|
|
{
|
|
plctxrx_cmd_resp_t *cmd = (plctxrx_cmd_resp_t *)data;
|
|
/* send to MCU */
|
|
iot_pkt_t *cmd_pkt = iot_pkt_alloc(sizeof(ge_frame_cmd_cfm_set_subfn20_t),
|
|
IOT_GREE_APP_MID);
|
|
uint8_t result = (0 == cmd->resp) ? 0 : 1;
|
|
IOT_ASSERT(cmd_pkt);
|
|
iot_pkt_put(cmd_pkt, sizeof(ge_frame_cmd_cfm_set_subfn20_t));
|
|
/* group cfm frame */
|
|
iot_proto_cfm_cmd_group(iot_pkt_data(cmd_pkt), sm->cur_subfn,
|
|
result, (uint8_t)cmd->resp, sm->seq);
|
|
iot_proto_send_to_mainboard(cmd_pkt);
|
|
|
|
if (result) {
|
|
/* switch cmd handle state to idle */
|
|
iot_proto_cmd_handle_state_init();
|
|
break;
|
|
}
|
|
|
|
if (sm->cur_subfn == PROTO_LEAVE_NW_SET_CMD) {
|
|
os_mem_set(prototask_contxt.cco_dev.mac, 0, IOT_MAC_ADDR_LEN);
|
|
os_mem_set(p_flash->public.pub.cco_mac, 0, IOT_MAC_ADDR_LEN);
|
|
need_save_flash = 1;
|
|
} else if (sm->cur_subfn == PROTO_LOCAL_MAC_SET_CMD) {
|
|
iot_mac_addr_cpy(p_flash->public.pub.local_mac,
|
|
prototask_contxt.local_dev.mac);
|
|
need_save_flash = 1;
|
|
}
|
|
/* switch cmd handle state to idle */
|
|
iot_proto_cmd_handle_state_init();
|
|
break;
|
|
}
|
|
case CMD_REMOTE_UP_LINK:
|
|
{
|
|
rpt2mcu = true;
|
|
ge_frame_cmd_cfm_set_subfn20_t *cfm_cmd =
|
|
(ge_frame_cmd_cfm_set_subfn20_t *)data;
|
|
switch (cfm_cmd->cmd) {
|
|
case PROTO_OP_WHITELIST_SET_CMD:
|
|
//case PROTO_PAIR_CFM_SET_CMD:
|
|
//case PROTO_CCO_START_GROUP_NET_CMD:
|
|
//case PROTO_CCO_END_GROUP_NET_CMD:
|
|
case PROTO_REBOOT_STA_CMD:
|
|
//case PROTO_UNPAIR_DEVS_CMD:
|
|
case PROTO_GE_GPIO_SET_CMD:
|
|
{
|
|
rpt2mcu = true;
|
|
cfm_cmd->seq = sm->seq;
|
|
/* switch cmd handle state to idle */
|
|
iot_proto_cmd_handle_state_init();
|
|
break;
|
|
}
|
|
#if 0
|
|
case PROTO_START_PAIR_CMD:
|
|
case PROTO_END_PAIR_CMD:
|
|
{
|
|
uint8_t dev_role = prototask_contxt.local_dev.dev_role;
|
|
rpt2mcu = prototask_contxt.pair_handler[dev_role](data,
|
|
len, dir, PROTO_CMD_CFM_CMD);
|
|
break;
|
|
}
|
|
#endif
|
|
default:
|
|
/* switch cmd handle state to idle */
|
|
iot_proto_cmd_handle_state_init();
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case CMD_REMOTE_DOWN_LINK:
|
|
{
|
|
plctxrx_cmd_resp_t *cmd = (plctxrx_cmd_resp_t *)data;
|
|
protpkt_tx_info_t txinfo = { 0 };
|
|
iot_pkt_t *cfm_pkt = NULL;
|
|
uint8_t result = (0 == cmd->resp)?0:1;
|
|
|
|
cfm_pkt = iot_pkt_alloc(sizeof(ge_frame_cmd_cfm_set_subfn20_t),
|
|
IOT_GREE_APP_MID);
|
|
IOT_ASSERT(cfm_pkt);
|
|
iot_pkt_put(cfm_pkt, sizeof(ge_frame_cmd_cfm_set_subfn20_t));
|
|
/* group cfm frame */
|
|
iot_proto_cfm_cmd_group(iot_pkt_data(cfm_pkt), sm->cur_subfn,
|
|
result, (uint8_t)cmd->resp, sm->seq);
|
|
/* CFM response to remote device */
|
|
iot_proto_fill_txinfo(&txinfo, 1, PLCTXRX_UNICAST, 3, 500, 1,
|
|
prototask_contxt.local_dev.mac, sm->dev.mac);
|
|
iot_proto_remote_cmd_send_to_plctxrx(iot_pkt_data(cfm_pkt),
|
|
sizeof(ge_frame_cmd_cfm_set_subfn20_t), &txinfo);
|
|
/* switch cmd handle state to idle */
|
|
iot_proto_cmd_handle_state_init();
|
|
|
|
if (cfm_pkt) {
|
|
iot_pkt_free(cfm_pkt);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (need_save_flash) {
|
|
iot_proto_flashsave(p_flash);
|
|
}
|
|
|
|
return rpt2mcu;
|
|
}
|
|
|
|
bool_t iot_proto_query_swver_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
(void)dir;
|
|
bool_t rpt2mcu = false;
|
|
proto_cmd_hdl_state_t *sm = iot_proto_cmd_handle_state_get();
|
|
iot_pkt_t *cmd_pkt;
|
|
ge_frame_fw_swver_query_subfn2_t *query_cmd =
|
|
(ge_frame_fw_swver_query_subfn2_t *)data;
|
|
plctxrx_cmd_arg_t cmd = { 0 };
|
|
ge_frame_fw_swver_resp_subfn2_t *resp_frm;
|
|
|
|
if (len != sizeof(ge_frame_fw_swver_query_subfn2_t)) {
|
|
iot_pkt_t *pkt =
|
|
iot_pkt_alloc(sizeof(ge_frame_fw_swver_resp_subfn2_t), IOT_GREE_APP_MID);
|
|
if (pkt == NULL) {
|
|
iot_cus_printf("[glpr][err]No Mem!\n");
|
|
return rpt2mcu;
|
|
}
|
|
resp_frm = (ge_frame_fw_swver_resp_subfn2_t *)iot_pkt_data(pkt);
|
|
iot_pkt_put(pkt, sizeof(*resp_frm));
|
|
|
|
os_mem_set(resp_frm, 0, sizeof(*resp_frm));
|
|
EXT_FN_FRM_PREPARE(resp_frm,
|
|
PROTO_GE_PLC_RESP_CMD, PROTO_FW_SWVER_RESP_CMD);
|
|
resp_frm->tail.check_sum =
|
|
ge_frm_checksum_calc((uint8_t *)resp_frm,
|
|
sizeof(*resp_frm) - sizeof(ge_frm_tail_t));
|
|
|
|
/* send to MCU */
|
|
iot_proto_send_to_mainboard(pkt);
|
|
|
|
iot_cus_printf("[glpr][err]%s cmd len mismatch\n",
|
|
"qurey software version");
|
|
return rpt2mcu;
|
|
}
|
|
|
|
cmd.cid.cid = PLCTXRX_CID_SWVER;
|
|
cmd.cid.opcode = PLCTXRX_OP_QUERY;
|
|
cmd.need_ack = true;
|
|
cmd.prio = 0;
|
|
cmd.dlen = 0;
|
|
/* alloc packet for sending cmd */
|
|
cmd_pkt = iot_pkt_alloc(sizeof(cmd)+cmd.dlen, IOT_GREE_APP_MID);
|
|
IOT_ASSERT(cmd_pkt);
|
|
iot_pkt_put(cmd_pkt, sizeof(cmd)+cmd.dlen);
|
|
/* copy plctxrx_cmd_arg_t */
|
|
os_mem_cpy(iot_pkt_data(cmd_pkt), &cmd, sizeof(cmd));
|
|
/* if async cmd, we need to set a state for response */
|
|
sm->state = PROTO_CMD_WAIT_SWVER_RESP;
|
|
sm->dir = CMD_LOCAL_UP_LINK;
|
|
sm->seq = query_cmd->seq;
|
|
/* send cmd to plctxrx layer */
|
|
iot_proto_cmd_send_to_plctxrx(cmd_pkt);
|
|
|
|
return rpt2mcu;
|
|
}
|
|
|
|
bool_t iot_proto_query_boot_info_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
(void)dir;
|
|
(void)data;
|
|
bool_t rpt2mcu = false;
|
|
proto_cmd_hdl_state_t *sm = iot_proto_cmd_handle_state_get();
|
|
iot_pkt_t *cmd_pkt;
|
|
ge_frame_bootinfo_query_subfn3_t *query_cmd =
|
|
(ge_frame_bootinfo_query_subfn3_t *)data;
|
|
plctxrx_cmd_arg_t cmd = { 0 };
|
|
ge_frame_sysinfo_resp_subfn3_t *resp_frm;
|
|
|
|
if (len != sizeof(ge_frame_bootinfo_query_subfn3_t)) {
|
|
iot_pkt_t *pkt =
|
|
iot_pkt_alloc(sizeof(ge_frame_sysinfo_resp_subfn3_t), IOT_GREE_APP_MID);
|
|
if (pkt == NULL) {
|
|
iot_cus_printf("[glpr][err]No Mem!\n");
|
|
return rpt2mcu;
|
|
}
|
|
resp_frm = (ge_frame_sysinfo_resp_subfn3_t *)iot_pkt_data(pkt);
|
|
iot_pkt_put(pkt, sizeof(*resp_frm));
|
|
|
|
os_mem_set(resp_frm, 0, sizeof(*resp_frm));
|
|
EXT_FN_FRM_PREPARE(resp_frm,
|
|
PROTO_GE_PLC_RESP_CMD, PROTO_BOOT_INFO_RESP_CMD);
|
|
resp_frm->tail.check_sum =
|
|
ge_frm_checksum_calc((uint8_t *)resp_frm,
|
|
sizeof(*resp_frm) - sizeof(ge_frm_tail_t));
|
|
|
|
/* send to MCU */
|
|
iot_proto_send_to_mainboard(pkt);
|
|
|
|
iot_cus_printf("[glpr][err]%s cmd len mismatch\n", "qurey boot info");
|
|
return rpt2mcu;
|
|
}
|
|
|
|
cmd.cid.cid = PLCTXRX_CID_BOOTINFO;
|
|
cmd.cid.opcode = PLCTXRX_OP_QUERY;
|
|
cmd.need_ack = true;
|
|
cmd.prio = 0;
|
|
cmd.dlen = 0;
|
|
/* alloc packet for sending cmd */
|
|
cmd_pkt = iot_pkt_alloc(sizeof(cmd)+cmd.dlen,IOT_GREE_APP_MID);
|
|
IOT_ASSERT(cmd_pkt);
|
|
iot_pkt_put(cmd_pkt, sizeof(cmd)+cmd.dlen);
|
|
/* copy plctxrx_cmd_arg_t */
|
|
os_mem_cpy(iot_pkt_data(cmd_pkt), &cmd, sizeof(cmd));
|
|
/* if async cmd, we need to set a state for response */
|
|
sm->state = PROTO_CMD_WAIT_BOOT_INFO_RESP;
|
|
sm->dir = CMD_LOCAL_UP_LINK;
|
|
sm->seq = query_cmd->seq;
|
|
/* send cmd to plctxrx layer */
|
|
iot_proto_cmd_send_to_plctxrx(cmd_pkt);
|
|
|
|
return rpt2mcu;
|
|
}
|
|
|
|
bool_t iot_proto_query_avail_nw_handler(uint8_t *data, uint16_t len,
|
|
transmit_direction_e_t dir)
|
|
{
|
|
(void)dir;
|
|
bool_t rpt2mcu = false;
|
|
|
|
proto_cmd_hdl_state_t *sm = iot_proto_cmd_handle_state_get();
|
|
iot_pkt_t *cmd_pkt;
|
|
ge_frame_avail_nw_query_subfn9_t *query_cmd =
|
|
(ge_frame_avail_nw_query_subfn9_t *)data;
|
|
ge_frame_avail_nw_resp_subfn9_t *resp_frm;
|
|
|
|
if (len != sizeof(ge_frame_avail_nw_query_subfn9_t)) {
|
|
iot_pkt_t *pkt =
|
|
iot_pkt_alloc(sizeof(ge_frame_avail_nw_resp_subfn9_t), IOT_GREE_APP_MID);
|
|
if (pkt == NULL) {
|
|
iot_cus_printf("[glpr][err]No Mem!\n");
|
|
return rpt2mcu;
|
|
}
|
|
resp_frm = (ge_frame_avail_nw_resp_subfn9_t *)iot_pkt_data(pkt);
|
|
iot_pkt_put(pkt, sizeof(*resp_frm));
|
|
|
|
os_mem_set(resp_frm, 0, sizeof(*resp_frm));
|
|
EXT_FN_FRM_PREPARE(resp_frm,
|
|
PROTO_GE_PLC_RESP_CMD, PROTO_AVAIL_NW_RESP_CMD);
|
|
resp_frm->tail.check_sum =
|
|
ge_frm_checksum_calc((uint8_t *)resp_frm,
|
|
sizeof(*resp_frm) - sizeof(ge_frm_tail_t));
|
|
|
|
/* send to MCU */
|
|
iot_proto_send_to_mainboard(pkt);
|
|
|
|
iot_cus_printf("[glpr][err]%s cmd len mismatch\n",
|
|
"qurey avail network");
|
|
return rpt2mcu;
|
|
}
|
|
|
|
plctxrx_cmd_arg_t cmd = { 0 };
|
|
cmd.cid.cid = PLCTXRX_CID_FIND_NETWORK;
|
|
cmd.cid.opcode = PLCTXRX_OP_QUERY;
|
|
cmd.need_ack = true;
|
|
cmd.prio = 0;
|
|
cmd.dlen = 0;
|
|
/* alloc packet for sending cmd */
|
|
cmd_pkt = iot_pkt_alloc(sizeof(cmd)+cmd.dlen,IOT_GREE_APP_MID);
|
|
IOT_ASSERT(cmd_pkt);
|
|
iot_pkt_put(cmd_pkt, sizeof(cmd)+cmd.dlen);
|
|
/* copy plctxrx_cmd_arg_t */
|
|
os_mem_cpy(iot_pkt_data(cmd_pkt), &cmd, sizeof(cmd));
|
|
/* if async cmd, we need to set a state for response */
|
|
sm->state = PROTO_CMD_WAIT_AVAIL_NETWORK_RESP;
|
|
sm->dir = CMD_LOCAL_UP_LINK;
|
|
sm->seq = query_cmd->seq;
|
|
/* send cmd to plctxrx layer */
|
|
iot_proto_cmd_send_to_plctxrx(cmd_pkt);
|
|
iot_cus_printf("[glpr]query avail nw send succ!\n");
|
|
|
|
return rpt2mcu;
|
|
}
|
|
|
|
bool_t iot_proto_query_tx_pwr_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
(void)dir;
|
|
|
|
bool_t rpt2mcu = false;
|
|
ge_frame_tx_pwr_query_subfn11_t *query_cmd = (ge_frame_tx_pwr_query_subfn11_t *)data;
|
|
proto_cmd_hdl_state_t *sm = iot_proto_cmd_handle_state_get();
|
|
iot_pkt_t *cmd_pkt;
|
|
ge_frame_tx_pwr_resp_subfn11_t *resp_frm;
|
|
|
|
if (len != sizeof(ge_frame_tx_pwr_query_subfn11_t)) {
|
|
iot_pkt_t *pkt =
|
|
iot_pkt_alloc(sizeof(ge_frame_tx_pwr_resp_subfn11_t), IOT_GREE_APP_MID);
|
|
if (pkt == NULL) {
|
|
iot_cus_printf("[glpr][err]No Mem!\n");
|
|
return rpt2mcu;
|
|
}
|
|
resp_frm = (ge_frame_tx_pwr_resp_subfn11_t *)iot_pkt_data(pkt);
|
|
iot_pkt_put(pkt, sizeof(*resp_frm));
|
|
|
|
os_mem_set(resp_frm, 0, sizeof(*resp_frm));
|
|
EXT_FN_FRM_PREPARE(resp_frm,
|
|
PROTO_GE_PLC_RESP_CMD, PROTO_TX_PWR_RESP_CMD);
|
|
resp_frm->tail.check_sum =
|
|
ge_frm_checksum_calc((uint8_t *)resp_frm,
|
|
sizeof(*resp_frm)-sizeof(ge_frm_tail_t));
|
|
/* send to MCU */
|
|
iot_proto_send_to_mainboard(pkt);
|
|
|
|
iot_cus_printf("[glpr][err]%s cmd len mismatch\n",
|
|
"qurey tx power");
|
|
return rpt2mcu;
|
|
}
|
|
/* send topo response to remote device */
|
|
plctxrx_cmd_arg_t cmd = { 0 };
|
|
cmd.cid.cid = PLCTXRX_CID_TX_PWR;
|
|
cmd.cid.opcode = PLCTXRX_OP_QUERY;
|
|
cmd.need_ack = true;
|
|
cmd.prio = 0;
|
|
/* SEQ: one byte */
|
|
cmd.dlen = 0;
|
|
/* alloc packet for sending cmd */
|
|
cmd_pkt = iot_pkt_alloc(sizeof(cmd), IOT_GREE_APP_MID);
|
|
IOT_ASSERT(cmd_pkt);
|
|
iot_pkt_put(cmd_pkt, sizeof(cmd));
|
|
/* copy plctxrx_cmd_arg_t */
|
|
os_mem_cpy(iot_pkt_data(cmd_pkt), &cmd, sizeof(cmd));
|
|
sm->state = PROTO_CMD_WAIT_TX_PWR_RESP;
|
|
sm->dir = CMD_LOCAL_UP_LINK;
|
|
sm->seq = query_cmd->seq;
|
|
/* send cmd to plctxrx layer */
|
|
iot_proto_cmd_send_to_plctxrx(cmd_pkt);
|
|
iot_cus_printf("[glpr]query_tx_pwr:query tx power cmd send succ!\n");
|
|
return rpt2mcu;
|
|
}
|
|
|
|
bool_t iot_proto_query_uart_thrpt_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
(void)dir;
|
|
bool_t rpt2mcu = false;
|
|
ge_frame_uart_thpt_resp_subfn12_t *resp_cmd;
|
|
ge_frame_uart0_thrpt_query_subfn12_t *query_cmd =
|
|
(ge_frame_uart0_thrpt_query_subfn12_t *)data;
|
|
|
|
iot_pkt_t *pkt =
|
|
iot_pkt_alloc(sizeof(ge_frame_uart_thpt_resp_subfn12_t), IOT_GREE_APP_MID);
|
|
if (pkt == NULL) {
|
|
iot_cus_printf("[glpr][err]No Mem!\n");
|
|
return rpt2mcu;
|
|
}
|
|
resp_cmd = (ge_frame_uart_thpt_resp_subfn12_t *)iot_pkt_data(pkt);
|
|
iot_pkt_put(pkt, sizeof(*resp_cmd));
|
|
|
|
os_mem_set(resp_cmd, 0, sizeof(*resp_cmd));
|
|
EXT_FN_FRM_PREPARE(resp_cmd,
|
|
PROTO_GE_PLC_RESP_CMD, PROTO_UART_THPT_RESP_CMD);
|
|
|
|
if (len == sizeof(ge_frame_uart0_thrpt_query_subfn12_t)) {
|
|
resp_cmd->seq = query_cmd->seq;
|
|
resp_cmd->recv_rate[0] = (uint8_t)(uart_thpt.recv_rate&0xFF);
|
|
resp_cmd->recv_rate[1] = (uint8_t)((uart_thpt.recv_rate>>8) & 0xFF );
|
|
resp_cmd->recv_rate[2] = (uint8_t)((uart_thpt.recv_rate>>16) & 0xFF );
|
|
|
|
resp_cmd->send_rate[0] = (uint8_t)(uart_thpt.send_rate&0xFF);
|
|
resp_cmd->send_rate[1] = (uint8_t)((uart_thpt.send_rate>>8) & 0xFF );
|
|
resp_cmd->send_rate[2] = (uint8_t)((uart_thpt.send_rate>>16) & 0xFF );
|
|
} else {
|
|
iot_cus_printf("[glpr][err]%s cmd len mismatch\n",
|
|
"qurey uart thoughput");
|
|
}
|
|
|
|
resp_cmd->tail.check_sum =
|
|
ge_frm_checksum_calc((uint8_t *)resp_cmd,
|
|
sizeof(*resp_cmd)-sizeof(ge_frm_tail_t));
|
|
|
|
/* send to MCU */
|
|
iot_proto_send_to_mainboard(pkt);
|
|
|
|
return rpt2mcu;
|
|
}
|
|
|
|
bool_t iot_proto_comm_fault_ind_subfn_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
(void)len;
|
|
bool_t rpt2mcu = false;
|
|
plctxrx_cmd_resp_t *cmd = (plctxrx_cmd_resp_t *)data;
|
|
/* only indication can report this message */
|
|
IOT_ASSERT(cmd->cid.opcode == PLCTXRX_OP_INDICATION);
|
|
|
|
switch (dir) {
|
|
case CMD_LOCAL_UP_LINK:
|
|
{
|
|
/* send to MCU */
|
|
ge_frame_comm_fault_rpt_set_subfn8_t *rpt_cmd;
|
|
plctxrx_cmd_comm_fault_ind_t *resp_cmd =
|
|
(plctxrx_cmd_comm_fault_ind_t*)cmd->data;
|
|
iot_pkt_t *cmd_pkt = iot_pkt_alloc(sizeof(ge_frame_comm_fault_rpt_set_subfn8_t),
|
|
IOT_GREE_APP_MID);
|
|
IOT_ASSERT(cmd_pkt);
|
|
rpt_cmd = (ge_frame_comm_fault_rpt_set_subfn8_t *)iot_pkt_data(cmd_pkt);
|
|
iot_pkt_put(cmd_pkt, sizeof(*rpt_cmd));
|
|
os_mem_set(rpt_cmd, 0, sizeof(*rpt_cmd));
|
|
rpt_cmd->type = resp_cmd->type;
|
|
rpt_cmd->seq = prototask_contxt.local_dev.ind_seq++;
|
|
rpt_cmd->reason = resp_cmd->reason;
|
|
EXT_FN_FRM_PREPARE(rpt_cmd,
|
|
PROTO_GE_PLC_SET_CMD, PROTO_COMM_FAULT_RPT_CMD);
|
|
rpt_cmd->tail.check_sum =
|
|
ge_frm_checksum_calc((uint8_t *)rpt_cmd,
|
|
sizeof(*rpt_cmd) - sizeof(ge_frm_tail_t));
|
|
iot_proto_send_to_mainboard(cmd_pkt);
|
|
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return rpt2mcu;
|
|
}
|
|
|
|
bool_t iot_proto_start_groupnet_subfn_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
bool_t rpt2mcu =false;
|
|
uint32_t reason = 0;
|
|
sta_dev_t *local_dev = &prototask_contxt.local_dev;
|
|
ge_frame_start_group_set_subfn13_t *frame = (ge_frame_start_group_set_subfn13_t*)data;
|
|
|
|
if (len != sizeof(ge_frame_start_group_set_subfn13_t)) {
|
|
reason = PROTO_REASON_LEN_MISSMATCH;
|
|
} else if (IOT_PLC_DEV_ROLE_CCO != local_dev->nw_role) {
|
|
reason = PROTO_REASON_NO_AUTHORITY;
|
|
} else if (IOT_PLC_DEV_ROLE_CCO != local_dev->nw_role &&
|
|
!prototask_contxt.local_dev.dev_ready) {
|
|
reason = PROTO_REASON_NOT_READY;
|
|
} else if (local_dev->nid != frame->nid) {
|
|
reason = PROTO_REASON_NID_MISSMATCH;
|
|
}
|
|
|
|
if (PROTO_REASON_OK != reason) {
|
|
iot_proto_resp_cfm_frame(reason,
|
|
dir, PROTO_CCO_START_GROUP_NET_CMD,
|
|
frame->seq, prototask_contxt.rx_info.mac);
|
|
iot_cus_printf("[glpr][err]Group start err:reason=%d\n", reason);
|
|
return rpt2mcu;
|
|
}
|
|
if (IOT_PLC_DEV_ROLE_CCO == local_dev->nw_role) {
|
|
iot_proto_cco_groupnet_sm(data, PROTO_CCO_START_GROUP_NET_CMD,
|
|
dir, NULL);
|
|
}
|
|
|
|
return rpt2mcu;
|
|
}
|
|
|
|
bool_t iot_proto_end_groupnet_subfn_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
bool_t rpt2mcu =false;
|
|
uint32_t reason = 0;
|
|
sta_dev_t *local_dev = &prototask_contxt.local_dev;
|
|
ge_frame_end_group_set_subfn14_t *frame = (ge_frame_end_group_set_subfn14_t*)data;
|
|
|
|
if (len != sizeof(ge_frame_end_group_set_subfn14_t)) {
|
|
reason = PROTO_REASON_LEN_MISSMATCH;
|
|
} else if (IOT_PLC_DEV_ROLE_CCO != local_dev->nw_role) {
|
|
reason = PROTO_REASON_NO_AUTHORITY;
|
|
} else if (IOT_PLC_DEV_ROLE_CCO != local_dev->nw_role &&
|
|
!prototask_contxt.local_dev.dev_ready) {
|
|
reason = PROTO_REASON_NOT_READY;
|
|
} else if (local_dev->nid != frame->nid) {
|
|
reason = PROTO_REASON_NID_MISSMATCH;
|
|
}
|
|
|
|
if (PROTO_REASON_OK != reason) {
|
|
iot_proto_resp_cfm_frame(reason,
|
|
dir, PROTO_CCO_END_GROUP_NET_CMD,
|
|
frame->seq, prototask_contxt.rx_info.mac);
|
|
iot_cus_printf("[glpr][err]Group end err:reason=%d\n", reason);
|
|
return rpt2mcu;
|
|
}
|
|
|
|
if (IOT_PLC_DEV_ROLE_CCO == local_dev->nw_role) {
|
|
iot_proto_cco_groupnet_sm(data,
|
|
PROTO_CCO_END_GROUP_NET_CMD, dir, NULL);
|
|
}
|
|
|
|
return rpt2mcu;
|
|
}
|
|
|
|
bool_t iot_proto_fw_swver_resp_subfn_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
(void)len;
|
|
bool_t rpt2mcu = false;
|
|
IOT_ASSERT(CMD_LOCAL_UP_LINK == dir);
|
|
iot_pkt_t *datapkt;
|
|
ge_frame_fw_swver_resp_subfn2_t *send_cmd;
|
|
proto_cmd_hdl_state_t* sm = iot_proto_cmd_handle_state_get();
|
|
plctxrx_cmd_resp_t *cmd = (plctxrx_cmd_resp_t *)data;
|
|
plctxrx_cmd_software_ver_resp_t *swver =
|
|
(plctxrx_cmd_software_ver_resp_t *)cmd->data;
|
|
|
|
/* group gree frame */
|
|
datapkt =
|
|
iot_pkt_alloc(sizeof(ge_frame_fw_swver_resp_subfn2_t), IOT_GREE_APP_MID);
|
|
IOT_ASSERT(datapkt);
|
|
|
|
iot_pkt_put(datapkt, sizeof(ge_frame_fw_swver_resp_subfn2_t));
|
|
|
|
send_cmd =
|
|
(ge_frame_fw_swver_resp_subfn2_t *)iot_pkt_data(datapkt);
|
|
|
|
os_mem_set(send_cmd, 0 ,sizeof(*send_cmd));
|
|
send_cmd->seq = sm->seq;
|
|
send_cmd->swver = swver->version;
|
|
EXT_FN_FRM_PREPARE(send_cmd,
|
|
PROTO_GE_PLC_RESP_CMD, PROTO_FW_SWVER_RESP_CMD);
|
|
send_cmd->tail.check_sum =
|
|
ge_frm_checksum_calc((uint8_t *)send_cmd,
|
|
sizeof(*send_cmd)-sizeof(ge_frm_tail_t));
|
|
|
|
/* switch back state to idle state */
|
|
iot_proto_cmd_handle_state_init();
|
|
|
|
/* send to MCU */
|
|
iot_proto_send_to_mainboard(datapkt);
|
|
|
|
return rpt2mcu;
|
|
|
|
}
|
|
|
|
bool_t iot_proto_boot_info_resp_subfn_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
(void)len;
|
|
bool_t rpt2mcu = false;
|
|
IOT_ASSERT(CMD_LOCAL_UP_LINK == dir);
|
|
iot_pkt_t *datapkt;
|
|
ge_frame_sysinfo_resp_subfn3_t *send_cmd;
|
|
proto_cmd_hdl_state_t* sm = iot_proto_cmd_handle_state_get();
|
|
plctxrx_cmd_resp_t *cmd = (plctxrx_cmd_resp_t *)data;
|
|
plctxrx_cmd_boot_info_resp_t *boot_info =
|
|
(plctxrx_cmd_boot_info_resp_t *)cmd->data;
|
|
|
|
/* group gree frame */
|
|
datapkt = iot_pkt_alloc(sizeof(*send_cmd), IOT_GREE_APP_MID);
|
|
IOT_ASSERT(datapkt);
|
|
|
|
iot_pkt_put(datapkt, sizeof(ge_frame_sysinfo_resp_subfn3_t));
|
|
|
|
send_cmd = (ge_frame_sysinfo_resp_subfn3_t *)iot_pkt_data(datapkt);
|
|
|
|
os_mem_set(send_cmd, 0, sizeof(*send_cmd));
|
|
send_cmd->seq = sm->seq;
|
|
send_cmd->boot_cnt = (uint16_t)boot_info->total_boot_cnt;
|
|
send_cmd->last_boot_reason = boot_info->last_reboot_reason;
|
|
send_cmd->run_time = boot_info->os_running_time;
|
|
EXT_FN_FRM_PREPARE(send_cmd,
|
|
PROTO_GE_PLC_RESP_CMD, PROTO_BOOT_INFO_RESP_CMD);
|
|
send_cmd->tail.check_sum = ge_frm_checksum_calc((uint8_t *)send_cmd,
|
|
sizeof(*send_cmd) - sizeof(ge_frm_tail_t));
|
|
|
|
/* switch back state to idle state ASAP */
|
|
iot_proto_cmd_handle_state_init();
|
|
|
|
/* send to MCU */
|
|
iot_proto_send_to_mainboard(datapkt);
|
|
|
|
return rpt2mcu;
|
|
}
|
|
|
|
bool_t iot_proto_avail_nw_resp_subfn_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
(void)len;
|
|
(void)dir;
|
|
bool_t rpt2mcu = false;
|
|
proto_cmd_hdl_state_t* sm = iot_proto_cmd_handle_state_get();
|
|
plctxrx_cmd_resp_t *cmd = (plctxrx_cmd_resp_t *)data;
|
|
plctxrx_cmd_network_t *net_info = (plctxrx_cmd_network_t*)cmd->data;
|
|
plctxrx_cmd_network_info_t *node =
|
|
(plctxrx_cmd_network_info_t *)net_info->node;
|
|
|
|
proto_neighbor_info_t *nb_node = prototask_contxt.neighbor_nw.node;
|
|
|
|
uint16_t frame_cnt = (net_info->count > 0) ? net_info->count : 1;
|
|
uint16_t size;
|
|
uint8_t joined_flag = 0;
|
|
uint16_t i;
|
|
|
|
if (prototask_contxt.local_dev.dev_ready) {
|
|
joined_flag = 1;
|
|
if (net_info->count > 0) {
|
|
frame_cnt++;
|
|
}
|
|
}
|
|
size = sizeof(ge_frame_avail_nw_resp_subfn9_t) * frame_cnt;
|
|
|
|
iot_pkt_t *data_pkt = iot_pkt_alloc(size, IOT_GREE_APP_MID);
|
|
IOT_ASSERT(data_pkt);
|
|
ge_frame_avail_nw_resp_subfn9_t *frame =
|
|
(ge_frame_avail_nw_resp_subfn9_t *)iot_pkt_data(data_pkt);
|
|
|
|
iot_pkt_put(data_pkt, size);
|
|
if (net_info->count > 0 || joined_flag == 1) {
|
|
prototask_contxt.neighbor_nw.count = net_info->count;
|
|
os_mem_set(prototask_contxt.neighbor_nw.node, 0,
|
|
sizeof(*nb_node) * PROTO_SUPPORT_MAX_NEIGHBOR_NET);
|
|
if (joined_flag) {
|
|
os_mem_set(frame, 0, sizeof(*frame));
|
|
frame->nid = prototask_contxt.local_dev.nid;
|
|
frame->seq = sm->seq;
|
|
frame->total_cnt = (uint8_t)frame_cnt;
|
|
frame->cur_cnt = 1;
|
|
frame->snr = 0;
|
|
if (IOT_PLC_DEV_ROLE_CCO == prototask_contxt.local_dev.nw_role) {
|
|
iot_mac_addr_cpy(frame->mac, prototask_contxt.local_dev.mac);
|
|
} else {
|
|
iot_mac_addr_cpy(frame->mac, prototask_contxt.cco_dev.mac);
|
|
}
|
|
|
|
EXT_FN_FRM_PREPARE(frame, PROTO_GE_PLC_RESP_CMD,
|
|
PROTO_AVAIL_NW_RESP_CMD);
|
|
frame->tail.check_sum = ge_frm_checksum_calc((uint8_t *)(frame),
|
|
sizeof(*frame) - sizeof(ge_frm_tail_t));
|
|
}
|
|
for (i = 0; i < net_info->count; i++) {
|
|
/* update the neighbor network info in local */
|
|
iot_mac_addr_cpy((nb_node + i)->mac, (node + i)->mac);
|
|
(nb_node + i)->nid = (uint8_t)((node + i)->nid & 0xFF);
|
|
(nb_node + i)->best_snr = (uint8_t)(node + i)->snr;
|
|
|
|
iot_cus_printf("[glpr]avail_nw_resp_subfn_handler:nw[%d]"
|
|
"report mac[%2x:%2x:%2x:%2x:%2x:%2x]\n",
|
|
(nb_node+i)->nid, (nb_node+i)->mac[0],
|
|
(nb_node+i)->mac[1], (nb_node+i)->mac[2],
|
|
(nb_node+i)->mac[3], (nb_node+i)->mac[4], (nb_node+i)->mac[5]);
|
|
|
|
os_mem_set(frame + i + joined_flag, 0, sizeof(*frame));
|
|
(frame + i + joined_flag)->nid = (uint8_t)((node + i)->nid & 0xFF);
|
|
(frame + i + joined_flag)->seq = sm->seq;
|
|
(frame + i + joined_flag)->total_cnt = (uint8_t)frame_cnt;
|
|
(frame + i + joined_flag)->cur_cnt = (uint8_t)(i + 1 + joined_flag);
|
|
(frame + i + joined_flag)->snr = (uint8_t)(node + i)->snr;
|
|
iot_mac_addr_cpy((frame + i + joined_flag)->mac, (node + i)->mac);
|
|
|
|
EXT_FN_FRM_PREPARE((frame + i + joined_flag),
|
|
PROTO_GE_PLC_RESP_CMD, PROTO_AVAIL_NW_RESP_CMD);
|
|
(frame + i + joined_flag)->tail.check_sum =
|
|
ge_frm_checksum_calc((uint8_t *)(frame + i + joined_flag),
|
|
sizeof(*(frame + i + joined_flag)) - sizeof(ge_frm_tail_t));
|
|
}
|
|
} else {
|
|
os_mem_set(frame, 0, sizeof(*frame));
|
|
frame->seq = sm->seq;
|
|
|
|
EXT_FN_FRM_PREPARE(frame,
|
|
PROTO_GE_PLC_RESP_CMD, PROTO_AVAIL_NW_RESP_CMD);
|
|
frame->tail.check_sum =
|
|
ge_frm_checksum_calc((uint8_t *)frame,
|
|
sizeof(*frame) - sizeof(ge_frm_tail_t));
|
|
}
|
|
/* report topo to MCU */
|
|
iot_proto_send_to_mainboard(data_pkt);
|
|
/* switch back state to idle state */
|
|
iot_proto_cmd_handle_state_init();
|
|
|
|
return rpt2mcu;
|
|
}
|
|
|
|
bool_t iot_proto_tx_power_resp_subfn_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
(void)dir;
|
|
(void)len;
|
|
(void)dir;
|
|
bool_t rpt2mcu = false;
|
|
uint16_t size;
|
|
proto_cmd_hdl_state_t *sm = iot_proto_cmd_handle_state_get();
|
|
plctxrx_cmd_resp_t *cmd = (plctxrx_cmd_resp_t *)data;
|
|
|
|
plctxrx_cmd_tx_pwr_t *tx_pwr_info = (plctxrx_cmd_tx_pwr_t*)cmd->data;
|
|
|
|
ge_frame_tx_pwr_resp_subfn11_t *frame;
|
|
size = sizeof(ge_frame_tx_pwr_resp_subfn11_t);
|
|
|
|
iot_pkt_t *data_pkt = iot_pkt_alloc(size, IOT_GREE_APP_MID);
|
|
IOT_ASSERT(data_pkt);
|
|
frame = (ge_frame_tx_pwr_resp_subfn11_t *)iot_pkt_data(data_pkt);
|
|
iot_pkt_put(data_pkt,size);
|
|
|
|
os_mem_set(frame, 0, sizeof(*frame));
|
|
frame->seq = sm->seq;
|
|
if (cmd->resp == PLCTXRX_RESP_ERROR) {
|
|
frame->tx_pwr = 0;
|
|
} else {
|
|
frame->tx_pwr = tx_pwr_info->tx_pwr;
|
|
}
|
|
EXT_FN_FRM_PREPARE(frame, PROTO_GE_PLC_RESP_CMD, PROTO_TX_PWR_RESP_CMD);
|
|
frame->tail.check_sum = ge_frm_checksum_calc((uint8_t *)frame,
|
|
sizeof(*frame)-sizeof(ge_frm_tail_t));
|
|
/* report topo to MCU */
|
|
iot_proto_send_to_mainboard(data_pkt);
|
|
/* switch back state to idle state */
|
|
iot_proto_cmd_handle_state_init();
|
|
|
|
return rpt2mcu;
|
|
|
|
}
|
|
|
|
bool_t iot_proto_ntb_resp_subfn_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
(void)dir;
|
|
(void)len;
|
|
bool_t rpt2mcu = false;
|
|
proto_cmd_hdl_state_t *sm = iot_proto_cmd_handle_state_get();
|
|
plctxrx_cmd_resp_t *cmd = (plctxrx_cmd_resp_t *)data;
|
|
|
|
plctxrx_cmd_ntb_resp_t *ntb_info = (plctxrx_cmd_ntb_resp_t*)cmd->data;
|
|
|
|
ge_frame_ntb_resp_subfn19_t *frame;
|
|
|
|
iot_pkt_t *data_pkt = iot_pkt_alloc(sizeof(*frame), IOT_GREE_APP_MID);
|
|
IOT_ASSERT(data_pkt);
|
|
frame = (ge_frame_ntb_resp_subfn19_t *)iot_pkt_data(data_pkt);
|
|
iot_pkt_put(data_pkt, sizeof(*frame));
|
|
|
|
os_mem_set(frame, 0, sizeof(*frame));
|
|
frame->seq = sm->seq;
|
|
frame->ntb = ntb_info->ntb;
|
|
EXT_FN_FRM_PREPARE(frame, PROTO_GE_PLC_RESP_CMD, PROTO_NTB_RESP_CMD);
|
|
frame->tail.check_sum = ge_frm_checksum_calc((uint8_t *)frame,
|
|
sizeof(*frame) - sizeof(ge_frm_tail_t));
|
|
/* report ntb to MCU */
|
|
iot_proto_send_to_mainboard(data_pkt);
|
|
/* switch back state to idle state */
|
|
iot_proto_cmd_handle_state_init();
|
|
|
|
return rpt2mcu;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_proto_node_info_report() - report node information
|
|
* handler
|
|
* @param data data which need to report
|
|
* @param dlen the data length
|
|
* @param total_cnt report information total count
|
|
* @param cur_cnt current time report information count
|
|
* @param type the node information type report
|
|
* @param done the node information report done
|
|
*/
|
|
void iot_proto_node_info_report(uint8_t *data, uint16_t dlen,
|
|
uint16_t total_cnt, uint16_t cur_cnt, uint8_t type, uint8_t done)
|
|
{
|
|
proto_cmd_hdl_state_t *sm = iot_proto_cmd_handle_state_get();
|
|
ge_frame_node_info_resp_subfn23_t *frame;
|
|
ge_frm_tail_t *tail;
|
|
uint8_t resp_len = (uint8_t)(sizeof(ge_frame_node_info_resp_subfn23_t) +
|
|
dlen + sizeof(ge_frm_tail_t));
|
|
iot_pkt_t *data_pkt = iot_pkt_alloc(resp_len, IOT_GREE_APP_MID);
|
|
|
|
if (NULL == data_pkt) {
|
|
iot_cus_printf("[glpr] alloc pkt error\n");
|
|
IOT_ASSERT(0);
|
|
return;
|
|
}
|
|
frame = (ge_frame_node_info_resp_subfn23_t *)iot_pkt_data(data_pkt);
|
|
iot_pkt_put(data_pkt, resp_len);
|
|
os_mem_set(frame, 0, sizeof(ge_frame_node_info_resp_subfn23_t));
|
|
frame->hdr.hdr.preamble = GE_FRM_PREAMBLE_CODE;
|
|
frame->hdr.hdr.data_len = resp_len - GE_FRM_MIN_LEN;
|
|
frame->hdr.hdr.fn = PROTO_GE_PLC_RESP_CMD;
|
|
frame->hdr.subfn = PROTO_NODE_INFO_RESP_CMD;
|
|
frame->seq = sm->seq;
|
|
frame->type = type;
|
|
|
|
if (data && dlen > 0) {
|
|
frame->total_cnt = total_cnt;
|
|
frame->cur_cnt = (uint8_t)cur_cnt;
|
|
frame->index = (uint8_t)((prototask_contxt.topo_resp_index +
|
|
QUERY_NODE_INFO_MAX_CNT_ONCE - 1) / QUERY_NODE_INFO_MAX_CNT_ONCE);
|
|
os_mem_cpy(frame->info, data, dlen);
|
|
}
|
|
prototask_contxt.topo_resp_index += cur_cnt;
|
|
|
|
tail = (ge_frm_tail_t *)(frame->info + dlen);
|
|
tail->check_sum = ge_frm_checksum_calc((uint8_t *)frame,
|
|
sizeof(ge_frame_node_info_resp_subfn23_t) + dlen);
|
|
tail->tail = GE_FRM_TAIL_CODE;
|
|
/* switch back state to idle state */
|
|
if (done) {
|
|
prototask_contxt.topo_resp_index = 0;
|
|
iot_proto_cmd_handle_state_init();
|
|
}
|
|
/* report node info to MCU */
|
|
iot_proto_send_to_mainboard(data_pkt);
|
|
}
|
|
|
|
/**
|
|
* @brief iot_proto_nw_info_report() - report network information
|
|
* @param max_level network max level
|
|
* @param data network level information data which need to report
|
|
* @param dlen the data length
|
|
*/
|
|
void iot_proto_nw_info_report(uint8_t max_level, uint8_t *data, uint8_t length)
|
|
{
|
|
proto_cmd_hdl_state_t *sm = iot_proto_cmd_handle_state_get();
|
|
ge_frame_nw_info_resp_subfn24_t *frame;
|
|
ge_frm_tail_t *tail;
|
|
uint8_t resp_len = sizeof(ge_frame_nw_info_resp_subfn24_t) + length +
|
|
sizeof(ge_frm_tail_t);
|
|
iot_pkt_t * data_pkt = iot_pkt_alloc(resp_len, IOT_GREE_APP_MID);
|
|
|
|
if (NULL == data_pkt) {
|
|
iot_cus_printf("[glpr] alloc pkt error\n");
|
|
return;
|
|
}
|
|
frame = (ge_frame_nw_info_resp_subfn24_t *)iot_pkt_data(data_pkt);
|
|
iot_pkt_put(data_pkt, resp_len);
|
|
os_mem_set(frame, 0, sizeof(ge_frame_nw_info_resp_subfn24_t));
|
|
frame->hdr.hdr.preamble = GE_FRM_PREAMBLE_CODE;
|
|
frame->hdr.hdr.data_len = resp_len - GE_FRM_MIN_LEN;
|
|
frame->hdr.hdr.fn = PROTO_GE_PLC_RESP_CMD;
|
|
frame->hdr.subfn = PROTO_NW_INFO_RESP_CMD;
|
|
frame->seq = sm->seq;
|
|
if (data && length > 0) {
|
|
frame->max_level = max_level;
|
|
os_mem_cpy(frame->level_info, data, length);
|
|
}
|
|
|
|
tail = (ge_frm_tail_t *)(frame->level_info + length);
|
|
tail->check_sum = ge_frm_checksum_calc((uint8_t *)frame,
|
|
sizeof(ge_frame_nw_info_resp_subfn24_t) + length);
|
|
tail->tail = GE_FRM_TAIL_CODE;
|
|
/* report network info to MCU */
|
|
iot_proto_send_to_mainboard(data_pkt);
|
|
/* switch back state to idle state */
|
|
iot_proto_cmd_handle_state_init();
|
|
}
|
|
|
|
/**
|
|
* @brief iot_proto_node_info_resp_subfn_handler() - report node infomation
|
|
* handler
|
|
* @param data data which need to report
|
|
* @param len the data length
|
|
* @param dir the data received direction
|
|
* @retval: whether need report to mcu.
|
|
*/
|
|
bool_t iot_proto_node_info_resp_subfn_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
(void)dir;
|
|
(void)len;
|
|
plctxrx_cmd_resp_t *cmd = (plctxrx_cmd_resp_t *)data;
|
|
iot_proto_node_info_report(cmd->data, cmd->dlen, cmd->index.total,
|
|
cmd->index.current, (uint8_t)cmd->resv, cmd->done);
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_proto_nw_info_resp_subfn_handler() - report network infomation
|
|
* handler
|
|
* @param data data which need to report
|
|
* @param len the data length
|
|
* @param dir the data received direction
|
|
* @retval: whether need report to mcu.
|
|
*/
|
|
bool_t iot_proto_nw_info_resp_subfn_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
(void)dir;
|
|
(void)len;
|
|
bool_t rpt2mcu = false;
|
|
plctxrx_cmd_resp_t *cmd = (plctxrx_cmd_resp_t *)data;
|
|
iot_plc_nw_info_query_rpt_t *nw_info =
|
|
(iot_plc_nw_info_query_rpt_t*)cmd->data;
|
|
uint8_t data_len = sizeof(iot_plc_nw_level_info_t) * nw_info->max_level;
|
|
|
|
iot_proto_nw_info_report(nw_info->max_level,
|
|
(uint8_t*)nw_info->nw_level_info, data_len);
|
|
|
|
return rpt2mcu;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_proto_gpio_resp_subfn_handler() - response gpio info.
|
|
* @param data data which need to resp
|
|
* @param len the data length
|
|
* @param dir the data received direction
|
|
* @retval: whether need report to mcu.
|
|
*/
|
|
bool_t iot_proto_gpio_resp_subfn_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
(void)len;
|
|
(void)dir;
|
|
bool_t rpt2mcu = false;
|
|
|
|
ge_frame_query_gpio_resp_subfn27_t *frame =
|
|
(ge_frame_query_gpio_resp_subfn27_t *)data;
|
|
|
|
if (iot_mac_addr_cmp(frame->dest_mac, prototask_contxt.local_dev.mac)) {
|
|
/* resp gpio info to uart */
|
|
iot_pkt_t *pkt = NULL;
|
|
uint8_t *data_ptr = NULL;
|
|
uint16_t data_len = sizeof(*frame);
|
|
|
|
pkt = iot_pkt_alloc(data_len, IOT_GREE_APP_MID);
|
|
data_ptr = (uint8_t*)iot_pkt_put(pkt, data_len);
|
|
os_mem_cpy(data_ptr, (uint8_t*)frame, data_len);
|
|
iot_proto_send_to_mainboard(pkt);
|
|
iot_proto_cmd_handle_state_init();
|
|
}
|
|
return rpt2mcu;
|
|
}
|
|
|
|
bool_t iot_proto_fb_bitmap_resp_subfn_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
(void)dir;
|
|
(void)len;
|
|
bool_t rpt2mcu = false;
|
|
uint8_t row = 0, col = 0;
|
|
proto_cmd_hdl_state_t *sm = iot_proto_cmd_handle_state_get();
|
|
plctxrx_cmd_resp_t *cmd = (plctxrx_cmd_resp_t *)data;
|
|
|
|
plctxrx_cmd_fb_bitmap_resp_t *bitmap_info =
|
|
(plctxrx_cmd_fb_bitmap_resp_t*)cmd->data;
|
|
|
|
ge_frame_fb_bitmap_resp_subfn20_t *frame;
|
|
|
|
iot_pkt_t *data_pkt = iot_pkt_alloc(sizeof(*frame), IOT_GREE_APP_MID);
|
|
IOT_ASSERT(data_pkt);
|
|
frame = (ge_frame_fb_bitmap_resp_subfn20_t *)iot_pkt_data(data_pkt);
|
|
iot_pkt_put(data_pkt, sizeof(*frame));
|
|
|
|
os_mem_set(frame, 0, sizeof(*frame));
|
|
frame->seq = sm->seq;
|
|
/* band id idx is less than 16 */
|
|
#define IOT_GE_BITMAP_COL_MAX 8
|
|
for (row = 0; row < sizeof(uint16_t); row++) {
|
|
for (col = 0; col < IOT_GE_BITMAP_COL_MAX; col++) {
|
|
if (((bitmap_info->fb_bitmap[row] & (1 << col)) >> col != 0)) {
|
|
frame->bitmap |= 1 << (row*IOT_GE_BITMAP_COL_MAX+col);
|
|
}
|
|
}
|
|
}
|
|
frame->is_scan_bitmap = bitmap_info->is_scan_bitmap;
|
|
EXT_FN_FRM_PREPARE(frame, PROTO_GE_PLC_RESP_CMD,
|
|
PROTO_FB_BITMAP_RESP_CMD);
|
|
frame->tail.check_sum = ge_frm_checksum_calc((uint8_t *)frame,
|
|
sizeof(*frame) - sizeof(ge_frm_tail_t));
|
|
/* report bitmap to MCU */
|
|
iot_proto_send_to_mainboard(data_pkt);
|
|
/* switch back state to idle state */
|
|
iot_proto_cmd_handle_state_init();
|
|
|
|
return rpt2mcu;
|
|
}
|
|
|
|
bool_t iot_proto_fix_rate_mode_resp_subfn_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
(void)dir;
|
|
(void)len;
|
|
bool_t rpt2mcu = false;
|
|
proto_cmd_hdl_state_t *sm = iot_proto_cmd_handle_state_get();
|
|
plctxrx_cmd_resp_t *cmd = (plctxrx_cmd_resp_t *)data;
|
|
|
|
plctxrx_cmd_fix_rate_mode_resp_t *fix_rate_mode =
|
|
(plctxrx_cmd_fix_rate_mode_resp_t*)cmd->data;
|
|
|
|
ge_frame_fix_rate_mode_resp_subfn21_t *frame;
|
|
|
|
iot_pkt_t *data_pkt = iot_pkt_alloc(sizeof(*frame), IOT_GREE_APP_MID);
|
|
IOT_ASSERT(data_pkt);
|
|
frame = (ge_frame_fix_rate_mode_resp_subfn21_t *)iot_pkt_data(data_pkt);
|
|
iot_pkt_put(data_pkt, sizeof(*frame));
|
|
|
|
os_mem_set(frame, 0, sizeof(*frame));
|
|
frame->seq = sm->seq;
|
|
frame->enable = fix_rate_mode->enable;
|
|
EXT_FN_FRM_PREPARE(frame, PROTO_GE_PLC_RESP_CMD,
|
|
PROTO_FIX_RATE_MODE_RESP_CMD);
|
|
frame->tail.check_sum = ge_frm_checksum_calc((uint8_t *)frame,
|
|
sizeof(*frame) - sizeof(ge_frm_tail_t));
|
|
/* report fix rate to MCU */
|
|
iot_proto_send_to_mainboard(data_pkt);
|
|
/* switch back state to idle state */
|
|
iot_proto_cmd_handle_state_init();
|
|
|
|
return rpt2mcu;
|
|
}
|
|
|
|
bool_t iot_proto_work_band_resp_subfn_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
(void)dir;
|
|
(void)len;
|
|
bool_t rpt2mcu = false;
|
|
proto_cmd_hdl_state_t *sm = iot_proto_cmd_handle_state_get();
|
|
plctxrx_cmd_resp_t *cmd = (plctxrx_cmd_resp_t *)data;
|
|
|
|
plctxrx_cmd_band_info_t *resp_band_info =
|
|
(plctxrx_cmd_band_info_t*)cmd->data;
|
|
|
|
ge_frame_work_band_resp_subfn22_t *frame;
|
|
|
|
iot_pkt_t *data_pkt = iot_pkt_alloc(sizeof(*frame), IOT_GREE_APP_MID);
|
|
IOT_ASSERT(data_pkt);
|
|
frame = (ge_frame_work_band_resp_subfn22_t *)iot_pkt_data(data_pkt);
|
|
iot_pkt_put(data_pkt, sizeof(*frame));
|
|
|
|
os_mem_set(frame, 0, sizeof(*frame));
|
|
frame->seq = sm->seq;
|
|
frame->band = resp_band_info->band_id;
|
|
EXT_FN_FRM_PREPARE(frame, PROTO_GE_PLC_RESP_CMD,
|
|
PROTO_WORK_BAND_RESP_CMD);
|
|
frame->tail.check_sum = ge_frm_checksum_calc((uint8_t *)frame,
|
|
sizeof(*frame) - sizeof(ge_frm_tail_t));
|
|
/* report work band to MCU */
|
|
iot_proto_send_to_mainboard(data_pkt);
|
|
/* switch back state to idle state */
|
|
iot_proto_cmd_handle_state_init();
|
|
|
|
return rpt2mcu;
|
|
}
|
|
|
|
/* Timout handler for querying white list or pair table. */
|
|
void iot_proto_wl_pt_remote_query_timeout_from_mcu(uint32_t state)
|
|
{
|
|
ge_frame_wl_resp_subfn7_t *p_whitelist_resp;
|
|
iot_pkt_t *p_pkt;
|
|
|
|
proto_cmd_hdl_state_t *sm = iot_proto_cmd_handle_state_get();
|
|
|
|
iot_cus_printf("[glpr]wlist ptable rmt %s timeout.\n", "query");
|
|
|
|
if (PROTO_CMD_WAIT_RMT_WHITELIST_RESP == state) {
|
|
p_pkt = iot_pkt_alloc(sizeof(*p_whitelist_resp), IOT_GREE_APP_MID);
|
|
if (!p_pkt)
|
|
return;
|
|
p_whitelist_resp = (ge_frame_wl_resp_subfn7_t *)iot_pkt_put
|
|
(p_pkt, sizeof(*p_whitelist_resp));
|
|
os_mem_set(p_whitelist_resp, 0x00, sizeof(*p_whitelist_resp));
|
|
EXT_FN_FRM_PREPARE(p_whitelist_resp,
|
|
PROTO_GE_PLC_RESP_CMD, PROTO_WHITELIST_RESP_CMD);
|
|
p_whitelist_resp->cco_flag = 0x01;
|
|
p_whitelist_resp->seq = sm->seq;
|
|
p_whitelist_resp->tail.check_sum = ge_frm_checksum_calc
|
|
((uint8_t *)p_whitelist_resp,
|
|
sizeof(*p_whitelist_resp) - sizeof(ge_frm_tail_t));
|
|
iot_proto_send_to_mainboard(p_pkt);
|
|
}
|
|
return;
|
|
}
|
|
|
|
/* send topo resp timeout to mcu */
|
|
void iot_proto_wait_rmt_topo_resp_timeout(proto_cmd_hdl_state_t *sm)
|
|
{
|
|
ge_frame_topo_resp_subfn5_t *frame;
|
|
uint16_t resp_len = 0;
|
|
ge_frm_tail_t *tail = NULL;
|
|
uint16_t topo_info_len = 0;
|
|
iot_pkt_t *rsp_data;
|
|
(void)sm;
|
|
|
|
switch (prototask_contxt.topo_info_type) {
|
|
case TOPO_INFO_TYPE_V0:
|
|
topo_info_len = sizeof(topo_info_v0_t);
|
|
break;
|
|
case TOPO_INFO_TYPE_V1:
|
|
topo_info_len = sizeof(topo_info_v1_t);
|
|
break;
|
|
default:
|
|
iot_cus_printf("[glpr][err]topo resp timeout error with type[%d]\n",
|
|
prototask_contxt.topo_info_type);
|
|
return;
|
|
}
|
|
|
|
resp_len = sizeof(ge_frame_topo_resp_subfn5_t) + topo_info_len +
|
|
sizeof(ge_frm_tail_t);
|
|
|
|
rsp_data = iot_pkt_alloc(resp_len, IOT_GREE_APP_MID);
|
|
IOT_ASSERT(rsp_data);
|
|
frame = (ge_frame_topo_resp_subfn5_t *)iot_pkt_data(rsp_data);
|
|
iot_pkt_put(rsp_data, resp_len);
|
|
os_mem_set(frame, 0, resp_len);
|
|
frame->type = prototask_contxt.topo_info_type;
|
|
GE_FRM_HDR_PREPARE(frame, PROTO_GE_PLC_RESP_CMD, PROTO_TOPO_RESP_CMD,
|
|
resp_len);
|
|
tail = (ge_frm_tail_t *)(frame->info + topo_info_len);
|
|
tail->check_sum = ge_frm_checksum_calc((uint8_t *)frame,
|
|
resp_len - sizeof(ge_frm_tail_t));
|
|
tail->tail = GE_FRM_TAIL_CODE;
|
|
iot_proto_send_to_mainboard(rsp_data);
|
|
}
|
|
|
|
bool_t iot_proto_cco_state_ind_subfn_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
(void)dir;
|
|
(void)len;
|
|
bool_t rpt2mcu = false;
|
|
iot_pkt_t *datapkt = NULL;
|
|
ge_frame_cco_stat_ind_set_subfn21_t* ind_frm;
|
|
|
|
plctxrx_cmd_resp_t *cmd = (plctxrx_cmd_resp_t *)data;
|
|
plctxrx_cmd_cco_sta_ind_t *state =
|
|
(plctxrx_cmd_cco_sta_ind_t *)cmd->data;
|
|
/* modify local device ready state */
|
|
prototask_contxt.local_dev.dev_ready = state->dev_ready;
|
|
|
|
/* save local nid in cco role */
|
|
prototask_contxt.local_dev.nid = state->nid;
|
|
|
|
iot_cus_printf("[glpr]state_ind:ready=%d\n", state->dev_ready);
|
|
|
|
datapkt = iot_pkt_alloc(sizeof(ge_frame_cco_stat_ind_set_subfn21_t),
|
|
IOT_GREE_APP_MID);
|
|
IOT_ASSERT(datapkt);
|
|
iot_pkt_put(datapkt, sizeof(ge_frame_cco_stat_ind_set_subfn21_t));
|
|
|
|
ind_frm = (ge_frame_cco_stat_ind_set_subfn21_t *)iot_pkt_data(datapkt);
|
|
|
|
os_mem_set(ind_frm, 0 ,sizeof(ge_frame_cco_stat_ind_set_subfn21_t));
|
|
EXT_FN_FRM_PREPARE(ind_frm,
|
|
PROTO_GE_PLC_SET_CMD, PROTO_CMD_CCO_STAT_IND_CMD);
|
|
|
|
ind_frm->ready = state->dev_ready;
|
|
ind_frm->nid = state->nid;
|
|
ind_frm->seq = prototask_contxt.local_dev.ind_seq++;
|
|
ind_frm->tail.check_sum =
|
|
ge_frm_checksum_calc((uint8_t *)ind_frm,
|
|
sizeof(*ind_frm)-sizeof(ge_frm_tail_t));
|
|
/* report cco stated network event to MCU */
|
|
iot_proto_send_to_mainboard(datapkt);
|
|
|
|
#if IOT_GE_PAGING_ENABLE
|
|
if (!os_is_timer_active(prototask_contxt.paging_timer)) {
|
|
os_start_timer(prototask_contxt.paging_timer,
|
|
PROTO_TMR_PAGING_TIMEOUT_INTVL);
|
|
}
|
|
#endif
|
|
|
|
return rpt2mcu;
|
|
}
|
|
|
|
bool_t iot_proto_set_join_nw_subfn_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
(void)dir;
|
|
bool_t rpt2mcu = false;
|
|
iot_pkt_t *cmd_pkt;
|
|
uint8_t i;
|
|
uint32_t reason = PROTO_REASON_OK;
|
|
plctxrx_cmd_arg_t cmd = { 0 };
|
|
plctxrx_cmd_join_network_t *join_info;
|
|
ge_frame_join_nw_set_subfn3_t *frm = (ge_frame_join_nw_set_subfn3_t *)data;
|
|
proto_cmd_hdl_state_t *sm = iot_proto_cmd_handle_state_get();
|
|
|
|
iot_cus_printf("[glpr]set_join_nw_subfn_handler nb_cnt=%d\n",
|
|
prototask_contxt.neighbor_nw.count);
|
|
|
|
sm->state = PROTO_CMD_WAIT_CMD_CFM;
|
|
sm->dir = CMD_LOCAL_UP_LINK;
|
|
sm->seq = frm->seq;
|
|
sm->cur_subfn = frm->hdr.subfn;
|
|
/* all machine, except outdoor machine can set join network */
|
|
if (IOT_PLC_DEV_ROLE_CCO == prototask_contxt.local_dev.nw_role) {
|
|
reason = PROTO_REASON_NO_AUTHORITY;
|
|
} else if (len != sizeof(ge_frame_join_nw_set_subfn3_t)) {
|
|
reason = PROTO_REASON_LEN_MISSMATCH;
|
|
} else if (prototask_contxt.local_dev.dev_ready) {
|
|
reason = PROTO_REASON_JOINED;
|
|
} else if (prototask_contxt.neighbor_nw.count == 0) {
|
|
reason = PROTO_REASON_NO_NB_NW_FOUND;
|
|
}
|
|
|
|
if (reason != PROTO_REASON_OK) {
|
|
goto err_cfm;
|
|
}
|
|
|
|
for (i = 0; i < prototask_contxt.neighbor_nw.count; i++) {
|
|
if (frm->nid == prototask_contxt.neighbor_nw.node[i].nid) {
|
|
iot_cus_printf("[glpr]set nid %d vs nod nid: %d\n",
|
|
frm->nid, prototask_contxt.neighbor_nw.node[i].nid);
|
|
|
|
cmd.cid.cid = PLCTXRX_CID_JOIN_NETWORK;
|
|
cmd.cid.opcode = PLCTXRX_OP_CONFIG;
|
|
cmd.prio = 0;
|
|
cmd.need_ack = true;
|
|
cmd.dlen = sizeof(plctxrx_cmd_join_network_t);
|
|
/* alloc packet for sending cmd */
|
|
cmd_pkt = iot_pkt_alloc(sizeof(cmd) + cmd.dlen, IOT_GREE_APP_MID);
|
|
IOT_ASSERT(cmd_pkt);
|
|
join_info = (plctxrx_cmd_join_network_t *) \
|
|
(iot_pkt_data(cmd_pkt) + sizeof(cmd));
|
|
join_info->nid= frm->nid;//add
|
|
iot_mac_addr_cpy(join_info->mac,
|
|
prototask_contxt.neighbor_nw.node[i].mac);
|
|
iot_cus_printf("[glpr]join_nid=%d mac:%2x:%2x:%2x:%2x:%2x:%2x\n",
|
|
join_info->nid, join_info->mac[0], join_info->mac[1],
|
|
join_info->mac[2], join_info->mac[3], join_info->mac[4],
|
|
join_info->mac[5]);
|
|
iot_pkt_put(cmd_pkt, sizeof(cmd) + cmd.dlen);
|
|
os_mem_cpy(iot_pkt_data(cmd_pkt), &cmd, sizeof(cmd));
|
|
iot_proto_cmd_send_to_plctxrx(cmd_pkt);
|
|
return rpt2mcu;
|
|
|
|
} else {
|
|
reason = PROTO_REASON_NID_MISSMATCH;
|
|
}
|
|
}
|
|
|
|
err_cfm:
|
|
iot_cus_printf("[glpr]join nw failed, reason:%d\n", reason);
|
|
iot_proto_resp_cfm_frame(reason, dir,
|
|
PROTO_JOIN_NW_SET_CMD, frm->seq, NULL);
|
|
|
|
/* switch cmd handle state to idle */
|
|
iot_proto_cmd_handle_state_init();
|
|
|
|
return rpt2mcu;
|
|
}
|
|
|
|
/* translate from txrx cid to gree fn, subfn */
|
|
uint8_t iot_proto_plctxtx_fn_subfn_get(plctxrx_cmd_resp_t *cmd,
|
|
uint8_t *fn, uint8_t *subfn)
|
|
{
|
|
IOT_ASSERT(cmd && fn && subfn);
|
|
uint8_t ret = ERR_FAIL;
|
|
switch (cmd->cid.cid) {
|
|
case PLCTXRX_CID_MAC:
|
|
{
|
|
switch (cmd->cid.opcode) {
|
|
case PLCTXRX_OP_RESPONSE:
|
|
{
|
|
*fn = PROTO_GE_PLC_RESP_CMD;
|
|
*subfn = PROTO_LOCAL_MAC_RESP_CMD;
|
|
ret = ERR_OK;
|
|
break;
|
|
}
|
|
case PLCTXRX_OP_CFM:
|
|
{
|
|
*fn = PROTO_GE_PLC_SET_CMD;
|
|
*subfn = PROTO_CMD_CFM_CMD;
|
|
ret = ERR_OK;
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case PLCTXRX_CID_TOPO:
|
|
{
|
|
*fn = PROTO_GE_PLC_RESP_CMD;
|
|
*subfn = PROTO_TOPO_RESP_CMD;
|
|
ret = ERR_OK;
|
|
break;
|
|
}
|
|
case PLCTXRX_CID_WHITELIST:
|
|
{
|
|
switch (cmd->cid.opcode) {
|
|
case PLCTXRX_OP_RESPONSE:
|
|
{
|
|
*fn = PROTO_GE_PLC_RESP_CMD;
|
|
*subfn = PROTO_WHITELIST_RESP_CMD;
|
|
ret = ERR_OK;
|
|
break;
|
|
}
|
|
case PLCTXRX_OP_CFM:
|
|
{
|
|
*fn = PROTO_GE_PLC_SET_CMD;
|
|
*subfn = PROTO_CMD_CFM_CMD;
|
|
ret = ERR_OK;
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case PLCTXRX_CID_FIND_NETWORK:
|
|
{
|
|
*fn = PROTO_GE_PLC_RESP_CMD;
|
|
*subfn = PROTO_AVAIL_NW_RESP_CMD;
|
|
ret = ERR_OK;
|
|
break;
|
|
}
|
|
case PLCTXRX_CID_JOIN_NETWORK:
|
|
{
|
|
switch (cmd->cid.opcode) {
|
|
case PLCTXRX_OP_CFM:
|
|
{
|
|
*fn = PROTO_GE_PLC_SET_CMD;
|
|
*subfn = PROTO_CMD_CFM_CMD;
|
|
ret = ERR_OK;
|
|
break;
|
|
}
|
|
case PLCTXRX_OP_INDICATION:
|
|
{
|
|
*fn = PROTO_GE_PLC_SET_CMD;
|
|
*subfn = PROTO_CONN_IND_RPT_CMD;
|
|
ret = ERR_OK;
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case PLCTXRX_CID_LEAVE_NETWORK:
|
|
{
|
|
if (PLCTXRX_OP_CFM == cmd->cid.opcode) {
|
|
*subfn = PROTO_CMD_CFM_CMD;
|
|
} else {
|
|
/* PLCTXRX_OP_INDICATION */
|
|
*subfn = PROTO_DISCONN_IND_RPT_CMD;
|
|
}
|
|
*fn = PROTO_GE_PLC_SET_CMD;
|
|
ret = ERR_OK;
|
|
break;
|
|
}
|
|
case PLCTXRX_CID_REJECT_STA:
|
|
{
|
|
*fn = PROTO_GE_PLC_SET_CMD;
|
|
*subfn = PROTO_REJECT_IND_RPT_CMD;
|
|
ret = ERR_OK;
|
|
break;
|
|
}
|
|
case PLCTXRX_CID_CCO_STATE:
|
|
{
|
|
*fn = PROTO_GE_PLC_SET_CMD;
|
|
*subfn = PROTO_CMD_CCO_STAT_IND_CMD;
|
|
ret = ERR_OK;
|
|
break;
|
|
}
|
|
case PLCTXRX_CID_VENDOR_INFO:
|
|
{
|
|
if (PLCTXRX_OP_CFM == cmd->cid.opcode) {
|
|
*fn = PROTO_GE_PLC_SET_CMD;
|
|
*subfn = PROTO_CMD_CFM_CMD;
|
|
}
|
|
ret = ERR_OK;
|
|
break;
|
|
}
|
|
case PLCTXRX_CID_SWVER:
|
|
{
|
|
*fn = PROTO_GE_PLC_RESP_CMD;
|
|
*subfn = PROTO_FW_SWVER_RESP_CMD;
|
|
ret = ERR_OK;
|
|
break;
|
|
}
|
|
case PLCTXRX_CID_BOOTINFO:
|
|
{
|
|
*fn = PROTO_GE_PLC_RESP_CMD;
|
|
*subfn = PROTO_BOOT_INFO_RESP_CMD;
|
|
ret = ERR_OK;
|
|
break;
|
|
}
|
|
case PLCTXRX_CID_NET_STS:
|
|
{
|
|
*fn = PROTO_GE_PLC_RESP_CMD;
|
|
*subfn = PROTO_NET_STS_RESP_CMD;
|
|
ret = ERR_OK;
|
|
break;
|
|
}
|
|
case PLCTXRX_CID_NID:
|
|
{
|
|
switch (cmd->cid.opcode) {
|
|
case PLCTXRX_OP_CFM:
|
|
{
|
|
*fn = PROTO_GE_PLC_SET_CMD;
|
|
*subfn = PROTO_CMD_CFM_CMD;
|
|
ret = ERR_OK;
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case PLCTXRX_CID_COMM_FAULT:
|
|
{
|
|
switch (cmd->cid.opcode) {
|
|
case PLCTXRX_OP_INDICATION:
|
|
{
|
|
*fn = PROTO_GE_PLC_SET_CMD;
|
|
*subfn = PROTO_COMM_FAULT_RPT_CMD;
|
|
ret = ERR_OK;
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case PLCTXRX_CID_TX_PWR:
|
|
{
|
|
switch (cmd->cid.opcode) {
|
|
case PLCTXRX_OP_RESPONSE:
|
|
{
|
|
*fn = PROTO_GE_PLC_RESP_CMD;
|
|
*subfn = PROTO_TX_PWR_RESP_CMD;
|
|
ret = ERR_OK;
|
|
break;
|
|
}
|
|
case PLCTXRX_OP_CFM:
|
|
{
|
|
*fn = PROTO_GE_PLC_SET_CMD;
|
|
*subfn = PROTO_CMD_CFM_CMD;
|
|
ret = ERR_OK;
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case PLCTXRX_CID_GRAPP_REG_CONF:
|
|
{
|
|
switch (cmd->cid.opcode) {
|
|
case PLCTXRX_OP_INDICATION:
|
|
{
|
|
*fn = PROTO_GE_PLC_SET_CMD;
|
|
*subfn = PROTO_APP_REG_CONF_IND;
|
|
ret = ERR_OK;
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case PLCTXRX_CID_BAND_ID:
|
|
{
|
|
switch (cmd->cid.opcode) {
|
|
case PLCTXRX_OP_CFM:
|
|
{
|
|
*fn = PROTO_GE_PLC_SET_CMD;
|
|
*subfn = PROTO_CMD_CFM_CMD;
|
|
ret = ERR_OK;
|
|
break;
|
|
}
|
|
case PLCTXRX_OP_RESPONSE:
|
|
{
|
|
*fn = PROTO_GE_PLC_RESP_CMD;
|
|
*subfn = PROTO_WORK_BAND_RESP_CMD;
|
|
ret = ERR_OK;
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case PLCTXRX_CID_VENDOR_DATA:
|
|
{
|
|
if (PLCTXRX_OP_CFM == cmd->cid.opcode) {
|
|
*fn = PROTO_GE_PLC_SET_CMD;
|
|
*subfn = PROTO_CMD_CFM_CMD;
|
|
}
|
|
ret = ERR_OK;
|
|
break;
|
|
}
|
|
case PLCTXRX_CID_NTB:
|
|
{
|
|
if (PLCTXRX_OP_RESPONSE == cmd->cid.opcode) {
|
|
*fn = PROTO_GE_PLC_RESP_CMD;
|
|
*subfn = PROTO_NTB_RESP_CMD;
|
|
}
|
|
ret = ERR_OK;
|
|
break;
|
|
}
|
|
case PLCTXRX_CID_FB_BITMAP:
|
|
{
|
|
switch (cmd->cid.opcode) {
|
|
case PLCTXRX_OP_RESPONSE:
|
|
{
|
|
*fn = PROTO_GE_PLC_RESP_CMD;
|
|
*subfn = PROTO_FB_BITMAP_RESP_CMD;
|
|
ret = ERR_OK;
|
|
break;
|
|
}
|
|
case PLCTXRX_OP_CFM:
|
|
{
|
|
*fn = PROTO_GE_PLC_SET_CMD;
|
|
*subfn = PROTO_CMD_CFM_CMD;
|
|
ret = ERR_OK;
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case PLCTXRX_CID_FIXED_RATE:
|
|
{
|
|
switch (cmd->cid.opcode) {
|
|
case PLCTXRX_OP_RESPONSE:
|
|
{
|
|
*fn = PROTO_GE_PLC_RESP_CMD;
|
|
*subfn = PROTO_FIX_RATE_MODE_RESP_CMD;
|
|
ret = ERR_OK;
|
|
break;
|
|
}
|
|
case PLCTXRX_OP_CFM:
|
|
{
|
|
*fn = PROTO_GE_PLC_SET_CMD;
|
|
*subfn = PROTO_CMD_CFM_CMD;
|
|
ret = ERR_OK;
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case PLCTXRX_CID_NODE_INFO:
|
|
{
|
|
if (PLCTXRX_OP_RESPONSE == cmd->cid.opcode) {
|
|
*fn = PROTO_GE_PLC_RESP_CMD;
|
|
*subfn = PROTO_NODE_INFO_RESP_CMD;
|
|
}
|
|
ret = ERR_OK;
|
|
break;
|
|
}
|
|
case PLCTXRX_CID_NW_INFO:
|
|
{
|
|
if (PLCTXRX_OP_RESPONSE == cmd->cid.opcode) {
|
|
*fn = PROTO_GE_PLC_RESP_CMD;
|
|
*subfn = PROTO_NW_INFO_RESP_CMD;
|
|
}
|
|
ret = ERR_OK;
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
/* update beacon vendor info */
|
|
uint8_t iot_proto_update_vendr(iot_pkt_t *pkt)
|
|
{
|
|
proto_vendor_info_t *vendr_info = (proto_vendor_info_t *)iot_pkt_data(pkt);
|
|
iot_pkt_t *ind_pkt;
|
|
ge_frame_bc_data_send_subfn162_t *data_cmd;
|
|
|
|
if (!os_mem_cmp(vendr_info->data, prototask_contxt.rxbc_data.data,
|
|
IOT_PLC_BEACON_DATA_MAX)) {
|
|
goto out;
|
|
}
|
|
|
|
ind_pkt = iot_pkt_alloc(sizeof(*data_cmd), IOT_GREE_APP_MID);
|
|
IOT_ASSERT(ind_pkt);
|
|
|
|
data_cmd = (ge_frame_bc_data_send_subfn162_t *)iot_pkt_data(ind_pkt);
|
|
os_mem_set(data_cmd, 0, sizeof(*data_cmd));
|
|
iot_pkt_put(ind_pkt, sizeof(*data_cmd));
|
|
|
|
EXT_FN_FRM_PREPARE(data_cmd, PROTO_GE_PLC_SET_CMD, PROTO_GE_BC_DATA_CMD);
|
|
os_mem_cpy(data_cmd->data, vendr_info->data, sizeof(*vendr_info));
|
|
os_mem_cpy(prototask_contxt.rxbc_data.data,
|
|
vendr_info->data, sizeof(*vendr_info));
|
|
|
|
data_cmd->tail.check_sum = ge_frm_checksum_calc((uint8_t *)data_cmd,
|
|
sizeof(*data_cmd)-sizeof(ge_frm_tail_t));
|
|
|
|
/* report data info to MCU */
|
|
iot_proto_send_to_mainboard(ind_pkt);
|
|
|
|
out:
|
|
iot_pkt_free(pkt);
|
|
return ERR_OK;
|
|
}
|
|
|
|
bool_t iot_proto_clr_flashinfo_handler(uint8_t *data,
|
|
uint16_t len, transmit_direction_e_t dir)
|
|
{
|
|
IOT_ASSERT(CMD_LOCAL_DOWN_LINK == dir);
|
|
ge_frame_clr_cust_flash_set_subfn25_t *set_cmd =
|
|
(ge_frame_clr_cust_flash_set_subfn25_t *)data;
|
|
uint32_t reason = 0;
|
|
bool_t rpt2mcu = false;
|
|
ge_app_pib_info_t *p_flash = &prototask_contxt.flashinfo;
|
|
|
|
if (len != sizeof(ge_frame_clr_cust_flash_set_subfn25_t)) {
|
|
reason = PROTO_REASON_LEN_MISSMATCH;
|
|
goto out;
|
|
}
|
|
|
|
os_mem_set(p_flash->public.pub.local_mac, 0, IOT_MAC_ADDR_LEN);
|
|
p_flash->public.pub.local_type = 0;
|
|
os_mem_set(p_flash->public.pub.cco_mac, 0, IOT_MAC_ADDR_LEN);
|
|
#if PLC_SUPPORT_CCO_ROLE
|
|
os_mem_set(p_flash->public.pub.dev_tbl, 0, sizeof(proto_dev_t)*STA_DEV_MAX);
|
|
p_flash->public.pub.dev_cnt = 0;
|
|
#endif
|
|
iot_proto_flashsave(p_flash);
|
|
|
|
goto out;
|
|
|
|
out:
|
|
iot_cus_printf("[glpr]Clear flash info:reason=%d\n", reason);
|
|
iot_proto_resp_cfm_frame(reason, dir,
|
|
PROTO_CLR_CUST_FLASH_CMD, set_cmd->seq, NULL);
|
|
|
|
return rpt2mcu;
|
|
}
|
|
|
|
|
|
void iot_proto_wl_save2flash(void)
|
|
{
|
|
#if PLC_SUPPORT_CCO_ROLE
|
|
ge_app_pib_info_t *p_flash = &(prototask_contxt.flashinfo);
|
|
proto_dev_t *p_table = prototask_contxt.dev_lst.dev;
|
|
uint16_t i, dev_cnt;
|
|
|
|
dev_cnt = prototask_contxt.dev_lst.valid_dev_cnt;
|
|
for (i = 0; i < dev_cnt; i++) {
|
|
/* Copy formal white list onto config from flash */
|
|
p_flash->public.pub.dev_tbl[i] = p_table[i];
|
|
}
|
|
p_flash->public.pub.dev_cnt = i;
|
|
/* Write flash. */
|
|
iot_proto_flashsave(p_flash);
|
|
iot_cus_printf("[glpr]whitelist save to flash!\n");
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
Enable/disable white list in CVG level.
|
|
action : 2 - disable; 3 - enable.
|
|
need_ack_cfm : true - plctxrx will ack cfm; false - No ack cfm.
|
|
*/
|
|
void iot_proto_whitelist_en_disable(uint8_t action, bool_t need_ack_cfm)
|
|
{
|
|
|
|
ge_app_pib_info_t *p_flash = &prototask_contxt.flashinfo;
|
|
iot_pkt_t *p_pkt;
|
|
plctxrx_cmd_whitelist_t *p_wlist;
|
|
plctxrx_cmd_arg_t *p_arg;
|
|
|
|
p_pkt = iot_pkt_alloc(sizeof(*p_wlist) + sizeof(*p_arg),
|
|
IOT_GREE_APP_MID);
|
|
IOT_ASSERT(p_pkt);
|
|
iot_pkt_put(p_pkt, sizeof(*p_wlist)+sizeof(*p_arg));
|
|
|
|
p_arg = (plctxrx_cmd_arg_t *)iot_pkt_data(p_pkt);
|
|
p_arg->cid.cid = PLCTXRX_CID_WHITELIST;
|
|
p_arg->cid.opcode = PLCTXRX_OP_CONFIG;
|
|
p_arg->prio = 0;
|
|
p_arg->need_ack = need_ack_cfm;
|
|
p_arg->dlen = sizeof(*p_wlist);
|
|
|
|
p_wlist = (plctxrx_cmd_whitelist_t *)p_arg->arg;
|
|
p_wlist->action = action;
|
|
p_wlist->listcnt = 0;
|
|
/* save whitelist state to flash */
|
|
if (p_flash->public.pub.wl_state != (action == GE_PROTO_WL_ENABLE)) {
|
|
p_flash->public.pub.wl_state = (action == GE_PROTO_WL_ENABLE);
|
|
iot_proto_flashsave(p_flash);
|
|
}
|
|
|
|
iot_proto_cmd_send_to_plctxrx(p_pkt);
|
|
}
|
|
|
|
/* Load config from customor flash. */
|
|
uint32_t iot_proto_flashload(ge_app_pib_info_t *p_info)
|
|
{
|
|
#if (HW_PLATFORM == HW_PLATFORM_SIMU)
|
|
(void)p_info;
|
|
iot_mac_addr_cpy(prototask_contxt.local_dev.mac, g_ucMACAddress);
|
|
#else
|
|
uint8_t *rw = NULL;
|
|
uint8_t temp_pt = MAX_PIB_TYPE;
|
|
(void)iot_pib_get_app_section(&rw, &temp_pt, IOT_PIB_APP_GET_WRITE_SECTION);
|
|
IOT_ASSERT(rw);
|
|
BUILD_BUG_ON(sizeof(ge_app_pib_info_t) == sizeof(app_pib_rw_t));
|
|
#if PLC_SUPPORT_CCO_ROLE
|
|
IOT_ASSERT(temp_pt == CCO_PIB_TYPE);
|
|
#else
|
|
IOT_ASSERT(temp_pt == STA_PIB_TYPE);
|
|
#endif
|
|
prototask_contxt.pib_rw = (app_pib_rw_t *)rw;
|
|
os_mem_cpy(&prototask_contxt.flashinfo, prototask_contxt.pib_rw,
|
|
sizeof(ge_app_pib_info_t));
|
|
#endif
|
|
return ERR_OK;
|
|
}
|
|
|
|
/* To dump our config info on flash. */
|
|
void iot_proto_dumpflash(ge_app_pib_info_t* p_info)
|
|
{
|
|
iot_cus_printf("\nMagic1 : 0x%02x%02x%02x%02x.",
|
|
p_info->magic1[0], p_info->magic1[1],
|
|
p_info->magic1[2], p_info->magic1[3]);
|
|
|
|
iot_cus_printf("\nLocal_dev:%d Mac: %02x-%02x-%02x-%02x-%02x-%02x.",
|
|
p_info->public.pub.local_type, p_info->public.pub.local_mac[0],
|
|
p_info->public.pub.local_mac[1], p_info->public.pub.local_mac[2],
|
|
p_info->public.pub.local_mac[3], p_info->public.pub.local_mac[4],
|
|
p_info->public.pub.local_mac[5]);
|
|
|
|
iot_cus_printf("\ncco Mac: %02x-%02x-%02x-%02x-%02x-%02x.",
|
|
p_info->public.pub.cco_mac[0], p_info->public.pub.cco_mac[1],
|
|
p_info->public.pub.cco_mac[2], p_info->public.pub.cco_mac[3],
|
|
p_info->public.pub.cco_mac[4], p_info->public.pub.cco_mac[5]);
|
|
|
|
iot_cus_printf("\nbaudidx=%d-wl_state=%d.",p_info->public.pub.baudidx,
|
|
p_info->public.pub.wl_state);
|
|
|
|
#if PLC_SUPPORT_CCO_ROLE
|
|
uint16_t i;
|
|
proto_dev_t *p_dev;
|
|
p_dev = p_info->public.pub.dev_tbl;
|
|
for (i = 0; i < p_info->public.pub.dev_cnt; i++) {
|
|
iot_cus_printf("\nDEV#%02d:", i);
|
|
iot_cus_printf("\n IP:%d.", p_dev->ip);
|
|
iot_cus_printf("\n Role:%d.", p_dev->dev_role);
|
|
iot_cus_printf("\n MAC:%02x-%02x-%02x-%02x-%02x-%02x.",
|
|
p_dev->mac[0], p_dev->mac[1], p_dev->mac[2],
|
|
p_dev->mac[3], p_dev->mac[4], p_dev->mac[5]);
|
|
p_dev++;
|
|
}
|
|
#endif
|
|
|
|
iot_cus_printf("\nMagic2 : 0x%02x%02x%02x%02x.",
|
|
p_info->magic2[0], p_info->magic2[1],
|
|
p_info->magic2[2], p_info->magic2[3]);
|
|
|
|
return;
|
|
}
|
|
|
|
/* Check the magic code to tell if our config damaged. */
|
|
uint32_t iot_proto_cust_flashinfo_check(ge_app_pib_info_t *p_info)
|
|
{
|
|
int32_t magic1, magic2;
|
|
|
|
magic1 = (p_info->magic1[0] << 24) | (p_info->magic1[1] << 16)
|
|
| (p_info->magic1[2] << 8) | p_info->magic1[3];
|
|
|
|
magic2 = (p_info->magic2[0] << 24) | (p_info->magic2[1] << 16)
|
|
| (p_info->magic2[2] << 8) | p_info->magic2[3];
|
|
|
|
iot_cus_printf("[glpr]Magic = 0x%08x, 0x%08x!\n",
|
|
magic1, magic2);
|
|
|
|
if ((IOT_PROTO_CUST_FLASHINFO_MAGIC1 != magic1)
|
|
||(IOT_PROTO_CUST_FLASHINFO_MAGIC2 != magic2)) {
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
return ERR_OK;
|
|
}
|
|
|
|
/* Repair this config when it is damaged. */
|
|
void iot_proto_cust_flashinfo_repair(ge_app_pib_info_t *p_info)
|
|
{
|
|
p_info->magic1[0] = (IOT_PROTO_CUST_FLASHINFO_MAGIC1 >> 24) & 0xFF;
|
|
p_info->magic1[1] = (IOT_PROTO_CUST_FLASHINFO_MAGIC1 >> 16) & 0xFF;
|
|
p_info->magic1[2] = (IOT_PROTO_CUST_FLASHINFO_MAGIC1 >> 8) & 0xFF;
|
|
p_info->magic1[3] = (IOT_PROTO_CUST_FLASHINFO_MAGIC1) & 0xFF;
|
|
|
|
p_info->magic2[0] = (IOT_PROTO_CUST_FLASHINFO_MAGIC2 >> 24) & 0xFF;
|
|
p_info->magic2[1] = (IOT_PROTO_CUST_FLASHINFO_MAGIC2 >> 16) & 0xFF;
|
|
p_info->magic2[2] = (IOT_PROTO_CUST_FLASHINFO_MAGIC2 >> 8) & 0xFF;
|
|
p_info->magic2[3] = (IOT_PROTO_CUST_FLASHINFO_MAGIC2) & 0xFF;
|
|
|
|
return;
|
|
}
|
|
|
|
/* This will store config onto customor flash area. */
|
|
uint32_t iot_proto_flashsave(ge_app_pib_info_t *p_info)
|
|
{
|
|
#if (HW_PLATFORM == HW_PLATFORM_SIMU)
|
|
(void)p_info;
|
|
#else
|
|
uint8_t ref;
|
|
uint16_t ticket;
|
|
|
|
// update info to pib
|
|
iot_pib_acquire_app_commit_ref(&ref);
|
|
os_mem_cpy(prototask_contxt.pib_rw, p_info, sizeof(*p_info));
|
|
iot_pib_release_app_commit_ref(&ref);
|
|
iot_pib_app_commit(&ticket);
|
|
#endif
|
|
return ERR_OK;
|
|
}
|
|
|
|
/* upgrade pib info from old pib section, in case that pib info lost
|
|
* after remote upgrade successfully
|
|
*/
|
|
void iot_proto_upgrade_app_pib_info(void)
|
|
{
|
|
#if HW_PLATFORM != HW_PLATFORM_SIMU
|
|
ge_app_pib_info_t *p_flash = &prototask_contxt.flashinfo;
|
|
|
|
if (ERR_OK != iot_pib_upgrade_app_cfg()) {
|
|
iot_cus_printf("%s: failed to upgrade app pib section\n", __FUNCTION__);
|
|
}
|
|
|
|
if (ERR_OK == iot_proto_flashload(p_flash)) {
|
|
iot_proto_flashsave(p_flash);
|
|
} else {
|
|
iot_cus_printf("%s: failed to load app pib cfg\n", __FUNCTION__);
|
|
}
|
|
#endif
|
|
|
|
return;
|
|
}
|
|
|
|
uint8_t uart_baud_find_index(uint32_t baudrate)
|
|
{
|
|
uint8_t idx;
|
|
uint32_t uart_baud[] = PROTO_GE_UART_BAUD_VALUE;
|
|
|
|
for(idx = 0; idx < PROTO_GE_UART_BAUD_IDX_MAX; idx++) {
|
|
if(baudrate == uart_baud[idx]) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
return idx;
|
|
}
|
|
|
|
/* check uart param */
|
|
bool_t iot_proto_uart_param_check(uint32_t baudrate, uint8_t parity,
|
|
uint8_t data_bits, uint8_t stop_bits)
|
|
{
|
|
switch (baudrate) {
|
|
case PROTO_GE_UART_BAUD_3000000:
|
|
case PROTO_GE_UART_BAUD_256000:
|
|
case PROTO_GE_UART_BAUD_115200:
|
|
case PROTO_GE_UART_BAUD_19200:
|
|
case PROTO_GE_UART_BAUD_9600:
|
|
case PROTO_GE_UART_BAUD_4800:
|
|
case PROTO_GE_UART_BAUD_2400:
|
|
break;
|
|
default:
|
|
return false;
|
|
}
|
|
|
|
switch (parity) {
|
|
case IOT_UART_PARITY_NONE:
|
|
case IOT_UART_PARITY_ODD:
|
|
case IOT_UART_PARITY_EVEN:
|
|
case IOT_UART_PARITY_MARK:
|
|
case IOT_UART_PARITY_SPACE:
|
|
break;
|
|
default:
|
|
return false;
|
|
}
|
|
|
|
switch (data_bits) {
|
|
case IOT_UART_DLEN_5_BITS:
|
|
case IOT_UART_DLEN_6_BITS:
|
|
case IOT_UART_DLEN_7_BITS:
|
|
case IOT_UART_DLEN_8_BITS:
|
|
break;
|
|
default:
|
|
return false;
|
|
}
|
|
|
|
switch (stop_bits) {
|
|
case IOT_UART_STOP_1_BITS:
|
|
case IOT_UART_STOP_1_5_BITS:
|
|
case IOT_UART_STOP_2_BITS:
|
|
break;
|
|
default:
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/* load flash info into dev wl and pair tbl */
|
|
void iot_proto_flashinfo_init(void)
|
|
{
|
|
uint32_t uart_baud[] = PROTO_GE_UART_BAUD_VALUE;
|
|
ge_app_pib_info_t *p_flash = &prototask_contxt.flashinfo;
|
|
|
|
/* do flash used check */
|
|
BUILD_BUG_ON(sizeof(public_use_t) <= IOT_APP_PUBLIC_SIZE);
|
|
BUILD_BUG_ON(sizeof(at_private_use_t) <= IOT_APP_AT_PRIVATE_SIZE);
|
|
BUILD_BUG_ON(sizeof(proto_private_use_t) <= IOT_APP_PROTO_PRIVATE_SIZE);
|
|
|
|
if (ERR_FAIL == iot_proto_flashload(p_flash) ||
|
|
ERR_FAIL == iot_proto_cust_flashinfo_check(p_flash)) {
|
|
iot_cus_printf("[glpr][err]Cannot get custom flash info!!");
|
|
os_mem_set(p_flash, 0x0, sizeof(*p_flash));
|
|
/* enable whitelist as default state */
|
|
#if HW_PLATFORM == HW_PLATFORM_SIMU
|
|
/* used the mac address defined in RTOSConfig.ini */
|
|
iot_mac_addr_cpy(p_flash->public.pub.local_mac, g_ucMACAddress);
|
|
if (prototask_contxt.local_dev.nw_role != IOT_PLC_DEV_ROLE_CCO) {
|
|
p_flash->public.pub.wl_state = 0;
|
|
} else {
|
|
p_flash->public.pub.wl_state = 1;
|
|
}
|
|
/* config uart baud to default index - 115200bit/s */
|
|
p_flash->public.pub.baudidx = 0;
|
|
#else
|
|
#if PLC_SUPPORT_STA_ROLE
|
|
/* default disable whitelist for sta */
|
|
p_flash->public.pub.wl_state = 0;
|
|
/* config uart param - 9600bit/s-EVEN-8-1 */
|
|
p_flash->public.pub.baudidx = 1;
|
|
/* for solar mppt: config uart param - 115200bit/s-EVEN-8-1 */
|
|
if (CUS_BOARD_ID_SOLRMPPT_V1_0 == iot_board_get_board_id()) {
|
|
p_flash->public.pub.baudidx = 0;
|
|
}
|
|
p_flash->public.pub.parity = IOT_UART_PARITY_EVEN;
|
|
p_flash->public.pub.data = IOT_UART_DLEN_8_BITS;
|
|
p_flash->public.pub.stop = IOT_UART_STOP_1_BITS;
|
|
#else
|
|
p_flash->public.pub.wl_state = 1;
|
|
/* config uart param - 115200bit/s-NONE-8-1 */
|
|
p_flash->public.pub.baudidx = 0;
|
|
p_flash->public.pub.parity = IOT_UART_PARITY_NONE;
|
|
p_flash->public.pub.data = IOT_UART_DLEN_8_BITS;
|
|
p_flash->public.pub.stop = IOT_UART_STOP_1_BITS;
|
|
#endif
|
|
#endif
|
|
iot_proto_cust_flashinfo_repair(&(prototask_contxt.flashinfo));
|
|
iot_proto_flashsave(p_flash);
|
|
} else {
|
|
#if PLC_SUPPORT_CCO_ROLE
|
|
uint16_t cnt;
|
|
proto_dev_t *p_dev = prototask_contxt.dev_lst.dev_tmp;
|
|
/* whitelist load */
|
|
p_flash->public.pub.dev_cnt =
|
|
(STA_DEV_MAX >= p_flash->public.pub.dev_cnt) ?
|
|
p_flash->public.pub.dev_cnt : 0;
|
|
for (cnt = 0; cnt < p_flash->public.pub.dev_cnt; cnt++) {
|
|
p_dev[cnt] = p_flash->public.pub.dev_tbl[cnt];
|
|
}
|
|
prototask_contxt.dev_lst.valid_dev_tmp_cnt = p_flash->public.pub.dev_cnt;
|
|
iot_proto_add_wl_tmp2formal();
|
|
#endif
|
|
/* config uart param */
|
|
if (p_flash->public.pub.baudidx >= PROTO_GE_UART_BAUD_IDX_MAX) {
|
|
p_flash->public.pub.baudidx = 0;
|
|
}
|
|
if (iot_proto_uart_param_check(uart_baud[p_flash->public.pub.baudidx],
|
|
p_flash->public.pub.parity, p_flash->public.pub.data,
|
|
p_flash->public.pub.stop) == false) {
|
|
p_flash->public.pub.baudidx = 0;
|
|
p_flash->public.pub.parity = DEF_UART_PARITY;
|
|
p_flash->public.pub.data = IOT_UART_DLEN_8_BITS;
|
|
p_flash->public.pub.stop = IOT_UART_STOP_1_BITS;
|
|
iot_proto_flashsave(p_flash);
|
|
}
|
|
}
|
|
/* config uart param */
|
|
iot_grapp_modify_uart_param(p_flash->public.pub.baudidx,
|
|
p_flash->public.pub.parity, p_flash->public.pub.data,
|
|
p_flash->public.pub.stop);
|
|
/* dump flash info */
|
|
iot_proto_dumpflash(&(prototask_contxt.flashinfo));
|
|
if ((p_flash->public.pub.edge_start_tm < UART_MONITOR_START_MIN) ||
|
|
(p_flash->public.pub.edge_start_tm > UART_MONITOR_START_MAX)) {
|
|
p_flash->public.pub.edge_start_tm = UART_MONITOR_START_TIMEOUT;
|
|
}
|
|
return;
|
|
}
|
|
|
|
#endif // IOT_GR_APP_ENABLE
|