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
|