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;
|
|
}
|
|
|