635 lines
22 KiB
C
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 */
|