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
 |