4814 lines
		
	
	
		
			152 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			4814 lines
		
	
	
		
			152 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/****************************************************************************
 | 
						|
 | 
						|
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
 | 
						|
 | 
						|
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
 | 
						|
be copied by any method or incorporated into another program without
 | 
						|
the express written consent of Aerospace C.Power. This Information or any portion
 | 
						|
thereof remains the property of Aerospace C.Power. The Information contained herein
 | 
						|
is believed to be accurate and Aerospace C.Power assumes no responsibility or
 | 
						|
liability for its use in any way and conveys no license or title under
 | 
						|
any patent or copyright and makes no representation or warranty that this
 | 
						|
Information is free from patent or copyright infringement.
 | 
						|
 | 
						|
****************************************************************************/
 | 
						|
/* 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_cli_sg_api.h"
 | 
						|
#include "iot_board_api.h"
 | 
						|
#include "iot_plc_led_api.h"
 | 
						|
 | 
						|
#include "iot_grapp.h"
 | 
						|
#include "iot_plctxrx.h"
 | 
						|
#include "iot_proto_common.h"
 | 
						|
#include "iot_proto_ge.h"
 | 
						|
#include "iot_gr_upgrade.h"
 | 
						|
#include "iot_pib_api.h"
 | 
						|
#include "iot_ntoh_api.h"
 | 
						|
#include "iot_adc_api.h"
 | 
						|
#include "iot_gpio_api.h"
 | 
						|
 | 
						|
#include "iot_proto_dl645.h"
 | 
						|
#include "iot_proto_cctt.h"
 | 
						|
 | 
						|
#include "iot_proto_modbus.h"
 | 
						|
#include "iot_edge_compute.h"
 | 
						|
 | 
						|
#if IOT_GR_APP_ENABLE
 | 
						|
#if GE_CRC_ENABLE
 | 
						|
/* CRC table for the CRC-16. */
 | 
						|
/* The poly is 0x8005 (x^16 + x^15 + x^2 + 1) */
 | 
						|
const uint16_t iot_crc16_tab[256] = {
 | 
						|
    0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
 | 
						|
    0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
 | 
						|
    0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
 | 
						|
    0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
 | 
						|
    0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
 | 
						|
    0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
 | 
						|
    0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
 | 
						|
    0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
 | 
						|
    0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
 | 
						|
    0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
 | 
						|
    0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
 | 
						|
    0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
 | 
						|
    0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
 | 
						|
    0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
 | 
						|
    0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
 | 
						|
    0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
 | 
						|
    0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
 | 
						|
    0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
 | 
						|
    0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
 | 
						|
    0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
 | 
						|
    0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
 | 
						|
    0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
 | 
						|
    0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
 | 
						|
    0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
 | 
						|
    0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
 | 
						|
    0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
 | 
						|
    0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
 | 
						|
    0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
 | 
						|
    0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
 | 
						|
    0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
 | 
						|
    0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
 | 
						|
    0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
 | 
						|
};
 | 
						|
#endif
 | 
						|
 | 
						|
enum proto_cmd_protocol_type_e {
 | 
						|
    NO_FRAME,
 | 
						|
    GE_FRAME,
 | 
						|
    MODBUS_FRAME,
 | 
						|
    DL645_FRAME,
 | 
						|
};
 | 
						|
 | 
						|
/* sta detected mac max count, interval 3 seconds */
 | 
						|
#define STA_DETECTED_MAC_MAX_CNT              (4)
 | 
						|
 | 
						|
void iot_proto_wl_pt_remote_set_timeout
 | 
						|
    (uint32_t type, uint32_t dir, uint8_t seq, uint8_t *dst_mac);
 | 
						|
 | 
						|
uint8_t ge_bcast_addr[IOT_MAC_ADDR_LEN] =
 | 
						|
    { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
 | 
						|
 | 
						|
/******************************************************************************
 | 
						|
 *****************************function define *********************************
 | 
						|
 ******************************************************************************/
 | 
						|
void iot_proto_task_post_msg(uint16_t msg_type, uint16_t msg_id, void* data,
 | 
						|
    transmit_direction_e_t dir, uint8_t prio);
 | 
						|
 | 
						|
static proto_savedmsg_node_t *iot_proto_msgnode_alloc(iot_mem_pool_t *pool);
 | 
						|
 | 
						|
static uint32_t iot_proto_msgnode_free(iot_mem_pool_t *pool,
 | 
						|
    proto_savedmsg_node_t *msgnode);
 | 
						|
 | 
						|
static void iot_proto_savedmsg_list_push_backend(proto_msg_saved_list_t *list,
 | 
						|
    list_node_t *node);
 | 
						|
 | 
						|
static proto_savedmsg_node_t *
 | 
						|
    iot_proto_savedmsg_list_pop_front(proto_msg_saved_list_t *list);
 | 
						|
 | 
						|
static void iot_proto_saved_msg_handle(void);
 | 
						|
 | 
						|
static uint16_t iot_proto_plc_data_group_frame(uint8_t *dst, uint8_t *src,
 | 
						|
    uint16_t src_len);
 | 
						|
 | 
						|
static void iot_proto_cus_app_msg_handle(iot_task_msg_t *msg);
 | 
						|
 | 
						|
void iot_proto_handle_save_cus_app_info_to_pib(iot_pkt_t *data);
 | 
						|
 | 
						|
static void post_monitor_start_timer(timer_id_t timer_id, void * arg);
 | 
						|
 | 
						|
static void post_monitor_start_timer_msg_handler(void);
 | 
						|
 | 
						|
/******************************************************************************
 | 
						|
 *****************************global variable define **************************
 | 
						|
 ******************************************************************************/
 | 
						|
/* debug macro for whitelist and pairtable */
 | 
						|
#define WHITELIST_PAIR_DEBUG              0
 | 
						|
 | 
						|
/* global buffer to hold uart input frame. */
 | 
						|
mcu_data_handle_t mcu_data;
 | 
						|
 | 
						|
/* buf, contain complete data, post to proto msg pool */
 | 
						|
uint8_t ge_buf[MCU_DATA_RECV_MAX];
 | 
						|
 | 
						|
prototask_contxt_t prototask_contxt;
 | 
						|
 | 
						|
/* msg pool for saved msg */
 | 
						|
static iot_mem_pool_t   *saved_msg_q;
 | 
						|
 | 
						|
/* gathering buffer for sending to MCU */
 | 
						|
uint8_t  glb_ul_tmp_buf[UL_TMP_BUF_LEN];
 | 
						|
/* record the length of the data received from plc */
 | 
						|
uint16_t glb_ul_data_len = 0;
 | 
						|
 | 
						|
/* function may gather the frames, up to 200 bytes */
 | 
						|
#define IOT_PROTO_LOG_BUF_LEN   384
 | 
						|
char proto_log_buf[IOT_PROTO_LOG_BUF_LEN];
 | 
						|
 | 
						|
/* uart0 t-put statistic infor */
 | 
						|
uart_thpt_t uart_thpt;
 | 
						|
 | 
						|
/* operable global gpio */
 | 
						|
iot_ge_gpio_config_t iot_ge_gpio_g[IOT_GE_VALID_GPIO_MAX];
 | 
						|
 | 
						|
/* LEDC01 module operable gpio pin number limit */
 | 
						|
uint8_t iot_ledc01_ge_gpio_valid[IOT_GE_LEDC01_VALID_GPIO_MAX] = {
 | 
						|
    10, 28, 36};
 | 
						|
 | 
						|
#define ARRAY_CNT(a)    (sizeof(a) / sizeof((a)[0]))
 | 
						|
 | 
						|
#if (HW_PLATFORM == HW_PLATFORM_SIMU)
 | 
						|
extern uint8_t ucIsClientMode;
 | 
						|
#endif
 | 
						|
 | 
						|
#define PARSE_FRM_MAX_LEN          (GE_FRM_MAX_LEN + GE_FRM_PLD_MAX_LEN)
 | 
						|
 | 
						|
bool_t mac_addr_is_bcast_addr(uint8_t *mac)
 | 
						|
{
 | 
						|
    if (iot_mac_addr_cmp(bcast_mac, mac)) {
 | 
						|
        return true;
 | 
						|
    } else {
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
bool_t mac_addr_is_valid_addr(uint8_t *mac)
 | 
						|
{
 | 
						|
    uint8_t tmp_mac[IOT_MAC_ADDR_LEN] = { 0 };
 | 
						|
    if (iot_mac_addr_cmp(mac, tmp_mac)) {
 | 
						|
        return false;
 | 
						|
    } else {
 | 
						|
        return true;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
bool_t mac_addr_in_flash_is_valid_addr(uint8_t *mac)
 | 
						|
{
 | 
						|
    uint8_t all_zero_mac[IOT_MAC_ADDR_LEN] = { 0 };
 | 
						|
    if (iot_mac_addr_cmp(mac, all_zero_mac) || iot_mac_addr_cmp(mac, bcast_mac)) {
 | 
						|
        return false;
 | 
						|
    } else {
 | 
						|
        return true;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void iot_common_bin_dump(uint8_t *data, uint32_t dlen)
 | 
						|
{
 | 
						|
    os_acquire_mutex(prototask_contxt.common_bin_dump_mutex);
 | 
						|
    uint32_t i = 0;
 | 
						|
    uint32_t offset = 0;
 | 
						|
    offset = iot_sprintf(proto_log_buf, "dump pkt[len:%d]",dlen);
 | 
						|
    for (i = 0; i < dlen; ++i) {
 | 
						|
        offset += iot_sprintf(proto_log_buf + offset, "%02X ", data[i]);
 | 
						|
        if (IOT_PROTO_LOG_BUF_LEN <= offset + 4) {
 | 
						|
            break;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    proto_log_buf[offset] = 0;
 | 
						|
    iot_cus_printf("%s\n", proto_log_buf);
 | 
						|
    os_release_mutex(prototask_contxt.common_bin_dump_mutex);
 | 
						|
    return;
 | 
						|
}
 | 
						|
 | 
						|
/******************************************************************************
 | 
						|
**********************************function realize*****************************
 | 
						|
******************************************************************************/
 | 
						|
void iot_proto_fill_txinfo(protpkt_tx_info_t* txinfo, bool_t need_ack,
 | 
						|
    txrx_type_e send_type, uint8_t retry_cnt, uint16_t retry_intvl,
 | 
						|
    uint16_t sta_cnt, uint8_t *src_mac, uint8_t *dst_mac)
 | 
						|
{
 | 
						|
    uint8_t i;
 | 
						|
 | 
						|
    txinfo->send_type  = send_type;
 | 
						|
    txinfo->src_module = IOT_PLCTXRX_MSDU_SRCMODULE_PROTO;
 | 
						|
    /* initilize mac  */
 | 
						|
    os_mem_set(txinfo->src_mac, 0, IOT_MAC_ADDR_LEN);
 | 
						|
    os_mem_set(txinfo->org_mac, 0, IOT_MAC_ADDR_LEN);
 | 
						|
    os_mem_set(txinfo->dst_mac, 0, IOT_MAC_ADDR_LEN);
 | 
						|
    /* why zero, because copy only 3 bytes */
 | 
						|
    os_mem_cpy(txinfo->src_mac, src_mac, IOT_MAC_ADDR_LEN);
 | 
						|
    os_mem_cpy(txinfo->org_mac, src_mac, IOT_MAC_ADDR_LEN);
 | 
						|
 | 
						|
    txinfo->sta_cnt = sta_cnt;
 | 
						|
    txinfo->retry_cnt = retry_cnt;
 | 
						|
    txinfo->retry_intvl = retry_intvl;
 | 
						|
    txinfo->need_ack = need_ack;
 | 
						|
 | 
						|
    if (dst_mac) {
 | 
						|
        for ( i = 0; i < txinfo->sta_cnt; i++) {
 | 
						|
            iot_mac_addr_cpy(txinfo->dst_mac + i * IOT_MAC_ADDR_LEN,
 | 
						|
                dst_mac + i * IOT_MAC_ADDR_LEN);
 | 
						|
        }
 | 
						|
    } else {
 | 
						|
        iot_mac_addr_cpy(txinfo->dst_mac, ge_bcast_addr);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
proto_cmd_hdl_state_t* iot_proto_cmd_handle_state_get()
 | 
						|
{
 | 
						|
    return &prototask_contxt.sm;
 | 
						|
}
 | 
						|
 | 
						|
void iot_proto_cmd_handle_state_init()
 | 
						|
{
 | 
						|
    os_mem_set(&prototask_contxt.sm, 0, sizeof(proto_cmd_hdl_state_t));
 | 
						|
}
 | 
						|
 | 
						|
void iot_proto_gpio_tab_init()
 | 
						|
{
 | 
						|
    uint8_t board_id = iot_board_get_board_id();
 | 
						|
    if ((CUS_BOARD_ID_LEDCSTA01 == board_id) || (CUS_BOARD_ID_LEDCCCO01 == board_id)) {
 | 
						|
        for(int i = 0; i < IOT_GE_LEDC01_VALID_GPIO_MAX; i++) {
 | 
						|
            iot_ge_gpio_g[i].gpio_num = iot_ledc01_ge_gpio_valid[i];
 | 
						|
            iot_ge_gpio_g[i].dir_mode = IOT_GE_GPIO_DIR_INPUT;
 | 
						|
            iot_ge_gpio_g[i].pull_mode = IOT_GE_GPIO_PULL_NONE;
 | 
						|
            iot_ge_gpio_g[i].gpio_state = IOT_GE_GPIO_CLOSE;
 | 
						|
            iot_gpio_open_as_input(iot_ge_gpio_g[i].gpio_num);
 | 
						|
            iot_gpio_set_pull_mode(iot_ge_gpio_g[i].gpio_num, GPIO_PULL_NONE);
 | 
						|
        }
 | 
						|
    }
 | 
						|
#if PLC_SUPPORT_STA_ROLE
 | 
						|
    if (CUS_BOARD_ID_LEDC_V3_0 == board_id &&
 | 
						|
        iot_hwver_is_ledc_v3_0_jy()) {
 | 
						|
        iot_gpio_open_as_output(HPLC_3P0_JY_EN_OUT3V3_PIN);
 | 
						|
        iot_gpio_open_as_output(HPLC_3P0_JY_EN_OUT12V_PIN);
 | 
						|
        iot_gpio_open_as_input(HPLC_3P0_JY_MONITOR_PIN);
 | 
						|
        iot_gpio_set_pull_mode(HPLC_3P0_JY_MONITOR_PIN, GPIO_PULL_UP);
 | 
						|
        iot_gpio_open_as_output(HPLC_3P0_JY_HW_WDG_PIN);
 | 
						|
        prototask_contxt.hw_watchdog_en = 1;
 | 
						|
        iot_adc_init();
 | 
						|
    }
 | 
						|
#endif
 | 
						|
    return;
 | 
						|
}
 | 
						|
 | 
						|
/* To clear command state for temporary white list & pair table operation. */
 | 
						|
void iot_proto_whitelist_state_init(void)
 | 
						|
{
 | 
						|
    os_mem_set(prototask_contxt.dev_lst.dev_tmp,
 | 
						|
        0, sizeof(proto_dev_t) * STA_DEV_MAX);
 | 
						|
    prototask_contxt.dev_lst.valid_dev_tmp_cnt = 0;
 | 
						|
    prototask_contxt.dev_lst.wl_ccofrag_cnt = 0;
 | 
						|
}
 | 
						|
 | 
						|
/* Timout handler for setting white list or pair table. */
 | 
						|
void iot_proto_wl_pt_remote_set_timeout(uint32_t state, uint32_t dir,
 | 
						|
                        uint8_t seq, uint8_t *dst_mac)
 | 
						|
{
 | 
						|
    uint32_t tmp_dir = 0;
 | 
						|
    iot_cus_printf("[glpr]" \
 | 
						|
        "wlist ptable rmt %s timeout.\n", "set");
 | 
						|
 | 
						|
    /* To switch async sm dir to sync dir to send response */
 | 
						|
    /* sm->dir means hope response from  */
 | 
						|
    if (CMD_LOCAL_UP_LINK == dir ||
 | 
						|
        CMD_REMOTE_UP_LINK == dir) {
 | 
						|
        /* tmp dir means org cmd from local down. just for unit cfm func */
 | 
						|
        tmp_dir = CMD_LOCAL_DOWN_LINK;
 | 
						|
    } else if (CMD_LOCAL_DOWN_LINK == dir ||
 | 
						|
        CMD_REMOTE_DOWN_LINK == dir) {
 | 
						|
        /* means send to remote by plc */
 | 
						|
        tmp_dir = CMD_REMOTE_UP_LINK;
 | 
						|
    }
 | 
						|
 | 
						|
    if (PROTO_CMD_WAIT_WHITE_LIST_SET == state) {
 | 
						|
        /* Timeout, so send command conform frame to uplayer. */
 | 
						|
        iot_proto_resp_cfm_frame(PROTO_REASON_TIME_OUT,
 | 
						|
            tmp_dir, PROTO_OP_WHITELIST_SET_CMD, seq, dst_mac);
 | 
						|
    }
 | 
						|
 | 
						|
    return;
 | 
						|
}
 | 
						|
 | 
						|
void iot_proto_wait_cmd_cfm_timeout(proto_cmd_hdl_state_t *sm)
 | 
						|
{
 | 
						|
    uint32_t tmp_dir = 0;
 | 
						|
    switch (sm->cur_subfn) {
 | 
						|
    case PROTO_OP_WHITELIST_SET_CMD:
 | 
						|
    case PROTO_CCO_START_GROUP_NET_CMD:
 | 
						|
    case PROTO_CCO_END_GROUP_NET_CMD:
 | 
						|
    case PROTO_REBOOT_STA_CMD:
 | 
						|
    case PROTO_GE_GPIO_SET_CMD:
 | 
						|
    case PROTO_GE_GPIO_CONFIG_CMD:
 | 
						|
    case PROTO_GE_GPIO_QUERY_CMD:
 | 
						|
    {
 | 
						|
        tmp_dir = CMD_LOCAL_DOWN_LINK;
 | 
						|
        iot_proto_resp_cfm_frame(PROTO_REASON_TIME_OUT,
 | 
						|
            tmp_dir, sm->cur_subfn, sm->seq, sm->dev.mac);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    default :
 | 
						|
        iot_cus_printf("[glpr][err]Wait cmd cfm TO,subfn=%d!\n", sm->cur_subfn);
 | 
						|
        IOT_ASSERT(0);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void iot_proto_mainboard_data_pend(iot_pkt_t *data)
 | 
						|
{
 | 
						|
    if (prototask_contxt.cache_pkt != NULL) {
 | 
						|
        iot_pkt_free(prototask_contxt.cache_pkt);
 | 
						|
    }
 | 
						|
    iot_cus_printf("cache pkt for send uart\n");
 | 
						|
 | 
						|
    prototask_contxt.cache_pkt = data;
 | 
						|
}
 | 
						|
 | 
						|
void iot_proto_resume_pkt_2_mainboard(void)
 | 
						|
{
 | 
						|
    if (prototask_contxt.cache_pkt != NULL) {
 | 
						|
        iot_proto_send_to_mainboard(prototask_contxt.cache_pkt);
 | 
						|
    }
 | 
						|
 | 
						|
    prototask_contxt.cache_pkt = NULL;
 | 
						|
}
 | 
						|
 | 
						|
/* This will send a iot_pkt_t of data to UART connected to mainboard. */
 | 
						|
void iot_proto_send_to_mainboard(iot_pkt_t *p_pkt)
 | 
						|
{
 | 
						|
    iot_cus_printf("[glpr]iot_proto_send_to_mainboard:\n");
 | 
						|
    iot_common_bin_dump(iot_pkt_data(p_pkt), iot_pkt_data_len(p_pkt));
 | 
						|
    uart_thpt.send_len += iot_pkt_data_len(p_pkt);
 | 
						|
 | 
						|
    if (prototask_contxt.proto_sendto_mainboard_fn) {
 | 
						|
        prototask_contxt.proto_sendto_mainboard_fn(p_pkt);
 | 
						|
    } else {
 | 
						|
        iot_pkt_free(p_pkt);
 | 
						|
    }
 | 
						|
 | 
						|
    return;
 | 
						|
}
 | 
						|
 | 
						|
void iot_proto_cmd_send_to_plctxrx(iot_pkt_t *p_pkt)
 | 
						|
{
 | 
						|
    if (prototask_contxt.gree_cmd_send_cb) {
 | 
						|
        prototask_contxt.gree_cmd_send_cb(p_pkt);
 | 
						|
    } else {
 | 
						|
        iot_pkt_free(p_pkt);
 | 
						|
    }
 | 
						|
 | 
						|
    return;
 | 
						|
}
 | 
						|
 | 
						|
void iot_proto_resp_cfm_frame(uint32_t resp, uint32_t dir,
 | 
						|
    uint32_t cmd, uint8_t seq, uint8_t *dst_mac)
 | 
						|
{
 | 
						|
    ge_frame_cmd_cfm_set_subfn20_t *p_cfm;
 | 
						|
    iot_pkt_t *p_pkt;
 | 
						|
    protpkt_tx_info_t info = { 0 };
 | 
						|
 | 
						|
 | 
						|
    iot_cus_printf("\n[glpr]cfm frame resp=%d, " \
 | 
						|
        "dir=%d, cmd=%d\n", resp, dir, cmd);
 | 
						|
 | 
						|
    p_pkt = iot_pkt_alloc(sizeof(*p_cfm), IOT_GREE_APP_MID);
 | 
						|
 | 
						|
    if (!p_pkt) {
 | 
						|
        iot_cus_printf("[glpr][err]No Mem!\n");
 | 
						|
        return;
 | 
						|
    }
 | 
						|
    p_cfm = (ge_frame_cmd_cfm_set_subfn20_t *)iot_pkt_data(p_pkt);
 | 
						|
    iot_proto_cfm_cmd_group(iot_pkt_put(p_pkt, sizeof(*p_cfm)),
 | 
						|
        (uint8_t)cmd, (PLCTXRX_RESP_OK == resp?0:1), (uint8_t)resp, seq);
 | 
						|
 | 
						|
    if (CMD_LOCAL_DOWN_LINK == dir) {
 | 
						|
        iot_proto_send_to_mainboard(p_pkt);
 | 
						|
    } else if (CMD_REMOTE_UP_LINK == dir) {
 | 
						|
        iot_proto_fill_txinfo(&info, 1, PLCTXRX_UNICAST, 2, 200, 1,
 | 
						|
            prototask_contxt.local_dev.mac, dst_mac);
 | 
						|
        iot_proto_remote_cmd_send_to_plctxrx
 | 
						|
            ((uint8_t *)p_cfm, sizeof(*p_cfm), &info);
 | 
						|
        iot_pkt_free(p_pkt);
 | 
						|
    } else {
 | 
						|
        iot_cus_printf("[glpr]Invalid dir!\n");
 | 
						|
        iot_pkt_free(p_pkt);
 | 
						|
    }
 | 
						|
 | 
						|
    return;
 | 
						|
}
 | 
						|
 | 
						|
void iot_proto_boot_ready_ind(uint8_t *local_mac)
 | 
						|
{
 | 
						|
    iot_pkt_t *rpt2mcu_pkt = NULL;
 | 
						|
    ge_frame_boot_ready_id_set_subfn24_t *boot_rdy_ind;
 | 
						|
 | 
						|
    rpt2mcu_pkt = iot_pkt_alloc(sizeof(*boot_rdy_ind), IOT_GREE_APP_MID);
 | 
						|
    if (rpt2mcu_pkt == NULL) {
 | 
						|
        return;
 | 
						|
    }
 | 
						|
    boot_rdy_ind =
 | 
						|
        (ge_frame_boot_ready_id_set_subfn24_t *)iot_pkt_data(rpt2mcu_pkt);
 | 
						|
    iot_pkt_put(rpt2mcu_pkt, sizeof(*boot_rdy_ind));
 | 
						|
 | 
						|
    os_mem_set(boot_rdy_ind, 0, sizeof(*boot_rdy_ind));
 | 
						|
    EXT_FN_FRM_PREPARE(boot_rdy_ind,
 | 
						|
        PROTO_GE_PLC_SET_CMD, PROTO_BOOT_READY_ID_CMD);
 | 
						|
    iot_mac_addr_cpy(boot_rdy_ind->local_mac, local_mac);
 | 
						|
    iot_proto_get_cco_mac(boot_rdy_ind->cco_mac);
 | 
						|
    boot_rdy_ind->seq = prototask_contxt.local_dev.ind_seq;
 | 
						|
    boot_rdy_ind->tail.check_sum = ge_frm_checksum_calc((uint8_t *)boot_rdy_ind,
 | 
						|
        sizeof(*boot_rdy_ind) - sizeof(ge_frm_tail_t));
 | 
						|
    iot_proto_send_to_mainboard(rpt2mcu_pkt);
 | 
						|
}
 | 
						|
 | 
						|
static void iot_proto_save_cmd(proto_msg_saved_list_t *list, uint8_t *data,
 | 
						|
    uint16_t len, plctxrx_rx_data_info_t *rx_info, transmit_direction_e_t dir,
 | 
						|
    uint16_t msg_id, uint16_t msg_type)
 | 
						|
{
 | 
						|
    proto_savedmsg_node_t *msg_node = iot_proto_msgnode_alloc(saved_msg_q);
 | 
						|
    iot_pkt_t *cmd_data;
 | 
						|
    uint8_t rxinfo_len = 0;
 | 
						|
    if (!msg_node) {
 | 
						|
        iot_cus_printf("[glpr][err]save cmd:msg pool is empty!\n");
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    if (rx_info) {
 | 
						|
        /* add rx_info and remove preamble,checksum and tail code */
 | 
						|
        rxinfo_len = sizeof(*rx_info);
 | 
						|
        len -= (GE_FRM_PREAMBLE_FIELD_LEN + GE_FRM_CHECKSUM_FIELD_LEN +
 | 
						|
            GE_FRM_TAIL_FILED_LEN);
 | 
						|
        data += GE_FRM_PREAMBLE_FIELD_LEN;
 | 
						|
    }
 | 
						|
    cmd_data = iot_pkt_alloc(len + rxinfo_len, IOT_GREE_APP_MID);
 | 
						|
    IOT_ASSERT(cmd_data);
 | 
						|
    if (rxinfo_len > 0) {
 | 
						|
        os_mem_cpy(iot_pkt_data(cmd_data), rx_info, sizeof(*rx_info));
 | 
						|
    }
 | 
						|
    os_mem_cpy(iot_pkt_data(cmd_data) + rxinfo_len, data, len);
 | 
						|
    iot_pkt_put(cmd_data, len + rxinfo_len);
 | 
						|
 | 
						|
    msg_node->data = cmd_data;
 | 
						|
    msg_node->dir  = dir;
 | 
						|
    msg_node->msg_id = msg_id;
 | 
						|
    msg_node->msg_type = msg_type;
 | 
						|
    iot_cus_printf("[glpr]save cmd:msg node=0x%x, node=0x%x\n", msg_node,
 | 
						|
        &msg_node->node);
 | 
						|
    iot_proto_savedmsg_list_push_backend(list, &msg_node->node);
 | 
						|
}
 | 
						|
 | 
						|
/* Return the index of mac in this dev_tb if found. */
 | 
						|
int32_t iot_proto_check_mac_exists(uint8_t *mac, proto_dev_t *dev_tb,
 | 
						|
    uint16_t valid_cnt)
 | 
						|
{
 | 
						|
    uint16_t i;
 | 
						|
    IOT_ASSERT(mac && dev_tb);
 | 
						|
    for (i = 0; i < valid_cnt; i++) {
 | 
						|
        if (iot_mac_addr_cmp(dev_tb[i].mac, mac))
 | 
						|
            return i;
 | 
						|
    }
 | 
						|
 | 
						|
    return -1;
 | 
						|
}
 | 
						|
 | 
						|
/* Return the index of new_wl in this dev_tb if aaded. */
 | 
						|
void iot_proto_add_wl_to_tmp(proto_dev_t *dev)
 | 
						|
{
 | 
						|
    proto_dev_t free_dev = { 0 };
 | 
						|
    proto_dev_list_t *dev_list = &prototask_contxt.dev_lst;
 | 
						|
    uint16_t cnt;
 | 
						|
 | 
						|
    IOT_ASSERT(dev);
 | 
						|
 | 
						|
    /* check if temporary list of whitelist is full */
 | 
						|
    if (dev_list->valid_dev_tmp_cnt >= STA_DEV_MAX)
 | 
						|
        return;
 | 
						|
 | 
						|
    /* Get a free place to store  */
 | 
						|
    for (cnt = 0; cnt < STA_DEV_MAX; cnt++) {
 | 
						|
        if (iot_mac_addr_cmp(free_dev.mac, dev_list->dev_tmp[cnt].mac)) {
 | 
						|
            os_mem_cpy(&dev_list->dev_tmp[cnt], dev, sizeof(proto_dev_t));
 | 
						|
            break;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /* device added */
 | 
						|
    if (cnt < STA_DEV_MAX) {
 | 
						|
        dev_list->valid_dev_tmp_cnt++;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void iot_proto_reboot_delay_timeout_timer(timer_id_t timer_id,
 | 
						|
                                            void * arg)
 | 
						|
{
 | 
						|
    (void)arg;
 | 
						|
    (void)timer_id;
 | 
						|
 | 
						|
     iot_proto_task_post_msg(PROTO_TIMER_MSG, PROTO_TIMER_REBOOT_STA_TIMEOUT,
 | 
						|
            NULL, 0, IOT_PROTO_TASK_QUEUE_LP);
 | 
						|
}
 | 
						|
 | 
						|
static void iot_proto_reboot_delay_timeout_handler(void)
 | 
						|
{
 | 
						|
    uint8_t reason = prototask_contxt.reboot_reason;
 | 
						|
    switch (reason) {
 | 
						|
    case REBOOT_ASSERT:
 | 
						|
    {
 | 
						|
        /* creat assert */
 | 
						|
        iot_cus_printf("[glpr]recv assert cmd\n");
 | 
						|
        IOT_ASSERT(0);
 | 
						|
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case REBOOT_WRITE_ZERO_ADDR:
 | 
						|
    {
 | 
						|
        /* recv test cmd to write 0 address */
 | 
						|
        iot_cus_printf("[glpr]test write zero address\n");
 | 
						|
        *((int *)(NULL)) = 0x7e7e7e7e;
 | 
						|
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case REBOOT_NORMAL:
 | 
						|
    default:
 | 
						|
        iot_cus_printf("[glpr] reboot cmd excuted\n");
 | 
						|
        iot_system_restart(IOT_SYS_RST_REASON_APP_REQ);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void iot_proto_sta_leave_delay_timeout_timer(timer_id_t timer_id,
 | 
						|
                                            void * arg)
 | 
						|
{
 | 
						|
    (void)arg;
 | 
						|
    (void)timer_id;
 | 
						|
 | 
						|
     iot_proto_task_post_msg(PROTO_TIMER_MSG, PROTO_TIMER_STA_LEAVE_TIMEOUT,
 | 
						|
            NULL, 0, IOT_PROTO_TASK_QUEUE_LP);
 | 
						|
}
 | 
						|
 | 
						|
static void iot_proto_sta_leave_delay_timeout_handler(void)
 | 
						|
{
 | 
						|
    proto_cmd_hdl_state_t *sm = iot_proto_cmd_handle_state_get();
 | 
						|
    plctxrx_cmd_arg_t *p_arg;
 | 
						|
    plctxrx_cmd_leave_net_t *p_leave;
 | 
						|
    iot_pkt_t *p_pkt;
 | 
						|
    uint32_t pkt_len;
 | 
						|
 | 
						|
    pkt_len = sizeof(*p_arg) + sizeof(*p_leave) + IOT_MAC_ADDR_LEN;
 | 
						|
    if (NULL == (p_pkt = iot_pkt_alloc(pkt_len, IOT_GREE_APP_MID))) {
 | 
						|
        iot_cus_printf("[glpr][err]No Mem!\n");
 | 
						|
    }
 | 
						|
 | 
						|
    p_arg = (plctxrx_cmd_arg_t *)iot_pkt_put(p_pkt, pkt_len);
 | 
						|
    p_leave = (plctxrx_cmd_leave_net_t *)p_arg->arg;
 | 
						|
 | 
						|
    p_arg->cid.cid = PLCTXRX_CID_LEAVE_NETWORK;
 | 
						|
    p_arg->cid.opcode = PLCTXRX_OP_CONFIG;
 | 
						|
    p_arg->prio = 0;
 | 
						|
    p_arg->need_ack = true;
 | 
						|
    p_arg->dlen = sizeof(*p_leave);
 | 
						|
 | 
						|
    p_leave->cnt = 1;
 | 
						|
    iot_mac_addr_cpy(p_leave->mac[0], prototask_contxt.cco_dev.mac);
 | 
						|
 | 
						|
    /* set sm state */
 | 
						|
    sm->state = PROTO_CMD_WAIT_CMD_CFM;
 | 
						|
    sm->dir = CMD_LOCAL_UP_LINK;
 | 
						|
    sm->seq = 0;//p_frame->seq;
 | 
						|
    sm->cur_subfn = PROTO_LEAVE_NW_SET_CMD;
 | 
						|
    iot_cus_printf("[glpr]sta leaving network\n");
 | 
						|
 | 
						|
    iot_proto_cmd_send_to_plctxrx(p_pkt);
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
static void iot_proto_statistic_timer(timer_id_t timer_id, void * arg)
 | 
						|
{
 | 
						|
    (void)arg;
 | 
						|
    (void)timer_id;
 | 
						|
 | 
						|
     iot_proto_task_post_msg(PROTO_TIMER_MSG, PROTO_TIMER_STATISTIC,
 | 
						|
            NULL, 0, IOT_PROTO_TASK_QUEUE_LP);
 | 
						|
}
 | 
						|
 | 
						|
static void iot_proto_statistic_infor_update(void)
 | 
						|
{
 | 
						|
    proto_dev_list_t *dev_lst = &prototask_contxt.dev_lst;
 | 
						|
 | 
						|
    prototask_contxt.statistic_cnt++;
 | 
						|
    if (prototask_contxt.statistic_cnt % PROTO_STASTIC_UPDATE_INTVL_CNT == 0) {
 | 
						|
        uart_thpt.recv_rate = (uart_thpt.recv_len * 2) / PROTO_STASTIC_UPDATE_INTVL_CNT;
 | 
						|
        uart_thpt.send_rate = (uart_thpt.send_len * 2) / PROTO_STASTIC_UPDATE_INTVL_CNT;
 | 
						|
 | 
						|
        uart_thpt.recv_len = 0;
 | 
						|
        uart_thpt.send_len = 0;
 | 
						|
        prototask_contxt.statistic_cnt = 0;
 | 
						|
 | 
						|
        iot_cus_printf("[glpr]software version:%d.%d.%d.%d\n", iot_version_major(),
 | 
						|
            iot_version_minor(), iot_version_micro(), iot_version_build());
 | 
						|
 | 
						|
    }
 | 
						|
    /* change cco network done state */
 | 
						|
    if (IOT_PLC_DEV_ROLE_CCO == prototask_contxt.local_dev.nw_role) {
 | 
						|
        if (prototask_contxt.flashinfo.public.pub.wl_state &&
 | 
						|
            (dev_lst->online_dev_cnt > 0) &&
 | 
						|
            (dev_lst->online_dev_cnt == dev_lst->valid_dev_cnt)) {
 | 
						|
            if (prototask_contxt.cco_net_done == 0) {
 | 
						|
                prototask_contxt.cco_net_done = 1;
 | 
						|
                iot_plc_led_request(IOT_PLC_LED_NET_FORMAT_DONE);
 | 
						|
            }
 | 
						|
        } else {
 | 
						|
            if (prototask_contxt.cco_net_done == 1) {
 | 
						|
                prototask_contxt.cco_net_done = 0;
 | 
						|
                iot_plc_led_request(IOT_PLC_LED_DIS_ASSOCIATED);
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
    if (prototask_contxt.statistic_cnt % PROTO_TIMER_GY_FEED_WDG_INTVL_CNT == 0) {
 | 
						|
        if ((IOT_PLC_DEV_ROLE_STA == prototask_contxt.local_dev.nw_role) &&
 | 
						|
            (CUS_BOARD_ID_LEDC_V3_0 == iot_board_get_board_id()) &&
 | 
						|
            iot_hwver_is_ledc_v3_0_jy() &&
 | 
						|
            prototask_contxt.hw_watchdog_en) {
 | 
						|
            iot_gpio_value_set(HPLC_3P0_JY_HW_WDG_PIN,
 | 
						|
                prototask_contxt.hw_watchdog_out);
 | 
						|
            prototask_contxt.hw_watchdog_out = !prototask_contxt.hw_watchdog_out;
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * @brief iot_proto_check_trial_run_pass(): do trial run check, if trial run
 | 
						|
 *                 fail and not join the network, need roll back software,
 | 
						|
 *                 only sta need to do this check.
 | 
						|
 */
 | 
						|
static void iot_proto_check_trial_run_pass(void)
 | 
						|
{
 | 
						|
    ge_app_pib_info_t *p_flash = &prototask_contxt.flashinfo;
 | 
						|
 | 
						|
    iot_cus_printf("[glpr]check trial_run_pass = %d\n",
 | 
						|
        p_flash->public.pub.trial_run_pass);
 | 
						|
    if (prototask_contxt.local_dev.nw_role == IOT_PLC_DEV_ROLE_STA &&
 | 
						|
        p_flash->public.pub.trial_run_pass == false) {
 | 
						|
        /* not join netwrok will switch boot part */
 | 
						|
        if (prototask_contxt.local_dev.dev_ready) {
 | 
						|
            p_flash->public.pub.trial_run_pass = true;
 | 
						|
            iot_cus_printf("[glpr]change trial_run_pass to true\n");
 | 
						|
            iot_proto_flashsave(p_flash);
 | 
						|
        } else {
 | 
						|
            iot_cus_printf("[glpr]switch boot part because trial run fail\n");
 | 
						|
            iot_switch_boot_part();
 | 
						|
            iot_system_restart(IOT_SYS_RST_REASON_APP_REQ);
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void iot_proto_statistic_timer_timeout_handler(void)
 | 
						|
{
 | 
						|
    iot_proto_statistic_infor_update();
 | 
						|
}
 | 
						|
 | 
						|
static void iot_proto_brd_data_rpt_window_timer(timer_id_t timer_id, void * arg)
 | 
						|
{
 | 
						|
    (void)arg;
 | 
						|
    (void)timer_id;
 | 
						|
 | 
						|
     iot_proto_task_post_msg(PROTO_TIMER_MSG, PROTO_TIMER_BRD_PKT_WINDOW_RPT,
 | 
						|
         NULL, 0, IOT_PROTO_TASK_QUEUE_LP);
 | 
						|
}
 | 
						|
 | 
						|
#if IOT_GE_PAGING_ENABLE
 | 
						|
static void iot_proto_paging_timer(timer_id_t timer_id, void * arg)
 | 
						|
{
 | 
						|
    (void)arg;
 | 
						|
    (void)timer_id;
 | 
						|
 | 
						|
     iot_proto_task_post_msg(PROTO_TIMER_MSG, PROTO_TIMER_PAGING_TIMEOUT,
 | 
						|
         NULL, 0, IOT_PROTO_TASK_QUEUE_LP);
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
static void iot_proto_trial_run_check_timer(timer_id_t timer_id, void * arg)
 | 
						|
{
 | 
						|
    (void)arg;
 | 
						|
    (void)timer_id;
 | 
						|
 | 
						|
     iot_proto_task_post_msg(PROTO_TIMER_MSG, PROTO_TIMER_TRIAL_RUN_CHECK,
 | 
						|
         NULL, 0, IOT_PROTO_TASK_QUEUE_LP);
 | 
						|
}
 | 
						|
 | 
						|
#if PLC_SUPPORT_STA_ROLE
 | 
						|
static void iot_proto_645_local_mode_timer(timer_id_t timer_id, void * arg)
 | 
						|
{
 | 
						|
    (void)arg;
 | 
						|
    (void)timer_id;
 | 
						|
 | 
						|
     iot_proto_task_post_msg(PROTO_TIMER_MSG, PROTO_TIMER_645_LOCAL_MODE,
 | 
						|
         NULL, 0, IOT_PROTO_TASK_QUEUE_LP);
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
static void iot_proto_brd_data_rpt_window_timer_handler(void)
 | 
						|
{
 | 
						|
    uint8_t *ptr = NULL;
 | 
						|
    iot_pkt_t *pkt =NULL;
 | 
						|
    uint16_t len = prototask_contxt.rpt_cache.data_len;
 | 
						|
    if (len != 0) {
 | 
						|
        pkt = iot_pkt_alloc(len, IOT_GREE_APP_MID);
 | 
						|
        if (pkt == NULL) {
 | 
						|
            iot_cus_printf("[grpr]NO memery, sending cached pkt failed\n");
 | 
						|
            return;
 | 
						|
        }
 | 
						|
        ptr = iot_pkt_data(pkt);
 | 
						|
        iot_pkt_put(pkt, len);
 | 
						|
        os_mem_cpy(ptr, prototask_contxt.rpt_cache.data, len);
 | 
						|
 | 
						|
        iot_proto_send_to_mainboard(pkt);
 | 
						|
        os_mem_set(&prototask_contxt.rpt_cache, 0, sizeof(proto_rpt_cache_t));
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
#if PLC_SUPPORT_CCO_ROLE
 | 
						|
static void iot_proto_sta_paging_timer_handler(void)
 | 
						|
{
 | 
						|
    iot_proto_sta_paging_mac();
 | 
						|
}
 | 
						|
#else
 | 
						|
static void iot_proto_sta_paging_timer_handler(void)
 | 
						|
{
 | 
						|
    /* for sta do nothing*/
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
void iot_proto_add_wl_tmp2formal(void)
 | 
						|
{
 | 
						|
    uint32_t i, j;
 | 
						|
    proto_dev_t *p_tmp_table, *p_formal_table;
 | 
						|
    uint16_t tmp_cnt, valid_cnt;
 | 
						|
    proto_dev_t free_dev = { 0 };
 | 
						|
    proto_dev_list_t *p_dev_list = &prototask_contxt.dev_lst;
 | 
						|
 | 
						|
    tmp_cnt = p_dev_list->valid_dev_tmp_cnt;
 | 
						|
    valid_cnt = p_dev_list->valid_dev_cnt;
 | 
						|
    p_tmp_table = p_dev_list->dev_tmp;
 | 
						|
    p_formal_table = p_dev_list->dev;
 | 
						|
 | 
						|
    if ((tmp_cnt + valid_cnt) > STA_DEV_MAX)
 | 
						|
        tmp_cnt = STA_DEV_MAX - valid_cnt;
 | 
						|
 | 
						|
    p_dev_list->valid_dev_cnt = tmp_cnt + valid_cnt;
 | 
						|
 | 
						|
    for (i = 0, j = 0; (i < STA_DEV_MAX) && (j < tmp_cnt); i++) {
 | 
						|
        if (iot_mac_addr_cmp(free_dev.mac, p_formal_table[i].mac)) {
 | 
						|
            p_formal_table[i] = p_tmp_table[j++];
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    return;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void iot_proto_del_wl_from_formal(void)
 | 
						|
{
 | 
						|
    uint32_t i, j;
 | 
						|
    proto_dev_t *p_tmp_table, *p_formal_table;
 | 
						|
    uint16_t tmp_cnt, valid_cnt;
 | 
						|
    proto_dev_t free_dev = { 0 };
 | 
						|
 | 
						|
    tmp_cnt = prototask_contxt.dev_lst.valid_dev_tmp_cnt;
 | 
						|
    valid_cnt = prototask_contxt.dev_lst.valid_dev_cnt;
 | 
						|
 | 
						|
    p_tmp_table = prototask_contxt.dev_lst.dev_tmp;
 | 
						|
    p_formal_table = prototask_contxt.dev_lst.dev;
 | 
						|
 | 
						|
    if (tmp_cnt > valid_cnt) {
 | 
						|
        iot_cus_printf("[gepr]tmp cnt=%d > valid cnt=%d\n", tmp_cnt, valid_cnt);
 | 
						|
        IOT_ASSERT(0);
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    prototask_contxt.dev_lst.valid_dev_cnt -= tmp_cnt;
 | 
						|
    /* delete device that need to be deleted in valid pair list */
 | 
						|
    for (i = 0; i < tmp_cnt; i++) {
 | 
						|
        for (j = 0; j < STA_DEV_MAX; j++) {
 | 
						|
            if (iot_mac_addr_cmp(p_formal_table[j].mac, p_tmp_table[i].mac)) {
 | 
						|
                os_mem_set(&p_formal_table[j], 0, sizeof(proto_dev_t));
 | 
						|
                if (prototask_contxt.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 */
 | 
						|
                    prototask_contxt.dev_lst.online_flag[j] = false;
 | 
						|
                }
 | 
						|
                break;
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /* clear temporary source buffer */
 | 
						|
    os_mem_set(p_tmp_table, 0, sizeof(proto_dev_t) * STA_DEV_MAX);
 | 
						|
 | 
						|
    /* re-org formal tbl. move empty, cached in tmp  */
 | 
						|
    for (i = 0, j = 0; i < STA_DEV_MAX && j < STA_DEV_MAX; i++) {
 | 
						|
        /**
 | 
						|
         * if device in dest table is not a free device
 | 
						|
         * then copy it to source tmporary buffer one by one.
 | 
						|
         */
 | 
						|
        if (!iot_mac_addr_cmp(free_dev.mac, p_formal_table[i].mac)) {
 | 
						|
            p_tmp_table[j] = p_formal_table[i];
 | 
						|
            j++;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    /* make the result back to normal tbl */
 | 
						|
    os_mem_cpy(p_formal_table, p_tmp_table, sizeof(proto_dev_t) * STA_DEV_MAX);
 | 
						|
 | 
						|
    return;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
Add/Delete white list to/from CVG level.
 | 
						|
action : 0 - delete; 1 - add.
 | 
						|
need_ack_cfm : true - plctxrx will ack cfm; false - No ack cfm.
 | 
						|
*/
 | 
						|
void iot_proto_whitelist_add_remove(uint8_t action, uint8_t *mac,
 | 
						|
    bool_t need_ack_cfm)
 | 
						|
{
 | 
						|
    uint16_t cnt, frag_cnt, i = 0, j = 0;
 | 
						|
    iot_pkt_t *p_pkt;
 | 
						|
    plctxrx_cmd_whitelist_t *p_wlist;
 | 
						|
    plctxrx_cmd_arg_t *p_arg;
 | 
						|
    uint16_t loop_cnt = 0;
 | 
						|
    uint16_t index = 0;
 | 
						|
 | 
						|
    /* one mac op or full table */
 | 
						|
    if (mac) {
 | 
						|
        cnt = 1;
 | 
						|
    } else {
 | 
						|
        cnt = prototask_contxt.dev_lst.valid_dev_tmp_cnt;
 | 
						|
        if (0 == cnt)
 | 
						|
            return;
 | 
						|
    }
 | 
						|
 | 
						|
    loop_cnt = (cnt <= PROTO_SET_CVG_WL_FRAG_CNT)?
 | 
						|
        1:(cnt/PROTO_SET_CVG_WL_FRAG_CNT
 | 
						|
        + (((cnt%PROTO_SET_CVG_WL_FRAG_CNT) == 0)?0:1));
 | 
						|
 | 
						|
    iot_cus_printf("[glpr]loop_cnt=%d,total_cnt=%d!\n",
 | 
						|
        loop_cnt, prototask_contxt.dev_lst.valid_dev_tmp_cnt);
 | 
						|
 | 
						|
    for (i = 1; i <= loop_cnt; i++) {
 | 
						|
        if (i*PROTO_SET_CVG_WL_FRAG_CNT > cnt) {
 | 
						|
            frag_cnt = cnt - (i - 1)*PROTO_SET_CVG_WL_FRAG_CNT;
 | 
						|
        } else {
 | 
						|
            frag_cnt = PROTO_SET_CVG_WL_FRAG_CNT;
 | 
						|
        }
 | 
						|
        p_pkt = iot_pkt_alloc(sizeof(*p_wlist) + sizeof(*p_arg) +
 | 
						|
            frag_cnt * IOT_MAC_ADDR_LEN, IOT_GREE_APP_MID);
 | 
						|
        if (!p_pkt) {
 | 
						|
            iot_cus_printf("[glpr][err]No Mem!\n");
 | 
						|
            return;
 | 
						|
        }
 | 
						|
 | 
						|
        p_arg = (plctxrx_cmd_arg_t *)iot_pkt_put(p_pkt, sizeof(*p_wlist) +
 | 
						|
            sizeof(*p_arg) + frag_cnt * IOT_MAC_ADDR_LEN);
 | 
						|
 | 
						|
        p_arg->cid.cid = PLCTXRX_CID_WHITELIST;
 | 
						|
        p_arg->cid.opcode = PLCTXRX_OP_CONFIG;
 | 
						|
        p_arg->prio = 0;
 | 
						|
        /* if proto layer need a confirm from plctxrx,
 | 
						|
         * then we make the last packet to response
 | 
						|
         * confirm cmd.
 | 
						|
         */
 | 
						|
        if (i + 1 > loop_cnt && true == need_ack_cfm) {
 | 
						|
            p_arg->need_ack = need_ack_cfm;
 | 
						|
        } else {
 | 
						|
            p_arg->need_ack = false;
 | 
						|
        }
 | 
						|
        p_arg->dlen = sizeof(*p_wlist) + frag_cnt * IOT_MAC_ADDR_LEN;
 | 
						|
        p_wlist = (plctxrx_cmd_whitelist_t *)p_arg->arg;
 | 
						|
        /* TODO need refine magic num */
 | 
						|
        p_wlist->action = action;
 | 
						|
        for (j = 0; j < frag_cnt; j++) {
 | 
						|
            index = (i - 1) * PROTO_SET_CVG_WL_FRAG_CNT + j;
 | 
						|
            if (mac) {
 | 
						|
                iot_mac_addr_cpy(p_wlist->maclist[j], mac);
 | 
						|
            } else {
 | 
						|
                iot_mac_addr_cpy(p_wlist->maclist[j],
 | 
						|
                    prototask_contxt.dev_lst.dev_tmp[index].mac);
 | 
						|
            }
 | 
						|
        }
 | 
						|
        p_wlist->listcnt = frag_cnt;
 | 
						|
        iot_proto_cmd_send_to_plctxrx(p_pkt);
 | 
						|
    }
 | 
						|
 | 
						|
    return;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
Clear white list from CVG layer.
 | 
						|
need_ack_cfm : true - plctxrx will ack cfm; false - No ack cfm.
 | 
						|
*/
 | 
						|
void iot_proto_whitelist_remove_all(bool_t need_ack_cfm)
 | 
						|
{
 | 
						|
    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 = GE_PROTO_ACTION_DEL_ALL;
 | 
						|
    p_wlist->listcnt = 0;
 | 
						|
 | 
						|
    iot_proto_cmd_send_to_plctxrx(p_pkt);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
This function will forword these frames that SET/QUERY white list.
 | 
						|
*/
 | 
						|
bool_t iot_proto_wl_or_pt_remote_set_or_query_to_cco
 | 
						|
    (uint8_t *data, uint16_t len, transmit_direction_e_t dir, uint8_t wait_type)
 | 
						|
{
 | 
						|
    (void)dir;
 | 
						|
    uint32_t cur_index = 0, total_index = 0;
 | 
						|
    protpkt_tx_info_t info = { 0 };
 | 
						|
    proto_cmd_hdl_state_t *sm = iot_proto_cmd_handle_state_get();
 | 
						|
    uint8_t wait_resp = 0;
 | 
						|
 | 
						|
    if (PROTO_CMD_WAIT_RMT_WHITELIST_CFM == wait_type) {
 | 
						|
        iot_cus_printf("[glpr]set whitelist to CCO.\n");
 | 
						|
        wait_resp = PROTO_CMD_WAIT_CMD_CFM;
 | 
						|
        /* AA AA 0B FE 05 ACTION 00 SEQ TOTAL_L TOTAL_H CUR_L CUR_H MAC0~5 SUM FF */
 | 
						|
        cur_index = 10;
 | 
						|
        total_index = 8;
 | 
						|
    } else if (PROTO_CMD_WAIT_RMT_WHITELIST_RESP == wait_type) {
 | 
						|
        iot_cus_printf("[glpr]query whitelist from CCO.\n");
 | 
						|
        wait_resp = PROTO_CMD_WAIT_RMT_WHITELIST_RESP;
 | 
						|
    }
 | 
						|
 | 
						|
    iot_proto_fill_txinfo(&info, 1, PLCTXRX_UNICAST, 2, 200, 1,
 | 
						|
        prototask_contxt.local_dev.mac, prototask_contxt.cco_dev.mac);
 | 
						|
 | 
						|
    if (PROTO_CMD_WAIT_RMT_WHITELIST_RESP == wait_resp) {
 | 
						|
        /* The 1st frame to start waiting resp tmr. */
 | 
						|
        sm->state = wait_resp;
 | 
						|
        sm->dir = CMD_REMOTE_UP_LINK; /* CFM up to mcu */
 | 
						|
    } else {
 | 
						|
        /* The last frame to switch waiting event as CFM. */
 | 
						|
        if ((data[cur_index] == data[total_index]) &&
 | 
						|
            (data[cur_index + 1] == data[total_index + 1])) {
 | 
						|
            sm->state = wait_resp;
 | 
						|
            sm->dir = CMD_REMOTE_UP_LINK; /* CFM up to mcu */
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    iot_proto_remote_cmd_send_to_plctxrx(data, len, &info);
 | 
						|
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
#if ENABLE_GE_DATA_SEND_TO_BEACON
 | 
						|
void iot_proto_vendor_info_set(uint8_t *p_passd,
 | 
						|
    bool_t need_ack, uint8_t net_start_flag)
 | 
						|
{
 | 
						|
    (void)p_passd;
 | 
						|
    (void)need_ack;
 | 
						|
    (void)net_start_flag;
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
void iot_proto_set_tx_power(uint8_t tx_power, uint8_t need_ack)
 | 
						|
{
 | 
						|
    iot_pkt_t *cmd_pkt;
 | 
						|
    plctxrx_cmd_arg_t cmd = { 0 };
 | 
						|
    plctxrx_cmd_tx_pwr_t tx_pwr;
 | 
						|
 | 
						|
    cmd.cid.cid = PLCTXRX_CID_TX_PWR;
 | 
						|
    cmd.cid.opcode = PLCTXRX_OP_CONFIG;
 | 
						|
    cmd.prio = 0;
 | 
						|
    cmd.need_ack = need_ack;
 | 
						|
    cmd.dlen = sizeof(plctxrx_cmd_tx_pwr_t);
 | 
						|
    /* alloc packet for sending cmd */
 | 
						|
    cmd_pkt = iot_pkt_alloc(sizeof(plctxrx_cmd_arg_t) + cmd.dlen,
 | 
						|
     IOT_GREE_APP_MID);
 | 
						|
    IOT_ASSERT(cmd_pkt);
 | 
						|
 | 
						|
    tx_pwr.tx_pwr = tx_power;
 | 
						|
    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), &tx_pwr, cmd.dlen);
 | 
						|
    /* send cmd to plctxrx layer */
 | 
						|
    iot_proto_cmd_send_to_plctxrx(cmd_pkt);
 | 
						|
}
 | 
						|
 | 
						|
void iot_proto_set_mac(uint8_t *mac, uint8_t dev_type, uint8_t need_ack)
 | 
						|
{
 | 
						|
    plctxrx_cmd_arg_t *plctxrx_cmd;
 | 
						|
    plctxrx_handle_mac_t *hd_mac;
 | 
						|
    iot_pkt_t *cmd_pkt = NULL;
 | 
						|
    uint16_t data_len = sizeof(*plctxrx_cmd) + sizeof(*hd_mac);
 | 
						|
    ge_app_pib_info_t *p_flash = &prototask_contxt.flashinfo;
 | 
						|
 | 
						|
    /* alloc packet for sending cmd */
 | 
						|
    cmd_pkt = iot_pkt_alloc(data_len, IOT_GREE_APP_MID);
 | 
						|
    if (cmd_pkt == NULL) {
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    prototask_contxt.macaddr_set = 1;
 | 
						|
    iot_mac_addr_cpy(prototask_contxt.local_dev.mac, mac);
 | 
						|
 | 
						|
    plctxrx_cmd = (plctxrx_cmd_arg_t*)iot_pkt_put(cmd_pkt, data_len);
 | 
						|
    plctxrx_cmd->cid.cid = PLCTXRX_CID_MAC;
 | 
						|
    plctxrx_cmd->cid.opcode = PLCTXRX_OP_CONFIG;
 | 
						|
    plctxrx_cmd->prio = 0;
 | 
						|
    plctxrx_cmd->need_ack = need_ack;
 | 
						|
    plctxrx_cmd->dlen = sizeof(plctxrx_handle_mac_t);
 | 
						|
 | 
						|
    hd_mac = (plctxrx_handle_mac_t*)plctxrx_cmd->arg;
 | 
						|
 | 
						|
    if (dev_type) {
 | 
						|
        hd_mac->dev_type = dev_type;
 | 
						|
    } else {
 | 
						|
#if PLC_SUPPORT_CCO_ROLE
 | 
						|
        hd_mac->dev_type = IOT_PLC_DEV_TYPE_CONCENTRATOR;
 | 
						|
#else
 | 
						|
        hd_mac->dev_type = IOT_PLC_DEV_TYPE_POWER_METER;
 | 
						|
#endif
 | 
						|
    }
 | 
						|
    iot_mac_addr_cpy(hd_mac->mac, mac);
 | 
						|
 | 
						|
    iot_cus_printf("[glpr]set mac addr downto plctxrx!\n");
 | 
						|
    /* send cmd to plctxrx layer */
 | 
						|
    iot_proto_cmd_send_to_plctxrx(cmd_pkt);
 | 
						|
 | 
						|
    /* 不需要回复ack且mac地址和存储地址不一样时需要存储flash */
 | 
						|
    if (!need_ack) {
 | 
						|
        iot_proto_cmd_handle_state_init();
 | 
						|
        if (!iot_mac_addr_cmp(p_flash->public.pub.local_mac, mac)) {
 | 
						|
            /* save new mac */
 | 
						|
            iot_mac_addr_cpy(p_flash->public.pub.local_mac, mac);
 | 
						|
            iot_proto_flashsave(p_flash);
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/* set flash mac or oem mac */
 | 
						|
void iot_proto_set_local_mac(void)
 | 
						|
{
 | 
						|
    uint8_t mac[IOT_MAC_ADDR_LEN] = { 0 };
 | 
						|
    ge_app_pib_info_t *p_flash = &prototask_contxt.flashinfo;
 | 
						|
 | 
						|
    if (iot_mac_addr_valid(p_flash->public.pub.local_mac)) {
 | 
						|
        /* set saved flash mac */
 | 
						|
        iot_mac_addr_cpy(mac, p_flash->public.pub.local_mac);
 | 
						|
    } else {
 | 
						|
        /* use oem mac */
 | 
						|
        iot_oem_get_module_mac(mac);
 | 
						|
    }
 | 
						|
 | 
						|
    iot_proto_set_mac(mac, 0, false);
 | 
						|
    /* report boot ready */
 | 
						|
    iot_proto_boot_ready_ind(mac);
 | 
						|
}
 | 
						|
 | 
						|
#if IOT_PSRAM_ENABLE
 | 
						|
static bool_t iot_proto_sw_uart_mode_handler(uint8_t *data,
 | 
						|
    uint16_t len, transmit_direction_e_t dir)
 | 
						|
{
 | 
						|
    (void)dir;
 | 
						|
    bool_t rpt2mcu =false;
 | 
						|
    uint8_t reason = PROTO_REASON_OK;
 | 
						|
    uint8_t uart_mode = 0;
 | 
						|
    iot_pkt_t *pkt;
 | 
						|
    ge_frame_cmd_cfm_set_subfn20_t *cfm_cmd;
 | 
						|
    ge_frame_sw_uart_mode_set_subfn27_t *set_cmd = (ge_frame_sw_uart_mode_set_subfn27_t *)data;
 | 
						|
    iot_oem_base_cfg_t *oem_base_cfg;
 | 
						|
    /* check param */
 | 
						|
    if (len != sizeof(*set_cmd)) {
 | 
						|
        reason = PROTO_REASON_LEN_MISSMATCH;
 | 
						|
    } else if (uart_mode == GR_AT_OP_MODE) {
 | 
						|
        reason = PROTO_REASON_DUP_SETTING;
 | 
						|
    }
 | 
						|
 | 
						|
    iot_cus_printf("[glpr]iot_proto_sw_uart_mode_handler\n");
 | 
						|
    if (PROTO_REASON_OK == reason) {
 | 
						|
        /* save uart mnode to oem */
 | 
						|
        iot_oem_get_base_cfg(&oem_base_cfg);
 | 
						|
        oem_base_cfg->iotapp_mode = GR_AT_OP_MODE;
 | 
						|
 | 
						|
        if (ERR_OK != iot_oem_set_base_cfg(oem_base_cfg)) {
 | 
						|
            iot_cus_printf("[glpr]set oem cfg uart mode error\n");
 | 
						|
            reason = PROTO_REASON_SWITCH_UART_MODE_ERR;
 | 
						|
        } else{
 | 
						|
            iot_cus_printf("[glpr]system will reboot after 3 seconds\n");
 | 
						|
            os_start_timer(prototask_contxt.reboot_tmr,
 | 
						|
                PROTO_TMR_SW_UART_MODE_DELAY_INTVL);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /* 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;
 | 
						|
}
 | 
						|
#else
 | 
						|
static bool_t iot_proto_sw_uart_mode_handler(uint8_t *data,
 | 
						|
    uint16_t len, transmit_direction_e_t dir)
 | 
						|
{
 | 
						|
    (void)len;
 | 
						|
    (void)dir;
 | 
						|
    bool_t rpt2mcu =false;
 | 
						|
    iot_pkt_t *pkt;
 | 
						|
    ge_frame_cmd_cfm_set_subfn20_t *cfm_cmd;
 | 
						|
    ge_frame_sw_uart_mode_set_subfn27_t *set_cmd = (ge_frame_sw_uart_mode_set_subfn27_t *)data;
 | 
						|
 | 
						|
    iot_cus_printf("[glpr][err]not support switch to GE mode\n");
 | 
						|
    /* 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 = PROTO_REASON_NOT_SUPPORT;
 | 
						|
    cfm_cmd->result = 1;
 | 
						|
    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;
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
static bool_t iot_proto_set_band_id_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;
 | 
						|
    plctxrx_cmd_arg_t cmd = { 0 };
 | 
						|
    uint8_t role = prototask_contxt.local_dev.nw_role;
 | 
						|
    proto_cmd_hdl_state_t *sm = iot_proto_cmd_handle_state_get();
 | 
						|
    ge_frame_band_id_set_subfn28_t *set_cmd =
 | 
						|
        (ge_frame_band_id_set_subfn28_t *)data;
 | 
						|
    plctxrx_cmd_band_info_t band_info;
 | 
						|
    /* check param */
 | 
						|
    if (len != sizeof(*set_cmd)) {
 | 
						|
        reason = PROTO_REASON_LEN_MISSMATCH;
 | 
						|
    } else if (role != IOT_PLC_DEV_ROLE_CCO) {
 | 
						|
        reason = PROTO_REASON_NO_AUTHORITY;
 | 
						|
    }
 | 
						|
 | 
						|
    iot_cus_printf("[glpr]iot_proto_set_band_id_handler\n");
 | 
						|
    if (PROTO_REASON_OK == reason) {
 | 
						|
        cmd.cid.cid = PLCTXRX_CID_BAND_ID;
 | 
						|
        cmd.cid.opcode = PLCTXRX_OP_CONFIG;
 | 
						|
        cmd.need_ack = true;
 | 
						|
        cmd.prio = 0;
 | 
						|
        cmd.dlen = sizeof(plctxrx_cmd_band_info_t);
 | 
						|
        /* 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 */
 | 
						|
        band_info.band_id = set_cmd->band_id;
 | 
						|
        os_mem_cpy(iot_pkt_data(cmd_pkt), &cmd, sizeof(cmd));
 | 
						|
        os_mem_cpy(iot_pkt_data(cmd_pkt) + sizeof(cmd), &band_info,
 | 
						|
            sizeof(plctxrx_cmd_band_info_t));
 | 
						|
        iot_pkt_put(cmd_pkt, sizeof(cmd) + cmd.dlen);
 | 
						|
        /* send cmd to plctxrx layer */
 | 
						|
        iot_proto_cmd_send_to_plctxrx(cmd_pkt);
 | 
						|
 | 
						|
        sm->dir   = CMD_LOCAL_UP_LINK;
 | 
						|
        sm->state = PROTO_CMD_WAIT_CMD_CFM;
 | 
						|
        sm->seq   = set_cmd->seq;
 | 
						|
        sm->cur_subfn = set_cmd->hdr.subfn;
 | 
						|
    }else {
 | 
						|
        iot_proto_resp_cfm_frame(reason, dir, PROTO_SET_BAND_ID_CMD,
 | 
						|
            set_cmd->seq, NULL);
 | 
						|
    }
 | 
						|
 | 
						|
    return rpt2mcu;
 | 
						|
}
 | 
						|
 | 
						|
static bool_t iot_proto_set_host_port_handler(uint8_t *data,
 | 
						|
    uint16_t len, transmit_direction_e_t dir)
 | 
						|
{
 | 
						|
    (void)dir;
 | 
						|
    bool_t rpt2mcu =false;
 | 
						|
    uint8_t reason = PROTO_REASON_OK;
 | 
						|
    iot_pkt_t *pkt;
 | 
						|
    ge_frame_cmd_cfm_set_subfn20_t *cfm_cmd;
 | 
						|
    ge_frame_host_port_set_subfn29_t *set_cmd =
 | 
						|
        (ge_frame_host_port_set_subfn29_t *)data;
 | 
						|
    iot_oem_base_cfg_t *oem_base_cfg;
 | 
						|
    iot_oem_get_base_cfg(&oem_base_cfg);
 | 
						|
 | 
						|
#if SUPPORT_HOST_PORT_ETH
 | 
						|
    /* check param */
 | 
						|
    if (len != sizeof(*set_cmd)) {
 | 
						|
        reason = PROTO_REASON_LEN_MISSMATCH;
 | 
						|
    } else if ((set_cmd->host_port != HOST_PORT_UART)
 | 
						|
        && (set_cmd->host_port != HOST_PORT_ETH)) {
 | 
						|
        reason = PROTO_REASON_PARAME_ERR;
 | 
						|
    } else if (oem_base_cfg->host_port == set_cmd->host_port) {
 | 
						|
        reason = PROTO_REASON_DUP_SETTING;
 | 
						|
    }
 | 
						|
#else
 | 
						|
    reason = PROTO_REASON_NOT_SUPPORT;
 | 
						|
#endif /* end SUPPORT_HOST_PORT_ETH */
 | 
						|
 | 
						|
    iot_cus_printf("[glpr]iot_proto_set_host_port_handler\n");
 | 
						|
    if (PROTO_REASON_OK == reason) {
 | 
						|
        /* save host port to oem */
 | 
						|
        oem_base_cfg->host_port = set_cmd->host_port;
 | 
						|
 | 
						|
        if (ERR_OK != iot_oem_set_base_cfg(oem_base_cfg)) {
 | 
						|
            iot_cus_printf("[glpr]set oem cfg host port error\n");
 | 
						|
            reason = PROTO_REASON_SET_HOST_PORT_ERR;
 | 
						|
        } else {
 | 
						|
            iot_cus_printf("[glpr]system will reboot after 3 seconds\n");
 | 
						|
            os_start_timer(prototask_contxt.reboot_tmr,
 | 
						|
                PROTO_TMR_SET_HOST_PORT_DELAY_INTVL);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /* 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;
 | 
						|
}
 | 
						|
 | 
						|
static bool_t iot_proto_disconn_ind_subfn_handler(uint8_t *data,
 | 
						|
                     uint16_t len, transmit_direction_e_t dir)
 | 
						|
{
 | 
						|
    (void)len;
 | 
						|
    uint8_t role = prototask_contxt.local_dev.nw_role;
 | 
						|
    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_leave_net_t *info;
 | 
						|
    info = (plctxrx_cmd_leave_net_t *)cmd->data;
 | 
						|
 | 
						|
    IOT_ASSERT(info->cnt > 0);
 | 
						|
 | 
						|
    if (IOT_PLC_DEV_ROLE_CCO == role) {
 | 
						|
        iot_proto_cco_groupnet_sm(NULL,
 | 
						|
            PROTO_DISCONN_IND_RPT_CMD, dir, info);
 | 
						|
    } else {
 | 
						|
        /* switch ready state to not ready */
 | 
						|
        prototask_contxt.local_dev.dev_ready = false;
 | 
						|
        /* report disconnect event to MCU */
 | 
						|
        iot_proto_report_disconn_event2mcu(info->mac[0]);
 | 
						|
    }
 | 
						|
    iot_cus_printf("[glpr]disconn_ind:"
 | 
						|
        "disconnect ind,valid_cnt=%d,online_cnt=%d\n",
 | 
						|
        dev_lst->valid_dev_cnt,dev_lst->online_dev_cnt);
 | 
						|
    return rpt2mcu;
 | 
						|
}
 | 
						|
 | 
						|
static bool_t iot_proto_reject_ind_subfn_handler(uint8_t *data,
 | 
						|
    uint16_t len, transmit_direction_e_t dir)
 | 
						|
{
 | 
						|
    bool_t rpt2mcu = false;
 | 
						|
    iot_pkt_t *pkt;
 | 
						|
    ge_frame_reject_ind_rpt_set_subfn36_t *ind_frm;
 | 
						|
    plctxrx_cmd_resp_t *cmd = (plctxrx_cmd_resp_t *)data;
 | 
						|
    plctxrx_cmd_reject_info_t *info =
 | 
						|
         (plctxrx_cmd_reject_info_t *)cmd->data;
 | 
						|
 | 
						|
    pkt = iot_pkt_alloc(sizeof(*ind_frm), IOT_GREE_APP_MID);
 | 
						|
    if (pkt == NULL) {
 | 
						|
        return rpt2mcu;
 | 
						|
    }
 | 
						|
    ind_frm = (ge_frame_reject_ind_rpt_set_subfn36_t *)iot_pkt_put(pkt,
 | 
						|
        sizeof(*ind_frm));
 | 
						|
    /* fill reject indication frame field */
 | 
						|
    EXT_FN_FRM_PREPARE(ind_frm,
 | 
						|
        PROTO_GE_PLC_SET_CMD, PROTO_REJECT_IND_RPT_CMD);
 | 
						|
    iot_mac_addr_cpy(ind_frm->mac, info->mac);
 | 
						|
    ind_frm->reason = info->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));
 | 
						|
    iot_proto_send_to_mainboard(pkt);
 | 
						|
    return rpt2mcu;
 | 
						|
}
 | 
						|
 | 
						|
static bool_t iot_proto_set_tx_power_subfn_handler(uint8_t *data,
 | 
						|
                     uint16_t len, transmit_direction_e_t dir)
 | 
						|
{
 | 
						|
    bool_t rpt2mcu = false;
 | 
						|
    ge_frame_tx_pwr_set_subfn22_t *set_cmd =
 | 
						|
        (ge_frame_tx_pwr_set_subfn22_t *)data;
 | 
						|
    proto_cmd_hdl_state_t *sm = iot_proto_cmd_handle_state_get();
 | 
						|
 | 
						|
    if (len != sizeof(ge_frame_tx_pwr_set_subfn22_t)) {
 | 
						|
        iot_proto_resp_cfm_frame(PROTO_REASON_LEN_MISSMATCH,
 | 
						|
            dir, PROTO_CMD_TX_PWR_CMD, set_cmd->seq, NULL);
 | 
						|
        iot_cus_printf("[glpr][err]%s cmd len mismatch\n", "set tx power");
 | 
						|
        return rpt2mcu;
 | 
						|
    } else if (set_cmd->txpwr > PROTO_TX_POWER_VALUE_MAX ||
 | 
						|
        set_cmd->txpwr < PROTO_TX_POWER_VALUE_MIN) {
 | 
						|
        iot_cus_printf("[glpr][err]set tx power value error\n");
 | 
						|
        iot_proto_resp_cfm_frame(PROTO_REASON_PARAME_ERR,
 | 
						|
            dir, PROTO_CMD_TX_PWR_CMD, set_cmd->seq, NULL);
 | 
						|
        return rpt2mcu;
 | 
						|
    }
 | 
						|
 | 
						|
    iot_proto_set_tx_power(set_cmd->txpwr, true);
 | 
						|
 | 
						|
    sm->dir   = CMD_LOCAL_UP_LINK;
 | 
						|
    sm->state = PROTO_CMD_WAIT_CMD_CFM;
 | 
						|
    sm->seq   = set_cmd->seq;
 | 
						|
    sm->cur_subfn = set_cmd->hdr.subfn;
 | 
						|
    /* send cmd to plctxrx layer */
 | 
						|
    iot_cus_printf("[glpr]set tx power succ!\n");
 | 
						|
 | 
						|
    return rpt2mcu;
 | 
						|
}
 | 
						|
 | 
						|
static iot_pkt_t *iot_proto_pack_dev_info()
 | 
						|
{
 | 
						|
    ge_frame_rpt_dev_verinfo_ind_subfn155_t *resp;
 | 
						|
    iot_pkt_t *pkt = iot_pkt_alloc(sizeof(*resp), IOT_GREE_APP_MID);
 | 
						|
 | 
						|
    if (!pkt) {
 | 
						|
        IOT_ASSERT(0);
 | 
						|
        return NULL;
 | 
						|
    }
 | 
						|
 | 
						|
    resp = (ge_frame_rpt_dev_verinfo_ind_subfn155_t *)iot_pkt_data(pkt);
 | 
						|
    iot_pkt_put(pkt, sizeof(*resp));
 | 
						|
 | 
						|
    os_mem_set(resp, 0, sizeof(*resp));
 | 
						|
    EXT_FN_FRM_PREPARE(resp,
 | 
						|
        PROTO_GE_PLC_SET_CMD, PROTO_RPT_DEV_VERINFO_IND_CMD);
 | 
						|
    resp->verinfo= iot_htonl(iot_version_hex());
 | 
						|
    resp->ver_type = iot_version_type();
 | 
						|
    iot_oem_get_chip_mmid(resp->chip_mmid, IOT_CHIP_MMID_LEN);
 | 
						|
    resp->hw_ver = iot_board_hw_version_hex();
 | 
						|
    resp->seq = prototask_contxt.local_dev.ind_seq++;
 | 
						|
    iot_mac_addr_cpy(resp->dev_mac, prototask_contxt.local_dev.mac);
 | 
						|
 | 
						|
    resp->tail.check_sum = ge_frm_checksum_calc((uint8_t *)resp,
 | 
						|
        sizeof(*resp) - sizeof(ge_frm_tail_t));
 | 
						|
 | 
						|
    return pkt;
 | 
						|
}
 | 
						|
 | 
						|
bool_t iot_proto_set_dev_verinfo_rpt_handler(uint8_t *data,
 | 
						|
    uint16_t len, transmit_direction_e_t dir)
 | 
						|
{
 | 
						|
    uint32_t reason = PROTO_REASON_OK;
 | 
						|
    bool_t rpt2mcu = false;
 | 
						|
    iot_pkt_t *rpt_rsp_pkt;
 | 
						|
    protpkt_tx_info_t txinfo = { 0 };
 | 
						|
    ge_frame_set_dev_verinfo_rpt_subfn33_t *set_rpt_cmd =
 | 
						|
        (ge_frame_set_dev_verinfo_rpt_subfn33_t *)data;
 | 
						|
 | 
						|
    switch (dir) {
 | 
						|
    case CMD_LOCAL_DOWN_LINK: {
 | 
						|
        if (len != sizeof(*set_rpt_cmd)) {
 | 
						|
            reason = PROTO_REASON_LEN_MISSMATCH;
 | 
						|
        }
 | 
						|
 | 
						|
        iot_proto_resp_cfm_frame(reason, dir, PROTO_SET_RPT_DEV_VERINFO_CMD,
 | 
						|
            set_rpt_cmd->seq, NULL);
 | 
						|
        if (PROTO_REASON_OK != reason)
 | 
						|
            goto out;
 | 
						|
        /* if target device is local or target mac is broadcast mac,
 | 
						|
         * then report local version info to MCU/PC.
 | 
						|
         */
 | 
						|
        if (iot_mac_addr_cmp(prototask_contxt.local_dev.mac, set_rpt_cmd->dest_mac)
 | 
						|
            || iot_mac_is_bcast(set_rpt_cmd->dest_mac)) {
 | 
						|
            rpt_rsp_pkt = iot_proto_pack_dev_info();
 | 
						|
            if (!rpt_rsp_pkt) {
 | 
						|
                iot_cus_printf("%s:rpt rsp no memory!\n", __FUNCTION__);
 | 
						|
                goto out;
 | 
						|
            }
 | 
						|
            iot_proto_send_to_mainboard(rpt_rsp_pkt);
 | 
						|
            goto out;
 | 
						|
        }
 | 
						|
 | 
						|
        /* send requst report indication cmd to target device */
 | 
						|
        iot_proto_fill_txinfo(&txinfo, true,
 | 
						|
            PLCTXRX_UNICAST, 0,
 | 
						|
            PROTO_UNICAST_RETRY_DEFAULT_INTVL, 1,
 | 
						|
            prototask_contxt.local_dev.mac, set_rpt_cmd->dest_mac);
 | 
						|
 | 
						|
        iot_proto_remote_cmd_send_to_plctxrx(data, len, &txinfo);
 | 
						|
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case CMD_REMOTE_UP_LINK: {
 | 
						|
        if (!iot_mac_addr_cmp(prototask_contxt.local_dev.mac,
 | 
						|
            set_rpt_cmd->dest_mac)
 | 
						|
            || iot_mac_is_bcast(set_rpt_cmd->dest_mac)) {
 | 
						|
            goto out;
 | 
						|
        }
 | 
						|
        rpt_rsp_pkt = iot_proto_pack_dev_info();
 | 
						|
        if (!rpt_rsp_pkt) {
 | 
						|
            iot_cus_printf("%s:rpt rsp no memory!\n", __FUNCTION__);
 | 
						|
            goto out;
 | 
						|
        }
 | 
						|
        /* report device version info to the device which requested */
 | 
						|
        iot_proto_fill_txinfo(&txinfo, true,
 | 
						|
            PLCTXRX_UNICAST, 0,
 | 
						|
            PROTO_UNICAST_RETRY_DEFAULT_INTVL, 1,
 | 
						|
            prototask_contxt.local_dev.mac, prototask_contxt.rx_info.mac);
 | 
						|
 | 
						|
        /* report ver info in the way recived set report cmd */
 | 
						|
        txinfo.force_tx_connless = prototask_contxt.rx_info.rx_type;
 | 
						|
 | 
						|
        iot_proto_remote_cmd_send_to_plctxrx(iot_pkt_data(rpt_rsp_pkt),
 | 
						|
            (uint8_t)iot_pkt_data_len(rpt_rsp_pkt), &txinfo);
 | 
						|
 | 
						|
        iot_pkt_free(rpt_rsp_pkt);
 | 
						|
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    default:
 | 
						|
        break;
 | 
						|
    }
 | 
						|
 | 
						|
out:
 | 
						|
    return rpt2mcu;
 | 
						|
}
 | 
						|
 | 
						|
void iot_proto_set_fb_bitmap(uint16_t *p_set_bitmap, bool_t need_ack)
 | 
						|
{
 | 
						|
    uint8_t i;
 | 
						|
    uint8_t row = 0, col = 0;
 | 
						|
    ge_app_pib_info_t *p_flash = &prototask_contxt.flashinfo;
 | 
						|
    iot_pkt_t *p_pkt;
 | 
						|
    plctxrx_cmd_fb_bitmap_t *p_bitmap;
 | 
						|
    plctxrx_cmd_arg_t *p_arg;
 | 
						|
    uint16_t fb_bitmap = 0;
 | 
						|
 | 
						|
    p_pkt = iot_pkt_alloc(sizeof(*p_arg) + sizeof(*p_bitmap), IOT_GREE_APP_MID);
 | 
						|
    IOT_ASSERT(p_pkt);
 | 
						|
    iot_pkt_put(p_pkt, sizeof(*p_arg) + sizeof(*p_bitmap));
 | 
						|
    p_arg = (plctxrx_cmd_arg_t *)iot_pkt_data(p_pkt);
 | 
						|
    p_arg->cid.cid = PLCTXRX_CID_FB_BITMAP;
 | 
						|
    p_arg->cid.opcode = PLCTXRX_OP_CONFIG;
 | 
						|
    p_arg->need_ack = need_ack;
 | 
						|
    p_arg->dlen = sizeof(plctxrx_cmd_fb_bitmap_t);
 | 
						|
 | 
						|
    if (p_set_bitmap) {
 | 
						|
        fb_bitmap = *p_set_bitmap;
 | 
						|
    } else {
 | 
						|
        if (p_flash->public.pub.fb_bitmap != 0) {
 | 
						|
            fb_bitmap = p_flash->public.pub.fb_bitmap;
 | 
						|
        } else {
 | 
						|
            /* default bitmap 8~11
 | 
						|
             * assign to mac band in customer range:
 | 
						|
             * PLC_LIB_FREQ_BAND_0     = 0, //2M to 12M
 | 
						|
             * PLC_LIB_FREQ_BAND_1     = 1, //2.4M to 5.6M
 | 
						|
             * PLC_LIB_FREQ_BAND_2     = 2, //700K to 3M
 | 
						|
             * PLC_LIB_FREQ_BAND_3     = 3, //1.7M to 3M
 | 
						|
             * PLC_LIB_FREQ_BAND_4     = 4, //5.6M to 12M
 | 
						|
             * PLC_LIB_FREQ_BAND_8     = 8, //5.8M to 9M
 | 
						|
             * PLC_LIB_FREQ_BAND_9     = 9, //4.9M to 24.4M
 | 
						|
             * PLC_LIB_FREQ_BAND_10    = 10,//28.3M to 34.5M
 | 
						|
             * PLC_LIB_FREQ_BAND_11    = 11,//4.9M to 12.2M
 | 
						|
             */
 | 
						|
            fb_bitmap |= 1 << PLC_LIB_FREQ_BAND_1;
 | 
						|
            fb_bitmap |= 1 << PLC_LIB_FREQ_BAND_2;
 | 
						|
            fb_bitmap |= 1 << PLC_LIB_FREQ_BAND_9;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    p_bitmap = (plctxrx_cmd_fb_bitmap_t *)p_arg->arg;
 | 
						|
    for (i = 0; i < sizeof(uint16_t)*8; i++) {
 | 
						|
        if (((fb_bitmap & (0x1 << i)) >> i) != 0) {
 | 
						|
            row = i >> 3;
 | 
						|
            col = i % 8;
 | 
						|
            p_bitmap->fb_bitmap[row] |= (1 << col);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /* save default band bitmap to app pib */
 | 
						|
    p_flash->public.pub.fb_bitmap = fb_bitmap;
 | 
						|
    iot_proto_flashsave(p_flash);
 | 
						|
 | 
						|
    iot_proto_cmd_send_to_plctxrx(p_pkt);
 | 
						|
}
 | 
						|
 | 
						|
static proto_fnhdl_tbl_t proto_set_subfnhdl_tbl[] = {
 | 
						|
    {PROTO_LOCAL_MAC_SET_CMD, iot_proto_set_local_mac_subfn_handler, 0},
 | 
						|
    {PROTO_JOIN_NW_SET_CMD, iot_proto_set_join_nw_subfn_handler,0},
 | 
						|
    {PROTO_OP_WHITELIST_SET_CMD, iot_proto_whitelist_set_handler, 0},
 | 
						|
    {PROTO_CONN_IND_RPT_CMD, iot_proto_conn_ind_subfn_handler, 0},
 | 
						|
    {PROTO_DISCONN_IND_RPT_CMD, iot_proto_disconn_ind_subfn_handler, 0},
 | 
						|
    {PROTO_CCO_START_GROUP_NET_CMD, iot_proto_start_groupnet_subfn_handler, 0},
 | 
						|
    {PROTO_CCO_END_GROUP_NET_CMD, iot_proto_end_groupnet_subfn_handler, 0},
 | 
						|
    {PROTO_REBOOT_STA_CMD,   iot_proto_reboot_sta_handler, 0},
 | 
						|
    {PROTO_CMD_CFM_CMD,    iot_proto_cmd_cfm_subfn_handler, 0},
 | 
						|
    {PROTO_CMD_CCO_STAT_IND_CMD, iot_proto_cco_state_ind_subfn_handler, 0},
 | 
						|
    {PROTO_CMD_TX_PWR_CMD , iot_proto_set_tx_power_subfn_handler, 0},
 | 
						|
    {PROTO_CCO_NID_SET_CMD, iot_proto_set_nid_subfn_handler, 0},
 | 
						|
    {PROTO_LEAVE_NW_SET_CMD, iot_proto_set_sta_leave_handler, 0},
 | 
						|
    {PROTO_COMM_FAULT_RPT_CMD, iot_proto_comm_fault_ind_subfn_handler, 0},
 | 
						|
    {PROTO_APP_REG_CONF_IND, iot_proto_grapp_reg_conf_ind_subfn_handler, 0},
 | 
						|
    {PROTO_CLR_CUST_FLASH_CMD, iot_proto_clr_flashinfo_handler, 0},
 | 
						|
    {PROTO_GE_DATA_CMD, iot_proto_data_handler, 0},
 | 
						|
    {PROTO_GE_UART_PARAM_SET_CMD, iot_proto_set_uart_param_handler, 0},
 | 
						|
    {PROTO_SW_UART_MODE_CMD, iot_proto_sw_uart_mode_handler, 0},
 | 
						|
    {PROTO_SET_BAND_ID_CMD, iot_proto_set_band_id_handler, 0},
 | 
						|
    {PROTO_SET_HOST_PORT_CMD, iot_proto_set_host_port_handler, 0},
 | 
						|
    {PROTO_GE_BC_DATA_CMD, iot_proto_bc_data_handler, 0},
 | 
						|
    {PROTO_SET_FB_BITMAP_CMD, iot_proto_set_fb_bitmap_handler, 0},
 | 
						|
    {PROTO_SET_FIX_RATE_MODE_CMD, iot_proto_set_fix_rate_mode_handler, 0},
 | 
						|
    {PROTO_SEND_STA_PAGING_CMD, iot_proto_sta_paging_handler, 0},
 | 
						|
    {PROTO_SET_RPT_DEV_VERINFO_CMD, iot_proto_set_dev_verinfo_rpt_handler, 0},
 | 
						|
    {PROTO_SET_SWITCH_BOOT_PART_CMD, iot_proto_switch_boot_part_handler, 0},
 | 
						|
    {PROTO_LOCAL_IP4_INFO_SET_CMD, iot_proto_set_local_ip4_subfn_handler, 0},
 | 
						|
    {PROTO_AES_SET_CMD, iot_proto_set_aes_handler, 0},
 | 
						|
    {PROTO_GE_GPIO_CONFIG_CMD, iot_proto_config_gpio_handler, 0},
 | 
						|
    {PROTO_GE_GPIO_SET_CMD, iot_proto_set_gpio_handler, 0},
 | 
						|
    {PROTO_GE_DELAY_TM_CMD, iot_proto_delay_time_handler, 0},
 | 
						|
    {PROTO_REJECT_IND_RPT_CMD, iot_proto_reject_ind_subfn_handler, 0},
 | 
						|
};
 | 
						|
 | 
						|
static bool_t iot_proto_set_fn_handler(uint8_t *data, uint16_t len,
 | 
						|
    transmit_direction_e_t dir)
 | 
						|
{
 | 
						|
    bool_t rpt2mcu = false;
 | 
						|
    bool_t need_save = false;
 | 
						|
    bool_t need_handle = false;
 | 
						|
    plctxrx_cmd_resp_t *cmd = NULL;
 | 
						|
    uint8_t ret;
 | 
						|
    uint8_t fn = 0, subfn = 0;
 | 
						|
    ge_extend_fn_hdr_t *frm_hdr;
 | 
						|
    proto_cmd_hdl_state_t *sm_state = iot_proto_cmd_handle_state_get();
 | 
						|
    uint8_t state = sm_state->state;
 | 
						|
    uint32_t i;
 | 
						|
    PROTO_FN_HANDLE handler = NULL;
 | 
						|
 | 
						|
    if (CMD_LOCAL_UP_LINK == dir) {
 | 
						|
        cmd = (plctxrx_cmd_resp_t *)data;
 | 
						|
        ret = iot_proto_plctxtx_fn_subfn_get(cmd, &fn, &subfn);
 | 
						|
        if (ret) {
 | 
						|
            iot_cus_printf("[glpr][err]set_fn_handler:cid=0x%x,opcode=0x%x\n",
 | 
						|
                            cmd->cid.cid, cmd->cid.opcode);
 | 
						|
            return rpt2mcu;
 | 
						|
        }
 | 
						|
    /* else ,it means it is a intact gree cmd frame */
 | 
						|
    } else {
 | 
						|
        frm_hdr = (ge_extend_fn_hdr_t *)data;
 | 
						|
        subfn = frm_hdr->subfn;
 | 
						|
    }
 | 
						|
 | 
						|
    iot_cus_printf("[glpr]set_fn_handler:subfn=%d,dir=%d,cur_state=%d\n",
 | 
						|
                    subfn, dir, state);
 | 
						|
 | 
						|
    if (PROTO_GE_DATA_CMD == subfn && state == PROTO_CMD_WAIT_MAC_RESP) {
 | 
						|
        ge_frame_data_send_set_subfn160_t *s160_data =
 | 
						|
            (ge_frame_data_send_set_subfn160_t*)data;
 | 
						|
        iot_cus_printf("recv mac:%02X %02x %02X %02x %02X %02x\n",
 | 
						|
            s160_data->dest_mac[0], s160_data->dest_mac[1],
 | 
						|
            s160_data->dest_mac[2], s160_data->dest_mac[3],
 | 
						|
            s160_data->dest_mac[4], s160_data->dest_mac[5]);
 | 
						|
        if (!iot_mac_addr_cmp(prototask_contxt.local_dev.mac,
 | 
						|
            s160_data->dest_mac)) {
 | 
						|
            if (!prototask_contxt.macaddr_set) {
 | 
						|
                /* set mac and type to CVG layer */
 | 
						|
                iot_proto_set_mac(s160_data->dest_mac, 0, false);
 | 
						|
                /* detect mac, set mac and report boot ready*/
 | 
						|
                iot_proto_boot_ready_ind(s160_data->dest_mac);
 | 
						|
            }
 | 
						|
            return rpt2mcu;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    if (prototask_contxt.macaddr_set == 0
 | 
						|
        && PROTO_APP_REG_CONF_IND != subfn
 | 
						|
        && PROTO_LOCAL_MAC_SET_CMD != subfn
 | 
						|
        && PROTO_GE_UART_PARAM_SET_CMD != subfn) {
 | 
						|
        iot_cus_printf("[glpr]no mac received! not handle\n");
 | 
						|
        return rpt2mcu;
 | 
						|
    }
 | 
						|
 | 
						|
    /* check if subfn is data cmd for general or uart param  or indication */
 | 
						|
    if (PROTO_GE_DATA_CMD == subfn || PROTO_GE_UART_PARAM_SET_CMD == subfn ||
 | 
						|
        PROTO_SEND_STA_PAGING_CMD == subfn || PROTO_GE_DELAY_TM_CMD == subfn ||
 | 
						|
        (cmd && cmd->cid.opcode == PLCTXRX_OP_INDICATION)) {
 | 
						|
        for (i = 0; i < ARRAY_CNT(proto_set_subfnhdl_tbl); i++) {
 | 
						|
            if (proto_set_subfnhdl_tbl[i].cmdid == subfn) {
 | 
						|
                handler = proto_set_subfnhdl_tbl[i].cmd_handle_fn;
 | 
						|
                break;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        if (handler) {
 | 
						|
            return handler(data, len, dir);
 | 
						|
        } else {
 | 
						|
            return rpt2mcu;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    switch (dir) {
 | 
						|
    case CMD_LOCAL_DOWN_LINK:
 | 
						|
    {
 | 
						|
        switch (state) {
 | 
						|
        case PROTO_CMD_IDLE:
 | 
						|
        {
 | 
						|
            /* not handle indication frame message which received from mcu */
 | 
						|
            if (subfn == PROTO_BOOT_READY_ID_CMD ||
 | 
						|
                subfn == PROTO_CONN_IND_RPT_CMD ||
 | 
						|
                subfn == PROTO_DISCONN_IND_RPT_CMD ||
 | 
						|
                subfn == PROTO_WHITELIST_IND_CMD ||
 | 
						|
                subfn == PROTO_PAIRTABLE_IND_CMD ||
 | 
						|
                subfn == PROTO_APP_REG_CONF_IND ||
 | 
						|
                subfn == PROTO_STA_LEAVE_IND ||
 | 
						|
                subfn == PROTO_MONITR_ONLINE_IND ||
 | 
						|
                subfn == PROTO_CMD_CCO_STAT_IND_CMD) {
 | 
						|
                iot_cus_printf("[glpr][war]subfn=%X,no need to handle\n",subfn);
 | 
						|
            } else {
 | 
						|
                need_handle = true;
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case PROTO_CMD_WAIT_MAC_RESP:
 | 
						|
        {
 | 
						|
            if (subfn == PROTO_LOCAL_MAC_SET_CMD) {
 | 
						|
                need_handle = true;
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case PROTO_CMD_WAIT_WHITE_LIST_SET:
 | 
						|
        {
 | 
						|
            if (subfn == PROTO_OP_WHITELIST_SET_CMD) {
 | 
						|
                need_handle = true;
 | 
						|
            } else {
 | 
						|
                need_save = true;
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        default:
 | 
						|
            need_save = true;
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case CMD_LOCAL_UP_LINK:
 | 
						|
    {
 | 
						|
        switch (state) {
 | 
						|
        case PROTO_CMD_IDLE:
 | 
						|
        {
 | 
						|
            switch (subfn) {
 | 
						|
            case PROTO_COMM_FAULT_RPT_CMD:
 | 
						|
            case PROTO_CONN_IND_RPT_CMD:
 | 
						|
            case PROTO_DISCONN_IND_RPT_CMD:
 | 
						|
            case PROTO_CMD_CCO_STAT_IND_CMD:
 | 
						|
            case PROTO_APP_REG_CONF_IND:
 | 
						|
            {
 | 
						|
                need_handle = true;
 | 
						|
                break;
 | 
						|
            }
 | 
						|
            default:
 | 
						|
                break;
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case PROTO_CMD_WAIT_CMD_CFM:
 | 
						|
        {
 | 
						|
            if (PROTO_CMD_CFM_CMD == subfn) {
 | 
						|
                need_handle = true;
 | 
						|
            } else {
 | 
						|
                need_save = true;
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case PROTO_CMD_WAIT_WHITE_LIST_SET:
 | 
						|
        {
 | 
						|
            if (PROTO_CMD_CFM_CMD == subfn) {
 | 
						|
                need_handle = true;
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        default:
 | 
						|
        {
 | 
						|
            if (PROTO_CMD_CFM_CMD != subfn) {
 | 
						|
                need_save = true;
 | 
						|
            } else {
 | 
						|
                // drop it
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        }
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case CMD_REMOTE_UP_LINK:
 | 
						|
    {
 | 
						|
        /**
 | 
						|
         * if remote cmd whitelist ind or pairtable indication,
 | 
						|
         * handle it as the highest priority.
 | 
						|
        */
 | 
						|
        if (PROTO_WHITELIST_IND_CMD == subfn ||
 | 
						|
            PROTO_PAIRTABLE_IND_CMD == subfn) {
 | 
						|
            need_handle = true;
 | 
						|
            break;
 | 
						|
        }
 | 
						|
 | 
						|
        /* swicth boot part indication command need report to uart */
 | 
						|
        if (PROTO_SWITCH_BOOT_PART_IND_CMD == subfn) {
 | 
						|
            rpt2mcu = true;
 | 
						|
            break;
 | 
						|
        }
 | 
						|
 | 
						|
        switch (state) {
 | 
						|
        case PROTO_CMD_IDLE:
 | 
						|
        {
 | 
						|
            if (PROTO_CMD_CFM_CMD != subfn) {
 | 
						|
                need_handle = true;
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case PROTO_CMD_WAIT_CMD_CFM:
 | 
						|
        {
 | 
						|
            if (PROTO_CMD_CFM_CMD == subfn) {
 | 
						|
                need_handle = true;
 | 
						|
            } else {
 | 
						|
                need_save = true;
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case PROTO_CMD_WAIT_WHITE_LIST_SET:
 | 
						|
        {
 | 
						|
            if (subfn == PROTO_OP_WHITELIST_SET_CMD) {
 | 
						|
                need_handle = true;
 | 
						|
            } else {
 | 
						|
                need_save = true;
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        /* if in other waiting state, save all cmd except
 | 
						|
         * PROTO_CMD_CFM_CMD.
 | 
						|
        */
 | 
						|
        default:
 | 
						|
        {
 | 
						|
            if (PROTO_CMD_CFM_CMD != subfn) {
 | 
						|
                need_save = true;
 | 
						|
            } else {
 | 
						|
                // drop it
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        }
 | 
						|
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    default:
 | 
						|
        break;
 | 
						|
    }
 | 
						|
 | 
						|
    iot_cus_printf("[glpr]subfn:%d handle:%d need_save:%d\n",
 | 
						|
                        subfn, need_handle,need_save);
 | 
						|
 | 
						|
    if (need_handle) {
 | 
						|
        for (i = 0; i < ARRAY_CNT(proto_set_subfnhdl_tbl); i++) {
 | 
						|
            if (proto_set_subfnhdl_tbl[i].cmdid == subfn) {
 | 
						|
                handler = proto_set_subfnhdl_tbl[i].cmd_handle_fn;
 | 
						|
                break;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        if (NULL != handler) {
 | 
						|
            rpt2mcu = handler(data, len, dir);
 | 
						|
            if (PROTO_CMD_IDLE == sm_state->state) {
 | 
						|
                /* clear wait response timer if it's active.  */
 | 
						|
                if (os_is_timer_active(prototask_contxt.wait_resp_timer)) {
 | 
						|
                    os_stop_timer(prototask_contxt.wait_resp_timer);
 | 
						|
                    iot_task_clean_msg(prototask_contxt.task_handle,
 | 
						|
                        PROTO_TIMER_MSG, PROTO_TIMER_WAIT_RESP_TIMEOUT);
 | 
						|
                }
 | 
						|
                /* push saved msg to task queue */
 | 
						|
                iot_proto_saved_msg_handle();
 | 
						|
            } else {
 | 
						|
                /* restart timer */
 | 
						|
                if (os_is_timer_active(prototask_contxt.wait_resp_timer)) {
 | 
						|
                    os_stop_timer(prototask_contxt.wait_resp_timer);
 | 
						|
                    iot_task_clean_msg(prototask_contxt.task_handle,
 | 
						|
                        PROTO_TIMER_MSG, PROTO_TIMER_WAIT_RESP_TIMEOUT);
 | 
						|
                }
 | 
						|
                os_start_timer(prototask_contxt.wait_resp_timer,
 | 
						|
                    PROTO_TIMER_WAIT_RESPONSE_TIMEOUT_INTVL);
 | 
						|
            }
 | 
						|
        } else {
 | 
						|
            iot_cus_printf("\n[glpr][error]No handler found!\n");
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    if (need_save) {
 | 
						|
        proto_msg_saved_list_t *list =
 | 
						|
            &prototask_contxt.saved_msg_list;
 | 
						|
        transmit_direction_e_t tmp_dir = 0;
 | 
						|
        uint16_t msg_type = 0;
 | 
						|
        uint16_t msg_id = 0;
 | 
						|
        plctxrx_rx_data_info_t *rxinfo = NULL;
 | 
						|
        switch (dir) {
 | 
						|
        case CMD_LOCAL_UP_LINK:
 | 
						|
        {
 | 
						|
            tmp_dir  = CMD_LOCAL_UP_LINK;
 | 
						|
            msg_type = PROTO_PLC_RX_MSG;
 | 
						|
            msg_id   = PROTO_PLCTXRX_RX_CMD_MSG;
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case CMD_LOCAL_DOWN_LINK:
 | 
						|
        {
 | 
						|
            tmp_dir  = DATA_DOWN_LINK;
 | 
						|
            msg_type = PROTO_MCU_RX_MSG;
 | 
						|
            msg_id   = 0;
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case CMD_REMOTE_UP_LINK:
 | 
						|
        {
 | 
						|
            tmp_dir  = DATA_UP_LINK;
 | 
						|
            msg_type = PROTO_PLC_RX_MSG;
 | 
						|
            msg_id   = PROTO_PLC_RX_DATA_MSG;
 | 
						|
            rxinfo = &prototask_contxt.rx_info;
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        default:
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        iot_cus_printf("[glpr]"
 | 
						|
            "Save this cmd msg!tmp_dir=%d,msg_id=%d,msg_type=%d\n",
 | 
						|
            tmp_dir,msg_id,msg_type);
 | 
						|
        iot_proto_save_cmd(list, data, len, rxinfo,
 | 
						|
                        tmp_dir, msg_id, msg_type);
 | 
						|
    }
 | 
						|
 | 
						|
    return rpt2mcu;
 | 
						|
}
 | 
						|
 | 
						|
static proto_fnhdl_tbl_t proto_query_subfnhdl_tbl[] = {
 | 
						|
    {PROTO_LOCAL_MAC_QUERY_CMD, iot_proto_query_local_mac_handler, 0},
 | 
						|
    {PROTO_FW_SWVER_QUERY_CMD, iot_proto_query_swver_handler, 0},
 | 
						|
    {PROTO_BOOTINFO_QUERY_CMD, iot_proto_query_boot_info_handler, 0},
 | 
						|
    {PROTO_TOPO_QUERY_CMD, iot_proto_query_topo_handler, 0},
 | 
						|
    {PROTO_NET_STS_QUERY_CMD, iot_proto_query_net_sts_handler, 0},
 | 
						|
    {PROTO_WHITELIST_QUERY_CMD, iot_proto_query_whitelist_handler, 0},
 | 
						|
    {PROTO_AVAIL_NW_QUERY_CMD, iot_proto_query_avail_nw_handler, 0},
 | 
						|
    {PROTO_TX_PWR_QUERY_CMD, iot_proto_query_tx_pwr_handler, 0},
 | 
						|
    {PROTO_UART_THRPT_QUERY_CMD, iot_proto_query_uart_thrpt_handler, 0},
 | 
						|
    {PROTO_NW_DETAILINFO_QUERY_CMD, iot_proto_query_nw_detailinfo_handler, 0},
 | 
						|
    {PROTO_GE_UART_PARAM_QUERY_CMD, iot_proto_query_uart_param_handler, 0},
 | 
						|
    {PROTO_GE_EXT_WL_QUERY_CMD, iot_proto_ext_query_wl_handler, 0},
 | 
						|
    {PROTO_NID_QUERY_CMD, iot_proto_query_nid_handler, 0},
 | 
						|
    {PROTO_WHITELIST_STATE_QUERY_CMD, iot_proto_query_wl_state_handler, 0},
 | 
						|
    {PROTO_MODULE_INFO_QUERY_CMD, iot_proto_query_module_info_handler, 0},
 | 
						|
    {PROTO_NTB_QUERY_CMD, iot_proto_query_ntb_handler, 0},
 | 
						|
    {PROTO_FB_BITMAP_QUERY_CMD, iot_proto_query_fb_bitmap_handler, 0},
 | 
						|
    {PROTO_FIX_RATE_QUERY_CMD, iot_proto_query_fix_rate_mode_handler, 0},
 | 
						|
    {PROTO_WORK_BAND_QUERY_CMD, iot_proto_query_work_band_handler, 0},
 | 
						|
    {PROTO_NODE_INFO_QUERY_CMD, iot_proto_query_node_info_handler, 0},
 | 
						|
    {PROTO_NW_INFO_QUERY_CMD, iot_proto_query_nw_info_handler, 0},
 | 
						|
    {PROTO_LOCAL_IP4_INFO_QUERY_CMD, iot_proto_query_local_ip4_handler, 0},
 | 
						|
    {PROTO_AES_QUERY_CMD, iot_proto_query_aes_handler, 0},
 | 
						|
    {PROTO_GE_GPIO_QUERY_CMD, iot_proto_query_gpio_handler, 0},
 | 
						|
};
 | 
						|
 | 
						|
static bool_t iot_proto_query_fn_handler(uint8_t *data,
 | 
						|
                        uint16_t len, transmit_direction_e_t dir)
 | 
						|
{
 | 
						|
    bool_t rpt2mcu = false;
 | 
						|
    bool_t need_save = false;
 | 
						|
    bool_t need_handle = false;
 | 
						|
    uint8_t subfn = 0;
 | 
						|
    ge_extend_fn_hdr_t *frm_hdr;
 | 
						|
    proto_cmd_hdl_state_t *sm_state = iot_proto_cmd_handle_state_get();
 | 
						|
    uint8_t state = sm_state->state;
 | 
						|
    uint32_t i;
 | 
						|
    PROTO_FN_HANDLE handler = NULL;
 | 
						|
 | 
						|
    frm_hdr = (ge_extend_fn_hdr_t *)data;
 | 
						|
    subfn = frm_hdr->subfn;
 | 
						|
 | 
						|
    iot_cus_printf("[glpr]query_fn_handler:subfn=%d,dir=%d,cur_state=%d\n",
 | 
						|
                    subfn, dir, state);
 | 
						|
 | 
						|
    /* uart param setting is highest priority */
 | 
						|
    if (PROTO_GE_UART_PARAM_QUERY_CMD == subfn) {
 | 
						|
        for (i = 0; i < ARRAY_CNT(proto_query_subfnhdl_tbl); i++) {
 | 
						|
            if (proto_query_subfnhdl_tbl[i].cmdid == subfn) {
 | 
						|
                handler = proto_query_subfnhdl_tbl[i].cmd_handle_fn;
 | 
						|
                break;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        if (handler) {
 | 
						|
            return handler(data, len, dir);
 | 
						|
        } else {
 | 
						|
            return rpt2mcu;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    if ((prototask_contxt.macaddr_set == 0)) {
 | 
						|
        iot_cus_printf("[glpr]no mac received! not handle]");
 | 
						|
        return rpt2mcu;
 | 
						|
    }
 | 
						|
 | 
						|
    switch (dir) {
 | 
						|
    case CMD_LOCAL_DOWN_LINK:
 | 
						|
    case CMD_REMOTE_UP_LINK:
 | 
						|
    {
 | 
						|
        switch (state) {
 | 
						|
        case PROTO_CMD_IDLE:
 | 
						|
        {
 | 
						|
            need_handle = true;
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        default:
 | 
						|
            need_save = true;
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    default:
 | 
						|
        IOT_ASSERT(0);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
 | 
						|
    iot_cus_printf("[glpr]subfn:%d handle:%d need_save:%d\n",
 | 
						|
                     subfn, need_handle,need_save);
 | 
						|
 | 
						|
    if (need_handle) {
 | 
						|
 | 
						|
        handler = NULL;
 | 
						|
 | 
						|
        for (i = 0; i < ARRAY_CNT(proto_query_subfnhdl_tbl); i++) {
 | 
						|
            if (proto_query_subfnhdl_tbl[i].cmdid == subfn) {
 | 
						|
                handler = proto_query_subfnhdl_tbl[i].cmd_handle_fn;
 | 
						|
                break;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        if (NULL != handler) {
 | 
						|
            rpt2mcu = handler(data, len, dir);
 | 
						|
            if (PROTO_CMD_IDLE != sm_state->state) {
 | 
						|
                /* start wait response timer */
 | 
						|
                os_start_timer(prototask_contxt.wait_resp_timer,
 | 
						|
                    PROTO_TIMER_WAIT_RESPONSE_TIMEOUT_INTVL);
 | 
						|
            }
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
            iot_cus_printf("\n[glpr]No handler found!");
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    if (need_save) {
 | 
						|
        proto_msg_saved_list_t *list =
 | 
						|
            &prototask_contxt.saved_msg_list;
 | 
						|
        transmit_direction_e_t tmp_dir = 0;
 | 
						|
        uint16_t msg_type = 0;
 | 
						|
        uint16_t msg_id = 0;
 | 
						|
        plctxrx_rx_data_info_t *rxinfo = NULL;
 | 
						|
        switch (dir) {
 | 
						|
        case CMD_LOCAL_DOWN_LINK:
 | 
						|
        {
 | 
						|
            tmp_dir  = DATA_DOWN_LINK;
 | 
						|
            msg_type = PROTO_MCU_RX_MSG;
 | 
						|
            msg_id   = 0;
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case CMD_REMOTE_UP_LINK:
 | 
						|
        {
 | 
						|
            tmp_dir  = DATA_UP_LINK;
 | 
						|
            msg_type = PROTO_PLC_RX_MSG;
 | 
						|
            msg_id   = PROTO_PLC_RX_DATA_MSG;
 | 
						|
            rxinfo = &prototask_contxt.rx_info;
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        default:
 | 
						|
            IOT_ASSERT(0);
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        iot_cus_printf("[glpr]"
 | 
						|
            "Save this cmd msg!tmp_dir=%d,msg_id=%d,msg_type=%d\n",
 | 
						|
            tmp_dir,msg_id,msg_type);
 | 
						|
        iot_proto_save_cmd(list, data, len, rxinfo,
 | 
						|
                    tmp_dir, msg_id, msg_type);
 | 
						|
    }
 | 
						|
    return rpt2mcu;
 | 
						|
}
 | 
						|
 | 
						|
static proto_fnhdl_tbl_t proto_query_resp_subfnhdl_tbl[] = {
 | 
						|
    {PROTO_LOCAL_MAC_RESP_CMD, iot_proto_local_mac_resp_handler, 0},
 | 
						|
    {PROTO_FW_SWVER_RESP_CMD, iot_proto_fw_swver_resp_subfn_handler, 0},
 | 
						|
    {PROTO_BOOT_INFO_RESP_CMD, iot_proto_boot_info_resp_subfn_handler, 0},
 | 
						|
    {PROTO_TOPO_RESP_CMD, iot_proto_topo_resp_subfn_handler, 0},
 | 
						|
    {PROTO_NET_STS_RESP_CMD, iot_proto_net_sts_resp_subfn_handler, 0},
 | 
						|
    {PROTO_WHITELIST_RESP_CMD, iot_proto_whitelist_resp_handler, 0},
 | 
						|
    {PROTO_AVAIL_NW_RESP_CMD, iot_proto_avail_nw_resp_subfn_handler, 0},
 | 
						|
    {PROTO_TX_PWR_RESP_CMD, iot_proto_tx_power_resp_subfn_handler, 0},
 | 
						|
    {PROTO_NTB_RESP_CMD, iot_proto_ntb_resp_subfn_handler, 0},
 | 
						|
    {PROTO_FB_BITMAP_RESP_CMD, iot_proto_fb_bitmap_resp_subfn_handler, 0},
 | 
						|
    {PROTO_FIX_RATE_MODE_RESP_CMD, iot_proto_fix_rate_mode_resp_subfn_handler, 0},
 | 
						|
    {PROTO_WORK_BAND_RESP_CMD, iot_proto_work_band_resp_subfn_handler, 0},
 | 
						|
    {PROTO_NODE_INFO_RESP_CMD, iot_proto_node_info_resp_subfn_handler, 0},
 | 
						|
    {PROTO_NW_INFO_RESP_CMD, iot_proto_nw_info_resp_subfn_handler, 0},
 | 
						|
    {PROTO_AES_RESP_CMD, iot_proto_resp_aes_handler, 0},
 | 
						|
    {PROTO_QUERY_GPIO_RESP_CMD, iot_proto_gpio_resp_subfn_handler, 0},
 | 
						|
};
 | 
						|
 | 
						|
static bool_t iot_proto_query_resp_fn_handler(uint8_t *data,
 | 
						|
                     uint16_t len, transmit_direction_e_t dir)
 | 
						|
{
 | 
						|
    bool_t rpt2mcu = false;
 | 
						|
    bool_t need_handle = false;
 | 
						|
    plctxrx_cmd_resp_t *cmd;
 | 
						|
    uint8_t ret;
 | 
						|
    uint8_t state;
 | 
						|
    uint8_t fn = 0, subfn = 0;
 | 
						|
    ge_extend_fn_hdr_t *frm_hdr;
 | 
						|
    proto_cmd_hdl_state_t *sm_state = iot_proto_cmd_handle_state_get();
 | 
						|
    uint32_t i;
 | 
						|
    PROTO_FN_HANDLE handler;
 | 
						|
 | 
						|
    if (CMD_LOCAL_UP_LINK == dir) {
 | 
						|
        cmd = (plctxrx_cmd_resp_t *)data;
 | 
						|
        ret = iot_proto_plctxtx_fn_subfn_get(cmd, &fn, &subfn);
 | 
						|
        if (ret) {
 | 
						|
            iot_cus_printf("[glpr][err]query_resp_fn_handler:cid=0x%x,opcode=0x%x\n",
 | 
						|
                            cmd->cid.cid, cmd->cid.opcode);
 | 
						|
            return rpt2mcu;
 | 
						|
        }
 | 
						|
    /* else ,it means it is a intact gree cmd frame */
 | 
						|
    } else {
 | 
						|
        frm_hdr = (ge_extend_fn_hdr_t *)data;
 | 
						|
        subfn = frm_hdr->subfn;
 | 
						|
    }
 | 
						|
 | 
						|
    iot_cus_printf("[glpr]query_resp_fn_handler:subfn=%d,dir=%d,cur_state=%d\n",
 | 
						|
        subfn, dir, sm_state->state);
 | 
						|
    state = sm_state->state;
 | 
						|
 | 
						|
    /* no mac, doesn't handle cmd */
 | 
						|
    if ((prototask_contxt.macaddr_set == 0) &&
 | 
						|
       (subfn != PROTO_LOCAL_MAC_RESP_CMD)) {
 | 
						|
        iot_cus_printf("[glpr]no mac received! not handle]");
 | 
						|
        return rpt2mcu;
 | 
						|
    }
 | 
						|
 | 
						|
    switch (dir) {
 | 
						|
    case CMD_LOCAL_DOWN_LINK:
 | 
						|
    {
 | 
						|
        switch (state) {
 | 
						|
        case PROTO_CMD_WAIT_MAC_RESP:
 | 
						|
        {
 | 
						|
            if (PROTO_LOCAL_MAC_RESP_CMD == subfn) {
 | 
						|
                need_handle = true;
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        default:
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case CMD_LOCAL_UP_LINK:
 | 
						|
    {
 | 
						|
        switch (state) {
 | 
						|
        case PROTO_CMD_WAIT_SWVER_RESP:
 | 
						|
        {
 | 
						|
            if (PROTO_FW_SWVER_RESP_CMD == subfn) {
 | 
						|
                need_handle = true;
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case PROTO_CMD_WAIT_BOOT_INFO_RESP:
 | 
						|
        {
 | 
						|
            if (PROTO_BOOT_INFO_RESP_CMD == subfn) {
 | 
						|
                need_handle = true;
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case PROTO_CMD_WAIT_TOPO_RESP:
 | 
						|
        {
 | 
						|
            if (PROTO_TOPO_RESP_CMD == subfn) {
 | 
						|
                need_handle = true;
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case PROTO_CMD_WAIT_NET_STS_RESP:
 | 
						|
        {
 | 
						|
            if (PROTO_NET_STS_RESP_CMD == subfn) {
 | 
						|
                need_handle = true;
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case PROTO_CMD_WAIT_RMT_WHITELIST_RESP:
 | 
						|
        {
 | 
						|
            if (PROTO_WHITELIST_RESP_CMD == subfn) {
 | 
						|
                need_handle = true;
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case PROTO_CMD_WAIT_AVAIL_NETWORK_RESP:
 | 
						|
        {
 | 
						|
            if (PROTO_AVAIL_NW_RESP_CMD == subfn) {
 | 
						|
                need_handle = true;
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case PROTO_CMD_WAIT_TX_PWR_RESP:
 | 
						|
        {
 | 
						|
            if (PROTO_TX_PWR_RESP_CMD == subfn) {
 | 
						|
                need_handle = true;
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case PROTO_CMD_WAIT_NTB_RESP:
 | 
						|
        {
 | 
						|
            if (PROTO_NTB_RESP_CMD == subfn) {
 | 
						|
                need_handle = true;
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case PROTO_CMD_WAIT_FB_BITMAP_RESP:
 | 
						|
        {
 | 
						|
            if (PROTO_FB_BITMAP_RESP_CMD == subfn) {
 | 
						|
                need_handle = true;
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case PROTO_CMD_WAIT_FIX_RATE_MODE_RESP:
 | 
						|
        {
 | 
						|
            if (PROTO_FIX_RATE_MODE_RESP_CMD == subfn) {
 | 
						|
                need_handle = true;
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case PROTO_CMD_WAIT_WORK_BAND_RESP:
 | 
						|
        {
 | 
						|
            if (PROTO_WORK_BAND_RESP_CMD == subfn) {
 | 
						|
                need_handle = true;
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case PROTO_CMD_WAIT_NODE_INFO_RESP:
 | 
						|
        {
 | 
						|
            if (PROTO_NODE_INFO_RESP_CMD == subfn) {
 | 
						|
                need_handle = true;
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case PROTO_CMD_WAIT_NW_INFO_RESP:
 | 
						|
        {
 | 
						|
            if (PROTO_NW_INFO_RESP_CMD == subfn) {
 | 
						|
                need_handle = true;
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case PROTO_CMD_DL645_WAIT_TOPO_INFO_RESP:
 | 
						|
        {
 | 
						|
            if (PROTO_TOPO_RESP_CMD == subfn) {
 | 
						|
                need_handle = true;
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        default:
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case CMD_REMOTE_UP_LINK:
 | 
						|
    {
 | 
						|
        switch (state) {
 | 
						|
        case PROTO_CMD_WAIT_TOPO_RESP:
 | 
						|
        {
 | 
						|
            if (PROTO_TOPO_RESP_CMD == subfn) {
 | 
						|
                need_handle = true;
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case PROTO_CMD_WAIT_RMT_WHITELIST_RESP:
 | 
						|
        {
 | 
						|
            if (PROTO_WHITELIST_RESP_CMD == subfn) {
 | 
						|
                need_handle = true;
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case PROTO_CMD_WAIT_CMD_CFM:
 | 
						|
        {
 | 
						|
            if (PROTO_QUERY_GPIO_RESP_CMD == subfn) {
 | 
						|
                need_handle = true;
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        default:
 | 
						|
            break;
 | 
						|
        }
 | 
						|
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case CMD_REMOTE_DOWN_LINK:
 | 
						|
        // do nothing
 | 
						|
        break;
 | 
						|
    default:
 | 
						|
        break;
 | 
						|
    }
 | 
						|
 | 
						|
    iot_cus_printf("[glpr]subfn:%d handle:%d\n", subfn, need_handle);
 | 
						|
    if (need_handle) {
 | 
						|
 | 
						|
        handler = NULL;
 | 
						|
 | 
						|
        for(i = 0; i < ARRAY_CNT(proto_query_resp_subfnhdl_tbl); i++) {
 | 
						|
            if (proto_query_resp_subfnhdl_tbl[i].cmdid == subfn)
 | 
						|
            {
 | 
						|
                handler = proto_query_resp_subfnhdl_tbl[i].cmd_handle_fn;
 | 
						|
                break;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        if (NULL != handler) {
 | 
						|
            rpt2mcu = handler(data, len, dir);
 | 
						|
        } else {
 | 
						|
            iot_cus_printf("\n[glpr][err]No handler found!");
 | 
						|
        }
 | 
						|
 | 
						|
        iot_cus_printf("[glpr]query_resp_fn:handled_state=%d\n",
 | 
						|
            sm_state->state);
 | 
						|
 | 
						|
        if (PROTO_CMD_IDLE == sm_state->state) {
 | 
						|
            /* clear wait response timer if it's active.  */
 | 
						|
            if (os_is_timer_active(prototask_contxt.wait_resp_timer)) {
 | 
						|
                os_stop_timer(prototask_contxt.wait_resp_timer);
 | 
						|
                iot_task_clean_msg(prototask_contxt.task_handle,
 | 
						|
                    PROTO_TIMER_MSG, PROTO_TIMER_WAIT_RESP_TIMEOUT);
 | 
						|
            }
 | 
						|
            /* get next cmd execute */
 | 
						|
            iot_proto_saved_msg_handle();
 | 
						|
        } else {
 | 
						|
            if (os_is_timer_active(prototask_contxt.wait_resp_timer)) {
 | 
						|
                os_stop_timer(prototask_contxt.wait_resp_timer);
 | 
						|
                iot_task_clean_msg(prototask_contxt.task_handle,
 | 
						|
                    PROTO_TIMER_MSG, PROTO_TIMER_WAIT_RESP_TIMEOUT);
 | 
						|
            }
 | 
						|
            os_start_timer(prototask_contxt.wait_resp_timer,
 | 
						|
                PROTO_TIMER_WAIT_RESPONSE_TIMEOUT_INTVL);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    return rpt2mcu;
 | 
						|
}
 | 
						|
 | 
						|
/* fncode handler table */
 | 
						|
static proto_fnhdl_tbl_t proto_subfn_hdl_tbl[] = {
 | 
						|
    {PROTO_GE_PLC_RESP_CMD,              iot_proto_query_resp_fn_handler, 0 },
 | 
						|
    {PROTO_GE_PLC_SET_CMD,               iot_proto_set_fn_handler,        0 },
 | 
						|
    {PROTO_GE_PLC_QUERY_CMD,             iot_proto_query_fn_handler,      0 },
 | 
						|
    /* for gree cmd number statistic  */
 | 
						|
    {0,                                  NULL,                            0 }
 | 
						|
};
 | 
						|
#if PLC_SUPPORT_CCO_ROLE && ENABLE_GREE_UPGRADE
 | 
						|
static proto_upgrade_fnhdl_tbl_t proto_upgrade_fnhdl_tbl[] = {
 | 
						|
    { PROTO_UPGRADE_DL,                 iot_proto_upgrade_fn_handler },
 | 
						|
    { 0,                                NULL },
 | 
						|
};
 | 
						|
#endif
 | 
						|
 | 
						|
uint8_t iot_proto_plctxrx_register(PLCXMIT_CMD_CB cmd_cb,
 | 
						|
                                    PLCXMIT_DATA_CB data_cb)
 | 
						|
{
 | 
						|
    IOT_ASSERT(cmd_cb && data_cb);
 | 
						|
    int8_t ret = ERR_FAIL;
 | 
						|
 | 
						|
    if (cmd_cb && data_cb) {
 | 
						|
        prototask_contxt.gree_cmd_send_cb = cmd_cb;
 | 
						|
        prototask_contxt.gree_data_send_cb = data_cb;
 | 
						|
#if HW_PLATFORM != HW_PLATFORM_SIMU
 | 
						|
        /* if app pib upgrade flag is set, copy old app pib info into new app
 | 
						|
         * pib section
 | 
						|
         */
 | 
						|
        if (iot_pib_app_upgrade_flag()) {
 | 
						|
            iot_cus_printf("%s: need to copy pib\n", __FUNCTION__);
 | 
						|
            iot_proto_upgrade_app_pib_info();
 | 
						|
        }
 | 
						|
#endif
 | 
						|
        iot_proto_flashinfo_init();
 | 
						|
        ret = ERR_OK;
 | 
						|
    }
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
/* get data from the crc pos in gree frame */
 | 
						|
uint16_t  iot_gree_get_crc_byte(uint8_t *data)
 | 
						|
{
 | 
						|
    uint16_t crc_data= 0;
 | 
						|
#if GE_CRC_ENABLE
 | 
						|
    crc_data = (data[1] << 8) | data[0];
 | 
						|
#else
 | 
						|
    crc_data = data[0];
 | 
						|
#endif
 | 
						|
    return crc_data;
 | 
						|
}
 | 
						|
 | 
						|
#if GE_CRC_ENABLE
 | 
						|
/* calculate frame checksum or crc */
 | 
						|
uint16_t ge_frm_checksum_calc(uint8_t *data, uint16_t len)
 | 
						|
{
 | 
						|
 | 
						|
    register uint16_t crc = 0xFFFF;
 | 
						|
    IOT_ASSERT(data && len);
 | 
						|
 | 
						|
    while (len--) {
 | 
						|
        crc = (crc>>8) ^ iot_crc16_tab[(crc ^ *data++) & 0xff];
 | 
						|
    }
 | 
						|
    return crc;
 | 
						|
}
 | 
						|
#else
 | 
						|
uint8_t ge_frm_checksum_calc(uint8_t *data, uint16_t len)
 | 
						|
{
 | 
						|
    uint16_t i;
 | 
						|
    uint8_t checksum = data[0];
 | 
						|
    IOT_ASSERT(data && len);
 | 
						|
 | 
						|
    for (i = 1; i < len; i++) {
 | 
						|
        checksum ^= data[i];
 | 
						|
    }
 | 
						|
    return checksum;
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
uint8_t ge_frame_data_len(uint8_t *data, uint16_t data_len,
 | 
						|
    uint16_t *frame_data_len)
 | 
						|
{
 | 
						|
    uint8_t error_code = ERR_OK;
 | 
						|
    ge_extend_fn_hdr_t *p_hdr = NULL;
 | 
						|
 | 
						|
    IOT_ASSERT(data && frame_data_len);
 | 
						|
    *frame_data_len = 0;
 | 
						|
    if (data_len < GE_FRM_DATA_CNT_FIELD_POS + 1) {
 | 
						|
        /* not a complete frame */
 | 
						|
        error_code = 1;
 | 
						|
        goto error;
 | 
						|
    }
 | 
						|
 | 
						|
    p_hdr = (ge_extend_fn_hdr_t *)data;
 | 
						|
    if ((p_hdr->hdr.fn == PROTO_UPGRADE_DL) &&
 | 
						|
        (p_hdr->subfn == PROTO_UPGRADE_DATA)) {
 | 
						|
        /* for gree upgrade cmds the data length is 0x91-0x98 or 0x9A */
 | 
						|
        if (GREE_CHECK_UPGRADE_CMD(p_hdr->hdr.data_len)) {
 | 
						|
            if (p_hdr->hdr.data_len == GREE_UPGRADE_DATA_CONTROL) {
 | 
						|
                if (data_len < GREE_UPGRADE_DATA_FRM_MIN_LEN) {
 | 
						|
                    /* not a complete frame */
 | 
						|
                    error_code = 1;
 | 
						|
                    goto error;
 | 
						|
                }
 | 
						|
                /* calc gree upgrade data len */
 | 
						|
                *frame_data_len = GREE_UPGRADE_DATA_FRM_CTL_LEN +
 | 
						|
                    data[GREE_UPGRADE_DATA_FRM_LEN_LOW_BYTE] +
 | 
						|
                    (data[GREE_UPGRADE_DATA_FRM_LEN_HIG_BYTE] << 8);
 | 
						|
            } else {
 | 
						|
                *frame_data_len =
 | 
						|
                    GREE_ACQUIRE_UPGRADE_CMD_LEN(p_hdr->hdr.data_len);
 | 
						|
            }
 | 
						|
        }
 | 
						|
    } else if ((p_hdr->hdr.fn == PROTO_GE_PLC_SET_CMD) &&
 | 
						|
        (p_hdr->subfn == PROTO_GE_DATA_CMD)) {
 | 
						|
        *frame_data_len = ACQUIRE_DATA_LEN(p_hdr->hdr.data_len);
 | 
						|
        if(data[GE_FRM_DATA_EXT_LEN_POS] & GE_FRM_DATA_EXT_FLAG) {
 | 
						|
            *frame_data_len += GE_EXT_DATA_LEN;
 | 
						|
        }
 | 
						|
    } else if (GE_CHECK_FRM_CMD(p_hdr->hdr.data_len)) {
 | 
						|
        *frame_data_len = ACQUIRE_DATA_LEN(p_hdr->hdr.data_len);
 | 
						|
    } else {
 | 
						|
        /* detec frame control length error */
 | 
						|
        error_code = 2;
 | 
						|
        *frame_data_len = 0;
 | 
						|
        goto error;
 | 
						|
    }
 | 
						|
 | 
						|
    /* check the frame is complete */
 | 
						|
    if (data_len >= (*frame_data_len + GE_FRM_MIN_LEN)) {
 | 
						|
        return ERR_OK;
 | 
						|
    } else  {
 | 
						|
        /* not a complete frame */
 | 
						|
        error_code = 1;
 | 
						|
        goto error;
 | 
						|
    }
 | 
						|
 | 
						|
error:
 | 
						|
 | 
						|
    iot_cus_printf("[glpr][war %d] ctl=%X flen=%d dlen=%d\n",
 | 
						|
        error_code, p_hdr->hdr.data_len, *frame_data_len, data_len);
 | 
						|
 | 
						|
    return error_code;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * iot_proto_ge_frame_check - parser a ge frame
 | 
						|
 * @recv_data:    descript of receive buffer.
 | 
						|
 * @p_gepool:     point to the pool whitch save the ge frame witch
 | 
						|
                  checked out from the uart buffer
 | 
						|
 * @gepool_size:  point to the data length in the p_gepool
 | 
						|
 * @ge_pkt_len:   point to the ge length if there is a frame can be checked out
 | 
						|
 * @retval: -     check result, GET_NO_FRAME, GET_ONE_FRAME or GET_HALF_FRAME
 | 
						|
 */
 | 
						|
static uint8_t iot_proto_ge_frame_check(mcu_data_handle_t *recv_data,
 | 
						|
    uint8_t *p_gepool, uint16_t *gepool_size, uint16_t *ge_pkt_len)
 | 
						|
{
 | 
						|
    uint8_t     check_result = GET_NO_FRAME;
 | 
						|
    uint8_t     ret = 0;
 | 
						|
    uint8_t     *buf = &recv_data->data[recv_data->data_pos];
 | 
						|
    uint16_t    gefrm_len = 0;
 | 
						|
    uint16_t    crc_data = 0;
 | 
						|
 | 
						|
    /* find the 1st preamble 0xAA. if not, the checking is fail */
 | 
						|
    if (0xAA == buf[0]) {
 | 
						|
        /* half frame, return */
 | 
						|
        if (GE_FRM_MIN_LEN > recv_data->total_len - recv_data->data_pos) {
 | 
						|
            check_result = GET_HALF_FRAME;
 | 
						|
            goto result;
 | 
						|
        }
 | 
						|
 | 
						|
        /* check second 0xAA. if not, return */
 | 
						|
        if (0xAA == buf[1]) {
 | 
						|
            ret = ge_frame_data_len(&buf[0],
 | 
						|
                recv_data->total_len - recv_data->data_pos , &gefrm_len);
 | 
						|
            if (ret == 2) {
 | 
						|
                /* frame control check error,drop */
 | 
						|
                goto result;
 | 
						|
            } else if (ret == 1) {
 | 
						|
                /* half frame, return */
 | 
						|
                check_result = GET_HALF_FRAME;
 | 
						|
                goto result;
 | 
						|
            }
 | 
						|
 | 
						|
            /* step to check end code 0xFF */
 | 
						|
            if (buf[gefrm_len + GE_FRM_TAIL_CODE_FIELD_POS] !=
 | 
						|
                GE_FRM_TAIL_CODE) {
 | 
						|
                /* not right, drop */
 | 
						|
                iot_cus_printf("[glpr][war]not end with FF\n");
 | 
						|
                goto result;
 | 
						|
            }
 | 
						|
 | 
						|
            /* crc check here */
 | 
						|
            crc_data = iot_gree_get_crc_byte(
 | 
						|
                &buf[gefrm_len + GE_FRM_CHECK_SUM_FIELD_POS]);
 | 
						|
            if (crc_data != ge_frm_checksum_calc(&buf[0], gefrm_len +
 | 
						|
                GE_FRM_CHECK_SUM_FIELD_POS)) {
 | 
						|
                /*crc not right, drop*/
 | 
						|
                iot_cus_printf("[glpr][war]detec pkt crc wrong\n");
 | 
						|
                goto result;
 | 
						|
            }
 | 
						|
 | 
						|
            /* finally, we got one pkt, so luckly */
 | 
						|
            if (*gepool_size + GE_FRM_MIN_LEN + gefrm_len > MCU_DATA_RECV_MAX) {
 | 
						|
                check_result = GET_OVERFLOW;
 | 
						|
                goto result;
 | 
						|
            }
 | 
						|
 | 
						|
            /* prepare output */
 | 
						|
            os_mem_cpy(&p_gepool[*gepool_size], &buf[0],
 | 
						|
                GE_FRM_MIN_LEN + gefrm_len);
 | 
						|
            *gepool_size += (GE_FRM_MIN_LEN + gefrm_len);
 | 
						|
            *ge_pkt_len = (GE_FRM_MIN_LEN + gefrm_len);
 | 
						|
            check_result = GET_ONE_FRAME;
 | 
						|
        }
 | 
						|
    }
 | 
						|
result:
 | 
						|
    return check_result;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * iot_proto_data_parse_and_post - parser command and post to task.
 | 
						|
 * @buf:        input buf need to parser
 | 
						|
 * @len:        buf len
 | 
						|
 * @post_func:  the function will post parsered command to task
 | 
						|
 * @param:  param passed to the post_func.
 | 
						|
 * @return:     parser result
 | 
						|
 */
 | 
						|
uint8_t iot_proto_data_parse_and_post(uint8_t *buf, uint16_t len,
 | 
						|
    POST_RECV_DATA post_func, uint32_t param)
 | 
						|
{
 | 
						|
    uint8_t*             pdata;
 | 
						|
    uint8_t*             pbuf;
 | 
						|
    uint8_t              check_result = GET_NO_FRAME;
 | 
						|
    uint16_t             total;
 | 
						|
    uint16_t             ge_buflen;
 | 
						|
    mcu_data_handle_t*   p_mcudata;
 | 
						|
    uint16_t             ge_len;
 | 
						|
    /* record the position modbus firstly check out a half frame each loop */
 | 
						|
    static uint16_t      modbus_half_predict;
 | 
						|
 | 
						|
    if (NULL == buf || len == 0) {
 | 
						|
        return ERR_FAIL;
 | 
						|
    }
 | 
						|
 | 
						|
    total = len;
 | 
						|
    pbuf = buf;
 | 
						|
    p_mcudata = &mcu_data;
 | 
						|
 | 
						|
    uart_thpt.recv_len += len;
 | 
						|
 | 
						|
    /* uart drv may report len > UART_RECV_SIZE_MAX, so we handle it in times */
 | 
						|
    do {
 | 
						|
        /* data_pos indicate possible gree frame start from. if it is larger
 | 
						|
           than max gree size, means pmcudata[0] ~ p_mcudata[GE_FRM_MAX_LEN] not
 | 
						|
           valide gree frame. however, it should not happen. paser function
 | 
						|
           should alreay remove garbage bytes.*/
 | 
						|
        if (p_mcudata->data_pos >= PARSE_FRM_MAX_LEN) {
 | 
						|
            iot_cus_printf("[glpr][err] data_pos:%d total:%d\n",
 | 
						|
                p_mcudata->data_pos, total);
 | 
						|
            goto error;
 | 
						|
        }
 | 
						|
 | 
						|
        pdata = &p_mcudata->data[p_mcudata->data_pos];
 | 
						|
        iot_cus_printf("[glpr]break frame pos= %d new_len=%d\n",
 | 
						|
            p_mcudata->data_pos, len);
 | 
						|
 | 
						|
        if (total > UART_RECV_SIZE_MAX) {
 | 
						|
            os_mem_cpy(pdata, pbuf, UART_RECV_SIZE_MAX);
 | 
						|
            pbuf += UART_RECV_SIZE_MAX;
 | 
						|
            total -= UART_RECV_SIZE_MAX;
 | 
						|
            p_mcudata->total_len = UART_RECV_SIZE_MAX + p_mcudata->data_pos;
 | 
						|
        } else {
 | 
						|
            os_mem_cpy(pdata, pbuf, total);
 | 
						|
            pbuf += total;
 | 
						|
            p_mcudata->total_len = total + p_mcudata->data_pos;
 | 
						|
            total = 0;
 | 
						|
        }
 | 
						|
        /* now position should be 0, one new paser cycle starts */
 | 
						|
        p_mcudata->data_pos = 0;
 | 
						|
        /* clean ge_buf */
 | 
						|
        ge_buflen = 0;
 | 
						|
        os_mem_set(ge_buf, 0, MCU_DATA_RECV_MAX);
 | 
						|
        check_result = GET_NO_FRAME;
 | 
						|
 | 
						|
        /*
 | 
						|
          do frame check from mcudata offset 0, and the function will return
 | 
						|
          full gree frame buffer, ge_buf, and ge_buflen. Also, wrong packet
 | 
						|
          in middle removed. remain half packet moved to head of p_mucdata.
 | 
						|
        */
 | 
						|
        while (p_mcudata->data_pos < p_mcudata->total_len) {
 | 
						|
            ge_len = 0;
 | 
						|
            /* if the function iot_proto_ge_frame_check() get a ge frame, the
 | 
						|
                frame should be copy to the ge_buf closely in the function.
 | 
						|
                ge_buflen is all data length in the ge_buf, it should add the
 | 
						|
                length of the frame in the function.
 | 
						|
                ge_len is the length of the ge frame, the p_mcudata->data_pos
 | 
						|
                should jump the whole length of the frame then check the next
 | 
						|
                positon if do not find a ge frame.
 | 
						|
                the value of ge_buf, ge_buflen, ge_len will not changed */
 | 
						|
            check_result = iot_proto_ge_frame_check(p_mcudata, ge_buf,
 | 
						|
                &ge_buflen, &ge_len);
 | 
						|
            if (check_result == GET_ONE_FRAME) {
 | 
						|
                p_mcudata->data_pos += ge_len;
 | 
						|
                modbus_half_predict = 0;
 | 
						|
                continue;
 | 
						|
            } else if (check_result == GET_HALF_FRAME) {
 | 
						|
                break;
 | 
						|
            } else if (check_result == GET_OVERFLOW) {
 | 
						|
                modbus_half_predict = 0;
 | 
						|
                break;
 | 
						|
            }
 | 
						|
 | 
						|
            /* if the function iot_proto_645_format_check() get a dl645 frame,
 | 
						|
                the frame should be handled then become a ge frame to copy to
 | 
						|
                the ge_buf closely in the function.
 | 
						|
                ge_buflen is all data length in the ge_buf, it should add the
 | 
						|
                length of the frame in thefunction.
 | 
						|
                ge_len is the length of the dl645 frame, the
 | 
						|
                p_mcudata->data_pos should jump the whole length of the dl645
 | 
						|
                frame then check the next positon if do not find a ge frame.
 | 
						|
                the value of ge_buf, ge_buflen, ge_len will not changed */
 | 
						|
            check_result = iot_proto_645_format_check(p_mcudata, ge_buf,
 | 
						|
                &ge_buflen, &ge_len);
 | 
						|
            if (check_result == GET_ONE_FRAME) {
 | 
						|
                p_mcudata->data_pos += ge_len;
 | 
						|
                modbus_half_predict = 0;
 | 
						|
                continue;
 | 
						|
            } else if (check_result == GET_HALF_FRAME) {
 | 
						|
                break;
 | 
						|
            } else if (check_result == GET_OVERFLOW) {
 | 
						|
                modbus_half_predict = 0;
 | 
						|
                break;
 | 
						|
            }
 | 
						|
#if PLC_SUPPORT_STA_ROLE
 | 
						|
            /* if the function iot_proto_modbus_format_check() get a modbus
 | 
						|
                frame, the frame should be handled then become a ge frame to
 | 
						|
                copy to the ge_buf closely in the function.
 | 
						|
                ge_buflen is all data length in the ge_buf, it should add the
 | 
						|
                length of the frame in the function.
 | 
						|
                ge_len is the length of the modbus frame,
 | 
						|
                the p_mcudata->data_pos should jump the whole length of the
 | 
						|
                modbus frame then check the next positon if do not find a ge
 | 
						|
                frame.
 | 
						|
                the value of ge_buf, ge_buflen, ge_len will not changed */
 | 
						|
            check_result = iot_proto_modbus_format_check(p_mcudata, ge_buf,
 | 
						|
                &ge_buflen, &ge_len);
 | 
						|
            if (check_result == GET_ONE_FRAME) {
 | 
						|
                p_mcudata->data_pos += ge_len;
 | 
						|
                modbus_half_predict = 0;
 | 
						|
                continue;
 | 
						|
            } else if (check_result == GET_HALF_FRAME) {
 | 
						|
                /* only the first half position should be record */
 | 
						|
                if (!modbus_half_predict) {
 | 
						|
                    /* add 1 to let the position '0' can be record too.
 | 
						|
                        when copy the half frame to front of
 | 
						|
                        p_mcudata->data_pos, it should minus 1 */
 | 
						|
                    modbus_half_predict = p_mcudata->data_pos + 1;
 | 
						|
                }
 | 
						|
 | 
						|
                check_result = GET_NO_FRAME;
 | 
						|
 | 
						|
            } else if (check_result == GET_OVERFLOW) {
 | 
						|
                iot_cus_printf("overflow data pos=%d\n", p_mcudata->data_pos);
 | 
						|
                iot_cus_printf("overflow left length =%d\n",
 | 
						|
                    total + p_mcudata->total_len - p_mcudata->data_pos);
 | 
						|
                modbus_half_predict = 0;
 | 
						|
                break;
 | 
						|
            }
 | 
						|
#endif
 | 
						|
            p_mcudata->data_pos++;
 | 
						|
        }
 | 
						|
 | 
						|
        if (modbus_half_predict) {
 | 
						|
            modbus_half_predict -= 1;
 | 
						|
            os_mem_cpy(p_mcudata->data, &p_mcudata->data[modbus_half_predict],
 | 
						|
                p_mcudata->total_len - modbus_half_predict);
 | 
						|
            p_mcudata->data_pos = p_mcudata->total_len - modbus_half_predict;
 | 
						|
            modbus_half_predict = 0;
 | 
						|
        } else if ((check_result == GET_HALF_FRAME) ||
 | 
						|
            (check_result == GET_OVERFLOW)) {
 | 
						|
            /* if half frame or overflow exist, save the rest of data */
 | 
						|
            os_mem_cpy(p_mcudata->data, &p_mcudata->data[p_mcudata->data_pos],
 | 
						|
                p_mcudata->total_len - p_mcudata->data_pos);
 | 
						|
            p_mcudata->data_pos = p_mcudata->total_len - p_mcudata->data_pos;
 | 
						|
        } else {
 | 
						|
            p_mcudata->total_len = 0;
 | 
						|
            p_mcudata->data_pos = 0;
 | 
						|
        }
 | 
						|
 | 
						|
        /* put filtered packeted in message queue */
 | 
						|
        if (ge_buflen > 0) {
 | 
						|
            if (post_func(ge_buf, ge_buflen, param)) {
 | 
						|
                goto error;
 | 
						|
            }
 | 
						|
        }
 | 
						|
    } while ((total > 0) || (check_result == GET_OVERFLOW));
 | 
						|
 | 
						|
    return ERR_OK;
 | 
						|
 | 
						|
error:
 | 
						|
    p_mcudata->data_pos = 0;
 | 
						|
 | 
						|
    return ERR_FAIL;
 | 
						|
}
 | 
						|
 | 
						|
/* post uart received command to task */
 | 
						|
uint8_t iot_proto_task_post_uart_cmd(uint8_t * data, uint16_t len, uint32_t param)
 | 
						|
{
 | 
						|
    uint8_t msg = PROTO_MCU_RX_MSG;
 | 
						|
    uint8_t msg_id = 0;
 | 
						|
    iot_pkt_t* send_pkt = NULL;
 | 
						|
    (void)param;
 | 
						|
    send_pkt = iot_pkt_alloc(len, IOT_GREE_APP_MID);
 | 
						|
    if (send_pkt) {
 | 
						|
        /* copy data from buf to data packet */
 | 
						|
        os_mem_cpy(iot_pkt_put(send_pkt, len), data, len);
 | 
						|
 | 
						|
        /* alloc message to insert proto task msg queue */
 | 
						|
        if (iot_hwver_is_ledc_v3_0_jy() &&
 | 
						|
            (iot_board_get_board_id() == CUS_BOARD_ID_LEDC_V3_0) &&
 | 
						|
            (IOT_PLC_DEV_ROLE_STA == prototask_contxt.local_dev.nw_role)) {
 | 
						|
            if (prototask_contxt.edge_obj.uart_hdl != NULL) {
 | 
						|
                msg = EDGE_UART_RX_MSG;
 | 
						|
            }
 | 
						|
        }
 | 
						|
        iot_proto_task_post_msg(msg, msg_id,
 | 
						|
            send_pkt, DATA_DOWN_LINK, IOT_PROTO_TASK_QUEUE_LP);
 | 
						|
        return ERR_OK;
 | 
						|
    } else {
 | 
						|
        iot_cus_printf("[glpr][err]no mem, frame len:%d\n", len);
 | 
						|
        return ERR_FAIL;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
#if IOT_GE_EXT_SDK_ENABLE
 | 
						|
/*
 | 
						|
 * uart drver calls, running in uart driver task.
 | 
						|
 * @buf: input data pointer
 | 
						|
 * @len: data len
 | 
						|
 */
 | 
						|
uint8_t iot_proto_uplayer_data_recv_func(uint8_t *buf, uint16_t len)
 | 
						|
{
 | 
						|
    /* extern sdk need parser uart data when recved */
 | 
						|
    return iot_proto_task_post_uart_cmd(buf, len, 0);
 | 
						|
}
 | 
						|
 | 
						|
#else
 | 
						|
/*
 | 
						|
 * uart drver calls, running in uart driver task.
 | 
						|
 * @buf: input data pointer
 | 
						|
 * @len: data len
 | 
						|
 */
 | 
						|
uint8_t iot_proto_uplayer_data_recv_func(uint8_t *buf, uint16_t len)
 | 
						|
{
 | 
						|
    return iot_proto_data_parse_and_post(buf, len, iot_proto_task_post_uart_cmd, 0);
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
/* hook */
 | 
						|
static uint8_t iot_proto_parse_fn(uint8_t *data)
 | 
						|
{
 | 
						|
    IOT_ASSERT(data);
 | 
						|
    ge_frm_hdr_t *hdr = (ge_frm_hdr_t *)data;
 | 
						|
    return hdr->fn;
 | 
						|
}
 | 
						|
 | 
						|
/* hook */
 | 
						|
uint8_t iot_proto_register_response_to_uplayer(PROTO_SENDTO_UPLAYER fn)
 | 
						|
{
 | 
						|
    uint8_t ret = ERR_FAIL;
 | 
						|
 | 
						|
    if (fn) {
 | 
						|
        prototask_contxt.proto_sendto_mainboard_fn = fn;
 | 
						|
        ret = ERR_FAIL;
 | 
						|
    }
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
/* hook */
 | 
						|
uint8_t iot_proto_register_update_cco_mac_to_uplayer(PROTO_UPDATA_CCO_MAC fn)
 | 
						|
{
 | 
						|
    uint8_t ret = ERR_FAIL;
 | 
						|
 | 
						|
    if (fn) {
 | 
						|
        prototask_contxt.update_cco_mac = fn;
 | 
						|
        ret = ERR_FAIL;
 | 
						|
    }
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
uint8_t iot_proto_is_ready(void)
 | 
						|
{
 | 
						|
    return prototask_contxt.local_dev.dev_ready ? 1 : 0;
 | 
						|
}
 | 
						|
 | 
						|
/* handle mcu message */
 | 
						|
static void iot_proto_mcu_msg_handle(iot_pkt_t *data,
 | 
						|
    transmit_direction_e_t dir)
 | 
						|
{
 | 
						|
    uint8_t fn;
 | 
						|
    uint16_t cur_pos = 0;
 | 
						|
    uint16_t total_len = (uint16_t)iot_pkt_data_len(data);
 | 
						|
    uint8_t *data_buf = iot_pkt_data(data);
 | 
						|
    uint8_t *tmp_buf;
 | 
						|
    /* data cnt in each gree frame */
 | 
						|
    uint16_t  data_len;
 | 
						|
    uint8_t i;
 | 
						|
    uint8_t ret = 0;
 | 
						|
    transmit_direction_e_t tmp_dir;
 | 
						|
    uint8_t fncode_hdlr_cnt = ARRAY_CNT(proto_subfn_hdl_tbl) - 1;
 | 
						|
#if PLC_SUPPORT_CCO_ROLE && ENABLE_GREE_UPGRADE
 | 
						|
    uint8_t upgrade_fncode_hdlr_cnt = ARRAY_CNT(proto_upgrade_fnhdl_tbl) - 1;
 | 
						|
#endif
 | 
						|
 | 
						|
    /* handle each intact frame extracted from uart data buffer */
 | 
						|
    do {
 | 
						|
        data_len = 0;
 | 
						|
        tmp_buf = data_buf + cur_pos;
 | 
						|
        if (cur_pos >= (total_len - 1)) {
 | 
						|
            iot_cus_printf("[grpr][err] pos=%d >= %d - 1\n", cur_pos, total_len);
 | 
						|
            break;
 | 
						|
        }
 | 
						|
 | 
						|
        ret = ge_frame_data_len(tmp_buf, total_len - cur_pos, &data_len);
 | 
						|
        if (ret != ERR_OK) {
 | 
						|
            /* not get a complete frame */
 | 
						|
            iot_cus_printf("[grpr][err] incomplete frame\n");
 | 
						|
            break;
 | 
						|
        }
 | 
						|
 | 
						|
        /* increase current pos to reach next intact frame */
 | 
						|
        cur_pos += data_len + GE_FRM_MIN_LEN;
 | 
						|
 | 
						|
        /* get fncode from gree frame */
 | 
						|
        fn = prototask_contxt.proto_pase_fn(tmp_buf);
 | 
						|
        /*
 | 
						|
        * if fn is extended fn,then direction must be
 | 
						|
        * CMD_LOCAL_DOWN_LINK.
 | 
						|
        */
 | 
						|
        if (PROTO_UPGRADE_DL == fn) {
 | 
						|
#if PLC_SUPPORT_CCO_ROLE && ENABLE_GREE_UPGRADE
 | 
						|
            for (i = 0; i < upgrade_fncode_hdlr_cnt; i++) {
 | 
						|
                if (fn == proto_upgrade_fnhdl_tbl[i].cmdid) {
 | 
						|
                    if (proto_upgrade_fnhdl_tbl[i].cmd_handle_fn) {
 | 
						|
                        proto_upgrade_fnhdl_tbl[i].cmd_handle_fn(tmp_buf,
 | 
						|
                            data_len + GE_FRM_MIN_LEN);
 | 
						|
                    }
 | 
						|
                    break;
 | 
						|
                }
 | 
						|
            }
 | 
						|
            /* find no fncode in fncode table */
 | 
						|
            if (i == upgrade_fncode_hdlr_cnt) {
 | 
						|
                iot_cus_printf("[glpr][err]not find %x in fncode table\n", fn);
 | 
						|
            }
 | 
						|
#else
 | 
						|
            iot_cus_printf("[glpr][info]upgrade %x not support\n",fn);
 | 
						|
#endif
 | 
						|
        } else if (PROTO_GE_PLC_QUERY_CMD == fn
 | 
						|
            || PROTO_GE_PLC_RESP_CMD == fn
 | 
						|
            || PROTO_GE_PLC_SET_CMD == fn) {
 | 
						|
            /* tag for direction send */
 | 
						|
            tmp_dir = CMD_LOCAL_DOWN_LINK;
 | 
						|
            /* look for fncode handler to handle rx data from MCU */
 | 
						|
            for (i = 0; i < fncode_hdlr_cnt; i++) {
 | 
						|
                if (fn == proto_subfn_hdl_tbl[i].cmdid) {
 | 
						|
                    if (proto_subfn_hdl_tbl[i].cmd_handle_fn) {
 | 
						|
                        proto_subfn_hdl_tbl[i].cmd_handle_fn(tmp_buf,
 | 
						|
                            data_len + GE_FRM_MIN_LEN, tmp_dir);
 | 
						|
                    }
 | 
						|
                    break;
 | 
						|
                }
 | 
						|
            }
 | 
						|
            /* find no fncode in fncode table */
 | 
						|
            if (i == fncode_hdlr_cnt) {
 | 
						|
                iot_cus_printf("[glpr][err] gree fn=0x%x not support\n", fn);
 | 
						|
            }
 | 
						|
        }
 | 
						|
    } while (cur_pos < total_len);
 | 
						|
 | 
						|
    iot_pkt_free(data);
 | 
						|
}
 | 
						|
 | 
						|
/* aggr received gree frame, cached to report mcu once */
 | 
						|
static void iot_proto_monitor_timeout_trigger_send(void)
 | 
						|
{
 | 
						|
    if (glb_ul_data_len > 0) {
 | 
						|
        iot_pkt_t *data =
 | 
						|
            iot_pkt_alloc(glb_ul_data_len, IOT_GREE_APP_MID);
 | 
						|
        IOT_ASSERT(data);
 | 
						|
        iot_pkt_put(data, glb_ul_data_len);
 | 
						|
        /* copy data from glb_ul_tmp_buf to packet */
 | 
						|
        os_mem_cpy(iot_pkt_data(data), glb_ul_tmp_buf, glb_ul_data_len);
 | 
						|
        /* to pick up DL645 frame and modbus frame in the FEA0 frame in data */
 | 
						|
        iot_handle_ge_from_plc(data);
 | 
						|
        /* report gree frame to MCU */
 | 
						|
        iot_proto_send_to_mainboard(data);
 | 
						|
        /* clear data buffer */
 | 
						|
        os_mem_set(glb_ul_tmp_buf, 0, glb_ul_data_len);
 | 
						|
        glb_ul_data_len = 0;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void iot_proto_query_mac_timeout_trigger_send(void)
 | 
						|
{
 | 
						|
    /* baud_index 1:9600, baud_index 2:2400 */
 | 
						|
    uint8_t baud_inx[]= {2, 1};
 | 
						|
 | 
						|
    if (prototask_contxt.macaddr_set) {
 | 
						|
        /* mac setted */
 | 
						|
        return;
 | 
						|
    }
 | 
						|
    if (prototask_contxt.detect_devmac_cnt < STA_DETECTED_MAC_MAX_CNT) {
 | 
						|
        /* set baud */
 | 
						|
        iot_grapp_modify_uart_param(
 | 
						|
            baud_inx[prototask_contxt.detect_devmac_cnt % 2],
 | 
						|
            IOT_UART_PARITY_EVEN,
 | 
						|
            IOT_UART_DLEN_8_BITS,
 | 
						|
            IOT_UART_STOP_1_BITS);
 | 
						|
        prototask_contxt.detect_devmac_cnt++;
 | 
						|
        iot_grapp_set_uart_config(greeapp->uart_com);
 | 
						|
        /* send cmd query mac */
 | 
						|
        iot_proto_query_mcu_mac();
 | 
						|
        /* restart timer */
 | 
						|
        os_start_timer(prototask_contxt.detect_timer,
 | 
						|
            PROTO_TIMER_QUERY_MAC_TIMEOUT_INTVL);
 | 
						|
        return;
 | 
						|
    }
 | 
						|
    /*timeout set mac */
 | 
						|
    iot_proto_set_local_mac();
 | 
						|
}
 | 
						|
 | 
						|
/* cmd response time out */
 | 
						|
static void iot_proto_wait_response_timeout_trigger_send(void)
 | 
						|
{
 | 
						|
    proto_cmd_hdl_state_t *sm = iot_proto_cmd_handle_state_get();
 | 
						|
    uint32_t do_clean;
 | 
						|
 | 
						|
    switch (sm->state) {
 | 
						|
    case PROTO_CMD_WAIT_WHITE_LIST_SET:
 | 
						|
    case PROTO_CMD_WAIT_PAIR_TABLE_SET:
 | 
						|
    {
 | 
						|
        iot_proto_wl_pt_remote_set_timeout(sm->state,
 | 
						|
                sm->dir, sm->seq, sm->dev.mac);
 | 
						|
        /* fail do clean */
 | 
						|
        iot_proto_whitelist_state_init();
 | 
						|
        iot_proto_pairtable_state_init();
 | 
						|
        do_clean = 1;
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case PROTO_CMD_WAIT_RMT_WHITELIST_RESP:
 | 
						|
    {
 | 
						|
        IOT_ASSERT(CMD_REMOTE_UP_LINK == sm->dir);
 | 
						|
        iot_proto_wl_pt_remote_query_timeout_from_mcu(sm->state);
 | 
						|
        do_clean = 1;
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case PROTO_CMD_WAIT_TOPO_RESP:
 | 
						|
    {
 | 
						|
        IOT_ASSERT(CMD_REMOTE_UP_LINK == sm->dir);
 | 
						|
        iot_proto_wait_rmt_topo_resp_timeout(sm);
 | 
						|
        do_clean = 1;
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case PROTO_CMD_WAIT_MAC_RESP:
 | 
						|
    case PROTO_CMD_WAIT_IP_RESP:
 | 
						|
    case PROTO_CMD_WAIT_SWVER_RESP:
 | 
						|
    case PROTO_CMD_WAIT_BOOT_INFO_RESP:
 | 
						|
    case PROTO_CMD_WAIT_PLCTXRX_CONFIG_RESP:
 | 
						|
    case PROTO_CMD_WAIT_PASSD_RESP:
 | 
						|
    case PROTO_CMD_WAIT_NET_STS_RESP:
 | 
						|
    case PROTO_CMD_WAIT_PLC_STS_RESP:
 | 
						|
    case PROTO_CMD_WAIT_AVAIL_NETWORK_RESP:
 | 
						|
    case PROTO_CMD_WAIT_GREE_STS_RESP:
 | 
						|
    case PROTO_CMD_WAIT_NTB_RESP:
 | 
						|
    case PROTO_CMD_WAIT_FB_BITMAP_RESP:
 | 
						|
    case PROTO_CMD_WAIT_FIX_RATE_MODE_RESP:
 | 
						|
    case PROTO_CMD_WAIT_WORK_BAND_RESP:
 | 
						|
    case PROTO_CMD_DL645_WAIT_TOPO_INFO_RESP:
 | 
						|
    {
 | 
						|
        /* we believe local not timeout */
 | 
						|
        do_clean = 1;
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case PROTO_CMD_WAIT_CMD_CFM:
 | 
						|
    {
 | 
						|
        IOT_ASSERT(CMD_REMOTE_UP_LINK == sm->dir);
 | 
						|
        iot_proto_wait_cmd_cfm_timeout(sm);
 | 
						|
        do_clean = 1;
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    default:
 | 
						|
        do_clean = 0;
 | 
						|
        break;
 | 
						|
    }
 | 
						|
 | 
						|
    if (do_clean) {
 | 
						|
        /* reinit cmd handle state */
 | 
						|
        iot_proto_cmd_handle_state_init();
 | 
						|
        /* handle next saved cmd, if we have */
 | 
						|
        iot_proto_saved_msg_handle();
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void iot_proto_timer_msg_handle(iot_task_msg_t *msg)
 | 
						|
{
 | 
						|
    iot_proto_msg_t *task_msg;
 | 
						|
    IOT_ASSERT(msg);
 | 
						|
 | 
						|
    task_msg = (iot_proto_msg_t*)msg;
 | 
						|
 | 
						|
    switch (task_msg->msg.id) {
 | 
						|
    case PROTO_TIMER_MONITOR_TIMEOUT:
 | 
						|
    {
 | 
						|
        /* ul data aggr timer */
 | 
						|
        iot_proto_monitor_timeout_trigger_send();
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case PROTO_TIMER_QUERY_MAC_TIMEOUT:
 | 
						|
    {
 | 
						|
        /* ask mcu for mac addr timer */
 | 
						|
        iot_proto_query_mac_timeout_trigger_send();
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case PROTO_TIMER_WAIT_RESP_TIMEOUT:
 | 
						|
    {
 | 
						|
        /* mcu cmd response timeout  */
 | 
						|
        iot_proto_wait_response_timeout_trigger_send();
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case PROTO_TIMER_REBOOT_STA_TIMEOUT:
 | 
						|
    {
 | 
						|
        /* delay reboot */
 | 
						|
        iot_proto_reboot_delay_timeout_handler();
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case PROTO_TIMER_STATISTIC:
 | 
						|
    {
 | 
						|
        iot_proto_statistic_timer_timeout_handler();
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case PROTO_TIMER_STA_LEAVE_TIMEOUT:
 | 
						|
    {
 | 
						|
        /* monitor leave net, need indicate to cco active. */
 | 
						|
        iot_proto_sta_leave_delay_timeout_handler();
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case PROTO_TIMER_UPDATE_STATE_TIMEOUT:
 | 
						|
    {
 | 
						|
#if PLC_SUPPORT_CCO_ROLE && ENABLE_GREE_UPGRADE
 | 
						|
        /* update upgrade state timer */
 | 
						|
        iot_proto_update_sta_upgrade_status();
 | 
						|
#endif
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case PROTO_TIMER_BRD_PKT_WINDOW_RPT:
 | 
						|
    {
 | 
						|
        iot_proto_brd_data_rpt_window_timer_handler();
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case PROTO_TIMER_PAGING_TIMEOUT:
 | 
						|
    {
 | 
						|
        iot_proto_sta_paging_timer_handler();
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case PROTO_TIMER_TRIAL_RUN_CHECK:
 | 
						|
    {
 | 
						|
        iot_proto_check_trial_run_pass();
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case PROTO_TIMER_645_LOCAL_MODE:
 | 
						|
    {
 | 
						|
#if PLC_SUPPORT_STA_ROLE
 | 
						|
        iot_proto_645_local_mode_timer_handler();
 | 
						|
#endif
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case PROTO_START_EDGE_TMR_ID:
 | 
						|
    {
 | 
						|
        post_monitor_start_timer_msg_handler();
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    default:
 | 
						|
        break;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
uint16_t iot_proto_get_plc_data_len(uint8_t *src_data, uint16_t data_len)
 | 
						|
{
 | 
						|
    uint16_t frm_len = 0;
 | 
						|
 | 
						|
    if((data_len >= GE_FRM_DATA_CNT_FIELD_LEN + GE_FRM_ID_FIELD_LEN) &&
 | 
						|
        (src_data != NULL)) {
 | 
						|
        IOT_ASSERT(src_data[0] <= GE_FRM_PLD_MAX_LEN);
 | 
						|
        frm_len = ACQUIRE_DATA_LEN(src_data[0]) +
 | 
						|
            GE_FRM_DATA_CNT_FIELD_LEN + GE_FRM_ID_FIELD_LEN;
 | 
						|
        if (src_data[1] == PROTO_GE_PLC_SET_CMD &&
 | 
						|
            src_data[2] == PROTO_GE_DATA_CMD) {
 | 
						|
            /* if data extend,frame len is need to add GE_EXT_DATA_LEN */
 | 
						|
            if (src_data[4] & GE_FRM_DATA_EXT_FLAG) {
 | 
						|
                frm_len += GE_EXT_DATA_LEN;
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    return frm_len;
 | 
						|
}
 | 
						|
 | 
						|
static uint16_t iot_proto_plc_data_group_frame(uint8_t *dst, uint8_t *src,
 | 
						|
    uint16_t src_len)
 | 
						|
{
 | 
						|
    /**
 | 
						|
     * payload of gree frame
 | 
						|
     * field:| data cnt | id |    data      |
 | 
						|
     * oct  :|   1 B    | 4B |   data cnt B |
 | 
						|
     */
 | 
						|
    uint16_t src_frm_len = 0;
 | 
						|
    IOT_ASSERT(src && dst);
 | 
						|
    uint8_t *tmp_buf = dst;
 | 
						|
    uint16_t check_sum = 0;
 | 
						|
    ge_extend_fn_hdr_t *dst_hdr;
 | 
						|
 | 
						|
    /* add preamble */
 | 
						|
    *((uint16_t *)tmp_buf) = GE_FRM_PREAMBLE_CODE;
 | 
						|
    tmp_buf += GE_FRM_PREAMBLE_FIELD_LEN;
 | 
						|
 | 
						|
    /* get net payload len */
 | 
						|
    src_frm_len = iot_proto_get_plc_data_len(src, src_len);
 | 
						|
 | 
						|
    /* add payload */
 | 
						|
    if (src_frm_len) {
 | 
						|
        os_mem_cpy(tmp_buf, src, src_frm_len);
 | 
						|
        dst_hdr = (ge_extend_fn_hdr_t*)dst;
 | 
						|
        /* set received connless type */
 | 
						|
        if (dst_hdr->hdr.fn == PROTO_GE_PLC_SET_CMD
 | 
						|
            && dst_hdr->subfn == PROTO_GE_DATA_CMD
 | 
						|
            && prototask_contxt.rx_info.rx_type) {
 | 
						|
            /* recv data frame, change receive connless type */
 | 
						|
            ge_frame_data_send_set_subfn160_t *data_frame =
 | 
						|
                    (ge_frame_data_send_set_subfn160_t *)dst;
 | 
						|
            data_frame->recv_connless |= 1;
 | 
						|
        }
 | 
						|
        tmp_buf += src_frm_len;
 | 
						|
        /* add check sum */
 | 
						|
        check_sum =
 | 
						|
            ge_frm_checksum_calc(dst, src_frm_len + GE_FRM_PREAMBLE_FIELD_LEN);
 | 
						|
        *tmp_buf = (uint8_t)(check_sum & 0xFF);
 | 
						|
#if GE_CRC_ENABLE
 | 
						|
        *(tmp_buf + 1) = (uint8_t)(check_sum >> 8);
 | 
						|
#endif
 | 
						|
        tmp_buf += GE_FRM_CHECKSUM_FIELD_LEN;
 | 
						|
 | 
						|
        /* add tail */
 | 
						|
        *tmp_buf = 0xFF;
 | 
						|
    }
 | 
						|
 | 
						|
    return src_frm_len;
 | 
						|
}
 | 
						|
 | 
						|
/* local txrx response handle */
 | 
						|
static void iot_proto_plctxrx_cmd_handle(iot_pkt_t *data,
 | 
						|
                                transmit_direction_e_t dir)
 | 
						|
{
 | 
						|
    uint16_t buf_len = (uint16_t)iot_pkt_data_len(data);
 | 
						|
    uint8_t *buf = iot_pkt_data(data);
 | 
						|
    uint8_t fn = 0, subfn = 0;
 | 
						|
    uint8_t ret;
 | 
						|
    plctxrx_cmd_resp_t *cmd = (plctxrx_cmd_resp_t *)buf;
 | 
						|
    iot_cus_printf("[glpr]cid==%d, opcode=%d dlen=%d\n", cmd->cid.cid,
 | 
						|
        cmd->cid.opcode, cmd->dlen);
 | 
						|
    ret = iot_proto_plctxtx_fn_subfn_get(cmd, &fn, &subfn);
 | 
						|
    IOT_ASSERT(!ret);
 | 
						|
 | 
						|
    uint8_t fncode_hdlr_cnt =
 | 
						|
                    sizeof(proto_subfn_hdl_tbl)/sizeof(proto_fnhdl_tbl_t) - 1;
 | 
						|
    uint8_t i;
 | 
						|
 | 
						|
    iot_cus_printf("[glpr]plctxrx cmd fn=%x, subfn=%d\n",fn, subfn);
 | 
						|
 | 
						|
    for (i = 0; i < fncode_hdlr_cnt; i++) {
 | 
						|
        if (proto_subfn_hdl_tbl[i].cmdid == fn) {
 | 
						|
            proto_subfn_hdl_tbl[i].cmd_handle_fn(buf, buf_len, dir);
 | 
						|
            break;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    IOT_ASSERT(i < fncode_hdlr_cnt);
 | 
						|
 | 
						|
    iot_pkt_free(data);
 | 
						|
}
 | 
						|
 | 
						|
static void iot_proto_plc_data_handle(iot_pkt_t *data,
 | 
						|
                                transmit_direction_e_t dir)
 | 
						|
{
 | 
						|
    uint16_t pos = 0;
 | 
						|
    uint16_t buf_len = (uint16_t)iot_pkt_data_len(data);
 | 
						|
    uint8_t *buf = iot_pkt_data(data);
 | 
						|
    uint8_t *ptr = glb_ul_tmp_buf;
 | 
						|
    bool_t need_report = false;
 | 
						|
    bool_t is_win_cached = false;
 | 
						|
    uint8_t i;
 | 
						|
    transmit_direction_e_t tmp_dir;
 | 
						|
    uint8_t fncode_hdlr_cnt =
 | 
						|
                    sizeof(proto_subfn_hdl_tbl)/sizeof(proto_fnhdl_tbl_t) - 1;
 | 
						|
    iot_pkt_t *tmp_pkt = NULL;
 | 
						|
    uint8_t *tmp_buf;
 | 
						|
 | 
						|
    tmp_pkt = iot_pkt_alloc(GE_EXT_DATA_FRM_MAX_LEN, IOT_GREE_APP_MID);
 | 
						|
    IOT_ASSERT(tmp_pkt);
 | 
						|
    iot_pkt_put(tmp_pkt, GE_EXT_DATA_FRM_MAX_LEN);
 | 
						|
 | 
						|
    tmp_buf = iot_pkt_data(tmp_pkt);
 | 
						|
    os_mem_set(tmp_buf, 0, GE_EXT_DATA_FRM_MAX_LEN);
 | 
						|
 | 
						|
    /* get rxinfo */
 | 
						|
    plctxrx_rx_data_info_t *rxinfo = (plctxrx_rx_data_info_t *)buf;
 | 
						|
 | 
						|
    /* point to data & get data len */
 | 
						|
    buf = (uint8_t *)(rxinfo + 1);
 | 
						|
    buf_len -= sizeof(*rxinfo);
 | 
						|
 | 
						|
    /* save remote device info */
 | 
						|
    os_mem_cpy(&prototask_contxt.rx_info, rxinfo, sizeof(*rxinfo));
 | 
						|
 | 
						|
    /* disable up uart cache timer */
 | 
						|
    if (os_is_timer_active(prototask_contxt.uart_monitor_timer)) {
 | 
						|
        os_stop_timer(prototask_contxt.uart_monitor_timer);
 | 
						|
        iot_task_clean_msg(prototask_contxt.task_handle,
 | 
						|
            PROTO_TIMER_MSG, PROTO_TIMER_MONITOR_TIMEOUT);
 | 
						|
    }
 | 
						|
 | 
						|
    /* maybe a big buffer,need to extract each intact gree frame */
 | 
						|
    while (pos < buf_len) {
 | 
						|
        uint8_t fn;
 | 
						|
        uint16_t src_frame_len;
 | 
						|
        /* TODO once gree enlarge pkt size, the local vair is not suitable */
 | 
						|
        uint16_t tmp_buf_len = GE_FRM_PREAMBLE_FIELD_LEN +
 | 
						|
                                GE_FRM_CHECKSUM_FIELD_LEN +
 | 
						|
                                GE_FRM_TAIL_FILED_LEN;
 | 
						|
        /* pure payload len */
 | 
						|
        src_frame_len = iot_proto_plc_data_group_frame(tmp_buf, &buf[pos],
 | 
						|
            buf_len - pos);
 | 
						|
        /* full pkt len */
 | 
						|
        tmp_buf_len += src_frame_len;
 | 
						|
        /* move analysis mark ahead */
 | 
						|
        pos += src_frame_len;
 | 
						|
        /* get fn handler */
 | 
						|
        fn = prototask_contxt.proto_pase_fn(tmp_buf);
 | 
						|
        prototask_contxt.num_fn_received++;
 | 
						|
        iot_cus_printf("[glpr]plc_data_handle:fn=0x%x,dir=%d,src_frame_len:%d,"
 | 
						|
            "total:%d,\n", fn, dir, src_frame_len, prototask_contxt.num_fn_received);
 | 
						|
 | 
						|
        /*
 | 
						|
         * if fn is extended fn,then direction must be
 | 
						|
         * CMD_REMOTE_UP_LINK. since this is plc data receive path.
 | 
						|
         * if FE A0 extend data frame received, it can't be handled here,
 | 
						|
         * uart_monitor_timer will dump this frame.
 | 
						|
        */
 | 
						|
        if (PROTO_GE_PLC_QUERY_CMD == fn
 | 
						|
         || PROTO_GE_PLC_RESP_CMD == fn
 | 
						|
         || PROTO_GE_PLC_SET_CMD == fn) {
 | 
						|
            tmp_dir = CMD_REMOTE_UP_LINK;
 | 
						|
            iot_common_bin_dump(tmp_buf, tmp_buf_len);
 | 
						|
            /* look for fncode handler to handle frame from plc */
 | 
						|
            for (i = 0; i < fncode_hdlr_cnt; i++) {
 | 
						|
                if (fn == proto_subfn_hdl_tbl[i].cmdid) {
 | 
						|
                    /* increase each fn counter */
 | 
						|
                    proto_subfn_hdl_tbl[i].cmd_num++;
 | 
						|
                    /* check if this frame should be reported to MCU. */
 | 
						|
                    need_report = proto_subfn_hdl_tbl[i].cmd_handle_fn(tmp_buf,
 | 
						|
                        tmp_buf_len, tmp_dir);
 | 
						|
                    is_win_cached = iot_proto_cache_data_for_window_rpt(tmp_buf,
 | 
						|
                        tmp_buf_len, tmp_dir);
 | 
						|
                    break;
 | 
						|
                }
 | 
						|
            }
 | 
						|
            IOT_ASSERT(i < fncode_hdlr_cnt);
 | 
						|
        }
 | 
						|
 | 
						|
        if (!need_report)
 | 
						|
            continue;
 | 
						|
 | 
						|
        /* each time report one fn to MCU */
 | 
						|
        prototask_contxt.num_fn_send++;
 | 
						|
        iot_cus_printf("[glpr] report mcu fnnum:%d,fn=0x%x\n",
 | 
						|
                        prototask_contxt.num_fn_send, fn);
 | 
						|
 | 
						|
        if (is_win_cached == false) {
 | 
						|
            /* group a big packet to report to MCU */
 | 
						|
            if (glb_ul_data_len + tmp_buf_len <= UL_TMP_BUF_LEN) {
 | 
						|
                ptr += glb_ul_data_len;
 | 
						|
                os_mem_cpy(ptr, tmp_buf, tmp_buf_len);
 | 
						|
                glb_ul_data_len += tmp_buf_len;
 | 
						|
            } else {
 | 
						|
                iot_pkt_t *pkt_data =
 | 
						|
                    iot_pkt_alloc(glb_ul_data_len,IOT_GREE_APP_MID);
 | 
						|
                IOT_ASSERT(pkt_data);
 | 
						|
                /* make tail pointer of packet ponit to data tail */
 | 
						|
                iot_pkt_put(pkt_data, glb_ul_data_len);
 | 
						|
                /* copy data to packet data field */
 | 
						|
                os_mem_cpy(iot_pkt_data(pkt_data), glb_ul_tmp_buf,
 | 
						|
                    glb_ul_data_len);
 | 
						|
                /* to pick up DL645 frame and modbus frame in the FEA0 frame
 | 
						|
                    in data */
 | 
						|
                iot_handle_ge_from_plc(pkt_data);
 | 
						|
                /* report gree frame to MCU */
 | 
						|
                iot_proto_send_to_mainboard(pkt_data);
 | 
						|
                os_mem_set(glb_ul_tmp_buf, 0, glb_ul_data_len);
 | 
						|
 | 
						|
                /* don't forget current handle pkt */
 | 
						|
                glb_ul_data_len = tmp_buf_len;
 | 
						|
                os_mem_cpy(glb_ul_tmp_buf, tmp_buf, glb_ul_data_len);
 | 
						|
            }
 | 
						|
        }
 | 
						|
        /* point ptr to head everytime. since re-point ptr every time used */
 | 
						|
        ptr = glb_ul_tmp_buf;
 | 
						|
    }
 | 
						|
 | 
						|
    /* arm uplink uart timer */
 | 
						|
    if (glb_ul_data_len > 0) {
 | 
						|
        os_start_timer(prototask_contxt.uart_monitor_timer,
 | 
						|
            PROTO_TIMER_MONITOR_TIMEOUT_INTVL);
 | 
						|
    }
 | 
						|
 | 
						|
    if (tmp_pkt) {
 | 
						|
        iot_pkt_free(tmp_pkt);
 | 
						|
    }
 | 
						|
 | 
						|
    iot_pkt_free(data);
 | 
						|
 | 
						|
    return;
 | 
						|
}
 | 
						|
 | 
						|
static void iot_proto_plc_msg_handle(iot_task_msg_t *msg)
 | 
						|
{
 | 
						|
    iot_proto_msg_t *task_msg;
 | 
						|
    IOT_ASSERT(msg);
 | 
						|
 | 
						|
    task_msg = (iot_proto_msg_t*)msg;
 | 
						|
 | 
						|
    switch (task_msg->msg.id) {
 | 
						|
    case PROTO_PLC_RX_DATA_MSG:
 | 
						|
    {
 | 
						|
        iot_proto_plc_data_handle(task_msg->data1,
 | 
						|
                        (transmit_direction_e_t)task_msg->data2);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case PROTO_PLCTXRX_RX_CMD_MSG:
 | 
						|
    {
 | 
						|
        iot_proto_plctxrx_cmd_handle(task_msg->data1,
 | 
						|
                        (transmit_direction_e_t)task_msg->data2);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    default:
 | 
						|
        if (task_msg->data1)
 | 
						|
            iot_pkt_free(task_msg->data1);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
#if PLC_SUPPORT_CCO_ROLE
 | 
						|
 | 
						|
static void iot_proto_cco_cli_rpt_wl_state(uint8_t req_id)
 | 
						|
{
 | 
						|
    iot_pkt_t *buf_pkt;
 | 
						|
    iot_cli_sg_rpt_wl_state_t *rsp;
 | 
						|
 | 
						|
    buf_pkt = iot_pkt_alloc(iot_cli_sg_get_headroom_req() + sizeof(*rsp),
 | 
						|
        IOT_GREE_APP_MID);
 | 
						|
    IOT_ASSERT(buf_pkt);
 | 
						|
 | 
						|
    rsp = (iot_cli_sg_rpt_wl_state_t*)iot_pkt_reserve(buf_pkt,
 | 
						|
        iot_cli_sg_get_headroom_req());
 | 
						|
 | 
						|
    rsp->state = prototask_contxt.flashinfo.public.pub.wl_state;
 | 
						|
 | 
						|
    iot_cli_sg_send_data_to_cli_interface(buf_pkt,
 | 
						|
        IOT_CLI_SG_MSG_RPT_WL_STATE, req_id);
 | 
						|
}
 | 
						|
 | 
						|
static void iot_proto_cco_cli_rpt_wl(uint8_t req_id, uint16_t start_index,
 | 
						|
    uint16_t count)
 | 
						|
{
 | 
						|
    iot_cli_sg_rpt_wl_t* rsp;
 | 
						|
    uint16_t rsp_len;
 | 
						|
    iot_pkt_t *buf_pkt;
 | 
						|
    uint16_t i;
 | 
						|
 | 
						|
    if (start_index > prototask_contxt.dev_lst.valid_dev_cnt) {
 | 
						|
        count = 0;
 | 
						|
    } else if (start_index + count - 1 > prototask_contxt.dev_lst.valid_dev_cnt) {
 | 
						|
        count = prototask_contxt.dev_lst.valid_dev_cnt - start_index + 1;
 | 
						|
    }
 | 
						|
    /* allocate buffer for response */
 | 
						|
    rsp_len = sizeof(iot_cli_sg_rpt_wl_t);
 | 
						|
    rsp_len += count * sizeof(rsp->node_info[0]);
 | 
						|
    rsp_len += iot_cli_sg_get_headroom_req();
 | 
						|
 | 
						|
    buf_pkt = iot_pkt_alloc(rsp_len, IOT_GREE_APP_MID);
 | 
						|
    IOT_ASSERT(buf_pkt);
 | 
						|
 | 
						|
    /* fill response info */
 | 
						|
    rsp = (iot_cli_sg_rpt_wl_t*)iot_pkt_reserve(buf_pkt,
 | 
						|
        iot_cli_sg_get_headroom_req());
 | 
						|
    rsp->total_count = prototask_contxt.dev_lst.valid_dev_cnt;
 | 
						|
    rsp->rsp_count = (uint8_t)count;
 | 
						|
 | 
						|
    for (i = 0; i < rsp->rsp_count; ++i) {
 | 
						|
        rsp->node_info[i].proto_type = IOT_CLI_SG_PROTO_TYPE_RAW_DATA;
 | 
						|
        iot_mac_addr_cpy(rsp->node_info[i].mac,
 | 
						|
            prototask_contxt.dev_lst.dev[start_index+i-1].mac);
 | 
						|
        iot_mac_addr_reverse(rsp->node_info[i].mac);
 | 
						|
    }
 | 
						|
 | 
						|
    iot_cli_sg_send_data_to_cli_interface(buf_pkt,
 | 
						|
        IOT_CLI_SG_MSG_RPT_WL, req_id);
 | 
						|
}
 | 
						|
 | 
						|
static void iot_proto_cco_cli_add_wl(uint8_t req_id, iot_cli_sg_add_wl_t *req)
 | 
						|
{
 | 
						|
    iot_pkt_t *buf_pkt;
 | 
						|
    iot_cli_sg_result_t *rsp;
 | 
						|
    proto_dev_t wlist;
 | 
						|
    uint16_t i;
 | 
						|
 | 
						|
    buf_pkt = iot_pkt_alloc(iot_cli_sg_get_headroom_req() + sizeof(*rsp),
 | 
						|
        IOT_GREE_APP_MID);
 | 
						|
    IOT_ASSERT(buf_pkt);
 | 
						|
    iot_proto_whitelist_state_init();
 | 
						|
 | 
						|
    for (i = 0; i < req->count; i++) {
 | 
						|
        iot_mac_addr_reverse(req->node_info[i].mac);
 | 
						|
        if ((0 > iot_proto_check_mac_exists(req->node_info[i].mac,
 | 
						|
            prototask_contxt.dev_lst.dev,
 | 
						|
            prototask_contxt.dev_lst.valid_dev_cnt)) &&
 | 
						|
            (0 > iot_proto_check_mac_exists(req->node_info[i].mac,
 | 
						|
            prototask_contxt.dev_lst.dev_tmp,
 | 
						|
            prototask_contxt.dev_lst.valid_dev_tmp_cnt))) {
 | 
						|
            /* mac not in dev_tmp and dev, need add */
 | 
						|
            os_mem_set(&wlist, 0x00, sizeof(wlist));
 | 
						|
            iot_mac_addr_cpy(wlist.mac, req->node_info[i].mac);
 | 
						|
            iot_proto_add_wl_to_tmp(&wlist);
 | 
						|
        }
 | 
						|
    }
 | 
						|
    if (prototask_contxt.dev_lst.valid_dev_tmp_cnt > 0) {
 | 
						|
        iot_proto_add_wl_tmp2formal();
 | 
						|
        iot_proto_whitelist_add_remove(GE_PROTO_ACTION_ADD, NULL, false);
 | 
						|
        iot_proto_wl_save2flash();
 | 
						|
        iot_proto_whitelist_state_init();
 | 
						|
    }
 | 
						|
 | 
						|
    rsp = (iot_cli_sg_result_t*)iot_pkt_reserve(buf_pkt,
 | 
						|
        iot_cli_sg_get_headroom_req());
 | 
						|
 | 
						|
    rsp->result = ERR_OK;
 | 
						|
    iot_cli_sg_send_data_to_cli_interface(buf_pkt,
 | 
						|
        IOT_CLI_SG_MSG_RPT_ADD_WL, req_id);
 | 
						|
}
 | 
						|
 | 
						|
static void iot_proto_cco_cli_rm_wl(uint8_t req_id, iot_cli_sg_rm_wl_t *req)
 | 
						|
{
 | 
						|
    iot_pkt_t *buf_pkt;
 | 
						|
    iot_cli_sg_result_t *rsp;
 | 
						|
    proto_dev_t wlist;
 | 
						|
    uint16_t i;
 | 
						|
 | 
						|
    buf_pkt = iot_pkt_alloc(iot_cli_sg_get_headroom_req() + sizeof(*rsp),
 | 
						|
        IOT_GREE_APP_MID);
 | 
						|
    IOT_ASSERT(buf_pkt);
 | 
						|
 | 
						|
    rsp = (iot_cli_sg_result_t*)iot_pkt_reserve(buf_pkt,
 | 
						|
        iot_cli_sg_get_headroom_req());
 | 
						|
 | 
						|
    iot_proto_whitelist_state_init();
 | 
						|
    for (i = 0; i < req->count; i++) {
 | 
						|
        iot_mac_addr_reverse(req->mac_addr[i]);
 | 
						|
        os_mem_set(&wlist, 0x00, sizeof(wlist));
 | 
						|
        iot_mac_addr_cpy(wlist.mac, req->mac_addr[i]);
 | 
						|
        iot_proto_add_wl_to_tmp(&wlist);
 | 
						|
    }
 | 
						|
 | 
						|
    iot_proto_whitelist_add_remove(GE_PROTO_ACTION_DEL, NULL, false);
 | 
						|
    iot_proto_del_wl_from_formal();
 | 
						|
    iot_proto_wl_save2flash();
 | 
						|
    iot_proto_whitelist_state_init();
 | 
						|
 | 
						|
    rsp->result = ERR_OK;
 | 
						|
    iot_cli_sg_send_data_to_cli_interface(buf_pkt,
 | 
						|
        IOT_CLI_SG_MSG_RPT_RM_WL, req_id);
 | 
						|
}
 | 
						|
 | 
						|
static void iot_proto_cco_cli_set_wl_state(uint8_t req_id,
 | 
						|
    iot_cli_sg_set_wl_state_t *req)
 | 
						|
{
 | 
						|
    iot_pkt_t *buf_pkt;
 | 
						|
    iot_cli_sg_result_t *rsp;
 | 
						|
 | 
						|
    buf_pkt = iot_pkt_alloc(iot_cli_sg_get_headroom_req() + sizeof(*rsp),
 | 
						|
        IOT_GREE_APP_MID);
 | 
						|
    IOT_ASSERT(buf_pkt);
 | 
						|
 | 
						|
    rsp = (iot_cli_sg_result_t*)iot_pkt_reserve(buf_pkt,
 | 
						|
        iot_cli_sg_get_headroom_req());
 | 
						|
    rsp->result = ERR_OK;
 | 
						|
 | 
						|
    if (req->state != prototask_contxt.flashinfo.public.pub.wl_state) {
 | 
						|
        if (req->state) {
 | 
						|
            iot_proto_whitelist_en_disable(GE_PROTO_WL_ENABLE, false);
 | 
						|
        } else {
 | 
						|
            iot_proto_whitelist_en_disable(GE_PROTO_WL_DISABLE, false);
 | 
						|
        }
 | 
						|
        rsp->result = ERR_OK;
 | 
						|
    }
 | 
						|
 | 
						|
    iot_cli_sg_send_data_to_cli_interface(buf_pkt,
 | 
						|
        IOT_CLI_SG_MSG_RPT_SET_WL_STATE, req_id);
 | 
						|
}
 | 
						|
 | 
						|
static void iot_proto_cco_cli_msg_handle(iot_proto_msg_t *msg)
 | 
						|
{
 | 
						|
    iot_pkt_t *pkt = (iot_pkt_t *)msg->data1;
 | 
						|
    iot_cli_sg_msg_header_t *hdr;
 | 
						|
 | 
						|
    if (NULL == pkt) {
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    hdr = (iot_cli_sg_msg_header_t *)iot_pkt_block_ptr(pkt, IOT_PKT_BLOCK_HEAD);
 | 
						|
    switch (hdr->msg_id) {
 | 
						|
    case IOT_CLI_SG_MSG_QUERY_WL_STATE:
 | 
						|
    {
 | 
						|
        iot_proto_cco_cli_rpt_wl_state(hdr->req_id);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case IOT_CLI_SG_MSG_QUERY_WL:
 | 
						|
    {
 | 
						|
        iot_cli_sg_query_wl_t *req;
 | 
						|
        req = (iot_cli_sg_query_wl_t *)iot_pkt_data(pkt);
 | 
						|
        iot_proto_cco_cli_rpt_wl(hdr->req_id, req->start_index, req->count);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case IOT_CLI_SG_MSG_ADD_WL:
 | 
						|
    {
 | 
						|
        iot_cli_sg_add_wl_t *req;
 | 
						|
        req = (iot_cli_sg_add_wl_t *)iot_pkt_data(pkt);
 | 
						|
        iot_proto_cco_cli_add_wl(hdr->req_id, req);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case IOT_CLI_SG_MSG_RM_WL:
 | 
						|
    {
 | 
						|
        iot_cli_sg_rm_wl_t *req;
 | 
						|
        req = (iot_cli_sg_rm_wl_t *)iot_pkt_data(pkt);
 | 
						|
        iot_proto_cco_cli_rm_wl(hdr->req_id, req);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case IOT_CLI_SG_MSG_SET_WL_STATE:
 | 
						|
    {
 | 
						|
        iot_cli_sg_set_wl_state_t *req;
 | 
						|
        req = (iot_cli_sg_set_wl_state_t *)iot_pkt_data(pkt);
 | 
						|
        iot_proto_cco_cli_set_wl_state(hdr->req_id, req);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    default:
 | 
						|
    {
 | 
						|
        iot_cus_printf("[gepr]cco_cli_msg, unknown msg_id=%d\n", hdr->msg_id);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    }
 | 
						|
 | 
						|
    iot_pkt_free(pkt);
 | 
						|
}
 | 
						|
 | 
						|
static void iot_proto_cco_cctt_msg_handle(iot_proto_msg_t *msg)
 | 
						|
{
 | 
						|
    IOT_ASSERT(msg);
 | 
						|
    uint8_t *data;
 | 
						|
    uint8_t data_len;
 | 
						|
    iot_pkt_t *pkt;
 | 
						|
    iot_proto_msg_t *task_msg = (iot_proto_msg_t*)msg;
 | 
						|
 | 
						|
    pkt = task_msg->data1;
 | 
						|
    if (pkt == NULL) {
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    data = iot_pkt_data(pkt);
 | 
						|
    data_len = iot_pkt_data_len(pkt);
 | 
						|
    switch (task_msg->msg.id) {
 | 
						|
    case CCTT_REBOOT_CCO:
 | 
						|
    {
 | 
						|
        iot_cctt_reboot_cco(data, data_len);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case CCTT_REBOOT_STA:
 | 
						|
    {
 | 
						|
        iot_cctt_reboot_sta(data, data_len);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case CCTT_QUERY_TOPO:
 | 
						|
    {
 | 
						|
        iot_cctt_query_topo(data, data_len);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case CCTT_ADD_WHITELIST:
 | 
						|
    {
 | 
						|
        iot_cctt_set_whitelist(data, data_len, GE_PROTO_ACTION_ADD);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case CCTT_DEL_WHITELIST:
 | 
						|
    {
 | 
						|
        iot_cctt_set_whitelist(data, data_len, GE_PROTO_ACTION_DEL);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case CCTT_QUERY_WHITELIST:
 | 
						|
    {
 | 
						|
        iot_cctt_read_whitelist(data, data_len);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case CCTT_SET_WL_STATE:
 | 
						|
    {
 | 
						|
        iot_cctt_set_wl_state(data, data_len);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case CCTT_CLR_WHITELIST:
 | 
						|
    {
 | 
						|
        iot_cctt_clear_whitelist(data, data_len);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case CCTT_CHECK_WL_MAC:
 | 
						|
    {
 | 
						|
        iot_cctt_check_whitelist_mac(data, data_len);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case CCTT_SET_PLC_NW:
 | 
						|
    {
 | 
						|
        iot_cctt_set_plc_nw(data, data_len);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case CCTT_READ_PLC_NW:
 | 
						|
    {
 | 
						|
        iot_cctt_get_plc_nw();
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case CCTT_REBOOT_MAC_LIST_PCO:
 | 
						|
    {
 | 
						|
        iot_cctt_reboot_mac_list_pco(data, data_len);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case CCTT_DELAYTIME:
 | 
						|
    {
 | 
						|
        iot_cctt_delaytime(data, data_len);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case CCTT_SET_RS485_CONFIG:
 | 
						|
    {
 | 
						|
        iot_cctt_set_rs485_config(data, data_len);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case CCTT_READ_RS485_CONFIG:
 | 
						|
    {
 | 
						|
        iot_cctt_read_rs485_config(data, data_len);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case CCTT_RS485_TRANS_DL645:
 | 
						|
    {
 | 
						|
        iot_cctt_rs485_trans_dl645(data, data_len);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case CCTT_RS485_TRANS_MODBUS:
 | 
						|
    {
 | 
						|
        iot_cctt_rs485_trans_modbus(data, data_len);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    default:
 | 
						|
        break;
 | 
						|
    }
 | 
						|
 | 
						|
    iot_pkt_free(pkt);
 | 
						|
}
 | 
						|
 | 
						|
/* handle dl645 topo resp */
 | 
						|
bool_t iot_proto_cctt_dl645_topo_resp(uint8_t *data,
 | 
						|
    uint16_t len, transmit_direction_e_t dir)
 | 
						|
{
 | 
						|
    plctxrx_cmd_resp_t *cmd;
 | 
						|
    plctxrx_handle_topo_v2_t *topo_info;
 | 
						|
    (void)dir;
 | 
						|
 | 
						|
    if (len > sizeof(plctxrx_cmd_resp_t) + sizeof(plctxrx_handle_topo_v2_t)) {
 | 
						|
        cmd = (plctxrx_cmd_resp_t *)data;
 | 
						|
        topo_info = (plctxrx_handle_topo_v2_t *)cmd->data;
 | 
						|
        iot_cco_resp_topo_to_cctt(topo_info->node, cmd->index.total,
 | 
						|
            topo_info->cnt, !cmd->done);
 | 
						|
        iot_cco_resp_topo_set_query_info(cmd->done, topo_info->cnt);
 | 
						|
    }
 | 
						|
 | 
						|
    iot_proto_cmd_handle_state_init();
 | 
						|
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * @brief iot_cco_handle_local_dl645_cmd() - handle the local cmd
 | 
						|
 *                                           data is del 0x33
 | 
						|
 * @param pkt:   point to the dl645 pkt data
 | 
						|
 */
 | 
						|
void iot_cco_handle_local_dl645_cmd(iot_pkt_t *pkt)
 | 
						|
{
 | 
						|
    iot_cctt_handle_local_dl645_cmd(pkt);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * @brief iot_handle_cco_delay_tm_ge_rm_pad_data() - cco handle the delay time
 | 
						|
                                                       message from plc
 | 
						|
 * @param data_input:    data in ptr
 | 
						|
 * @param data_output:   data out ptr
 | 
						|
 * @return:              ge frm len
 | 
						|
 */
 | 
						|
uint8_t iot_handle_cco_delay_tm_ge_rm_pad_data(uint8_t *data_input,
 | 
						|
    uint8_t *data_output)
 | 
						|
{
 | 
						|
    uint8_t tmp_len = sizeof(ge_frame_delay_time_subfn166_t);
 | 
						|
    uint8_t tail_len = sizeof(ge_frm_tail_t);
 | 
						|
    ge_frm_tail_t *tail;
 | 
						|
    ge_frame_delay_time_subfn166_t *frame =
 | 
						|
        (ge_frame_delay_time_subfn166_t *)data_output;
 | 
						|
 | 
						|
    if (data_input == NULL || data_output == NULL) {
 | 
						|
        iot_cus_printf("[err]%s data ptr is null\n", "delay tm");
 | 
						|
        return 0;
 | 
						|
    }
 | 
						|
    /* when FE A6 frame remove pad data, copy data_input to data_output, and
 | 
						|
    recalculate data len and crc in data_output */
 | 
						|
    os_mem_cpy(data_output, data_input, tmp_len);
 | 
						|
    frame->hdr.hdr.data_len = tmp_len + tail_len - GE_FRM_MIN_LEN;
 | 
						|
    tail = (ge_frm_tail_t *)(data_output + tmp_len);
 | 
						|
    tail->check_sum = ge_frm_checksum_calc(data_output, tmp_len);
 | 
						|
    tail->tail = GE_FRM_TAIL_CODE;
 | 
						|
    tmp_len += tail_len;
 | 
						|
 | 
						|
    return tmp_len;
 | 
						|
}
 | 
						|
 | 
						|
#else /* PLC_SUPPORT_CCO_ROLE */
 | 
						|
 | 
						|
static void iot_proto_cco_cli_msg_handle(iot_proto_msg_t *msg)
 | 
						|
{
 | 
						|
    if (msg->data1)
 | 
						|
        iot_pkt_free(msg->data1);
 | 
						|
}
 | 
						|
 | 
						|
static void iot_proto_cco_cctt_msg_handle(iot_proto_msg_t *msg)
 | 
						|
{
 | 
						|
    if (msg->data1)
 | 
						|
        iot_pkt_free(msg->data1);
 | 
						|
}
 | 
						|
 | 
						|
bool_t iot_proto_cctt_dl645_topo_resp(uint8_t *data,
 | 
						|
    uint16_t len, transmit_direction_e_t dir)
 | 
						|
{
 | 
						|
    (void)data;
 | 
						|
    (void)len;
 | 
						|
    (void)dir;
 | 
						|
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
#endif /* end PLC_SUPPORT_CCO_ROLE */
 | 
						|
 | 
						|
static void iot_proto_task_handle_msg(iot_task_h task_h,
 | 
						|
    iot_task_msg_t *msg)
 | 
						|
{
 | 
						|
    iot_proto_msg_t *task_msg;
 | 
						|
    IOT_ASSERT(task_h == prototask_contxt.task_handle);
 | 
						|
    IOT_ASSERT(msg);
 | 
						|
 | 
						|
    task_msg = (iot_proto_msg_t*)msg;
 | 
						|
    switch (task_msg->msg.type) {
 | 
						|
    /* handle msg from uart */
 | 
						|
    case PROTO_MCU_RX_MSG:
 | 
						|
    {
 | 
						|
        if (task_msg->msg.id == PROTO_MCU_RX_DL645_MSG) {
 | 
						|
#if PLC_SUPPORT_CCO_ROLE
 | 
						|
            iot_cco_handle_local_dl645_cmd(task_msg->data1);
 | 
						|
#endif
 | 
						|
            if (task_msg->data1) {
 | 
						|
                iot_pkt_free(task_msg->data1);
 | 
						|
            }
 | 
						|
        } else {
 | 
						|
            iot_proto_mcu_msg_handle(task_msg->data1,
 | 
						|
                (transmit_direction_e_t)task_msg->data2);
 | 
						|
        }
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    /* handle msg from plctxrx layer */
 | 
						|
    case PROTO_PLC_RX_MSG:
 | 
						|
    {
 | 
						|
        iot_proto_plc_msg_handle(&task_msg->msg);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    /* handle msg from timer */
 | 
						|
    case PROTO_TIMER_MSG:
 | 
						|
    {
 | 
						|
        iot_proto_timer_msg_handle(&task_msg->msg);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case PROTO_CUS_APP_MSG:
 | 
						|
    {
 | 
						|
        iot_proto_cus_app_msg_handle(&task_msg->msg);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case PROTO_CLI_MSG:
 | 
						|
    {
 | 
						|
        iot_proto_cco_cli_msg_handle(task_msg);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case PROTO_CCTT_MSG:
 | 
						|
    {
 | 
						|
        iot_proto_cco_cctt_msg_handle(task_msg);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case EDGE_UART_RX_MSG:
 | 
						|
    case EDGE_INPUT_MSG:
 | 
						|
    case EDGE_TIMER_MSG:
 | 
						|
    case EDGE_INTERNAL_MSG:
 | 
						|
    {
 | 
						|
        iot_edge_state_machine(task_msg->msg.type, task_msg->msg.id,
 | 
						|
            task_msg->data1);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case EDGE_OUTPUT_MSG:
 | 
						|
    {
 | 
						|
        iot_proto_edge_msg_output_msg_handler(task_msg->msg.id,
 | 
						|
            task_msg->data1);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    default:
 | 
						|
        break;
 | 
						|
    }
 | 
						|
 | 
						|
    iot_task_free_msg(prototask_contxt.task_handle, &task_msg->msg);
 | 
						|
}
 | 
						|
 | 
						|
static void iot_proto_task_handle_msg_cancel(iot_task_h task_h,
 | 
						|
                                            iot_task_msg_t *msg)
 | 
						|
{
 | 
						|
    iot_proto_msg_t *task_msg;
 | 
						|
    IOT_ASSERT(task_h == prototask_contxt.task_handle);
 | 
						|
    IOT_ASSERT(msg);
 | 
						|
 | 
						|
    task_msg = (iot_proto_msg_t*)msg;
 | 
						|
    switch (task_msg->msg.type) {
 | 
						|
    case PROTO_MCU_RX_MSG:
 | 
						|
    {
 | 
						|
        if (task_msg->data1)
 | 
						|
            iot_pkt_free(task_msg->data1);
 | 
						|
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case PROTO_PLC_RX_MSG:
 | 
						|
    {
 | 
						|
        if (task_msg->data1)
 | 
						|
            iot_pkt_free(task_msg->data1);
 | 
						|
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case PROTO_TIMER_MSG:
 | 
						|
    {
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case PROTO_CLI_MSG:
 | 
						|
    {
 | 
						|
        if (task_msg->data1)
 | 
						|
            iot_pkt_free(task_msg->data1);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    default:
 | 
						|
        break;
 | 
						|
    }
 | 
						|
 | 
						|
    iot_task_free_msg(prototask_contxt.task_handle, &task_msg->msg);
 | 
						|
}
 | 
						|
 | 
						|
/* cut preamble, checksum and tail field of a inract frame */
 | 
						|
/* send data to plctxrx  */
 | 
						|
void iot_proto_data_send_to_plctxrx(uint8_t *data, uint16_t len,
 | 
						|
                              protpkt_tx_info_t *txinfo)
 | 
						|
{
 | 
						|
    iot_pkt_t *send_pkt;
 | 
						|
    uint8_t *ptr;
 | 
						|
    uint16_t org_frm_len;
 | 
						|
    uint16_t cur_frm_len;
 | 
						|
    uint16_t i;
 | 
						|
 | 
						|
    uint8_t role = prototask_contxt.local_dev.nw_role;
 | 
						|
    bool_t is_ready = prototask_contxt.local_dev.dev_ready;
 | 
						|
    uint16_t total_frm_len = 0;
 | 
						|
 | 
						|
    switch (role) {
 | 
						|
    case IOT_PLC_DEV_ROLE_STA:
 | 
						|
    case IOT_PLC_DEV_ROLE_PCO:
 | 
						|
    {
 | 
						|
        if (!is_ready) {
 | 
						|
            /* send connless packet */
 | 
						|
            txinfo->force_tx_connless = 1;
 | 
						|
            txinfo->need_ack = false;
 | 
						|
            iot_cus_printf("[glpr][info]STA is not ready,send connless pkt!\n");
 | 
						|
        }
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case IOT_PLC_DEV_ROLE_CCO:
 | 
						|
    {
 | 
						|
        if (!is_ready) {
 | 
						|
            iot_cus_printf("[glpr][err]CCO not ready!\n");
 | 
						|
            return;
 | 
						|
        }
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    default:
 | 
						|
        IOT_ASSERT(0);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
 | 
						|
    send_pkt = iot_pkt_alloc(len, IOT_GREE_APP_MID);
 | 
						|
 | 
						|
    if (!send_pkt) {
 | 
						|
        IOT_ASSERT(send_pkt);
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    ptr = data;
 | 
						|
    /** del preamble code,checksum code and tail
 | 
						|
     * code of each gree frame
 | 
						|
     */
 | 
						|
    for (i = 0; i < len;) {
 | 
						|
        org_frm_len = ACQUIRE_DATA_LEN(ptr[GE_FRM_DATA_LEN_POS]) +
 | 
						|
            GE_FRM_MIN_LEN;
 | 
						|
        if(ptr[GE_FRM_DATA_EXT_LEN_POS] & GE_FRM_DATA_EXT_FLAG) {
 | 
						|
           org_frm_len += GE_EXT_DATA_LEN;
 | 
						|
        }
 | 
						|
        IOT_ASSERT(org_frm_len >= GE_FRM_MIN_LEN
 | 
						|
            && org_frm_len <= GE_EXT_DATA_FRM_MAX_LEN);
 | 
						|
        cur_frm_len = org_frm_len - GE_FRM_PREAMBLE_FIELD_LEN
 | 
						|
                          - GE_FRM_CHECKSUM_FIELD_LEN
 | 
						|
                          - GE_FRM_TAIL_FILED_LEN;
 | 
						|
 | 
						|
        os_mem_cpy(iot_pkt_data(send_pkt) + total_frm_len,
 | 
						|
            ptr + GE_FRM_PREAMBLE_FIELD_LEN, cur_frm_len);
 | 
						|
        total_frm_len += cur_frm_len;
 | 
						|
        iot_pkt_put(send_pkt, cur_frm_len);
 | 
						|
        /*+1 means move one byte forward */
 | 
						|
        i   += org_frm_len + 1;
 | 
						|
        ptr += org_frm_len;
 | 
						|
    }
 | 
						|
 | 
						|
    if (prototask_contxt.gree_data_send_cb) {
 | 
						|
        /* here send data to remote peer */
 | 
						|
        prototask_contxt.gree_data_send_cb(iot_pkt_data(send_pkt),
 | 
						|
            (uint16_t)iot_pkt_data_len(send_pkt), txinfo);
 | 
						|
    }
 | 
						|
 | 
						|
    iot_pkt_free(send_pkt);
 | 
						|
}
 | 
						|
 | 
						|
void iot_proto_remote_cmd_send_to_plctxrx
 | 
						|
    (uint8_t *data, uint16_t len, protpkt_tx_info_t *txinfo)
 | 
						|
{
 | 
						|
    iot_cus_printf("[glpr]cmd_send_to_plctxrx:\n");
 | 
						|
 | 
						|
    iot_common_bin_dump(data, len);
 | 
						|
 | 
						|
    iot_proto_data_send_to_plctxrx(data, len, txinfo);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
   prot layer copy txrx msdu agin in one buffer. txrx split effort no used.
 | 
						|
   TODO, remove txrx layer split effort. make it more general
 | 
						|
*/
 | 
						|
uint8_t iot_proto_plc_data_recv_func(protpkt_list_t  *report_framelist,
 | 
						|
                                        plctxrx_rx_data_info_t *rxinfo)
 | 
						|
{
 | 
						|
    IOT_ASSERT(report_framelist && rxinfo
 | 
						|
                && (report_framelist->frame_cnt > 0)
 | 
						|
                && (report_framelist->total_len > 0));
 | 
						|
    uint8_t *buf, *tmp;
 | 
						|
    list_node_t* node = report_framelist->list_head;
 | 
						|
    /* alloc pkt */
 | 
						|
    iot_pkt_t *pkt = iot_pkt_alloc(report_framelist->total_len+sizeof(*rxinfo), \
 | 
						|
                        IOT_GREE_APP_MID);
 | 
						|
    IOT_ASSERT(pkt);
 | 
						|
    buf = iot_pkt_data(pkt);
 | 
						|
    os_mem_cpy(buf, rxinfo, sizeof(*rxinfo));
 | 
						|
    iot_pkt_put(pkt, sizeof(*rxinfo));
 | 
						|
    /* copy data from each node */
 | 
						|
    tmp = iot_pkt_block_ptr(pkt, IOT_PKT_BLOCK_TAIL);
 | 
						|
    while (report_framelist->frame_cnt--) {
 | 
						|
        IOT_ASSERT(node);
 | 
						|
        os_mem_cpy(tmp, node->data, node->len);
 | 
						|
        iot_pkt_put(pkt, node->len);
 | 
						|
        tmp += node->len;
 | 
						|
        node = node->next;
 | 
						|
    }
 | 
						|
 | 
						|
    IOT_ASSERT(!node &&
 | 
						|
            (buf+report_framelist->total_len+sizeof(*rxinfo) == tmp));
 | 
						|
 | 
						|
    iot_proto_task_post_msg(PROTO_PLC_RX_MSG, PROTO_PLC_RX_DATA_MSG,
 | 
						|
                        pkt, DATA_UP_LINK, IOT_PROTO_TASK_QUEUE_LP);
 | 
						|
 | 
						|
    return ERR_OK;
 | 
						|
}
 | 
						|
 | 
						|
/* local txrx cmd response  */
 | 
						|
uint8_t iot_proto_plctxrx_cmd_resp_recv_func(iot_pkt_t *data)
 | 
						|
{
 | 
						|
    IOT_ASSERT(data);
 | 
						|
 | 
						|
    iot_proto_task_post_msg(PROTO_PLC_RX_MSG, PROTO_PLCTXRX_RX_CMD_MSG,
 | 
						|
                         data, CMD_LOCAL_UP_LINK, IOT_PROTO_TASK_QUEUE_LP);
 | 
						|
    return ERR_OK;
 | 
						|
}
 | 
						|
 | 
						|
/* callback for uart recv timeout checking timer */
 | 
						|
static void iot_proto_uart_monitor_timeout_timer(
 | 
						|
    timer_id_t timer_id, void * arg)
 | 
						|
{
 | 
						|
    (void)timer_id;
 | 
						|
    (void)arg;
 | 
						|
 | 
						|
    iot_proto_task_post_msg(PROTO_TIMER_MSG, PROTO_TIMER_MONITOR_TIMEOUT,
 | 
						|
            NULL, 0, IOT_PROTO_TASK_QUEUE_LP);
 | 
						|
}
 | 
						|
 | 
						|
/* callback for querying MCU mac timeout checking timer */
 | 
						|
static void iot_proto_query_mac_timeout_timer(
 | 
						|
    timer_id_t timer_id, void * arg)
 | 
						|
{
 | 
						|
    (void)timer_id;
 | 
						|
    (void)arg;
 | 
						|
    iot_proto_task_post_msg(PROTO_TIMER_MSG, PROTO_TIMER_QUERY_MAC_TIMEOUT,
 | 
						|
        NULL, 0, IOT_PROTO_TASK_QUEUE_LP);
 | 
						|
}
 | 
						|
 | 
						|
/* callback for update upgrade state timeout checking timer */
 | 
						|
static void iot_proto_update_upgrade_state_timeout_timer(
 | 
						|
    timer_id_t timer_id, void * arg)
 | 
						|
{
 | 
						|
    (void)timer_id;
 | 
						|
    (void)arg;
 | 
						|
 | 
						|
    iot_proto_task_post_msg(PROTO_TIMER_MSG, PROTO_TIMER_UPDATE_STATE_TIMEOUT,
 | 
						|
            NULL, 0, IOT_PROTO_TASK_QUEUE_LP);
 | 
						|
}
 | 
						|
 | 
						|
/* callback for waiting response timeout checking timer */
 | 
						|
static void iot_proto_wait_resp_cmd_timeout_timer(
 | 
						|
    timer_id_t timer_id, void * arg)
 | 
						|
{
 | 
						|
    (void)timer_id;
 | 
						|
    (void)arg;
 | 
						|
 | 
						|
    iot_proto_task_post_msg(PROTO_TIMER_MSG, PROTO_TIMER_WAIT_RESP_TIMEOUT,
 | 
						|
            NULL, 0, IOT_PROTO_TASK_QUEUE_LP);
 | 
						|
}
 | 
						|
 | 
						|
/* post dl645 command msg for handle  */
 | 
						|
uint8_t iot_proto_post_dl645_cmd_msg(uint8_t *data, uint16_t len)
 | 
						|
{
 | 
						|
    iot_pkt_t *pkt;
 | 
						|
 | 
						|
    pkt = iot_pkt_alloc(len, IOT_GREE_APP_MID);
 | 
						|
    if (pkt == NULL) {
 | 
						|
        return ERR_NOMEM;
 | 
						|
    }
 | 
						|
 | 
						|
    os_mem_cpy(iot_pkt_put(pkt, len), data, len);
 | 
						|
 | 
						|
    iot_proto_task_post_msg(PROTO_MCU_RX_MSG, PROTO_MCU_RX_DL645_MSG,
 | 
						|
        pkt, DATA_DOWN_LINK, IOT_PROTO_TASK_QUEUE_LP);
 | 
						|
 | 
						|
    return ERR_OK;
 | 
						|
}
 | 
						|
 | 
						|
/* below msg pool operation */
 | 
						|
static proto_savedmsg_node_t *iot_proto_msgnode_alloc(iot_mem_pool_t *pool)
 | 
						|
{
 | 
						|
    IOT_ASSERT(pool);
 | 
						|
 | 
						|
    proto_savedmsg_node_t *msgnode;
 | 
						|
    msgnode = (proto_savedmsg_node_t *)iot_mem_pool_alloc(pool);
 | 
						|
    return msgnode;
 | 
						|
}
 | 
						|
 | 
						|
static uint32_t iot_proto_msgnode_free(iot_mem_pool_t *pool,
 | 
						|
                                    proto_savedmsg_node_t *msgnode)
 | 
						|
{
 | 
						|
    IOT_ASSERT(pool && msgnode);
 | 
						|
 | 
						|
    return iot_mem_pool_free(pool, msgnode);
 | 
						|
}
 | 
						|
 | 
						|
static void iot_proto_savedmsg_list_push_backend(proto_msg_saved_list_t *list,
 | 
						|
                                list_node_t *node)
 | 
						|
{
 | 
						|
    IOT_ASSERT(list && node);
 | 
						|
 | 
						|
    if (!list->head) {
 | 
						|
        IOT_ASSERT(0 == list->depth);
 | 
						|
        list->head = list->tail = node;
 | 
						|
    } else {
 | 
						|
        list->tail->next = node;
 | 
						|
        list->tail = node;
 | 
						|
    }
 | 
						|
    list->depth++;
 | 
						|
    node->next = NULL;
 | 
						|
 | 
						|
    return;
 | 
						|
}
 | 
						|
 | 
						|
static proto_savedmsg_node_t *
 | 
						|
    iot_proto_savedmsg_list_pop_front(proto_msg_saved_list_t *list)
 | 
						|
{
 | 
						|
    IOT_ASSERT(list);
 | 
						|
    list_node_t *link;
 | 
						|
    proto_savedmsg_node_t *savedmsg_node;
 | 
						|
 | 
						|
    if (list->depth <= 0)
 | 
						|
        return NULL;
 | 
						|
 | 
						|
    link = list->head;
 | 
						|
    list->head = list->head->next;
 | 
						|
    list->depth--;
 | 
						|
    if (0 == list->depth)
 | 
						|
        list->tail = NULL;
 | 
						|
 | 
						|
    savedmsg_node = container_of(link, proto_savedmsg_node_t, node);
 | 
						|
    return savedmsg_node;
 | 
						|
}
 | 
						|
 | 
						|
static void iot_proto_saved_msg_handle(void)
 | 
						|
{
 | 
						|
    proto_savedmsg_node_t *savedmsg_node;
 | 
						|
    proto_msg_saved_list_t *list = &prototask_contxt.saved_msg_list;
 | 
						|
    uint16_t depth = list->depth;
 | 
						|
 | 
						|
    /* check if there are messages in msg saved list */
 | 
						|
    if (list->depth <= 0)
 | 
						|
        return;
 | 
						|
 | 
						|
    while (depth--) {
 | 
						|
        /* get fist cmd */
 | 
						|
        savedmsg_node = iot_proto_savedmsg_list_pop_front(list);
 | 
						|
        IOT_ASSERT(savedmsg_node);
 | 
						|
        /* post messgae and bring info with msg */
 | 
						|
        iot_proto_task_post_msg(savedmsg_node->msg_type,
 | 
						|
                                savedmsg_node->msg_id,
 | 
						|
                                savedmsg_node->data,
 | 
						|
                                (transmit_direction_e_t)savedmsg_node->dir,
 | 
						|
                                IOT_PROTO_TASK_QUEUE_LP);
 | 
						|
        /* return handled cmd into cmd_q */
 | 
						|
        iot_proto_msgnode_free(saved_msg_q, savedmsg_node);
 | 
						|
    }
 | 
						|
 | 
						|
    return;
 | 
						|
}
 | 
						|
 | 
						|
void iot_proto_task_post_msg(uint16_t msg_type, uint16_t msg_id, void* data,
 | 
						|
    transmit_direction_e_t dir, uint8_t prio)
 | 
						|
{
 | 
						|
    iot_task_msg_t      *msg;
 | 
						|
    iot_proto_msg_t  *task_msg;
 | 
						|
    msg = iot_task_alloc_msg_with_reserved(prototask_contxt.task_handle, 0);
 | 
						|
    if (!msg) {
 | 
						|
        IOT_ASSERT(0);
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    task_msg = (iot_proto_msg_t*)msg;
 | 
						|
    task_msg->msg.type = msg_type;
 | 
						|
    task_msg->msg.id = msg_id;
 | 
						|
    task_msg->data1 = data;
 | 
						|
    task_msg->data2 = dir;
 | 
						|
    iot_task_queue_msg(prototask_contxt.task_handle, &task_msg->msg, prio);
 | 
						|
}
 | 
						|
 | 
						|
static void iot_proto_cus_app_msg_handle(iot_task_msg_t *msg)
 | 
						|
{
 | 
						|
    iot_proto_msg_t *task_msg;
 | 
						|
    IOT_ASSERT(msg);
 | 
						|
    task_msg = (iot_proto_msg_t*)msg;
 | 
						|
 | 
						|
    switch (task_msg->msg.id) {
 | 
						|
    case PROTO_CUS_APP_SAVE_PIB_MSG:
 | 
						|
        iot_proto_handle_save_cus_app_info_to_pib(task_msg->data1);
 | 
						|
        break;
 | 
						|
    default:
 | 
						|
        IOT_ASSERT(0);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
#if PLC_SUPPORT_CCO_ROLE
 | 
						|
/* for cli task register */
 | 
						|
static void iot_proto_task_cli_callback(void *param, iot_pkt_t *pkt)
 | 
						|
{
 | 
						|
    (void)param;
 | 
						|
    iot_proto_task_post_msg(PROTO_CLI_MSG, 0, pkt, 0, IOT_PROTO_TASK_QUEUE_LP);
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
/**
 | 
						|
 * @brief iot_proto_custom_pib_info_load() - To load custom pib info
 | 
						|
 * @param cus_pib_info: - point to custom pib info
 | 
						|
 * @param size: - load custom pib info size need smaller than defined
 | 
						|
 */
 | 
						|
void iot_proto_custom_pib_info_load(void *cus_pib_info, uint8_t size)
 | 
						|
{
 | 
						|
    if (size > 0 && size <= IOT_PROTO_CUST_APP_FLASH_SIZE) {
 | 
						|
        os_mem_cpy(cus_pib_info,
 | 
						|
            prototask_contxt.flashinfo.proto_prv.proto.custom_pib_info, size);
 | 
						|
    } else {
 | 
						|
        iot_cus_printf("[glpr][err]pib_info_load size=%d need <= %d!\n",
 | 
						|
            size, IOT_PROTO_CUST_APP_FLASH_SIZE);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * @brief iot_proto_custom_pib_info_save() - To save custom pib information
 | 
						|
 * @param cus_pib_info: - point to custom pib info which recv from custom app
 | 
						|
 * @param size: - save custom pib info size, need smaller than defined
 | 
						|
 */
 | 
						|
void iot_proto_custom_pib_info_save(void *cus_pib_info, uint8_t size)
 | 
						|
{
 | 
						|
    iot_pkt_t *p_pkt;
 | 
						|
    uint8_t *data;
 | 
						|
 | 
						|
    if (size > 0 && size <= IOT_PROTO_CUST_APP_FLASH_SIZE) {
 | 
						|
        p_pkt = iot_pkt_alloc(size, IOT_GREE_APP_MID);
 | 
						|
 | 
						|
        if (!p_pkt) {
 | 
						|
            iot_cus_printf("[glpr][err]No Mem!\n");
 | 
						|
            return;
 | 
						|
        }
 | 
						|
 | 
						|
        data = iot_pkt_put(p_pkt, size);
 | 
						|
        os_mem_cpy(data, cus_pib_info, size);
 | 
						|
 | 
						|
        iot_proto_task_post_msg(PROTO_CUS_APP_MSG, PROTO_CUS_APP_SAVE_PIB_MSG,
 | 
						|
            p_pkt, 0, IOT_PROTO_TASK_QUEUE_LP);
 | 
						|
    } else {
 | 
						|
        iot_cus_printf("[glpr][err]pib_info_save size=%d need <= %d!\n",
 | 
						|
            size, IOT_PROTO_CUST_APP_FLASH_SIZE);
 | 
						|
    }
 | 
						|
}
 | 
						|
/**
 | 
						|
 * @brief iot_proto_handle_save_cus_app_info_to_pib() - handle msg to save
 | 
						|
 * custom app information to pib
 | 
						|
 * @param data: pkt inlude led_info
 | 
						|
 */
 | 
						|
void iot_proto_handle_save_cus_app_info_to_pib(iot_pkt_t *data)
 | 
						|
{
 | 
						|
    ge_app_pib_info_t *p_flash = &prototask_contxt.flashinfo;
 | 
						|
 | 
						|
    os_mem_cpy(p_flash->proto_prv.proto.custom_pib_info, iot_pkt_data(data),
 | 
						|
        iot_pkt_data_len(data));
 | 
						|
 | 
						|
    iot_proto_flashsave(p_flash);
 | 
						|
 | 
						|
    iot_pkt_free(data);
 | 
						|
 | 
						|
    return;
 | 
						|
}
 | 
						|
 | 
						|
void iot_handle_ge_from_plc(iot_pkt_t *p_pkt)
 | 
						|
{
 | 
						|
    /* the index of the input data */
 | 
						|
    uint16_t index = 0;
 | 
						|
    /* the data length of the input pkt */
 | 
						|
    uint16_t input_data_len;
 | 
						|
    /* the data length of the frame unpacked from ge frame */
 | 
						|
    uint16_t data_len_after_handle = 0;
 | 
						|
    /* the data length of each data frame */
 | 
						|
    uint16_t frame_data_len;
 | 
						|
    uint8_t* buf;
 | 
						|
    ge_frame_data_send_set_subfn160_t *p_buf;
 | 
						|
    ge_frame_delay_time_subfn166_t *p_tm_buf;
 | 
						|
    ge_extend_fn_hdr_t *p_buf_hdr;
 | 
						|
 | 
						|
    buf = iot_pkt_data(p_pkt);
 | 
						|
    input_data_len = iot_pkt_data_len(p_pkt);
 | 
						|
    if (buf == NULL) {
 | 
						|
        IOT_ASSERT(0);
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    while (index < input_data_len) {
 | 
						|
        p_buf = (ge_frame_data_send_set_subfn160_t *)&buf[index];
 | 
						|
        p_tm_buf = (ge_frame_delay_time_subfn166_t *)&buf[index];
 | 
						|
        IOT_ASSERT(p_buf);
 | 
						|
        IOT_ASSERT(p_tm_buf);
 | 
						|
        if ((p_buf->hdr.hdr.fn == PROTO_GE_PLC_SET_CMD) &&
 | 
						|
            (p_buf->hdr.subfn == PROTO_GE_DATA_CMD) &&
 | 
						|
            (p_buf->resv == DL645_07_RESV0_RESV)) {
 | 
						|
            frame_data_len = p_buf->hdr.hdr.data_len;
 | 
						|
#if PLC_SUPPORT_STA_ROLE
 | 
						|
            /* If a dl645 frame is included in a FEA0 ge frame, the handling of
 | 
						|
                frame may be three conditions:
 | 
						|
                1 get the dl645 frame and send it to the uart
 | 
						|
                2 get the extend frame and send it to the uart
 | 
						|
                3 handle it in local model
 | 
						|
                the 3 condition won't send any data the uart, the data should be
 | 
						|
                take away.
 | 
						|
                the 1 and 2 condition should send data to uart, when those
 | 
						|
                frames are being checked out, the function
 | 
						|
                iot_handle_ge_to_dl645() will get the frames witch need to send
 | 
						|
                to the uart and copy them to the front of buf closely. finally,
 | 
						|
                the length of the frame in the buf is shorter than original
 | 
						|
                length of buf, the data length of pkt should be shrinked to the
 | 
						|
                finally length */
 | 
						|
            data_len_after_handle += iot_handle_ge_to_dl645(&buf[index],
 | 
						|
                &buf[data_len_after_handle]);
 | 
						|
            index += frame_data_len +
 | 
						|
                sizeof(ge_frame_data_send_set_subfn160_t) +
 | 
						|
                sizeof(ge_frm_tail_t) - IOT_MAC_ADDR_LEN;
 | 
						|
#else /* PLC_SUPPORT_STA_ROLE */
 | 
						|
            /* get other frame datas */
 | 
						|
            os_mem_cpy(&buf[data_len_after_handle],
 | 
						|
                &buf[index + GE_FEA0_HEAD_LEN],
 | 
						|
                frame_data_len - IOT_MAC_ADDR_LEN);
 | 
						|
            data_len_after_handle += frame_data_len - IOT_MAC_ADDR_LEN;
 | 
						|
            index += frame_data_len +
 | 
						|
                sizeof(ge_frame_data_send_set_subfn160_t) +
 | 
						|
                sizeof(ge_frm_tail_t) - IOT_MAC_ADDR_LEN;
 | 
						|
        } else if ((p_tm_buf->hdr.hdr.fn == PROTO_GE_PLC_SET_CMD) &&
 | 
						|
            (p_tm_buf->hdr.subfn == PROTO_GE_DELAY_TM_CMD)) {
 | 
						|
            if (p_tm_buf->resv == DL645_07_RESV0_RESV) {
 | 
						|
                /* If the type pose of the FE A6 frame is DL645_TYPE,
 | 
						|
                we need to reconstruct dl645 frame from ge frame */
 | 
						|
                frame_data_len = p_tm_buf->hdr.hdr.data_len;
 | 
						|
                data_len_after_handle += iot_handle_cco_delay_tm_pack_ge_to_dl645
 | 
						|
                    (&buf[index], &buf[data_len_after_handle]);
 | 
						|
                index += frame_data_len + GE_FRM_MIN_LEN;
 | 
						|
            } else if (p_tm_buf->resv == GE_TYPE) {
 | 
						|
                /* If the type pose of the FE A6 frame is GE_TYPE,
 | 
						|
                we need to remove pad data from ge frame */
 | 
						|
                frame_data_len = p_tm_buf->hdr.hdr.data_len;
 | 
						|
                data_len_after_handle += iot_handle_cco_delay_tm_ge_rm_pad_data
 | 
						|
                    (&buf[index], &buf[data_len_after_handle]);
 | 
						|
                index += frame_data_len + GE_FRM_MIN_LEN;
 | 
						|
            }
 | 
						|
#endif /* end PLC_SUPPORT_STA_ROLE */
 | 
						|
        } else {
 | 
						|
            p_buf_hdr = (ge_extend_fn_hdr_t *)&buf[index];
 | 
						|
            frame_data_len = p_buf_hdr->hdr.data_len;
 | 
						|
            if (p_buf->data_ext_flag) {
 | 
						|
                frame_data_len += GE_EXT_DATA_LEN;
 | 
						|
            }
 | 
						|
            os_mem_cpy(&buf[data_len_after_handle], &buf[index],
 | 
						|
                GE_FRM_MIN_LEN + frame_data_len);
 | 
						|
            index += GE_FRM_MIN_LEN + frame_data_len;
 | 
						|
            data_len_after_handle += GE_FRM_MIN_LEN + frame_data_len;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    if (input_data_len > data_len_after_handle) {
 | 
						|
        iot_pkt_shrink(p_pkt, input_data_len - data_len_after_handle);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
uint8_t is_edge_running(void)
 | 
						|
{
 | 
						|
    return (prototask_contxt.edge_obj.uart_hdl != NULL);
 | 
						|
}
 | 
						|
 | 
						|
void iot_edge_delay_start(void)
 | 
						|
{
 | 
						|
    if (os_is_timer_active(prototask_contxt.edge_monitor_start_tmr)) {
 | 
						|
        os_stop_timer(prototask_contxt.edge_monitor_start_tmr);
 | 
						|
        iot_task_clean_msg(prototask_contxt.task_handle,
 | 
						|
            PROTO_TIMER_MSG, PROTO_START_EDGE_TMR_ID);
 | 
						|
    }
 | 
						|
 | 
						|
    os_start_timer(prototask_contxt.edge_monitor_start_tmr,
 | 
						|
        prototask_contxt.flashinfo.public.pub.edge_start_tm);
 | 
						|
}
 | 
						|
 | 
						|
/* edge out msg */
 | 
						|
void iot_edge_post_to_proto_msg_handle(void *p_data, uint8_t msg_id)
 | 
						|
{
 | 
						|
    iot_proto_task_post_msg(EDGE_OUTPUT_MSG, msg_id, p_data, 0,
 | 
						|
        IOT_PROTO_TASK_QUEUE_LP);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * @brief post_monitor_start_timer() - call back function of
 | 
						|
                                       prototask_contxt.edge_monitor_start_tmr
 | 
						|
 * @param timer_id                     timer id
 | 
						|
 * @param arg                          data
 | 
						|
 */
 | 
						|
static void post_monitor_start_timer(timer_id_t timer_id, void * arg)
 | 
						|
{
 | 
						|
    (void)arg;
 | 
						|
    (void)timer_id;
 | 
						|
 | 
						|
    iot_proto_task_post_msg(PROTO_TIMER_MSG, PROTO_START_EDGE_TMR_ID,
 | 
						|
        NULL, 0, IOT_PROTO_TASK_QUEUE_LP);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * @brief post_monitor_start_timer_msg_handler() - handle function of
 | 
						|
                                       prototask_contxt.edge_monitor_start_tmr
 | 
						|
 */
 | 
						|
static void post_monitor_start_timer_msg_handler(void)
 | 
						|
{
 | 
						|
    void **pp_output_data;
 | 
						|
    iot_pkt_t *p_pkt;
 | 
						|
 | 
						|
    p_pkt = iot_pkt_alloc(sizeof(uint32_t), IOT_GREE_APP_MID);
 | 
						|
    if (!p_pkt) {
 | 
						|
        iot_cus_printf("[glpr][err]No Mem!\n");
 | 
						|
        return;
 | 
						|
    }
 | 
						|
    pp_output_data = (void **)iot_pkt_put(p_pkt, sizeof(uint32_t));
 | 
						|
    *pp_output_data = greeapp->uart_com;
 | 
						|
    greeapp->uart_com = NULL;
 | 
						|
    proto_post_data_to_edge_msg_handle(EDGE_INPUT_REQ_START_ID,
 | 
						|
        pp_output_data, sizeof(uint32_t));
 | 
						|
    iot_pkt_free(p_pkt);
 | 
						|
}
 | 
						|
 | 
						|
/* iot_plcuart_pl_task_init - plc uart protocol handle task initialize */
 | 
						|
uint32_t iot_proto_task_init()
 | 
						|
{
 | 
						|
    uint32_t ret = ERR_OK;
 | 
						|
 | 
						|
    os_mem_set(&prototask_contxt, 0, sizeof(prototask_contxt_t));
 | 
						|
 | 
						|
    prototask_contxt.task_cfg.stack_size = 0;
 | 
						|
    prototask_contxt.task_cfg.task_prio = IOT_GRAPP_PROTO_TASK_PRIO;
 | 
						|
    prototask_contxt.task_cfg.msg_size = sizeof(iot_proto_msg_t);
 | 
						|
    prototask_contxt.task_cfg.msg_cnt = IOT_PROTO_TASK_POOL_SIZE;
 | 
						|
    prototask_contxt.task_cfg.queue_cnt = IOT_PROTO_TASK_QUEUE_MAX_PRIO;
 | 
						|
    prototask_contxt.task_cfg.queue_cfg[IOT_PROTO_TASK_QUEUE_LP].quota = 0;
 | 
						|
    prototask_contxt.task_cfg.msg_exe_func = iot_proto_task_handle_msg;
 | 
						|
    prototask_contxt.task_cfg.msg_cancel_func
 | 
						|
        = iot_proto_task_handle_msg_cancel;
 | 
						|
    /* create task */
 | 
						|
    prototask_contxt.task_handle
 | 
						|
        = iot_task_create(IOT_GREE_APP_MID, &prototask_contxt.task_cfg);
 | 
						|
 | 
						|
    if (prototask_contxt.task_handle == NULL) {
 | 
						|
        ret = ERR_FAIL;
 | 
						|
        goto error_0;
 | 
						|
    }
 | 
						|
 | 
						|
    /* init  prototask_contxt protocol hanler process*/
 | 
						|
    prototask_contxt.proto_pase_fn = iot_proto_parse_fn;
 | 
						|
    prototask_contxt.proto_cmd_hdl_tbl   = proto_subfn_hdl_tbl;
 | 
						|
 | 
						|
    /* com0 drv period check timer */
 | 
						|
    prototask_contxt.uart_monitor_timer =
 | 
						|
                    os_create_timer(IOT_GREE_APP_MID, false,
 | 
						|
                    iot_proto_uart_monitor_timeout_timer,
 | 
						|
                    &prototask_contxt);
 | 
						|
    if (prototask_contxt.uart_monitor_timer == 0) {
 | 
						|
        ret = ERR_FAIL;
 | 
						|
        goto error_1;
 | 
						|
    }
 | 
						|
 | 
						|
    /* init command handle state */
 | 
						|
    iot_proto_cmd_handle_state_init();
 | 
						|
 | 
						|
    /* init gpio tab */
 | 
						|
    iot_proto_gpio_tab_init();
 | 
						|
 | 
						|
    /* init local device */
 | 
						|
#if (HW_PLATFORM == HW_PLATFORM_SIMU)
 | 
						|
    if (ucIsClientMode == 0) {
 | 
						|
        prototask_contxt.local_dev.nw_role  = IOT_PLC_DEV_ROLE_CCO;
 | 
						|
    } else {
 | 
						|
        prototask_contxt.local_dev.nw_role  = IOT_PLC_DEV_ROLE_STA;
 | 
						|
    }
 | 
						|
#else
 | 
						|
 | 
						|
#if PLC_SUPPORT_CCO_ROLE
 | 
						|
    prototask_contxt.local_dev.nw_role  = IOT_PLC_DEV_ROLE_CCO;
 | 
						|
#else
 | 
						|
    prototask_contxt.local_dev.nw_role  = IOT_PLC_DEV_ROLE_STA;
 | 
						|
#endif
 | 
						|
#endif
 | 
						|
 | 
						|
    if (iot_hwver_is_ledc_v3_0_jy() &&
 | 
						|
        (iot_board_get_board_id() == CUS_BOARD_ID_LEDC_V3_0) &&
 | 
						|
        (IOT_PLC_DEV_ROLE_STA == prototask_contxt.local_dev.nw_role)) {
 | 
						|
        iot_edge_init();
 | 
						|
    }
 | 
						|
 | 
						|
    /* init saved message queue pool */
 | 
						|
    ret = iot_mem_pool_new(IOT_GREE_APP_MID, PROTO_SAVED_MSG_NODE_NUM,
 | 
						|
        sizeof(proto_savedmsg_node_t), &saved_msg_q, 1);
 | 
						|
    if (ret) {
 | 
						|
        goto error_2;
 | 
						|
    }
 | 
						|
 | 
						|
    if (prototask_contxt.local_dev.nw_role != IOT_PLC_DEV_ROLE_CCO &&
 | 
						|
        !iot_hwver_is_ledc_v3_0_jy()) {
 | 
						|
        /* init proto timer to retry to query mac from MCU */
 | 
						|
        prototask_contxt.detect_timer = os_create_timer(IOT_GREE_APP_MID, false,
 | 
						|
            iot_proto_query_mac_timeout_timer,
 | 
						|
            NULL);
 | 
						|
        if (prototask_contxt.detect_timer == 0) {
 | 
						|
            ret = ERR_FAIL;
 | 
						|
            goto error_3;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /* init wait response timer for async cmd handle */
 | 
						|
    prototask_contxt.wait_resp_timer =
 | 
						|
                    os_create_timer(IOT_GREE_APP_MID, false,
 | 
						|
                    iot_proto_wait_resp_cmd_timeout_timer,
 | 
						|
                    &prototask_contxt);
 | 
						|
    if (prototask_contxt.wait_resp_timer == 0) {
 | 
						|
        ret = ERR_FAIL;
 | 
						|
        goto error_4;
 | 
						|
    }
 | 
						|
 | 
						|
    prototask_contxt.reboot_tmr =
 | 
						|
                    os_create_timer(IOT_GREE_APP_MID, false,
 | 
						|
                    iot_proto_reboot_delay_timeout_timer,
 | 
						|
                    &prototask_contxt);
 | 
						|
    if (prototask_contxt.reboot_tmr == 0) {
 | 
						|
        ret = ERR_FAIL;
 | 
						|
        goto error_5;
 | 
						|
    }
 | 
						|
 | 
						|
    prototask_contxt.statisc_tmr =
 | 
						|
                    os_create_timer(IOT_GREE_APP_MID, true,
 | 
						|
                    iot_proto_statistic_timer,
 | 
						|
                    &prototask_contxt);
 | 
						|
    if (prototask_contxt.statisc_tmr == 0) {
 | 
						|
        ret = ERR_FAIL;
 | 
						|
        goto error_6;
 | 
						|
    }
 | 
						|
 | 
						|
    os_start_timer(prototask_contxt.statisc_tmr, PROTO_TIMER_STATIST_INTVL);
 | 
						|
 | 
						|
    prototask_contxt.leave_tmr =
 | 
						|
                    os_create_timer(IOT_GREE_APP_MID, false,
 | 
						|
                    iot_proto_sta_leave_delay_timeout_timer,
 | 
						|
                    &prototask_contxt);
 | 
						|
    if (prototask_contxt.leave_tmr == 0) {
 | 
						|
        ret = ERR_FAIL;
 | 
						|
        goto error_7;
 | 
						|
    }
 | 
						|
 | 
						|
    /* init update upgrade state timer */
 | 
						|
    prototask_contxt.upgrade_tmr =
 | 
						|
                    os_create_timer(IOT_GREE_APP_MID, false,
 | 
						|
                    iot_proto_update_upgrade_state_timeout_timer, NULL);
 | 
						|
    if (prototask_contxt.upgrade_tmr == 0) {
 | 
						|
        ret = ERR_FAIL;
 | 
						|
        goto error_8;
 | 
						|
    }
 | 
						|
 | 
						|
    prototask_contxt.rpt_window_tmr =
 | 
						|
                    os_create_timer(IOT_GREE_APP_MID, false,
 | 
						|
                    iot_proto_brd_data_rpt_window_timer,
 | 
						|
                    &prototask_contxt);
 | 
						|
    if (prototask_contxt.rpt_window_tmr == 0) {
 | 
						|
        ret = ERR_FAIL;
 | 
						|
        goto error_9;
 | 
						|
    }
 | 
						|
 | 
						|
#if IOT_GE_PAGING_ENABLE
 | 
						|
    if (IOT_PLC_DEV_ROLE_CCO == prototask_contxt.local_dev.nw_role) {
 | 
						|
        prototask_contxt.paging_timer =
 | 
						|
                    os_create_timer(IOT_GREE_APP_MID, true,
 | 
						|
                    iot_proto_paging_timer,
 | 
						|
                    &prototask_contxt);
 | 
						|
        if (prototask_contxt.paging_timer == 0) {
 | 
						|
            ret = ERR_FAIL;
 | 
						|
            goto error_10;
 | 
						|
        }
 | 
						|
    }
 | 
						|
#endif
 | 
						|
 | 
						|
    if (IOT_PLC_DEV_ROLE_STA == prototask_contxt.local_dev.nw_role &&
 | 
						|
        TRIAL_RUN_CHECK_ENABLE) {
 | 
						|
        prototask_contxt.trial_run_tmr =
 | 
						|
                    os_create_timer(IOT_GREE_APP_MID, false,
 | 
						|
                    iot_proto_trial_run_check_timer, NULL);
 | 
						|
        if (prototask_contxt.trial_run_tmr == 0) {
 | 
						|
            ret = ERR_FAIL;
 | 
						|
            goto error_11;
 | 
						|
        }
 | 
						|
 | 
						|
        os_start_timer(prototask_contxt.trial_run_tmr,
 | 
						|
            IOT_APP_FW_RECOVER_TIME);
 | 
						|
    }
 | 
						|
 | 
						|
#if PLC_SUPPORT_STA_ROLE
 | 
						|
    prototask_contxt.dl645_localmode_tmr =
 | 
						|
                    os_create_timer(IOT_GREE_APP_MID, false,
 | 
						|
                    iot_proto_645_local_mode_timer, NULL);
 | 
						|
    if (prototask_contxt.dl645_localmode_tmr == 0) {
 | 
						|
        ret = ERR_FAIL;
 | 
						|
        goto error_12;
 | 
						|
    }
 | 
						|
#endif
 | 
						|
 | 
						|
    /* Create global timer end. */
 | 
						|
#if PLC_SUPPORT_CCO_ROLE
 | 
						|
    prototask_contxt.cli_interface.recv = iot_proto_task_cli_callback;
 | 
						|
    prototask_contxt.cli_interface.param = NULL;
 | 
						|
    ret = iot_cli_sg_interface_register(&prototask_contxt.cli_interface);
 | 
						|
#endif
 | 
						|
    if (ret) {
 | 
						|
        goto error_13;
 | 
						|
    }
 | 
						|
 | 
						|
    prototask_contxt.common_bin_dump_mutex = os_create_mutex(0);
 | 
						|
    if (prototask_contxt.common_bin_dump_mutex == NULL) {
 | 
						|
        iot_cus_printf("common_bin_dump mutex create failed \n");
 | 
						|
        goto error_13;
 | 
						|
    }
 | 
						|
 | 
						|
    prototask_contxt.edge_monitor_start_tmr =
 | 
						|
                    os_create_timer(IOT_GREE_APP_MID, false,
 | 
						|
                    post_monitor_start_timer, NULL);
 | 
						|
    if (prototask_contxt.edge_monitor_start_tmr == 0) {
 | 
						|
        ret = ERR_FAIL;
 | 
						|
        goto error_13;
 | 
						|
    }
 | 
						|
 | 
						|
    if (iot_hwver_is_ledc_v3_0_jy() &&
 | 
						|
        (iot_board_get_board_id() == CUS_BOARD_ID_LEDC_V3_0) &&
 | 
						|
        (IOT_PLC_DEV_ROLE_STA == prototask_contxt.local_dev.nw_role)) {
 | 
						|
        if (iot_edge_tmr_init()) {
 | 
						|
            goto error_14;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
#if PLC_SUPPORT_CCO_ROLE
 | 
						|
    cctt_init();
 | 
						|
#endif
 | 
						|
 | 
						|
    goto success;
 | 
						|
error_14:
 | 
						|
    os_delete_timer(prototask_contxt.edge_monitor_start_tmr);
 | 
						|
error_13:
 | 
						|
#if PLC_SUPPORT_STA_ROLE
 | 
						|
    if (prototask_contxt.dl645_localmode_tmr > 0) {
 | 
						|
        os_delete_timer(prototask_contxt.dl645_localmode_tmr);
 | 
						|
    }
 | 
						|
error_12:
 | 
						|
#endif
 | 
						|
    if (prototask_contxt.trial_run_tmr > 0) {
 | 
						|
        os_delete_timer(prototask_contxt.trial_run_tmr);
 | 
						|
    }
 | 
						|
error_11:
 | 
						|
#if IOT_GE_PAGING_ENABLE
 | 
						|
    if (prototask_contxt.paging_timer > 0) {
 | 
						|
        os_delete_timer(prototask_contxt.paging_timer);
 | 
						|
    }
 | 
						|
error_10:
 | 
						|
#endif
 | 
						|
    os_delete_timer(prototask_contxt.rpt_window_tmr);
 | 
						|
error_9:
 | 
						|
    os_delete_timer(prototask_contxt.upgrade_tmr);
 | 
						|
error_8:
 | 
						|
    os_delete_timer(prototask_contxt.leave_tmr);
 | 
						|
error_7:
 | 
						|
    os_delete_timer(prototask_contxt.statisc_tmr);
 | 
						|
error_6:
 | 
						|
    os_delete_timer(prototask_contxt.reboot_tmr);
 | 
						|
error_5:
 | 
						|
    os_delete_timer(prototask_contxt.wait_resp_timer);
 | 
						|
error_4:
 | 
						|
    if (prototask_contxt.detect_timer > 0) {
 | 
						|
        os_delete_timer(prototask_contxt.detect_timer);
 | 
						|
    }
 | 
						|
error_3:
 | 
						|
    iot_mem_pool_destroy(saved_msg_q);
 | 
						|
error_2:
 | 
						|
    os_delete_timer(prototask_contxt.uart_monitor_timer);
 | 
						|
error_1:
 | 
						|
    iot_task_delete(prototask_contxt.task_handle);
 | 
						|
error_0:
 | 
						|
    os_mem_set(&prototask_contxt, 0, sizeof(prototask_contxt_t));
 | 
						|
success:
 | 
						|
    iot_cus_printf("[glpr]:proto_task_init %s!\n", ret ? "fail" : "success");
 | 
						|
    return ret;
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
void iot_proto_task_deinit()
 | 
						|
{
 | 
						|
    os_delete_timer(prototask_contxt.uart_monitor_timer);
 | 
						|
    os_delete_timer(prototask_contxt.detect_timer);
 | 
						|
    os_delete_timer(prototask_contxt.wait_resp_timer);
 | 
						|
    os_delete_timer(prototask_contxt.reboot_tmr);
 | 
						|
    os_delete_timer(prototask_contxt.statisc_tmr);
 | 
						|
    os_delete_timer(prototask_contxt.leave_tmr);
 | 
						|
    if (saved_msg_q) {
 | 
						|
        iot_mem_pool_destroy(saved_msg_q);
 | 
						|
        saved_msg_q = NULL;
 | 
						|
    }
 | 
						|
    if (prototask_contxt.task_handle) {
 | 
						|
        os_delete_task(prototask_contxt.task_handle);
 | 
						|
    }
 | 
						|
    os_mem_set(&prototask_contxt, 0, sizeof(prototask_contxt_t));
 | 
						|
}
 | 
						|
 | 
						|
uint8_t iot_proto_get_cco_mac(uint8_t* mac)
 | 
						|
{
 | 
						|
    IOT_ASSERT(mac);
 | 
						|
 | 
						|
#if PLC_SUPPORT_STA_ROLE
 | 
						|
    if (!iot_mac_addr_valid(prototask_contxt.cco_dev.mac)) {
 | 
						|
        return ERR_FAIL;
 | 
						|
    }
 | 
						|
    os_mem_cpy(mac, prototask_contxt.cco_dev.mac, IOT_MAC_ADDR_LEN);
 | 
						|
#endif
 | 
						|
 | 
						|
#if PLC_SUPPORT_CCO_ROLE
 | 
						|
    if (!iot_mac_addr_valid(prototask_contxt.local_dev.mac)) {
 | 
						|
        return ERR_FAIL;
 | 
						|
    }
 | 
						|
    os_mem_cpy(mac, prototask_contxt.local_dev.mac, IOT_MAC_ADDR_LEN);
 | 
						|
#endif
 | 
						|
 | 
						|
    return ERR_OK;
 | 
						|
}
 | 
						|
 | 
						|
uint8_t iot_proto_cli_uart_gpio_reassign(uint8_t rxpin, uint8_t txpin)
 | 
						|
{
 | 
						|
    uint8_t cli_port = iot_board_get_uart(UART_CLI_PORT);
 | 
						|
 | 
						|
    if (cli_port >= IOT_UART_PORT_SUPP_MAX) {
 | 
						|
        return 0;
 | 
						|
    }
 | 
						|
 | 
						|
    return iot_uart_reassign_pin(cli_port, rxpin, txpin);
 | 
						|
}
 | 
						|
 | 
						|
#endif
 |