/**************************************************************************** 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_task.h" #include "iot_app_meta_api.h" #include "iot_plc_sync_api.h" #include "app_proto_dlt645.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 "app_main_dlt645.h" extern void iot_print_config(uint8_t enable); /* app entry of iot dlt645 app */ static app_entity_t g_iot_dlt645app_entry; /* timer for dump pkt infomation */ static timer_id_t g_pkt_info_timer; /** * @brief iot_main_data_from_plc_handle() - handle network data from plc layer. * @param [in] pkt : pkt with plc network data . * @return None. */ static void iot_main_data_from_plc_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 = iot_main_get_app_entry(); /* Check if this packet belongs to me. */ if ((IOT_PLC_APP_ID_BCAST != hdr->app_id) && (IOT_PLC_APP_DEMO_ID != hdr->app_id)) { 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 (IOT_PLC_DEV_ROLE_STA == rpt->dev_role) { /* Notify Online Event (local) */ iot_cus_task_onoffline_report(rpt->cco_mac, STA_ONLINE_EVENT); } app_entry->dev.dev_ready = true; 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); app_entry->dev.dev_ready = false; if (IOT_PLC_DEV_ROLE_STA == rpt->dev_role) { /* Notify Offline Event (local) */ if (iot_mac_addr_valid(rpt->cco_mac)) { iot_cus_task_onoffline_report(rpt->cco_mac, STA_OFFLINE_EVENT); } else if (iot_mac_addr_valid(app_entry->dev.cco_addr)) { iot_cus_task_onoffline_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); /* Notify Online Event */ iot_cus_task_onoffline_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 */ iot_cus_task_onoffline_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 = (int8_t)msdu->snr; APP_PRINTF("MSDU RECEIVED FROM MAC#"MAC_FMT, MAC_ARG(msdu->src)); iot_check_meta_data(pkt); if (iot_plc_is_client_mode()) { iot_meta_rcd_app_msdu_info(msdu, hdr->msg_id == IOT_PLC_MSG_MSDU_RECV); } if (iot_mac_addr_cmp(msdu->dst, app_entry->dev.mac_addr) || iot_mac_is_bcast(msdu->dst)) { iot_main_task_msg_post(E_MAIN_MSG_FROM_PLCMAC, E_MAIN_MSG_ID_645PKT_RECV, (void*)pkt); /* Packet will not be freed here. */ pkt = NULL; } break; } default : { break; } } if (pkt) { iot_pkt_free(pkt); } return; } /** * @brief iot_main_645pkt_from_plc_handle() - handle 645pkt from plc layer. * @param [in] pkt : pkt with dlt645 frame. * @return None. */ static uint16_t iot_main_645pkt_from_plc_handle(iot_pkt_t *pkt) { iot_plc_msdu_recv_t *msdu; uint16_t ret = ERR_FAIL; uint8_t *frame; uint32_t frame_len = 0; bool_t is_frame = false; app_entity_t *app_entry = NULL; app_custom_data *app_data = NULL; iot_pkt_t *pkt_ack = NULL; app_entry = iot_main_get_app_entry(); app_entry->receivetime = iot_plc_get_ntb(app_entry->app_hdl); msdu = (iot_plc_msdu_recv_t*)(iot_pkt_data(pkt) + sizeof(iot_plc_msg_header_t)); APP_PRINTF("msdu->len=%d pkt_len=%d", msdu->len, iot_pkt_data_len(pkt)); app_data = (app_custom_data*)msdu->data; frame = (uint8_t *)(app_data + 1); frame_len = msdu->len - sizeof(app_custom_data); APP_PRINT_BUF("[INF] BINARY DATA FROM PLC: ", frame, frame_len); APP_PRINTF("plc_id = %x ",app_data->id); /* data format check, only 645 frames are supported. */ proto_645_check_frame_handler(frame, frame_len, &is_frame); if (!is_frame) { ret = ERR_FAIL; goto out; } ret = app_dlt645_local_handle(APP_TASK_MAIN, (proto_645_header_t *)frame, frame_len, &pkt_ack); if (ERR_OK == ret) { /* ack frame, send back to plc. */ app_plc_tx(iot_pkt_data(pkt_ack), iot_pkt_data_len(pkt_ack), msdu->src, ID_PLC_DLT645_DATA, NULL); iot_pkt_free(pkt_ack); goto out; } else { /* unhandled frame, send to customer task. */ iot_pkt_pull(pkt, (size_t)(frame - iot_pkt_data(pkt))); iot_cus_task_msg_post(E_CUS_MSG_FROM_MAINTASK, E_CUS_MSG_ID_645PKT_RECV, pkt); return ERR_OK; } out: iot_pkt_free(pkt); return ret; } /** * @brief iot_main_msg_from_plcmac_handle() - handle message from plc layer. * @param [in] id : message id. * @param [in] data : message data. * @return None. */ static void iot_main_msg_from_plcmac_handle(uint16_t id, void *data) { iot_pkt_t *pkt = (iot_pkt_t *)data; if ((NULL == pkt) || (0 == iot_pkt_data_len(pkt))) { APP_PRINTF("[ERR] %s Packet is NULL !!", __FUNCTION__); return; } switch (id) { /* main task receive data from plc layer */ case E_MAIN_MSG_ID_PLCMAC_RECV: { iot_main_data_from_plc_handle(pkt); break; } /* main task receive dlt645 frame form plc layer */ case E_MAIN_MSG_ID_645PKT_RECV: { iot_main_645pkt_from_plc_handle(pkt); break; } default: { iot_pkt_free(pkt); break; } } return; } /** * @brief iot_main_645pkt_from_custask_handle() - handle 645pkt from customer task. * @param [in] pkt : pkt with dlt645 frame. * @return None. */ static void iot_main_645pkt_from_custask_handle(iot_pkt_t *pkt) { uint32_t ret = ERR_FAIL; iot_pkt_t *pkt_ack = NULL; proto_645_header_t *frame = (proto_645_header_t *)iot_pkt_data(pkt); uint16_t frame_len = iot_pkt_data_len(pkt); uint8_t dst_addr[IOT_MAC_ADDR_LEN] = {0}; ret = app_dlt645_local_handle(APP_TASK_MAIN, frame, frame_len, &pkt_ack); if (ERR_OK == ret) { /* ack frame, send back to customer task. */ iot_cus_task_msg_post(E_CUS_MSG_FROM_MAINTASK, E_CUS_MSG_ID_645PKT_RECV, pkt_ack); } else { /* unhandled frame, send to plc. */ if (iot_plc_is_client_mode()) { iot_mac_addr_cpy(dst_addr, app_get_cco_mac_addr()); iot_mac_addr_reverse(dst_addr); } else { iot_mac_addr_cpy(dst_addr, frame->addr); } app_plc_tx(iot_pkt_data(pkt), iot_pkt_data_len(pkt), dst_addr, ID_PLC_DLT645_DATA, NULL); } iot_pkt_free(pkt); } /** * @brief iot_main_msg_from_custask_handle() - handle message from customer task. * @param [in] id : message id. * @param [in] data : message data. * @return None. */ static void iot_main_msg_from_custask_handle(uint16_t id, void *data) { iot_pkt_t *pkt = (iot_pkt_t *)data; if ((NULL == pkt) || (0 == iot_pkt_data_len(pkt))) { APP_PRINTF("[ERR] %s Packet is NULL !!", __FUNCTION__); return; } switch (id) { /* main task receive dlt645 frame form customer task */ case E_MAIN_MSG_ID_645PKT_RECV: { iot_main_645pkt_from_custask_handle(pkt); break; } default: { iot_pkt_free(pkt); break; } } return; } /** * @brief iot_main_645pkt_from_custask_handle() - handle 645pkt send to plc. * @param [in] pkt : pkt with dlt645 frame. * @return None. */ static void iot_main_send_plc_pkt_handle(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; app_entry = iot_main_get_app_entry(); app_handle = app_entry->app_hdl; data_len = iot_pkt_data_len(pkt) - sizeof(append_tx_info_t); 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_connless) { /* custom force send connless */ is_connless = 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; } } if (!is_bcast) { msg_type = IOT_PLC_MSG_TYPE_UNICAST; } 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; } 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, 0); } else { 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, 0); } 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); os_mem_cpy(ptr, app_data, data_len); 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); } /** * @brief iot_main_msg_from_maintask_handle() - handle message from main task. * @param [in] id : message id. * @param [in] data : message data. * @return None. */ static void iot_main_msg_from_maintask_handle(uint16_t id, void *data) { iot_pkt_t *pkt = (iot_pkt_t *)data; if ((NULL == pkt) || ((0 == iot_pkt_data_len(pkt)) && (E_MAIN_MSG_ID_CLIAPP_RECV != id))) { APP_PRINTF("[ERR] %s Packet is NULL !!", __FUNCTION__); return; } switch (id) { /* main task receive data from cli app*/ case E_MAIN_MSG_ID_CLIAPP_RECV: { iot_app_handle_cli_msg(pkt); break; } /* main task send dlt645 frame to plc layer */ case E_MAIN_MSG_ID_645PKT_TO_PLC: { iot_main_send_plc_pkt_handle(pkt); break; } default: { iot_pkt_free(pkt); break; } } return; } /** * @brief iot_main_sta_signal_led_timer_handle() - STA handle signal led timer * @param None. * @return None. */ static void iot_main_sta_signal_led_timer_handle(void) { app_entity_t *app_entry = NULL; app_entry = iot_main_get_app_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; } /** * @brief iot_main_cco_net_done_check_handle() - CCO handle net done check * @param None. * @return None. */ static void iot_main_cco_net_done_check_handle(void) { uint8_t wl_state; uint16_t topo_num; uint16_t wl_cnt; iot_plc_topo_info *topo = NULL; app_entity_t *app_entry = NULL; app_entry = iot_main_get_app_entry(); /* check and change cco network done state */ if (IOT_PLC_DEV_ROLE_CCO == app_entry->dev.dev_role) { 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 iot_main_msg_from_timer_handle() - handle message from timer. * @param [in] id : message id. * @param [in] data : message data. * @return None. */ static void iot_main_msg_from_timer_handle(app_timer_id_e id, void *data) { app_entity_t *app_entry = NULL; app_entry = iot_main_get_app_entry(); switch (id) { /* app timer for reboot local device. */ case APP_TIMER_ID_REBOOT: iot_system_restart(IOT_SYS_RST_REASON_APP_REQ); break; /* app timer for set mac address. */ case APP_TIMER_ID_SET_MAC: app_set_mac_addr(app_entry->dev.mac_addr); break; /* app timer for signal led show. */ case APP_TIMER_ID_SIGNAL_LED: iot_main_sta_signal_led_timer_handle(); break; /* app timer for check if network done. */ case APP_TIMER_ID_NET_DONE_CHECK: iot_main_cco_net_done_check_handle(); break; default: break; } } /** * @brief iot_main_event_handle() - handle task event. * @param [in] task_h : iot task handle, not used. * @param [in] event : task event. * @return None. */ static void iot_main_event_handle(iot_task_h task_h, uint32_t event) { (void)task_h; (void)event; APP_PRINTF("[INF] %s", __FUNCTION__); return; } /** * @brief iot_main_msg_handle() - handle message by type. * @param [in] task_h : iot task handle, not used. * @param [in] msg : message. * @return None. */ static void iot_main_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_MAIN_MSG_VALID(dm_msg->msg.type))) { /* Maybe this can cause memory overflow! */ APP_PRINTF("[ERR] %s Invalid MSG !!", __FUNCTION__); return; } switch (dm_msg->msg.type) { case E_MAIN_MSG_FROM_PLCMAC: { iot_main_msg_from_plcmac_handle(dm_msg->msg.id, dm_msg->data); break; } case E_MAIN_MSG_FROM_CUSTASK: { iot_main_msg_from_custask_handle(dm_msg->msg.id, dm_msg->data); break; } case E_MAIN_MSG_FROM_MAINTASK: { iot_main_msg_from_maintask_handle(dm_msg->msg.id, dm_msg->data); break; } case E_MAIN_MSG_FROM_TIMER: { iot_main_msg_from_timer_handle(dm_msg->msg.id, dm_msg->data); break; } default: break; } iot_task_free_msg(task_h, &(dm_msg->msg)); return; } /** * @brief iot_main_msg_cancel() - handle message canceling. * @param [in] task_h : iot task handle, not used. * @param [in] msg : message. * @return None. */ static void iot_main_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_MAIN_MSG_VALID(dm_msg->msg.type))) { /* Maybe this can cause memory overflow! */ APP_PRINTF("[ERR] CANCEL AN INVALID MSG !!"); return; } if ( (E_MAIN_MSG_FROM_PLCMAC == dm_msg->msg.type) || (E_MAIN_MSG_FROM_MAINTASK == dm_msg->msg.type) || (E_MAIN_MSG_FROM_CUSTASK == dm_msg->msg.type) || (E_MAIN_MSG_FROM_TIMER == dm_msg->msg.type)) { iot_pkt_t *pkt = (iot_pkt_t *)dm_msg->data; if (pkt) { iot_pkt_free(pkt); } } iot_task_free_msg(task_h, &(dm_msg->msg)); return; } /** * @brief iot_main_task_init() - Initialize main task. * @param None. * @return ERR_OK : Initialize done; * @return ERR_FAIL : Initialize failed; */ static uint32_t iot_main_task_init(void) { app_entity_t *app_entry = NULL; app_entry = iot_main_get_app_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 = iot_main_event_handle; t_cfg->msg_exe_func = iot_main_msg_handle; t_cfg->msg_cancel_func = iot_main_msg_cancel; msg_task->handle = iot_task_create(IOT_APP_DL645_MID, t_cfg); if (NULL == msg_task->handle) { APP_PRINTF("[ERR] %s Create Task Failed !!", __FUNCTION__); return ERR_FAIL; } return ERR_OK; } /** * @brief iot_main_cli_msg_callback() - handle data from cli. * @param [in] data: cli data. * @return ERR_OK : handle done; */ static uint32_t iot_main_cli_msg_callback(void *data) { iot_main_task_msg_post(E_MAIN_MSG_FROM_MAINTASK, E_MAIN_MSG_ID_CLIAPP_RECV, data); return ERR_OK; } /** * @brief iot_main_plc_recv_callback() - handle data from plc layer. * @param [in] param: not used. * @param [in] pkt: pkt with plc data. * @return None; */ static void iot_main_plc_recv_callback(void *param, iot_pkt_t *pkt) { (void)param; if (false == sync_api_msg_from_mac_handle(pkt)) { iot_main_task_msg_post(E_MAIN_MSG_FROM_PLCMAC, E_MAIN_MSG_ID_PLCMAC_RECV, (void *)pkt); } return; } /** * @brief iot_main_app_plc_reg() - register this app to plc layer, * so we can transmit or receive packet from it * @param None. * @return ERR_OK : register done; * @return ERR_FAIL : register failed; */ static uint32_t iot_main_app_plc_reg(void) { iot_plc_app_t app; app_entity_t *app_entry = NULL; app_entry = iot_main_get_app_entry(); app.app_id = IOT_PLC_APP_DEMO_ID; app.param = NULL; app.prio = APP_PLC_CMD_PRIO; app.recv = iot_main_plc_recv_callback; 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; } /** * @brief iot_main_band_init() - app band set up. * @param None. * @return None. */ static void iot_main_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 = iot_main_get_app_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); 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); } } /* 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); } } /** * @brief iot_main_board_info_report() - Report basic information of this board. * @param None. * @return None. */ static void iot_main_board_info_report(void) { uint32_t size; iot_oem_base_cfg_t * oem_cfg; app_entity_t *app_entry = NULL; app_entry = iot_main_get_app_entry(); size = custom_dev_query_rw_size(); (void)iot_oem_get_base_cfg(&oem_cfg); 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(oem_cfg->module_mac)); 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*******************************************************" "*******"); /* Init Local MAC */ os_mem_cpy(app_entry->dev.mac_addr, oem_cfg->module_mac, IOT_MAC_ADDR_LEN); return; } #if APP_ENABLE_DUMP_PKT_INFO /** * @brief iot_main_pkt_info_timer_callback() - timer callback for pkt inf dump. * @param [in] timer_id: timer id. * @param [in] arg: not used. * @return None. */ static void iot_main_pkt_info_timer_callback(timer_id_t timer_id, void * arg) { uint8_t i; uint32_t bufsz, freenum, totalnum; (void)arg; if (timer_id == g_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 /** * @brief iot_main_module_init() - Initialize dlt645 app resource. * @param None. * @return ERR_OK : register done; * @return ERR_FAIL : register failed; */ static uint32_t iot_main_module_init(void) { uint16_t ret = ERR_FAIL; app_dev_info *dev; app_entity_t *app_entry = NULL; app_entry = iot_main_get_app_entry(); os_mem_set(app_entry, 0x0, sizeof(*app_entry)); /* Enable the customer-printf(). */ iot_cus_print_config(true); iot_print_config(ENABLE_PLC_LIB_LOG); iot_main_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; dev = &(app_entry->dev); dev->link_id = APP_LINK_ID; dev->nid = 1; dev->dev_role = IOT_PLC_DEV_ROLE_INVALID; dev->dev_ready = false; APP_PRINTF(" MESSAGE TASK INITIALIZING..."); if (ERR_OK != (ret = iot_main_task_init())) { APP_PRINTF("[ERR] MSG TASK INIT FAILED !!"); break; } APP_PRINTF(" DLT645 APP REGISTERING..."); if (ERR_OK != (ret = iot_main_app_plc_reg())) { APP_PRINTF("[ERR] APP REGISTER FAILED !!"); break; } iot_sync_api_init_app_hdl(app_entry->app_hdl, IOT_APP_DL645_MID, iot_main_cli_msg_callback); /* initialize pib config */ app_pib_conf_init(); /* sub system initialize */ app_dlt645_init(); iot_main_dlt645_local_handle_register(); APP_PRINTF(" USER TASK INITIALIZING..."); if (ERR_OK != (ret = iot_cus_task_init())) { APP_PRINTF("[ERR] USER TASK INIT FAILED !!"); break; } #if APP_ENABLE_DUMP_PKT_INFO g_pkt_info_timer = os_create_timer(IOT_APP_DL645_MID, true, iot_main_pkt_info_timer_callback, NULL); if (0 == g_pkt_info_timer) { iot_cus_printf("[cus_task]create cmd timer failed.\n"); break; } os_start_timer(g_pkt_info_timer, APP_PKT_INFO_TIMER_PERIOD); #endif if (iot_plc_is_client_mode()) { /* 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; } } else { /* creat and start a timer to check if network done */ if (0 == app_timer_start(APP_TIMER_ID_NET_DONE_CHECK, IOT_PLC_NET_DONE_CHECK_INTVAL, TIMER_TYPE_PERIOD)) { APP_PRINTF("[ERR] CREATE NET DONE TIMER FAILED !!"); break; } } if (iot_plc_is_client_mode()) { /* close watchdog */ iot_plc_wdg_set(app_entry->app_hdl, 0, 0); } /* band initialize */ iot_main_band_init(); if (iot_plc_is_client_mode()) { /* initialize meta information */ iot_meta_init(IOT_APP_SELECTION, IOT_APP_DL645_MID); } /* todo: add upgrade */ // app_proto_upgrd_contxt_init(); ret = ERR_OK; }while(0); APP_PRINTF("MODULE INITIALIZED %s.", ret ? "WITH ERROR" : "SUCCESSFULLY"); return ret; } uint32_t iot_main_task_msg_post(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 = iot_main_get_app_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; } inline app_entity_t *iot_main_get_app_entry(void) { return &g_iot_dlt645app_entry; } uint32_t app_iot_dl645_entry(void) { uint32_t ret = ERR_FAIL; iot_cus_printf("\r\n APP ENTRY IOT_DLT645...\r\n"); ret = iot_main_module_init(); if (ERR_OK != ret) { ret = ERR_PENDING; } return ret; }