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