1283 lines
		
	
	
		
			39 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1283 lines
		
	
	
		
			39 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /****************************************************************************
 | |
| 
 | |
| Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
 | |
| 
 | |
| This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
 | |
| be copied by any method or incorporated into another program without
 | |
| the express written consent of Aerospace C.Power. This Information or any portion
 | |
| thereof remains the property of Aerospace C.Power. The Information contained herein
 | |
| is believed to be accurate and Aerospace C.Power assumes no responsibility or
 | |
| liability for its use in any way and conveys no license or title under
 | |
| any patent or copyright and makes no representation or warranty that this
 | |
| Information is free from patent or copyright infringement.
 | |
| 
 | |
| ****************************************************************************/
 | |
| 
 | |
| #include "app_uart.h"
 | |
| #include "app_main.h"
 | |
| #include "iot_app_meta_api.h"
 | |
| #include "iot_plc_sync_api.h"
 | |
| #include "app_cus_task.h"
 | |
| #include "iot_app_pib_cco_api.h"
 | |
| #include "iot_app_pib_sta_api.h"
 | |
| #include "iot_plc_led_api.h"
 | |
| #include "iot_oem_api.h"
 | |
| #include "iot_app_meta_api.h"
 | |
| #include "app_1901.h"
 | |
| #include "app_upg.h"
 | |
| 
 | |
| #if (IOT_APP_SELECTION == IOT_APP_DEF_18_AT_APP)
 | |
| #include "app_bypass_proc.h"
 | |
| #include "app_atcmd_proc.h"
 | |
| #include "app_atcmd_handle.h"
 | |
| #endif
 | |
| 
 | |
| #if (IOT_APP_SELECTION == IOT_APP_DEF_25_AT_MICRO_CCTT)
 | |
| #include "app_atcmd_proc.h"
 | |
| #include "app_atcmd_handle.h"
 | |
| #endif
 | |
| 
 | |
| #if APP_IO_OPERATION_ENABLE
 | |
| #include "app_gpio.h"
 | |
| #endif /* end APP_IO_OPERATION_ENABLE */
 | |
| 
 | |
| extern void iot_print_config(uint8_t enable);
 | |
| 
 | |
| app_entity_t g_app_entry;
 | |
| static timer_id_t pkt_info_timer;
 | |
| 
 | |
| inline app_entity_t *app_get_main_entry()
 | |
| {
 | |
|     return &g_app_entry;
 | |
| }
 | |
| 
 | |
| uint8_t app_work_mode_register(uint8_t work_mode, void *parser_func,
 | |
|     void *data_handle_func, void* reporter_func)
 | |
| {
 | |
|     uint16_t ret = ERR_FAIL;
 | |
|     app_entity_t *app_entry = NULL;
 | |
| 
 | |
|     if (work_mode > APP_WORK_MODE_MAX) {
 | |
|         goto out;
 | |
|     }
 | |
| 
 | |
|     app_entry = app_get_main_entry();
 | |
| 
 | |
|     if (app_entry->work_mode_reg[work_mode].enable == APP_WORK_MODE_DISABLE) {
 | |
|         app_entry->work_mode_reg[work_mode].data_parser = (app_data_parser_func
 | |
|             ) parser_func;
 | |
|         app_entry->work_mode_reg[work_mode].data_handle = (app_data_handle_func
 | |
|             ) data_handle_func;
 | |
|         app_entry->work_mode_reg[work_mode].on_off_report = (
 | |
|             app_onoffline_stat_report ) reporter_func;
 | |
|         app_entry->work_mode_reg[work_mode].enable = APP_WORK_MODE_ENABLE;
 | |
| 
 | |
|         ret = ERR_OK;
 | |
|     }
 | |
| 
 | |
| out:
 | |
|     if (ret) {
 | |
|         APP_PRINTF("[ERR] register work mode = %d failed!!!", work_mode);
 | |
|     }
 | |
| 
 | |
|     return ret;
 | |
| }
 | |
| 
 | |
| uint8_t app_work_mode_unregister(uint8_t work_mode)
 | |
| {
 | |
|     uint16_t ret = ERR_FAIL;
 | |
|     app_entity_t *app_entry = NULL;
 | |
| 
 | |
|     if (work_mode > APP_WORK_MODE_MAX) {
 | |
|         goto out;
 | |
|     }
 | |
| 
 | |
|     app_entry = app_get_main_entry();
 | |
| 
 | |
|     if (app_entry->work_mode_reg[work_mode].enable == APP_WORK_MODE_ENABLE) {
 | |
|         app_entry->work_mode_reg[work_mode].enable = APP_WORK_MODE_DISABLE;
 | |
| 
 | |
|         ret = ERR_OK;
 | |
|         goto out;
 | |
|     }
 | |
| 
 | |
| out:
 | |
|     if (ret) {
 | |
|         APP_PRINTF("[ERR] unregister work mode = %d failed!!!", work_mode);
 | |
|     }
 | |
| 
 | |
|     return ret;
 | |
| }
 | |
| 
 | |
| uint8_t app_set_work_mode(uint8_t work_mode)
 | |
| {
 | |
|     app_entity_t *app_entry = NULL;
 | |
| 
 | |
|     if (work_mode > APP_WORK_MODE_MAX) {
 | |
|         APP_PRINTF("[ERR] set work mode = %d failed, invalid work mode.", work_mode);
 | |
|         return ERR_FAIL;
 | |
|     }
 | |
| 
 | |
|     app_entry = app_get_main_entry();
 | |
| 
 | |
|     app_entry->work_mode_now = work_mode;
 | |
|     APP_PRINTF("[INF] set work mode = %d successrully ...", work_mode);
 | |
| 
 | |
|     return ERR_OK;
 | |
| }
 | |
| 
 | |
| uint8_t app_get_work_mode()
 | |
| {
 | |
|     app_entity_t *app_entry = NULL;
 | |
| 
 | |
|     app_entry = app_get_main_entry();
 | |
| 
 | |
|     return app_entry->work_mode_now;
 | |
| }
 | |
| 
 | |
| static uint16_t app_data_frame_parse(uint8_t * buffer, uint32_t buffer_len,
 | |
|     app_source_e source)
 | |
| {
 | |
|     uint8_t work_mode = 0;
 | |
|     uint16_t ret = ERR_FAIL;
 | |
|     app_entity_t *app_entry = NULL;
 | |
| 
 | |
| #if (IOT_APP_SELECTION == IOT_APP_DEF_18_AT_APP)
 | |
|     /* if uart rx '+++', switch to AT cmd mode */
 | |
|     if ((APP_WORK_MODE_AT != app_get_work_mode()) &&
 | |
|         (buffer_len == CHECK_ATCMD_BUF_SIZE) &&
 | |
|         iot_strstr((char*)buffer, "+++")) {
 | |
|         AT_RESP_OK();
 | |
|         app_set_work_mode(APP_WORK_MODE_AT);
 | |
|         return ERR_FAIL;
 | |
|     }
 | |
| #endif
 | |
| 
 | |
|     app_entry = app_get_main_entry();
 | |
|     work_mode = app_get_work_mode();
 | |
|     if (app_entry->work_mode_reg[work_mode].enable == APP_WORK_MODE_ENABLE ) {
 | |
|         app_entry->work_mode_reg[work_mode].data_parser(buffer, buffer_len, source);
 | |
|         ret = ERR_OK;
 | |
|     }
 | |
| 
 | |
|     if (ret) {
 | |
|         APP_PRINTF("[ERR] %s - unregistered work mode = %d!!!", __FUNCTION__,
 | |
|             work_mode);
 | |
|     }
 | |
| 
 | |
|     return ret;
 | |
| }
 | |
| 
 | |
| static uint16_t app_onoffline_state_report(uint8_t *dev_mac, uint8_t status)
 | |
| {
 | |
|     uint8_t work_mode = 0;
 | |
|     uint16_t ret = ERR_FAIL;
 | |
|     app_entity_t *app_entry = NULL;
 | |
| 
 | |
|     if (false == app_get_sta_join_notify()) {
 | |
|         return ERR_NOSUPP;
 | |
|     }
 | |
| 
 | |
|     app_entry = app_get_main_entry();
 | |
|     work_mode = app_get_work_mode();
 | |
|     if (app_entry->work_mode_reg[work_mode].enable == APP_WORK_MODE_ENABLE ) {
 | |
|         app_entry->work_mode_reg[work_mode].on_off_report(dev_mac, status);
 | |
|         ret = ERR_OK;
 | |
|     }
 | |
| 
 | |
|     if (ret) {
 | |
|         APP_PRINTF("[ERR] %s - unregistered work mode = %d!!!", __FUNCTION__,
 | |
|             work_mode);
 | |
|     }
 | |
| 
 | |
|     return ret;
 | |
| }
 | |
| 
 | |
| uint32_t app_post_msg(uint16_t msg_type, uint16_t msg_id, void *data)
 | |
| {
 | |
|     iot_task_msg_t *msg;
 | |
|     app_msg_t     *task_msg;
 | |
|     app_entity_t *app_entry = NULL;
 | |
| 
 | |
|     app_entry = app_get_main_entry();
 | |
| 
 | |
|     msg = iot_task_alloc_msg_with_reserved(app_entry->msg_task.handle, 0);
 | |
|     if (NULL == msg) {
 | |
|         APP_PRINTF("[ERR] %s Alloc MSG Buffer Failed !!", __FUNCTION__);
 | |
|         return ERR_FAIL;
 | |
|     }
 | |
| 
 | |
|     task_msg = (app_msg_t *)msg;
 | |
|     task_msg->msg.type = msg_type;
 | |
|     task_msg->msg.id = msg_id;
 | |
|     task_msg->data = data;
 | |
| 
 | |
|     iot_task_queue_msg(app_entry->msg_task.handle, &task_msg->msg, APP_TASK_MSG_PRIO);
 | |
| 
 | |
|     return ERR_OK;
 | |
| }
 | |
| 
 | |
| /* recv cli message post to task */
 | |
| uint32_t app_demo_post_msg_cli(void *data)
 | |
| {
 | |
|     app_post_msg(E_APP_MSG_PROCESS, E_CMD_ID_RCV_FROM_CLI, data);
 | |
|     return ERR_OK;
 | |
| }
 | |
| 
 | |
| /* handle message recv from plc */
 | |
| static uint16_t iot_app_plc_msg_handle(iot_pkt_t *pkt)
 | |
| {
 | |
|     iot_plc_msg_header_t *hdr;
 | |
|     iot_plc_msdu_recv_t *msdu;
 | |
|     uint16_t ret = ERR_FAIL;
 | |
|     uint8_t work_mode;
 | |
|     uint8_t *frame;
 | |
|     uint32_t frame_len = 0;
 | |
|     app_entity_t *app_entry = NULL;
 | |
|     recv_info_t rx_info = {0};
 | |
| 
 | |
| #if SUPPORT_IEEE_1901
 | |
|     app_plc_frame_data_hi *app_data;
 | |
| #else
 | |
|     app_custom_data *app_data;
 | |
| #endif /* end SUPPORT_IEEE_1901 */
 | |
| 
 | |
|     app_entry = app_get_main_entry();
 | |
|     app_entry->receivetime = iot_plc_get_ntb(app_entry->app_hdl);
 | |
|     hdr = (iot_plc_msg_header_t*)iot_pkt_data(pkt);
 | |
|     msdu = (iot_plc_msdu_recv_t*)(hdr + 1);
 | |
|     work_mode = app_get_work_mode();
 | |
| 
 | |
|     APP_PRINTF("msdu->len=%d pkt_len=%d", msdu->len, iot_pkt_data_len(pkt));
 | |
| 
 | |
| #if SUPPORT_IEEE_1901
 | |
| 
 | |
|     app_data = (app_plc_frame_data_hi*)msdu->data;
 | |
|     frame = (uint8_t *)(app_data + 1);
 | |
|     frame_len = msdu->len - sizeof(app_plc_frame_data_hi);
 | |
| #else
 | |
|     app_data = (app_custom_data*)msdu->data;
 | |
| 
 | |
|     frame = (uint8_t *)(app_data + 1);
 | |
|     frame_len = msdu->len - sizeof(app_custom_data);
 | |
| #endif /* end SUPPORT_IEEE_1901 */
 | |
|     APP_PRINT_BUF("[INF] BINARY DATA FORWORD TO UART: ", frame, frame_len);
 | |
| 
 | |
|     APP_PRINTF("plc_id = %x mode=%d",app_data->id, work_mode);
 | |
| 
 | |
|     if (app_entry->work_mode_reg[work_mode].enable == APP_WORK_MODE_ENABLE) {
 | |
|         iot_mac_addr_cpy(rx_info.mac, msdu->src);
 | |
|         /* 0: connless 1: conn */
 | |
|         rx_info.recv_flag = (hdr->msg_id == IOT_PLC_MSG_MSDU_RECV);
 | |
|         rx_info.recv_snr = msdu->snr;
 | |
|         rx_info.recv_rssi = msdu->rssi;
 | |
|         if (rx_info.recv_rssi == APP_INV_RSSI) {
 | |
|             rx_info.recv_rssi = BEST_RSSI;
 | |
|         }
 | |
|         app_entry->work_mode_reg[work_mode].data_handle(app_data->id,
 | |
|             APP_SOURCE_PLC,
 | |
|             frame, frame_len, &rx_info);
 | |
|         ret = ERR_OK;
 | |
|     }
 | |
| 
 | |
|     iot_pkt_free(pkt);
 | |
| 
 | |
|     if (ret) {
 | |
|         APP_PRINTF("[ERR] %s - unregistered work mode = %d!!!", __FUNCTION__,
 | |
|             work_mode);
 | |
|     }
 | |
| 
 | |
|      return ret;
 | |
| }
 | |
| 
 | |
| static void iot_app_send_plc_msg(iot_pkt_t *pkt)
 | |
| {
 | |
|     iot_pkt_t *msdu_pkt;
 | |
|     uint8_t *ptr;
 | |
|     app_custom_data *app_data;
 | |
|     append_tx_info_t *tx_info;
 | |
|     uint8_t msg_type = IOT_PLC_MSG_TYPE_BCAST;
 | |
|     uint16_t data_len;
 | |
|     uint16_t msdu_len;
 | |
|     uint16_t meta_len = 0;
 | |
|     uint8_t is_connless = false;
 | |
|     uint8_t is_sta = false;
 | |
|     uint8_t is_bcast = false;
 | |
|     iot_plc_topo_info * topo_info = NULL;
 | |
|     iot_plc_app_h app_handle;
 | |
|     app_entity_t *app_entry = NULL;
 | |
|     uint8_t retry_cnt = 0;
 | |
| 
 | |
|     app_entry = app_get_main_entry();
 | |
|     app_handle = app_entry->app_hdl;
 | |
| 
 | |
| #if SUPPORT_IEEE_1901
 | |
| 
 | |
|     data_len = iot_pkt_data_len(pkt) - sizeof(append_tx_info_t) -
 | |
|         sizeof(app_custom_data) + sizeof(app_plc_frame_data_hi);
 | |
| #else
 | |
|     data_len = iot_pkt_data_len(pkt) - sizeof(append_tx_info_t);
 | |
| #endif /* end SUPPORT_IEEE_1901 */
 | |
| 
 | |
|     tx_info = (append_tx_info_t *)iot_pkt_data(pkt);
 | |
|     app_data = (app_custom_data *)(tx_info + 1);
 | |
| 
 | |
|     if (app_entry->dev.dev_role != IOT_PLC_DEV_ROLE_CCO) {
 | |
|         is_sta = true;
 | |
|     }
 | |
| 
 | |
|     is_bcast = iot_mac_is_bcast(app_data->mac);
 | |
|     if (tx_info->force_type == SEND_FORCE_TYPE_CONNLESS) {
 | |
|         /* custom force send connless */
 | |
|         is_connless = true;
 | |
|     } else if (tx_info->force_type == SEND_FORCE_TYPE_CONNECT) {
 | |
|         /* custom force send connected */
 | |
|         is_connless = false;
 | |
|         if ((!is_sta) && (!iot_plc_sta_is_online(app_data->mac))) {
 | |
|             /* if the sta is offline, bcast send msdu pkt */
 | |
|             is_bcast = true;
 | |
|         }
 | |
|     } else {
 | |
|         if ((!is_sta) && (is_bcast)) {
 | |
|             /* the cco bcast, if sta num is 0 should offline bcast */
 | |
|             iot_plc_cco_query_nw_topo(&topo_info, 0, 2);
 | |
|             if (topo_info->total_cnt <= 1) {
 | |
|                 is_connless = true;
 | |
|             }
 | |
|         } else if ((!is_sta) && (!iot_plc_sta_is_online(app_data->mac))) {
 | |
|             /* if the sta is offline, send conncet_less msdu pkt */
 | |
|             is_connless = true;
 | |
|         } else if (is_sta && is_bcast) {
 | |
|             /* sta send broadcast, need send connless */
 | |
|             is_connless = true;
 | |
|         } else if (is_sta && (!app_entry->dev.dev_ready)) {
 | |
|             /* sta not joined network, need send connless*/
 | |
|             is_connless = true;
 | |
|         } else if (is_sta && app_entry->dev.dev_ready &&
 | |
|             !iot_mac_addr_cmp(app_data->mac, app_entry->dev.cco_addr)) {
 | |
|             /* joined network sta not send data to cco, need send connless */
 | |
|             is_connless = true;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     msdu_len = iot_plc_calc_msdu_len_with_pad_info(data_len, is_connless,
 | |
|         &meta_len);
 | |
| 
 | |
|     if (is_connless) {
 | |
|         /* if the sta is offline, send conncet_less msdu pkt */
 | |
|         if (is_sta || (!is_bcast)) {
 | |
|             msg_type = IOT_PLC_MSG_TYPE_CONN_LESS_DATA;
 | |
|         } else {
 | |
|             msg_type = IOT_PLC_MSG_TYPE_CONN_LESS_DATA_ALL;
 | |
|         }
 | |
| #if SUPPORT_IEEE_1901
 | |
|         /* when in SILA APP, send connectionless none
 | |
|         head mode data to one sta */
 | |
| #if (IOT_APP_SELECTION == IOT_APP_DEF_18_AT_APP)
 | |
|         if (is_sta || (!is_bcast)) {
 | |
|             msg_type = IOT_PLC_MSG_TYPE_CONN_LESS_DATA;
 | |
|         } else {
 | |
|             msg_type = IOT_PLC_MSG_TYPE_CONN_LESS_DATA_ALL;
 | |
|         }
 | |
| #elif (IOT_APP_SELECTION == IOT_APP_DEF_24_SILA_AT_APP)
 | |
|         if (is_sta || (!is_bcast)) {
 | |
|             msg_type = IOT_PLC_MSG_TYPE_NHM_DATA;
 | |
|         } else {
 | |
|             msg_type = IOT_PLC_MSG_TYPE_NHM_DATA_ALL;
 | |
|         }
 | |
|         app_handle = app_entry->sila_nhm_hdl;
 | |
| #endif
 | |
| #else
 | |
| #endif /* end SUPPORT_IEEE_1901 */
 | |
|         APP_PRINTF("Broadcast pkt type %d sent by offline sta " MAC_FMT,
 | |
|             msg_type, MAC_ARG(app_entry->dev.mac_addr));
 | |
|         msdu_pkt = iot_plc_alloc_conn_less_msdu(app_handle,
 | |
|             msg_type, app_data->mac, app_entry->dev.mac_addr,
 | |
|             app_entry->dev.link_id, msdu_len, retry_cnt);
 | |
|     } else {
 | |
|         if (is_bcast) {
 | |
|             if ((!is_sta) && (app_entry->user_type == USER_TYPE_SUNSOLAR1)) {
 | |
|                 retry_cnt = 2;
 | |
|                 msg_type = IOT_PLC_MSG_TYPE_BCAST_ALL;
 | |
|             }
 | |
|         } else {
 | |
|             msg_type = IOT_PLC_MSG_TYPE_UNICAST;
 | |
|         }
 | |
| 
 | |
|         msdu_pkt = iot_plc_alloc_msdu(app_handle,
 | |
|             msg_type, IOT_PLC_ACK_TYPE_NONE,
 | |
|             app_data->mac,
 | |
|             app_entry->dev.mac_addr,
 | |
|             app_entry->dev.link_id, msdu_len, retry_cnt);
 | |
|     }
 | |
| 
 | |
|     if (NULL == msdu_pkt) {
 | |
|         iot_pkt_free(pkt);
 | |
|         APP_PRINTF("[ERR] %s Alloc Packet Failed !!", __FUNCTION__);
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     ptr = iot_pkt_block_ptr(msdu_pkt, IOT_PKT_BLOCK_TAIL);
 | |
| 
 | |
| #if SUPPORT_IEEE_1901
 | |
|     /* extend append_tx_info_t data block in front */
 | |
|     iot_pkt_pull(pkt, sizeof(append_tx_info_t));
 | |
|     package_1901_frame(ptr, pkt);
 | |
| #else
 | |
|     os_mem_cpy(ptr, app_data, data_len);
 | |
| #endif /* end SUPPORT_IEEE_1901 */
 | |
| 
 | |
|     iot_pkt_put(msdu_pkt, data_len);
 | |
| 
 | |
|     iot_pkt_free(pkt);
 | |
| 
 | |
|     iot_plc_add_meta_info(msdu_pkt, meta_len);
 | |
| 
 | |
|     APP_PRINT_BUF("[INF] BINARY DATA FORWORD TO PLC:",
 | |
|         iot_pkt_data(msdu_pkt), iot_pkt_data_len(msdu_pkt));
 | |
| 
 | |
|     /* Forword to PLC. */
 | |
|     iot_plc_send_msdu(app_handle, msdu_pkt);
 | |
| }
 | |
| 
 | |
| /* This is the handle for messages from this module. */
 | |
| static void app_msg_process_handle(uint16_t id, void *data)
 | |
| {
 | |
|     iot_pkt_t *pkt = (iot_pkt_t *)data;
 | |
|     uint32_t data_len = iot_pkt_data_len(pkt);
 | |
| 
 | |
|     if ((NULL == pkt) || ((0 == data_len) && E_CMD_ID_RCV_FROM_CLI != id)) {
 | |
|         APP_PRINTF("[ERR] %s Packet is NULL !!", __FUNCTION__);
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     if (E_CMD_ID_RCV_FROM_PLC == id) {
 | |
|         iot_app_plc_msg_handle(pkt);
 | |
|     } else if (E_CMD_ID_RCV_FROM_CLI == id) {
 | |
|         iot_app_handle_cli_msg(pkt);
 | |
|     } else if(E_CMD_ID_SEND_DATA_TO_PLC == id) {
 | |
|         /* send data to plc */
 | |
|         iot_app_send_plc_msg(pkt);
 | |
|     } else if (E_CMD_ID_RCV_FROM_UART == id) {
 | |
|         app_data_frame_parse(iot_pkt_data(pkt), data_len, APP_SOURCE_UART);
 | |
|         iot_pkt_free(pkt);
 | |
|     } else {
 | |
|         iot_pkt_free(pkt);
 | |
|     }
 | |
| 
 | |
|     return;
 | |
| }
 | |
| 
 | |
| static void app_msg_from_mac_handle(iot_pkt_t *pkt)
 | |
| {
 | |
|     iot_plc_msg_header_t *hdr = (iot_plc_msg_header_t*)iot_pkt_data(pkt);
 | |
|     app_entity_t *app_entry = NULL;
 | |
| 
 | |
|     app_entry = app_get_main_entry();
 | |
| 
 | |
|     /* Check if this packet belongs to me. */
 | |
| #if SUPPORT_IEEE_1901
 | |
|     if ((IOT_PLC_APP_ID_BCAST != hdr->app_id)
 | |
|         && (IOT_PLC_APP_SMART_GRID != hdr->app_id)
 | |
|         && (IOT_PLC_SILA_NHM_ID != hdr->app_id)) {
 | |
| #else
 | |
|     if ((IOT_PLC_APP_ID_BCAST != hdr->app_id)
 | |
|         && (IOT_PLC_APP_DEMO_ID != hdr->app_id)) {
 | |
| #endif /* end SUPPORT_IEEE_1901 */
 | |
|         APP_PRINTF("[ERR] INVALID PACKET FROM MAC,APP ID#%d.", hdr->app_id);
 | |
|         iot_pkt_free(pkt);
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     /* Check if I'm registerd before handling msg. */
 | |
|     if ((!app_entry->app_reg) &&
 | |
|         (IOT_PLC_MSG_APP_REG_CONF != hdr->msg_id)) {
 | |
|         APP_PRINTF("[ERR] INVALID PACKET FROM MAC,MSG ID#%d.", hdr->msg_id);
 | |
|         iot_pkt_free(pkt);
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     switch (hdr->msg_id) {
 | |
|         case IOT_PLC_MSG_APP_REG_CONF :
 | |
|         {
 | |
|             iot_plc_app_reg_conf_t* rpt = (iot_plc_app_reg_conf_t*)(hdr + 1);
 | |
| 
 | |
|             if ((IOT_PLC_SUCCESS == rpt->result) ||
 | |
|                 (IOT_PLC_SUCCESS_MODIFIED == rpt->result)) {
 | |
|                 app_entry->app_reg = true;
 | |
|                 iot_plc_query_dev_info(app_entry->app_hdl, IOT_PLC_API_REQ_ID_DEFAULT);
 | |
|                 APP_PRINTF("[INF] APP REGISTERED SUCCESSFULLY.");
 | |
|             }
 | |
| 
 | |
|             break;
 | |
|         }
 | |
|         case IOT_PLC_MSG_DEV_STATE_CHANGE_RPT :
 | |
|         {
 | |
|             iot_plc_dev_state_change_rpt_t* rpt =
 | |
|                 (iot_plc_dev_state_change_rpt_t*)(hdr + 1);
 | |
| 
 | |
|             if (rpt->is_ready) {
 | |
|                 APP_PRINTF("[INF] STATE CHANGE REPORT MAC GET READY, MY ROLE TYPE#%d.",
 | |
|                     rpt->dev_role);
 | |
|                 APP_PRINTF("CCO MAC "MAC_FMT, MAC_ARG(rpt->cco_mac));
 | |
| 
 | |
|                 APP_PRINTF("LOCAL MAC "MAC_FMT, MAC_ARG(rpt->local_mac));
 | |
|                 if (app_entry->dev.dev_ready == false) {
 | |
|                     app_entry->dev.dev_ready = true;
 | |
|                 }
 | |
| 
 | |
|                 if (IOT_PLC_DEV_ROLE_CCO != rpt->dev_role) {
 | |
|                     iot_mac_addr_cpy(app_entry->dev.rmt_addr, rpt->cco_mac);
 | |
|                     app_onoffline_state_report(rpt->cco_mac, STA_ONLINE_EVENT);
 | |
|                 }
 | |
| 
 | |
|                 app_entry->dev.dev_role   = rpt->dev_role;
 | |
|                 app_entry->dev.nid        = rpt->nid;
 | |
| 
 | |
|                 iot_mac_addr_cpy(app_entry->dev.mac_addr, rpt->local_mac);
 | |
|                 iot_mac_addr_cpy(app_entry->dev.cco_addr, rpt->cco_mac);
 | |
|             } else {
 | |
|                 APP_PRINTF("[INF] MAC IS NOT READY #%d.", hdr->msg_id);
 | |
|                 if (app_entry->dev.dev_ready) {
 | |
|                     app_entry->dev.dev_ready = false;
 | |
| 
 | |
|                     if (IOT_PLC_DEV_ROLE_CCO != rpt->dev_role) {
 | |
|                         APP_PRINTF("[INF] STA leave net reason:%d.",
 | |
|                             rpt->leave_net_reason);
 | |
|                         /* Notify Offline Event (local) */
 | |
|                         if (iot_mac_addr_valid(rpt->cco_mac)) {
 | |
|                             app_onoffline_state_report(rpt->cco_mac,
 | |
|                                 STA_OFFLINE_EVENT);
 | |
|                         } else {
 | |
|                             app_onoffline_state_report(app_entry->dev.cco_addr,
 | |
|                                 STA_OFFLINE_EVENT);
 | |
|                             os_mem_set(app_entry->dev.cco_addr, 0,
 | |
|                                 IOT_MAC_ADDR_LEN);
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|             break;
 | |
|         }
 | |
|         case IOT_PLC_MSG_DEV_INFO_RPT :
 | |
|         {
 | |
|             iot_plc_dev_info_rpt_t* rpt =
 | |
|                 (iot_plc_dev_info_rpt_t*)(hdr + 1);
 | |
|             app_entry->dev.dev_ready  = rpt->is_ready;
 | |
|             app_entry->u_snr          = rpt->snr;
 | |
|             iot_mac_addr_cpy(app_entry->dev.mac_addr, rpt->local_mac);
 | |
|             if (rpt->is_ready) {
 | |
|                 APP_PRINTF("[INF] DEVICE INFO REPORT MAC GET READY, MY ROLE TYPE#%d.",
 | |
|                     rpt->dev_role);
 | |
|                 APP_PRINTF("CCO MAC "MAC_FMT, MAC_ARG(rpt->cco_mac));
 | |
|                 APP_PRINTF("LOCAL MAC "MAC_FMT, MAC_ARG(rpt->local_mac));
 | |
| 
 | |
|                 app_entry->dev.dev_role   = rpt->dev_role;
 | |
| 
 | |
|                 iot_mac_addr_cpy(app_entry->dev.cco_addr, rpt->cco_mac);
 | |
|             } else {
 | |
|                 APP_PRINTF("[INF] MAC IS NOT READY #%d.", hdr->msg_id);
 | |
|             }
 | |
| 
 | |
|             break;
 | |
|         }
 | |
|         case IOT_PLC_MSG_STA_JOIN_INFO :
 | |
|         {
 | |
|             iot_plc_sta_join_info_t* rpt = (iot_plc_sta_join_info_t*)(hdr + 1);
 | |
|             APP_PRINTF("STA JOINED : MAC#"MAC_FMT, MAC_ARG(rpt->sta_info.addr));
 | |
| 
 | |
|             if (IOT_PLC_DEV_ROLE_CCO == app_entry->dev.dev_role) {
 | |
|                 iot_plc_led_request(IOT_PLC_LED_ASSOCIATED);
 | |
|                 /* Keep the remote device as the last one we got. */
 | |
|                 iot_mac_addr_cpy(app_entry->dev.rmt_addr, rpt->sta_info.addr);
 | |
|                 /* Notify Online Event */
 | |
|                 app_onoffline_state_report(rpt->sta_info.addr, STA_ONLINE_EVENT);
 | |
|             }
 | |
| 
 | |
|             break;
 | |
|         }
 | |
|         case IOT_PLC_MSG_STA_LEAVE_INFO :
 | |
|         {
 | |
|             uint32_t cnt;
 | |
|             iot_plc_sta_leave_info_t* rpt =
 | |
|                 (iot_plc_sta_leave_info_t*)(hdr + 1);
 | |
| 
 | |
|             for (cnt = 0; cnt < rpt->sta_count; cnt++) {
 | |
|                 APP_PRINTF("STA LEAVED : MAC#"MAC_FMT, MAC_ARG(rpt->sta[cnt].mac_addr));
 | |
| 
 | |
|                 if (IOT_PLC_DEV_ROLE_CCO == app_entry->dev.dev_role) {
 | |
|                     iot_plc_led_request(IOT_PLC_LED_DIS_ASSOCIATED);
 | |
|                     /* Notify Offline Event */
 | |
|                     app_onoffline_state_report(rpt->sta[cnt].mac_addr, STA_OFFLINE_EVENT);
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             break;
 | |
|         }
 | |
|         case IOT_PLC_MSG_CONN_LESS_RECV :
 | |
|         case IOT_PLC_MSG_MSDU_RECV :
 | |
|         {
 | |
|             iot_plc_msdu_recv_t *msdu = (iot_plc_msdu_recv_t*)(hdr + 1);
 | |
|             app_entry->u_snr = msdu->snr;
 | |
|             APP_PRINTF("MSDU RECEIVED FROM MAC#"MAC_FMT, MAC_ARG(msdu->src));
 | |
|             iot_check_meta_data(pkt);
 | |
| #if PLC_SUPPORT_STA_ROLE
 | |
|             iot_meta_rcd_app_msdu_info(msdu,
 | |
|                 hdr->msg_id == IOT_PLC_MSG_MSDU_RECV);
 | |
| #endif
 | |
|             if (!iot_mac_addr_cmp(msdu->src, app_entry->dev.mac_addr)) {
 | |
|                 app_post_msg(E_APP_MSG_PROCESS, E_CMD_ID_RCV_FROM_PLC, (void*)pkt);
 | |
|                 /* Packet will not be freed here. */
 | |
|                 pkt = NULL;
 | |
|             }
 | |
|             break;
 | |
|         }
 | |
|         default :
 | |
|         {
 | |
|             break;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     if (pkt) {
 | |
|         iot_pkt_free(pkt);
 | |
|     }
 | |
| 
 | |
|     return;
 | |
| }
 | |
| 
 | |
| void app_end_idf(void)
 | |
| {
 | |
|     uint8_t i, add_cnt = 0;
 | |
|     uint16_t start = 0;
 | |
|     uint8_t * data;
 | |
|     iot_pkt_t *pkt;
 | |
|     iot_plc_topo_info * topo_info = NULL;
 | |
| 
 | |
|     iot_plc_cco_query_nw_topo(&topo_info, start, APP_WHITELIST_SETUP_MAX);
 | |
| 
 | |
|     pkt = iot_pkt_alloc(APP_WHITELIST_SETUP_MAX * IOT_MAC_ADDR_LEN, IOT_APP_DEMO_MID);
 | |
|     if (pkt == NULL) {
 | |
|         APP_PRINTF("[ERR] %s Packet Alloc Failed !!", __FUNCTION__);
 | |
|         return;
 | |
|     }
 | |
|     data = (uint8_t *)iot_pkt_put(pkt, APP_WHITELIST_SETUP_MAX * IOT_MAC_ADDR_LEN);
 | |
|     if (topo_info->total_cnt) {
 | |
|         do {
 | |
|             add_cnt = 0;
 | |
|             for (i = 0; i < topo_info->cur_cnt; i++) {
 | |
|                 if ((start + i) > 0) {
 | |
|                     iot_mac_addr_reverse(topo_info->topo_info[i].mac);
 | |
|                     iot_mac_addr_cpy(data + add_cnt * IOT_MAC_ADDR_LEN, topo_info->topo_info[i].mac);
 | |
|                     add_cnt++;
 | |
|                 }
 | |
|             }
 | |
|             if (add_cnt) {
 | |
|                 // add whitelist
 | |
|                 iot_plc_cco_set_whitelist_func(IOT_PLC_WL_ADD, add_cnt, data);
 | |
|             }
 | |
|             start += topo_info->cur_cnt;
 | |
|             if (topo_info->total_cnt >= start) {
 | |
|                 break;
 | |
|             }
 | |
|             iot_plc_cco_query_nw_topo(&topo_info, start, APP_WHITELIST_SETUP_MAX);
 | |
|             if (0 == topo_info->cur_cnt) {
 | |
|                 break;
 | |
|             }
 | |
|         } while (1);
 | |
|     }
 | |
|     iot_pkt_free(pkt);
 | |
|     // enable whitelist
 | |
|     iot_plc_cco_set_whitelist_func(IOT_PLC_WL_ENABLE, 0, NULL);
 | |
|     app_set_idf_status(false);
 | |
|     iot_cus_printf("IDFEND\n");
 | |
| }
 | |
| 
 | |
| static void app_sta_signal_led_timer_func(void)
 | |
| {
 | |
|     app_entity_t *app_entry = NULL;
 | |
| 
 | |
|     app_entry = app_get_main_entry();
 | |
| 
 | |
|     if (app_entry->u_snr >= IOT_SNR_STRONG_MIN_THR) {
 | |
|         iot_plc_led_request(IOT_PLC_LED_SIGNAL_STRONG);
 | |
|     } else if (app_entry->u_snr >= IOT_SNR_GOOD_MIN_THR) {
 | |
|         iot_plc_led_request(IOT_PLC_LED_SIGNAL_GOOD);
 | |
|     } else {
 | |
|         iot_plc_led_request(IOT_PLC_LED_SIGNAL_WEAK);
 | |
|     }
 | |
| 
 | |
|     iot_plc_query_dev_info(app_entry->app_hdl, IOT_PLC_API_REQ_ID_DEFAULT);
 | |
| 
 | |
|     return;
 | |
| }
 | |
| 
 | |
| static void app_cco_net_done_check_or_bcast_func(void)
 | |
| {
 | |
|     uint8_t bcast_mac[IOT_MAC_ADDR_LEN] = { 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF };
 | |
|     uint8_t wl_state;
 | |
|     uint16_t topo_num;
 | |
|     uint16_t wl_cnt;
 | |
|     iot_plc_topo_info *topo = NULL;
 | |
|     app_entity_t *app_entry = NULL;
 | |
|     append_tx_info_t tx_info = {0};
 | |
| 
 | |
|     app_entry = app_get_main_entry();
 | |
| 
 | |
|     if (IOT_PLC_DEV_ROLE_CCO == app_entry->dev.dev_role) {
 | |
|         /* the timer period is 500ms, when the cco_bcast_per_cnt count to the
 | |
|         period, cco broadcast data and clear cco_bcast_per_cnt */
 | |
|         if (app_entry->app_cfg.bcast.status == APP_BCAST_STATUS_ON &&
 | |
|             app_entry->app_cfg.bcast.period != 0 &&
 | |
|             app_entry->app_cfg.bcast.len != 0) {
 | |
|             app_entry->cco_bcast_per_cnt++;
 | |
|             if (0 == (app_entry->cco_bcast_per_cnt %
 | |
|                 app_entry->app_cfg.bcast.period)) {
 | |
|                 app_entry->cco_bcast_per_cnt = 0;
 | |
|                 if (app_entry->app_cfg.bcast.send_flag) {
 | |
|                     tx_info.force_type = SEND_FORCE_TYPE_CONNLESS;
 | |
|                 } else {
 | |
|                     tx_info.force_type = SEND_FORCE_TYPE_DEF;
 | |
|                 }
 | |
|                 app_plc_tx(app_entry->app_cfg.bcast.data,
 | |
|                     app_entry->app_cfg.bcast.len, bcast_mac, ID_PLC_AT_DATA,
 | |
|                     &tx_info);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /* check and change cco network done state */
 | |
|         wl_state = iot_plc_cco_get_whiltlist_state_func();
 | |
|         iot_plc_cco_query_nw_topo(&topo, 0, 5);
 | |
|         if (NULL == topo) {
 | |
|             return;
 | |
|         }
 | |
|         topo_num = topo->total_cnt;
 | |
|         wl_cnt = iot_app_get_wl_cnt();
 | |
| 
 | |
|         if (wl_state && (topo_num > 1) && (topo_num -1 == wl_cnt)) {
 | |
|             if (app_entry->dev.cco_net_done == 0) {
 | |
|                 app_entry->dev.cco_net_done = 1;
 | |
|                 iot_plc_led_request(IOT_PLC_LED_NET_FORMAT_DONE);
 | |
|                 APP_PRINTF("[info]%s network done !", __FUNCTION__);
 | |
|             }
 | |
|         } else {
 | |
|             if (app_entry->dev.cco_net_done == 1) {
 | |
|                 app_entry->dev.cco_net_done = 0;
 | |
|                 iot_plc_led_request(IOT_PLC_LED_DIS_ASSOCIATED);
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * @brief   handle timer message
 | |
|  * @param   id: timer msg id
 | |
|  * @param   data: timer_id can use for restart or delete
 | |
|  */
 | |
| static void app_on_msg_timer(app_timer_id_e id, void *data)
 | |
| {
 | |
|     switch (id) {
 | |
|         case APP_TIMER_ID_REBOOT:
 | |
|             iot_system_restart(IOT_SYS_RST_REASON_APP_REQ);
 | |
|             os_delete_timer((timer_id_t)data);
 | |
|             break;
 | |
|         case APP_TIMER_ID_IDF_CHECK:
 | |
|             app_end_idf();
 | |
|             os_delete_timer((timer_id_t)data);
 | |
|             break;
 | |
|         case APP_TIMER_ID_SIGNAL_LED:
 | |
|             app_sta_signal_led_timer_func();
 | |
|             break;
 | |
|         case APP_TIMER_ID_NET_DONE_CHECK_OR_BCAST:
 | |
|             app_cco_net_done_check_or_bcast_func();
 | |
|             break;
 | |
|         default:
 | |
|             break;
 | |
|     }
 | |
| }
 | |
| 
 | |
| static void app_event_handle(iot_task_h task_h, uint32_t event)
 | |
| {
 | |
|     (void)task_h;
 | |
|     (void)event;
 | |
| #if 0
 | |
|     if(BIT(E_DEMO_EV_TIMR) & event)
 | |
|     {
 | |
|         app_demo_led_blink();
 | |
| 
 | |
|         app_demo_stamp_running_time();
 | |
| 
 | |
|         app_demo_device_query();
 | |
| #if IOT_ADC_DEMO_ENABLE
 | |
|         if(g_adc_info)
 | |
|         {
 | |
|             app_demo_adc_periodic_sample();
 | |
|         }
 | |
| #endif
 | |
|     }
 | |
| #endif
 | |
|     APP_PRINTF("[INF] %s", __FUNCTION__);
 | |
|     return;
 | |
| }
 | |
| 
 | |
| static void app_msg_handle(iot_task_h task_h, iot_task_msg_t *msg)
 | |
| {
 | |
|     app_msg_t *dm_msg = (app_msg_t *)msg;
 | |
| 
 | |
|     (void)task_h;
 | |
| 
 | |
|     if ((NULL == dm_msg) || (!APP_MSG_VALID(dm_msg->msg.type))) {
 | |
|         /* Maybe this can cause memory overflow! */
 | |
|         APP_PRINTF("[ERR] %s Invalid MSG !!", __FUNCTION__);
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     if (E_APP_MSG_PROCESS == dm_msg->msg.type) {
 | |
|         app_msg_process_handle(dm_msg->msg.id, dm_msg->data);
 | |
|     } else if(E_APP_MSG_FROM_MAC == dm_msg->msg.type) {
 | |
|         app_msg_from_mac_handle((iot_pkt_t *)dm_msg->data);
 | |
|     } else if (E_APP_MSG_TIMER == dm_msg->msg.type) {
 | |
|         app_on_msg_timer(dm_msg->msg.id, dm_msg->data);
 | |
|     }
 | |
| 
 | |
|     iot_task_free_msg(task_h, &(dm_msg->msg));
 | |
| 
 | |
|     return;
 | |
| }
 | |
| 
 | |
| /* As all message data is a packet, so just free() it. */
 | |
| static void app_msg_common_cancel(uint16_t id, void *data)
 | |
| {
 | |
|     (void)id;
 | |
|     iot_pkt_t *pkt = (iot_pkt_t*)data;
 | |
| 
 | |
|     if (pkt) {
 | |
|         iot_pkt_free(pkt);
 | |
|     }
 | |
| 
 | |
|     return;
 | |
| }
 | |
| 
 | |
| static void app_msg_cancel(iot_task_h task_h, iot_task_msg_t *msg)
 | |
| {
 | |
|     app_msg_t *dm_msg = (app_msg_t *)msg;
 | |
| 
 | |
|     (void)task_h;
 | |
| 
 | |
|     if ((NULL == dm_msg) || (!APP_MSG_VALID(dm_msg->msg.type))) {
 | |
|         /* Maybe this can cause memory overflow! */
 | |
|         APP_PRINTF("[ERR] CANCEL AN INVALID MSG !!");
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     if ((E_APP_MSG_PROCESS == dm_msg->msg.type)
 | |
|         || (E_APP_MSG_FROM_MAC == dm_msg->msg.type)) {
 | |
|         app_msg_common_cancel(dm_msg->msg.id, dm_msg->data);
 | |
|     }
 | |
| 
 | |
|     iot_task_free_msg(task_h, &(dm_msg->msg));
 | |
| 
 | |
|     return;
 | |
| }
 | |
| 
 | |
| static uint16_t app_msg_task_init(void)
 | |
| {
 | |
|     app_entity_t *app_entry = NULL;
 | |
| 
 | |
|     app_entry = app_get_main_entry();
 | |
|     app_msg_task_h *msg_task = &(app_entry->msg_task);
 | |
|     iot_task_config_t *t_cfg = &(msg_task->cfg);
 | |
| 
 | |
|     t_cfg->stack_size = 0;
 | |
|     t_cfg->task_prio = APP_MSG_HANDLE_TASK_PRIO;
 | |
|     t_cfg->msg_size = sizeof(app_msg_t);
 | |
|     t_cfg->msg_cnt = APP_MSG_PENDING_LIMIT;
 | |
|     t_cfg->queue_cnt = APP_MSG_TASK_PRIO_QUE;
 | |
|     t_cfg->queue_cfg[0].quota = 0;
 | |
|     t_cfg->task_event_func = app_event_handle;
 | |
|     t_cfg->msg_exe_func = app_msg_handle;
 | |
|     t_cfg->msg_cancel_func = app_msg_cancel;
 | |
| 
 | |
|     msg_task->handle = iot_task_create(IOT_APP_DEMO_MID, t_cfg);
 | |
|     if (NULL == msg_task->handle) {
 | |
|         APP_PRINTF("[ERR] %s Create Task Failed !!", __FUNCTION__);
 | |
|         return ERR_FAIL;
 | |
|     }
 | |
| 
 | |
|     return ERR_OK;
 | |
| }
 | |
| 
 | |
| /* Post the packet from plc-layer to message queue. */
 | |
| static void app_plc_rcv(void *param, iot_pkt_t *pkt)
 | |
| {
 | |
|     (void)param;
 | |
| 
 | |
|     if (false == sync_api_msg_from_mac_handle(pkt)) {
 | |
|         app_post_msg(E_APP_MSG_FROM_MAC, E_CMD_ID_RCV_FROM_PLC, (void *)pkt);
 | |
|     }
 | |
| 
 | |
|     return;
 | |
| }
 | |
| 
 | |
| #if SUPPORT_IEEE_1901
 | |
| static void app_sila_nhm_plc_rcv(void *param, iot_pkt_t *pkt)
 | |
| {
 | |
|     (void)param;
 | |
|     iot_plc_msg_header_t *hdr = (iot_plc_msg_header_t*)iot_pkt_data(pkt);
 | |
| 
 | |
|     if (IOT_PLC_SILA_NHM_ID == hdr->app_id) {
 | |
|         app_post_msg(E_APP_MSG_FROM_MAC, E_CMD_ID_RCV_FROM_PLC, (void *)pkt);
 | |
|     } else {
 | |
|         iot_pkt_free(pkt);
 | |
|     }
 | |
| 
 | |
|     return;
 | |
| }
 | |
| #else
 | |
| #endif /* end SUPPORT_IEEE_1901 */
 | |
| 
 | |
| /* Register an APP to PLC-layer,so we can transmit/receive packet from it. */
 | |
| uint32_t app_plc_reg(void)
 | |
| {
 | |
|     iot_plc_app_t app;
 | |
|     app_entity_t *app_entry = NULL;
 | |
| 
 | |
|     app_entry = app_get_main_entry();
 | |
| 
 | |
| #if SUPPORT_IEEE_1901
 | |
|     /* if support ieee 1901 protocol, we register an extra app handle for non
 | |
|      * header mode.
 | |
|      */
 | |
|     app.app_id = IOT_PLC_SILA_NHM_ID;
 | |
|     app.param   = NULL;
 | |
|     app.prio    = APP_PLC_CMD_PRIO;
 | |
|     app.recv    = app_sila_nhm_plc_rcv;
 | |
| 
 | |
|     app_entry->sila_nhm_hdl = iot_plc_register_app(&app);
 | |
| 
 | |
|     if (NULL == app_entry->sila_nhm_hdl) {
 | |
|         APP_PRINTF("[ERR] REGISTER NHM FAILED !!");
 | |
|         return ERR_FAIL;
 | |
|     }
 | |
|     /* register app handle for cus_at app. */
 | |
|     app.app_id = IOT_PLC_APP_SMART_GRID;
 | |
| #else
 | |
|     app.app_id = IOT_PLC_APP_DEMO_ID;
 | |
| #endif /* end SUPPORT_IEEE_1901 */
 | |
|     app.param   = NULL;
 | |
|     app.prio    = APP_PLC_CMD_PRIO;
 | |
|     app.recv    = app_plc_rcv;
 | |
| 
 | |
|     app_entry->app_hdl = iot_plc_register_app(&app);
 | |
| 
 | |
|     if (NULL == app_entry->app_hdl) {
 | |
|         APP_PRINTF("[ERR] REGISTER APP FAILED !!");
 | |
|         return ERR_FAIL;
 | |
|     }
 | |
| 
 | |
|     return ERR_OK;
 | |
| }
 | |
| 
 | |
| /* set sta scan band */
 | |
| void app_set_sta_scan_band(uint8_t band_id)
 | |
| {
 | |
|     app_entity_t *app_entry = NULL;
 | |
| 
 | |
|     app_entry = app_get_main_entry();
 | |
| 
 | |
|     iot_cus_printf("%s: set scan band to band %d\n", __FUNCTION__, band_id);
 | |
|     uint8_t fb_bitmap[IOT_PLC_BAND_BITMAP_SIZE] = { 0 };
 | |
| 
 | |
|     fb_bitmap[band_id / 8] |= 1 << (band_id % 8);
 | |
| 
 | |
|     iot_plc_set_scan_band_bitmap(app_entry->app_hdl,
 | |
|         IOT_PLC_API_REQ_ID_DEFAULT, fb_bitmap, IOT_PLC_BAND_BITMAP_SIZE);
 | |
| }
 | |
| 
 | |
| void app_band_init(void)
 | |
| {
 | |
|     uint8_t band = 0;
 | |
|     uint8_t fb_bitmap[IOT_PLC_BAND_BITMAP_SIZE] = { 0 };
 | |
|     uint8_t *p_fb_bitmap;
 | |
|     app_entity_t *app_entry = NULL;
 | |
| 
 | |
|     app_entry = app_get_main_entry();
 | |
| 
 | |
|     if (iot_plc_is_client_mode()) {
 | |
|         if (0 == iot_app_get_scan_band_in_pib(&p_fb_bitmap)) {
 | |
|             /* default set sta only scan band 1, freq: 2.4M to 5.6M */
 | |
|             fb_bitmap[APP_DEFAULT_FREQ_BAND / 8] |=
 | |
|                 1 << (APP_DEFAULT_FREQ_BAND % 8);
 | |
|             if (app_entry->user_type == USER_TYPE_SUNSOLAR1) {
 | |
|                 fb_bitmap[PLC_LIB_FREQ_BAND_8 / 8] |=
 | |
|                     1 << (PLC_LIB_FREQ_BAND_8 % 8);
 | |
|             }
 | |
|             iot_plc_set_scan_band_bitmap(app_entry->app_hdl,
 | |
|                 IOT_PLC_API_REQ_ID_DEFAULT, fb_bitmap, IOT_PLC_BAND_BITMAP_SIZE);
 | |
|             iot_app_save_scan_band_to_pib(fb_bitmap, IOT_PLC_BAND_BITMAP_SIZE);
 | |
|         } else {
 | |
|             iot_plc_set_scan_band_bitmap(app_entry->app_hdl,
 | |
|                 IOT_PLC_API_REQ_ID_DEFAULT, p_fb_bitmap,
 | |
|                 IOT_PLC_BAND_BITMAP_SIZE);
 | |
|         }
 | |
|     } else {
 | |
|         /* set frequency band, default set band 1 */
 | |
|         band = iot_app_get_work_band_in_pib();
 | |
|         if (0 == band) {
 | |
|             app_set_freq_band(APP_DEFAULT_FREQ_BAND);
 | |
|             iot_app_save_work_band_to_pib(APP_DEFAULT_FREQ_BAND);
 | |
|         } else {
 | |
|             app_set_freq_band(band - 1);
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| /* Report the basic information of this board. */
 | |
| void app_board_info_report(void)
 | |
| {
 | |
|     uint32_t size;
 | |
|     app_entity_t *app_entry = NULL;
 | |
| 
 | |
|     app_entry = app_get_main_entry();
 | |
| 
 | |
|     size = custom_dev_query_rw_size();
 | |
| 
 | |
|     iot_cus_printf("\r\n************************** INFORMATION ****************"
 | |
|         "*******");
 | |
|     iot_cus_printf("\r\n* This application is designed by Aerospace C.Power");
 | |
|     iot_cus_printf("\r\n* And it's a guide to show how to use PLC-communication"
 | |
|         " module");
 | |
|     iot_cus_printf("\r\n* and periphera devices.");
 | |
|     iot_cus_printf("\r\n* MAC ADDRS : "MAC_FMT, MAC_ARG(app_entry->dev.mac_addr));
 | |
|     iot_cus_printf("\r\n* USER FLASH SIZE : %dbytes.(Size is optional.)", size);
 | |
|     iot_cus_printf("\r\n* FREE MEM SIZE : %dbytes.", os_mem_free_get());
 | |
|     iot_cus_printf("\r\n*******************************************************"
 | |
|         "*******");
 | |
| 
 | |
|     return;
 | |
| }
 | |
| 
 | |
| #if APP_ENABLE_DUMP_PKT_INFO
 | |
| static void app_pkt_info_timer_exe(timer_id_t timer_id, void * arg)
 | |
| {
 | |
|     uint8_t i;
 | |
|     uint32_t bufsz, freenum, totalnum;
 | |
|     (void)arg;
 | |
| 
 | |
|     if (timer_id == pkt_info_timer) {
 | |
|         APP_PRINTF("pkt info:");
 | |
|         for (i = 0; i < 8; i++) {
 | |
|             iot_pkt_pktpool_status(i, &bufsz, &freenum, &totalnum);
 | |
|             if (bufsz == 0) {
 | |
|                 break;
 | |
|             }
 | |
|             iot_cus_printf("pkt size(%4lu) free_n:%2lu total_n:%2lu\n",
 | |
|                 bufsz, freenum, totalnum);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return;
 | |
| }
 | |
| #endif
 | |
| 
 | |
| #if PLC_SUPPORT_CCO_ROLE
 | |
| void app_check_idf(void)
 | |
| {
 | |
|     /* check need auto networking */
 | |
|     APP_PRINTF("IDFSTATUS %d", app_get_idf_status());
 | |
|     if (app_get_idf_status()) {
 | |
|         /* disable whitelist */
 | |
|         iot_plc_cco_set_whitelist_func(IOT_PLC_WL_DISABLE, 0, NULL);
 | |
|         /* clear whitelist */
 | |
|         iot_plc_cco_set_whitelist_func(IOT_PLC_WL_DEL_ALL, 0, NULL);
 | |
|         /* start timer for end group, enable whitelist */
 | |
|         app_timer_start(APP_TIMER_ID_IDF_CHECK,
 | |
|             APP_TIMER_IDF_CHECK_PERIOD, TIMER_TYPE_ONCE);
 | |
|     }
 | |
| }
 | |
| #else
 | |
| void app_check_idf(void)
 | |
| {
 | |
| }
 | |
| #endif
 | |
| 
 | |
| /* alloc outbuf pkt for response */
 | |
| uint8_t app_outbuf_init(void)
 | |
| {
 | |
|     app_entity_t *app_entry = app_get_main_entry();
 | |
|     iot_pkt_t *out_pkt = iot_pkt_alloc(MAX_RSP_DATA_LEN, IOT_APP_DEMO_MID);
 | |
| 
 | |
|     if (out_pkt == NULL) {
 | |
|         APP_PRINTF("[ERR] %s Packet Alloc Failed !!", __FUNCTION__);
 | |
|         return ERR_FAIL;
 | |
|     }
 | |
|     app_entry->out_buf = iot_pkt_put(out_pkt, MAX_RSP_DATA_LEN);
 | |
| 
 | |
|     return ERR_OK;
 | |
| }
 | |
| 
 | |
| uint16_t app_module_init(void)
 | |
| {
 | |
|     uint16_t ret = ERR_FAIL;
 | |
|     app_dev_info *dev;
 | |
|     app_entity_t *app_entry = NULL;
 | |
| 
 | |
|     app_entry = app_get_main_entry();
 | |
|     os_mem_set(app_entry, 0x0, sizeof(*app_entry));
 | |
| 
 | |
|     app_outbuf_init();
 | |
| 
 | |
|     /* Enable the customer-printf(). */
 | |
|     iot_cus_print_config(true);
 | |
|     iot_print_config(ENABLE_PLC_LIB_LOG);
 | |
| 
 | |
|     iot_oem_get_module_mac(app_entry->dev.mac_addr);
 | |
|     app_entry->user_type = iot_oem_get_user_type();
 | |
| 
 | |
|     app_board_info_report();
 | |
| 
 | |
|     APP_PRINTF("\r\n    MODULE INITIALIZING...");
 | |
| 
 | |
|     /* load custom config */
 | |
|     app_load_nv_conf();
 | |
| 
 | |
|     do {
 | |
|         app_entry->app_hdl = NULL;
 | |
|         app_entry->app_reg = false;
 | |
|         app_entry->net_enable = 1;
 | |
| 
 | |
|         dev = &(app_entry->dev);
 | |
| 
 | |
|         dev->link_id    = APP_LINK_ID;
 | |
|         dev->nid        = 1;
 | |
|         dev->rmt_valid  = false;
 | |
|         dev->dev_role   = IOT_PLC_DEV_ROLE_INVALID;
 | |
|         dev->dev_ready  = false;
 | |
| 
 | |
|         APP_PRINTF("    MESSAGE TASK INITIALIZING...");
 | |
|         if (ERR_OK != (ret = app_msg_task_init())) {
 | |
|             APP_PRINTF("[ERR] MSG TASK INIT FAILED !!");
 | |
|             break;
 | |
|         }
 | |
|         APP_PRINTF("    APP REGISTERING...");
 | |
|         if (ERR_OK != (ret = app_plc_reg())) {
 | |
|             APP_PRINTF("[ERR] APP REGISTER FAILED !!");
 | |
|             break;
 | |
|         }
 | |
| 
 | |
|         iot_sync_api_init_app_hdl(app_entry->app_hdl, IOT_APP_DEMO_MID,
 | |
|             app_demo_post_msg_cli);
 | |
| 
 | |
|         /* initialize pib config */
 | |
|         app_pib_conf_init();
 | |
| 
 | |
|         APP_PRINTF("    USER TASK INITIALIZING...");
 | |
|         if (ERR_OK != (ret = app_cus_task_init())) {
 | |
|             APP_PRINTF("[ERR] USER TASK INIT FAILED !!");
 | |
|             break;
 | |
|         }
 | |
| 
 | |
|     #if APP_ENABLE_DUMP_PKT_INFO
 | |
|         pkt_info_timer = os_create_timer(IOT_APP_DEMO_MID, true,
 | |
|             app_pkt_info_timer_exe, NULL);
 | |
|         if (0 == pkt_info_timer) {
 | |
|             iot_cus_printf("[cus_task]create cmd timer failed.\n");
 | |
|             break;
 | |
|         }
 | |
|         os_start_timer(pkt_info_timer, APP_PKT_INFO_TIMER_PERIOD);
 | |
|     #endif
 | |
| 
 | |
|     #if PLC_SUPPORT_STA_ROLE
 | |
|         /* creat and start a timer for signal led show */
 | |
|         if (0 == app_timer_start(APP_TIMER_ID_SIGNAL_LED,
 | |
|             IOT_PLC_SIGNAL_LED_SHOW_INTVAL, TIMER_TYPE_PERIOD)) {
 | |
|             APP_PRINTF("[ERR] CREATE SIGNAL LED TIMER FAILED !!");
 | |
|             break;
 | |
|         }
 | |
|     #endif
 | |
| 
 | |
|     #if PLC_SUPPORT_CCO_ROLE
 | |
|         /* creat and start a timer to check if network done or broadcast data */
 | |
|         if (0 == app_timer_start(APP_TIMER_ID_NET_DONE_CHECK_OR_BCAST,
 | |
|             IOT_PLC_NET_DONE_CHECK_INTVAL, TIMER_TYPE_PERIOD)) {
 | |
|             APP_PRINTF("[ERR] CREATE NET DONE TIMER FAILED !!");
 | |
|             break;
 | |
|         }
 | |
|     #endif
 | |
| 
 | |
| #if (IOT_APP_SELECTION == IOT_APP_DEF_18_AT_APP)
 | |
|         app_work_mode_register(APP_WORK_MODE_BYPASS, app_bypass_data_parse,
 | |
|             app_bypass_data_handle, app_atcmd_onoffline_rsp);
 | |
|         app_work_mode_register(APP_WORK_MODE_AT, app_atcmd_data_parse,
 | |
|             app_atcmd_data_handle, app_atcmd_onoffline_rsp);
 | |
| #endif
 | |
| 
 | |
| #if (IOT_APP_SELECTION == IOT_APP_DEF_25_AT_MICRO_CCTT)
 | |
|         app_work_mode_register(APP_WORK_MODE_AT, app_atcmd_data_parse,
 | |
|             app_atcmd_data_handle, app_atcmd_onoffline_rsp);
 | |
| #endif
 | |
| 
 | |
|         if (iot_plc_is_client_mode()) {
 | |
|             /* close watchdog */
 | |
|             iot_plc_wdg_set(app_entry->app_hdl, 0, 0);
 | |
|         }
 | |
| #if APP_IO_OPERATION_ENABLE
 | |
|         /* gpio initialize */
 | |
|         app_io_init();
 | |
| #endif /* end APP_IO_OPERATION_ENABLE */
 | |
|         /* band initialize */
 | |
|         app_band_init();
 | |
|         /* set work mode */
 | |
| #if (IOT_AT_ONLY == 1)
 | |
|         if (APP_WORK_MODE_AT != app_entry->app_cfg.factory.work_mode &&
 | |
|             APP_WORK_MODE_BYPASS != app_entry->app_cfg.factory.work_mode) {
 | |
|             app_set_work_mode_to_nv(APP_WORK_MODE_AT);
 | |
|         }
 | |
| #endif /* end IOT_AT_ONLY for set mode */
 | |
|         app_set_work_mode(app_get_init_work_mode());
 | |
| 
 | |
| #if (IOT_APP_SELECTION == IOT_APP_DEF_18_AT_APP)
 | |
|         /* AT mode initialize */
 | |
|         app_atcmd_init();
 | |
| #endif
 | |
| 
 | |
| #if PLC_SUPPORT_STA_ROLE
 | |
|         /* load group info */
 | |
|         app_load_group_from_nv();
 | |
|         /* initialize meta information */
 | |
|         iot_meta_init(IOT_APP_DEF_18_AT_APP, IOT_APP_DEMO_MID);
 | |
| #endif
 | |
| 
 | |
|         /* check cco auto grouping */
 | |
|         app_check_idf();
 | |
| 
 | |
|         app_proto_upgrd_contxt_init();
 | |
| 
 | |
| #if (IOT_AT_ONLY == 0)
 | |
|         extern void app_proto_init();
 | |
|         /* sub system initialize */
 | |
|         app_proto_init();
 | |
| #endif /* end IOT_AT_ONLY */
 | |
| 
 | |
|         ret = ERR_OK;
 | |
|     }while(0);
 | |
| 
 | |
|     APP_PRINTF("MODULE INITIALIZED %s.", ret ? "WITH ERROR" : "SUCCESSFULLY");
 | |
| 
 | |
|     return ret;
 | |
| }
 | |
| 
 | |
| uint32_t app_at_entry(void)
 | |
| {
 | |
|     uint32_t ret = ERR_FAIL;
 | |
| 
 | |
|     iot_cus_printf("\r\n APP ENTRY FUNCTIONS-SHOW...\r\n");
 | |
|     ret = app_module_init();
 | |
| 
 | |
|     if (ERR_OK != ret) {
 | |
|         ret = ERR_PENDING;
 | |
|     }
 | |
| 
 | |
|     return ret;
 | |
| }
 | |
| 
 |