1066 lines
32 KiB
C
1066 lines
32 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_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;
|
|
}
|