Files
kunlun/app/ping/iot_ping.c
2024-09-28 14:24:04 +08:00

635 lines
22 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.
****************************************************************************/
/* os_ship header files */
#include "os_task_api.h"
#include "os_event_api.h"
#include "os_timer_api.h"
#include "os_utils_api.h"
/* iot common header files */
#include "iot_plc_cco_api.h"
#include "iot_module_api.h"
#include "iot_queue_api.h"
#include "iot_mem_pool_api.h"
#include "iot_config_api.h"
#include "iot_app_api.h"
#include "iot_errno_api.h"
#include "iot_io_api.h"
#include "iot_dbglog_api.h"
#include "iot_ntoh_api.h"
#include "iot_ping.h"
#include "iot_ip_ping.h"
#if IOT_PING_APP_ENABLE
#define PING_PAYLOAD_SIZE 900
#if IOT_LWIP_SUPPORT
#define IOT_PING_IPV4_STA 1
#define IOT_PING_IPV6_STA (!IOT_PING_IPV4_STA && LWIP_IPV6)
#define IOT_PING_IPV4_CCO 1
#define IOT_PING_IPV6_CCO (!IOT_PING_IPV4_CCO && LWIP_IPV6)
#if LWIP_IPV6
static void iot_ping_gen_ip6_addr(ip_addr_t *ip_addr, uint8_t *mac_addr)
{
ip_2_ip6(ip_addr)->addr[0] = iot_htonl(0xfe800000ul);
ip_2_ip6(ip_addr)->addr[1] = 0;
ip_2_ip6(ip_addr)->addr[2] =
iot_htonl((((uint32_t)(mac_addr[0] ^ 0x02)) << 24)
| ((uint32_t)(mac_addr[1]) << 16)
| ((uint32_t)(mac_addr[2]) << 8)
| (0xff));
ip_2_ip6(ip_addr)->addr[3] = iot_htonl((0xfeul << 24)
| ((uint32_t)(mac_addr[3]) << 16)
| ((uint32_t)(mac_addr[4]) << 8)
| (mac_addr[5]));
IP_SET_TYPE(ip_addr, IPADDR_TYPE_V6);
}
#endif
#else /* IOT_LWIP_SUPPORT */
#define IOT_PING_IPV4_STA 0
#define IOT_PING_IPV6_STA 0
#define IOT_PING_IPV4_CCO 0
#define IOT_PING_IPV6_CCO 0
#endif /* IOT_LWIP_SUPPORT */
static iot_ping_task_data_t *ping_task_data = NULL;
void iot_ping_post_msg(uint32_t prio, uint16_t msg_type,
uint16_t msg_id, void* data1,
uint32_t data2)
{
iot_task_msg_t *msg;
iot_ping_task_msg_t *task_msg;
msg = iot_task_alloc_msg_with_reserved(ping_task_data->task_handle, 0);
if (!msg) {
iot_printf("%s, no msg\n", __FUNCTION__);
return;
}
task_msg = (iot_ping_task_msg_t*)msg;
task_msg->msg.type = msg_type;
task_msg->msg.id = msg_id;
task_msg->data = data1;
task_msg->data2 = data2;
iot_task_queue_msg(ping_task_data->task_handle,
&task_msg->msg, (uint8_t)prio);
}
void iot_plc_ping_post_msg(uint16_t msg_type, uint16_t msg_id)
{
iot_ping_post_msg(IOT_PING_TASK_QUEUE_LP, msg_type, msg_id, NULL, 0);
}
/* ping_timer_func() - timer function for ping
* it triggers a topo query periodically
* @timer_id: id of the timer
* @arg: argument pass back to the callback function
*/
void ping_timer_func(timer_id_t timer_id, void * arg)
{
(void)timer_id;
iot_ping_task_data_t *task_data = (iot_ping_task_data_t*)arg;
if (task_data->dev_ready) {
if (task_data->dev_role == IOT_PLC_DEV_ROLE_CCO) {
++task_data->set_nid_count;
if (task_data->set_nid_count < IOT_PING_SET_NID_CNT_LIMIT) {
iot_plc_ping_post_msg(IOT_PING_TIMER_MSG,
IOT_TIMER_QUERY_NB_NW);
iot_plc_ping_post_msg(IOT_PING_TIMER_MSG,
IOT_TIMER_QUERY_NID);
iot_plc_ping_post_msg(IOT_PING_TIMER_MSG,
IOT_TIMER_QUERY_NW_TOPO);
} else {
task_data->set_nid_count = 0;
// disable setting nid to avoid network reset
iot_printf("%s: set_nid disabled\n", __FUNCTION__);
//iot_printf("%s: set_nid to 0n%d\n", __FUNCTION__, nid);
//iot_plc_ping_post_msg(IOT_PING_TIMER_MSG,
// IOT_TIMER_SET_NID, nid);
++task_data->nid;
}
} else if (task_data->dev_role == IOT_PLC_DEV_ROLE_INVALID) {
iot_printf("%s: query_dev_info\n", __FUNCTION__);
iot_plc_ping_post_msg(IOT_PING_TIMER_MSG,
IOT_TIMER_QUERY_DEV_INTO);
} else {
os_stop_timer(timer_id);
}
}
}
/* iot_plc_recv_ping() - callback method to receive packet from app
* @param: param from app
* @pkt: iot_pkt_t from app containing the request
*/
void iot_plc_recv_ping(void *param, iot_pkt_t *pkt)
{
(void)param;
iot_ping_post_msg((uint8_t)IOT_PING_TASK_QUEUE_LP,
IOT_PING_MAC_MSG, 0, pkt, 0);
}
void iot_plc_ping_handle_timer_msg(iot_ping_task_msg_t* task_msg)
{
switch (task_msg->msg.id) {
case IOT_TIMER_QUERY_DEV_INTO:
{
iot_plc_query_dev_info(ping_task_data->app_handle,
IOT_PLC_API_REQ_ID_DEFAULT);
break;
}
case IOT_TIMER_QUERY_NB_NW:
{
iot_plc_query_nb_nw_info(ping_task_data->app_handle,
IOT_PLC_API_REQ_ID_DEFAULT);
break;
}
case IOT_TIMER_QUERY_NID:
{
iot_plc_query_nid(ping_task_data->app_handle,
IOT_PLC_API_REQ_ID_DEFAULT);
break;
}
case IOT_TIMER_QUERY_NW_TOPO:
{
iot_plc_query_nw_topo(ping_task_data->app_handle,
IOT_PLC_API_REQ_ID_DEFAULT,
IOT_PLC_CCO_TOPO_REQ_DATA_VER_V0,
IOT_PLC_QUERY_TOPO_START_AS_TEI, 1, 5);
break;
}
case IOT_TIMER_SET_NID:
{
iot_plc_set_nid(ping_task_data->app_handle, IOT_PLC_API_REQ_ID_DEFAULT,
task_msg->data2);
break;
}
default:
break;
}
}
void iot_plc_ping_handle_mac_msg(iot_pkt_t *pkt)
{
iot_plc_msg_header_t *hdr =
(iot_plc_msg_header_t*)iot_pkt_block_ptr(pkt, IOT_PKT_BLOCK_DATA);
if (hdr->app_id != IOT_PLC_APP_ID_BCAST &&
hdr->app_id != IOT_PING_APP_ID) {
// drop corrupted message
iot_pkt_free(pkt);
return;
}
if (ping_task_data->app_registered == 0 &&
hdr->msg_id != IOT_PLC_MSG_APP_REG_CONF) {
// only handle app register confirm message before app registered
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 (rpt->result == IOT_PLC_SUCCESS ||
rpt->result == IOT_PLC_SUCCESS_MODIFIED) {
ping_task_data->app_registered = 1;
}
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);
ping_task_data->dev_role = rpt->dev_role;
if (!ping_task_data->dev_ready && rpt->is_ready) {
/* dev becomes available to serve app request */
iot_printf("%s: MAC layer is ready!\n", __FUNCTION__);
iot_printf("%s:nid=%lu, cco mac=%02X:%02X:%02X:%02X:%02X:%02X\n",
__FUNCTION__, rpt->nid,
rpt->cco_mac[0], rpt->cco_mac[1],
rpt->cco_mac[2], rpt->cco_mac[3],
rpt->cco_mac[4], rpt->cco_mac[5]);
ping_task_data->dev_ready = rpt->is_ready;
iot_mac_addr_cpy(ping_task_data->mac_addr, rpt->local_mac);
if (ping_task_data->dev_role == IOT_PLC_DEV_ROLE_CCO) {
os_start_timer(ping_task_data->ping_timer,
IOT_PING_CHECK_TOPO_INTERVAL);
} else {
#if IOT_PING_IPV4_STA
if (!ping_task_data->ipv4_ping_start) {
static ip_addr_t ipv4_cco_addr;
IP_ADDR4(&ipv4_cco_addr, 10, 0, 0, 1);
ping_init(&ipv4_cco_addr);
ping_task_data->ipv4_ping_start = 1;
}
#endif /* IOT_PING_IPV4_STA */
#if IOT_PING_IPV6_STA
if (!ping_task_data->ipv6_ping_start) {
static ip_addr_t ipv6_cco_addr;
iot_ping_gen_ip6_addr(&ipv6_cco_addr, rpt->cco_mac);
ping_init(&ipv6_cco_addr);
ping_task_data->ipv6_ping_start = 1;
}
#endif /* IOT_PING_IPV6_STA */
}
} else if (ping_task_data->dev_ready && !rpt->is_ready) {
/* dev becomes unavailable. It cannot serve app request */
iot_printf("%s: MAC layer is NOT ready!\n", __FUNCTION__);
ping_task_data->dev_ready = rpt->is_ready;
os_stop_timer(ping_task_data->ping_timer);
}
break;
}
case IOT_PLC_MSG_DEV_INFO_RPT:
{
iot_plc_dev_info_rpt_t* rpt = (iot_plc_dev_info_rpt_t*)(hdr + 1);
ping_task_data->dev_role = rpt->dev_role;
iot_mac_addr_cpy(ping_task_data->mac_addr, rpt->local_mac);
ping_task_data->dev_ready = rpt->is_ready;
if (ping_task_data->dev_ready) {
iot_printf("%s: MAC layer is ready.\n", __FUNCTION__);
} else {
iot_printf("%s: MAC layer is NOT ready!\n", __FUNCTION__);
}
break;
}
case IOT_PLC_MSG_STA_JOIN_INFO:
{
iot_plc_sta_join_info_t* rpt = (iot_plc_sta_join_info_t*)(hdr + 1);
iot_printf("%s: %d sta_joined. proxy = 0n%d: \
mac=%02X:%02X:%02X:%02X:%02X:%02X. dev_type=%d. \
physical phase[1-3]=%d.%d.%d. \
software version=%X\n",
__FUNCTION__, rpt->sta_info.sta_tei, rpt->sta_info.proxy_tei,
rpt->sta_info.addr[0], rpt->sta_info.addr[1],
rpt->sta_info.addr[2], rpt->sta_info.addr[3],
rpt->sta_info.addr[4], rpt->sta_info.addr[5],
rpt->sta_info.dev_type, rpt->sta_info.logic_phase1,
rpt->sta_info.logic_phase2, rpt->sta_info.logic_phase3,
rpt->sta_info.sw_ver);
#if IOT_PING_IPV4_CCO
if (!ping_task_data->ipv4_ping_start) {
static ip_addr_t ipv4_sta_addr;
uint32_t tmp;
IP_ADDR4(&ipv4_sta_addr, 10, 0, 0, 0);
tmp = ip_addr_get_ip4_u32(&ipv4_sta_addr);
tmp = iot_ntohl(tmp);
tmp &= 0xFFFF0000;
tmp += rpt->sta_info.sta_tei;
tmp = iot_htonl(tmp);
ip_addr_set_ip4_u32(&ipv4_sta_addr, tmp);
ping_init(&ipv4_sta_addr);
ping_task_data->ipv4_ping_start = 1;
}
#endif /* IOT_PING_IPV4_CCO */
#if IOT_PING_IPV6_CCO
if (!ping_task_data->ipv6_ping_start) {
static ip_addr_t ipv6_sta_addr;
iot_ping_gen_ip6_addr(&ipv6_sta_addr, rpt->sta_info.addr);
ping_init(&ipv6_sta_addr);
ping_task_data->ipv6_ping_start = 1;
}
#endif /* IOT_PING_IPV6_CCO */
break;
}
case IOT_PLC_MSG_STA_LEAVE_INFO:
{
iot_plc_sta_leave_info_t* rpt = (iot_plc_sta_leave_info_t*)(hdr + 1);
iot_printf("%s: STA_LEAVE_INFO. sta_count = %d\n",
__FUNCTION__, rpt->sta_count);
for (uint8_t i = 0; i < rpt->sta_count; ++i) {
iot_printf("%s: %d sta_leave[%d]. proxy = 0n%d: \
mac=%02X:%02X:%02X:%02X:%02X:%02X\n",
__FUNCTION__, rpt->sta[i].tei, i, rpt->sta[i].proxy,
rpt->sta[i].mac_addr[0], rpt->sta[i].mac_addr[1],
rpt->sta[i].mac_addr[2], rpt->sta[i].mac_addr[3],
rpt->sta[i].mac_addr[4], rpt->sta[i].mac_addr[5]);
}
break;
}
case IOT_PLC_MSG_MSDU_RECV:
{
iot_plc_msdu_recv_t *msdu = (iot_plc_msdu_recv_t*)(hdr + 1);
iot_printf("%s:recv_msdu: %d[%02X] mac:[%2X:%2X:%2X:%2X:%2X:%2X]\n",
__FUNCTION__, msdu->data[0], msdu->data[0],
msdu->src[0], msdu->src[1], msdu->src[2],
msdu->src[3], msdu->src[4], msdu->src[5]);
iot_dbglog_input(IOT_APP_PING_MID, DBGLOG_INFO_LVL_2,
IOT_PING_RECV_MSDU, 8, msdu->data[0], msdu->data[0],
msdu->src[0], msdu->src[1], msdu->src[2],
msdu->src[3], msdu->src[4], msdu->src[5]);
if (!ping_task_data->dev_ready) {
/* if dev is not ready, don't handle the MSDU */
break;
}
if (ping_task_data->dev_role == IOT_PLC_DEV_ROLE_STA ||
ping_task_data->dev_role == IOT_PLC_DEV_ROLE_PCO) {
iot_pkt_t*msdu_pkt;
uint8_t* ptr;
uint32_t wait_time = 500 + os_rand() % 1000;
os_delay(wait_time);
// STA shall send ack to ping, reverse src and dest.
msdu_pkt = iot_plc_alloc_msdu(ping_task_data->app_handle,
IOT_PLC_MSG_TYPE_UNICAST, IOT_PLC_ACK_TYPE_NONE, msdu->src,
ping_task_data->mac_addr, ping_task_data->link_id,
PING_PAYLOAD_SIZE, IOT_PLC_LOCAL_RETRY_CNT);
ptr = iot_pkt_block_ptr(msdu_pkt, IOT_PKT_BLOCK_TAIL);
*ptr = ping_task_data->mac_addr[5]; // reply the last mac byte
iot_pkt_put(msdu_pkt, 1);
iot_plc_send_msdu(ping_task_data->app_handle, msdu_pkt);
iot_printf("%s: STA [%2X:%2X:%2X:%2X:%2X:%2X] send ping ack\n",
__FUNCTION__, ping_task_data->mac_addr[0],
ping_task_data->mac_addr[1], ping_task_data->mac_addr[2],
ping_task_data->mac_addr[3], ping_task_data->mac_addr[4],
ping_task_data->mac_addr[5]);
iot_dbglog_input(IOT_APP_PING_MID, DBGLOG_INFO_LVL_2,
IOT_PING_SEND_ACK, 6, ping_task_data->mac_addr[0],
ping_task_data->mac_addr[1], ping_task_data->mac_addr[2],
ping_task_data->mac_addr[3], ping_task_data->mac_addr[4],
ping_task_data->mac_addr[5]);
}
break;
}
case IOT_PLC_MSG_NW_ID_RPT:
{
iot_plc_nid_rpt_t *rpt = (iot_plc_nid_rpt_t*)(hdr + 1);
iot_printf("%s:query nid reply:[0x%06X]\n", __FUNCTION__, rpt->nid);
break;
}
case IOT_PLC_MSG_LID_CONF:
{
iot_plc_lid_alloc_conf_t *cfm = (iot_plc_lid_alloc_conf_t*)(hdr + 1);
iot_printf("%s:lid alloc:result = %d, lid=%d\n", __FUNCTION__,
cfm->result, cfm->lid);
break;
}
case IOT_PLC_MSG_NW_NEIGHBOR_RPT:
{
iot_plc_nb_nw_rpt_t *rpt = (iot_plc_nb_nw_rpt_t*)(hdr + 1);
iot_printf("%s: nbnw reply:======================\n", __FUNCTION__);
iot_printf("%s: nbnw reply:count = %d\n", __FUNCTION__, rpt->count);
for (int i = 0; i < rpt->count; ++i) {
iot_printf("%s: nbnw reply:nid[%d], sp_flag = %d, bd = %d\n",
__FUNCTION__, rpt->nb_info[i].nid,
rpt->nb_info[i].sp_flag,
rpt->nb_info[i].bandwidth);
}
iot_printf("%s: nbnw reply:----------------------\n", __FUNCTION__);
break;
}
case IOT_PLC_MSG_NW_WL_RPT:
{
iot_plc_wl_rpt_t *rpt = (iot_plc_wl_rpt_t*)(hdr + 1);
iot_printf("%s: wl reply:========================\n", __FUNCTION__);
iot_printf("%s: wl reply:total = %d, count = %d, done = %d\n",
__FUNCTION__, rpt->total_count, rpt->count, rpt->done);
for (int i = 0; i < rpt->count; ++i) {
iot_printf("%s: wl reply:mac=%02X:%02X:%02X:%02X:%02X:%02X\n",
__FUNCTION__, rpt->mac_addr[i][0], rpt->mac_addr[i][1],
rpt->mac_addr[i][2], rpt->mac_addr[i][3],
rpt->mac_addr[i][4], rpt->mac_addr[i][5]);
}
iot_printf("%s: wl reply:------------------------\n", __FUNCTION__);
if (rpt->done) {
ping_task_data->wl_entry_index = 1;
} else {
ping_task_data->wl_entry_index += rpt->count;
iot_plc_query_whitelist(ping_task_data->app_handle,
IOT_PLC_API_REQ_ID_DEFAULT, ping_task_data->wl_entry_index,
(uint16_t)12);
}
break;
}
case IOT_PLC_MSG_NW_TOPO_RPT:
{
iot_printf("%s: topo reply:======================\n", __FUNCTION__);
if (hdr->req_id == IOT_PLC_API_REQ_ID_DEFAULT) {
iot_plc_nw_topo_rpt_t* rpt = (iot_plc_nw_topo_rpt_t*)(hdr + 1);
iot_plc_node_info_v0_t *node = (iot_plc_node_info_v0_t *)rpt->data;
for (uint32_t i = 0; i < rpt->count; ++i) {
iot_printf("%s: 0n%d mac=[%02X:%02X:%02X:%02X:%02X:%02X], \
proxy:0n%d\n", __FUNCTION__, node[i].sta_tei,
node[i].addr[0], node[i].addr[1],
node[i].addr[2], node[i].addr[3],
node[i].addr[4], node[i].addr[5],
node[i].proxy_tei);
}
iot_printf("%s: topo reply end = %d------------------\n",
__FUNCTION__, rpt->done);
if (rpt->done == 0) {
iot_plc_query_nw_topo(ping_task_data->app_handle,
IOT_PLC_API_REQ_ID_DEFAULT,
IOT_PLC_CCO_TOPO_REQ_DATA_VER_V0,
IOT_PLC_QUERY_TOPO_START_AS_TEI,
node[rpt->count - 1].sta_tei + 1, 3);
} else {
/* broadcast the ping packet to all node */
static int bcast_type = 0;
uint8_t msg_type = IOT_PLC_MSG_TYPE_BCAST;
if (bcast_type++ % 2) {
msg_type = IOT_PLC_MSG_TYPE_BCAST_1HOP;
}
iot_pkt_t*msdu_pkt = iot_plc_alloc_msdu(
ping_task_data->app_handle, msg_type,
IOT_PLC_ACK_TYPE_NONE, NULL, ping_task_data->mac_addr,
ping_task_data->link_id, PING_PAYLOAD_SIZE,
IOT_PLC_LOCAL_RETRY_CNT);
uint8_t* ptr = iot_pkt_block_ptr(msdu_pkt, IOT_PKT_BLOCK_TAIL);
*ptr = 0xAC; // send 0xAC as ping
iot_pkt_put(msdu_pkt, 1);
iot_plc_send_msdu(ping_task_data->app_handle, msdu_pkt);
iot_dbglog_input(IOT_APP_PING_MID, DBGLOG_INFO_LVL_2,
IOT_PING_SEND_PING_BCAST, 2, msg_type, *ptr);
}
}
break;
}
default:
break;
}
iot_pkt_free(pkt);
}
static void iot_ping_task_handle_msg(iot_task_h task_h, iot_task_msg_t *msg)
{
iot_ping_task_msg_t *task_msg;
IOT_ASSERT(task_h == ping_task_data->task_handle);
IOT_ASSERT(msg);
task_msg = (iot_ping_task_msg_t*)msg;
switch (task_msg->msg.type) {
case IOT_PING_MAC_MSG:
{
iot_plc_ping_handle_mac_msg(task_msg->data);
break;
}
case IOT_PING_TIMER_MSG:
{
iot_plc_ping_handle_timer_msg(task_msg);
break;
}
default:
IOT_ASSERT(0);
break;
}
iot_task_free_msg(ping_task_data->task_handle, &task_msg->msg);
}
static void iot_ping_task_handle_msg_cancel(iot_task_h task_h,
iot_task_msg_t *msg)
{
iot_ping_task_msg_t *task_msg;
IOT_ASSERT(task_h == ping_task_data->task_handle);
IOT_ASSERT(msg);
task_msg = (iot_ping_task_msg_t*)msg;
switch (task_msg->msg.type) {
case IOT_PING_MAC_MSG:
{
if (task_msg->data) {
iot_pkt_free(task_msg->data);
}
break;
}
case IOT_PING_TIMER_MSG:
{
break;
}
default:
break;
}
iot_task_free_msg(ping_task_data->task_handle, &task_msg->msg);
}
uint32_t iot_ping_task_init()
{
uint32_t ret = ERR_OK;
iot_plc_app_t ping_app = {0};
ping_app.app_id = IOT_PING_APP_ID;
ping_app.param = NULL;
ping_app.prio = 3;
ping_app.recv = iot_plc_recv_ping;
if (ping_task_data) {
ret = ERR_AGAIN;
goto error_0;
}
ping_task_data = os_mem_malloc(IOT_APP_PING_MID, sizeof(*ping_task_data));
if (!ping_task_data) {
ret = ERR_NOMEM;
goto error_0;
}
ping_task_data->app_handle = NULL;
ping_task_data->link_id = IOT_PING_TASK_LIKE_ID;
ping_task_data->dev_role = IOT_PLC_DEV_ROLE_INVALID;
ping_task_data->nid = 1;
ping_task_data->task_cfg.stack_size = 0;
ping_task_data->task_cfg.task_prio = IOT_PING_TASK_PRIO;
ping_task_data->task_cfg.msg_size = sizeof(iot_ping_task_msg_t);
ping_task_data->task_cfg.msg_cnt = IOT_PING_TASK_POOL_SIZE;
ping_task_data->task_cfg.queue_cnt = IOT_PING_TASK_QUEUE_MAX_PRIO;
ping_task_data->task_cfg.queue_cfg[IOT_PING_TASK_QUEUE_HP].quota = 0;
ping_task_data->task_cfg.msg_exe_func = iot_ping_task_handle_msg;
ping_task_data->task_cfg.msg_cancel_func = iot_ping_task_handle_msg_cancel;
ping_task_data->task_handle = iot_task_create(IOT_APP_PING_MID,
&ping_task_data->task_cfg);
if (ping_task_data->task_handle == NULL) {
ret = ERR_FAIL;
goto error_1;
}
ping_task_data->ping_timer = os_create_timer(IOT_APP_PING_MID, 1,
ping_timer_func,
ping_task_data);
if (ping_task_data->ping_timer == 0) {
ret = ERR_FAIL;
goto error_2;
}
ping_task_data->app_handle = iot_plc_register_app(&ping_app);
if (ping_task_data->app_handle == NULL) {
ret = ERR_FAIL;
goto error_3;
}
goto success;
error_3:
os_delete_timer(ping_task_data->ping_timer);
ping_task_data->ping_timer = 0;
error_2:
iot_task_delete(ping_task_data->task_handle);
ping_task_data->task_handle = NULL;
error_1:
os_mem_free(ping_task_data);
error_0:
success:
return ret;
}
/*
* app_entry: entry for ping app
* @return:
* ERR_PENDING - if application want to delay the plc network formation.
* otherwise - plc network formation will be started automatically.
*/
uint32_t app_ping_entry()
{
iot_ping_task_init();
return ERR_OK;
}
#endif /* IOT_PING_APP_ENABLE */