1039 lines
30 KiB
C
1039 lines
30 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 shim includes */
|
|
#include "os_types.h"
|
|
#include "os_lock.h"
|
|
#include "os_mem.h"
|
|
#include "os_task.h"
|
|
#include "os_utils.h"
|
|
|
|
/*iot include*/
|
|
#include "iot_errno.h"
|
|
#include "iot_io.h"
|
|
#include "iot_utils.h"
|
|
#include "iot_config.h"
|
|
#include "iot_oem.h"
|
|
#include "iot_frame_parse.h"
|
|
#include "iot_uart_h.h"
|
|
#include "iot_task.h"
|
|
#include "iot_utils.h"
|
|
#include "iot_crc.h"
|
|
#include "iot_system.h"
|
|
|
|
#include "iot_cli.h"
|
|
#include "iot_cli_msg.h"
|
|
#include "iot_cli_tx_rx.h"
|
|
#include "iot_cli_plc_nw.h"
|
|
#include "iot_cli_host_interface.h"
|
|
#include "iot_cli_flash_log.h"
|
|
#include "iot_cli_dbg_log.h"
|
|
#include "iot_cli_common.h"
|
|
#include "iot_cli_ul_buf.h"
|
|
#include "iot_cli_bt_communicator.h"
|
|
#include "iot_cli_plc_mgr_alive.h"
|
|
#include "iot_cli_common_api.h"
|
|
|
|
#ifdef CLI_MINI_MODE_ENABLE
|
|
#include "dma_uart.h"
|
|
#define IOT_CLI_MSG_POOL_SIZE 16
|
|
#else
|
|
#define IOT_CLI_MSG_POOL_SIZE 64
|
|
#endif
|
|
#define IOT_CLI_POOL_MAX_PRIO 4
|
|
|
|
/* defint cli addr type */
|
|
#define IOT_CLI_INVALID_ADDR 0
|
|
#define IOT_CLI_BROADCAST_ADDR 1
|
|
#define IOT_CLI_UNICAST_ADDR 2
|
|
|
|
extern iot_cli_host_info_t *host_info;
|
|
|
|
FTM_MSG_HANDLER cli_ftm_func_p = NULL;
|
|
PT_BOARD_MSG_HANDLER cli_pd_board_func_p = NULL;
|
|
|
|
/* cli data to app callback */
|
|
APP_CLI_MSG_HANDLER cli_send_data_to_app = NULL;
|
|
|
|
#if IOT_CLI_IC_TOOL_EN
|
|
IC_TOOL_MSG_HANDLER cli_ic_tool_func_p = NULL;
|
|
IC_TOOL_MSG_HANDLER cli_ic_rf_tool_func_p = NULL;
|
|
#endif
|
|
|
|
uint8_t cli_ftm_mode = 0;
|
|
uint32_t cli_module_type = MODULE_TYPE_CCO;
|
|
iot_cli_t cli;
|
|
|
|
#define IOT_CLI_TASK_STACK_SIZE 512
|
|
|
|
static void cli_uart_rx_frame(
|
|
void* pcli, void *buffer, uint32_t len, void* rxdesc);
|
|
static void cli_handle_msg(iot_cli_msg_t *msg);
|
|
|
|
#ifdef CLI_MINI_MODE_ENABLE
|
|
|
|
static void cli_mini_mode_uart_rx(void *buffer, uint32_t len);
|
|
|
|
#define CLI_MINI_UART_INIT (1)
|
|
#define CLI_MINI_UART_PREAMBLE_RECVED (2)
|
|
#define CLI_MINI_UART_HEADER_RECVED (3)
|
|
|
|
#define CLI_MINI_UART_BUFFER (256)
|
|
|
|
uint8_t cli_mini_uart_buffer[CLI_MINI_UART_BUFFER] = {0};
|
|
uint8_t mini_mode_state = CLI_MINI_UART_INIT;
|
|
uint16_t msg_data_recved = 0;
|
|
uint16_t msg_len = 0;
|
|
|
|
static uint8_t cli_check_pattern(
|
|
uint8_t *buffer, uint8_t len, uint8_t pattern_code)
|
|
{
|
|
for (uint8_t i = 0; i < len; i++) {
|
|
if (buffer[i] != pattern_code)
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
iot_printf("cli msg pattern found %x\n", pattern_code);
|
|
return 1;
|
|
}
|
|
|
|
static uint8_t cli_find_pattern(
|
|
uint8_t *buffer, uint16_t len, uint8_t pattern_code,
|
|
uint8_t patternLen, uint16_t *idx)
|
|
{
|
|
if ((len < patternLen) || (idx == NULL)) {
|
|
return 0;
|
|
}
|
|
|
|
for (uint8_t i = 0; i <= (len - patternLen); i++) {
|
|
if (cli_check_pattern(
|
|
buffer + i, patternLen, pattern_code)) {
|
|
*idx = i + patternLen;
|
|
|
|
iot_printf("cli msg idx %x\n", *idx);
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void cli_enable_mini_mode_uart_rx()
|
|
{
|
|
iot_printf("enable mini mode uart rx\n");
|
|
mini_mode_state = CLI_MINI_UART_INIT;
|
|
msg_data_recved = 0;
|
|
msg_len = 0;
|
|
//enable uart read
|
|
uart_dma_read(
|
|
cli_mini_uart_buffer,
|
|
CLI_MSG_PREAMBLE_LEN,
|
|
cli_mini_mode_uart_rx,
|
|
NULL, 1);
|
|
}
|
|
|
|
static void cli_mini_mode_uart_init_state_recv(
|
|
void *buffer, uint16_t len)
|
|
{
|
|
iot_printf("cli mini mode init state rx\n");
|
|
if ((CLI_MSG_PREAMBLE_LEN == len) &&
|
|
cli_check_pattern(buffer, (uint8_t)len, CLI_PREAMBLE_CODE)) {
|
|
mini_mode_state = CLI_MINI_UART_PREAMBLE_RECVED;
|
|
uart_dma_read(
|
|
cli_mini_uart_buffer,
|
|
CLI_MSG_HEADER_LEN,
|
|
cli_mini_mode_uart_rx,
|
|
NULL, 1);
|
|
} else {
|
|
cli_enable_mini_mode_uart_rx();
|
|
}
|
|
}
|
|
|
|
static uint8_t cli_check_header_valid(cli_msg_hdr_t * hdr)
|
|
{
|
|
uint8_t addr[CLI_MAC_ADDR_LEN] = { 0 };
|
|
if ((0 == os_mem_cmp(
|
|
hdr->src_mac, addr, CLI_MAC_ADDR_LEN)) &&
|
|
(0 == os_mem_cmp(
|
|
hdr->src_mac, addr, CLI_MAC_ADDR_LEN)) &&
|
|
(hdr->msg_len <= CLI_MSG_PAYLOAD_MAX_LEN)) {
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static uint8_t cli_mini_mode_uart_move_msg(uint16_t *idx)
|
|
{
|
|
if (idx &&
|
|
cli_find_pattern(cli_mini_uart_buffer,
|
|
msg_data_recved, CLI_PREAMBLE_CODE,
|
|
CLI_MSG_PREAMBLE_LEN, idx)) {
|
|
msg_data_recved -= *idx;
|
|
os_mem_cpy(
|
|
cli_mini_uart_buffer,
|
|
cli_mini_uart_buffer + *idx,
|
|
msg_data_recved);
|
|
iot_printf("find another msg idx %d\n", *idx);
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static void cli_mini_mode_uart_find_next_msg()
|
|
{
|
|
uint16_t idx = 0;
|
|
uint16_t read_len = 0;
|
|
iot_printf("cli mini mode find next msg\n");
|
|
if (cli_mini_mode_uart_move_msg(&idx)) {
|
|
iot_printf("next msg idx %d\n", idx);
|
|
while (msg_data_recved > 0) {
|
|
if (msg_data_recved < CLI_MSG_HEADER_LEN) {
|
|
mini_mode_state = CLI_MINI_UART_PREAMBLE_RECVED;
|
|
read_len = CLI_MSG_HEADER_LEN - msg_data_recved;
|
|
iot_printf("read cli header left, len %d\n", read_len);
|
|
break;
|
|
} else {
|
|
cli_msg_hdr_t * hdr =
|
|
(cli_msg_hdr_t *)cli_mini_uart_buffer;
|
|
if (cli_check_header_valid(hdr)) {
|
|
read_len = idx;
|
|
iot_printf("read cli body left, len %d\n", read_len);
|
|
break;
|
|
} else if (cli_mini_mode_uart_move_msg(&idx)) {
|
|
iot_printf("find next msg\n");
|
|
continue;
|
|
} else {
|
|
cli_enable_mini_mode_uart_rx();
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
uart_dma_read(
|
|
cli_mini_uart_buffer +
|
|
msg_data_recved,
|
|
read_len, cli_mini_mode_uart_rx,
|
|
NULL, 1);
|
|
} else {
|
|
cli_enable_mini_mode_uart_rx();
|
|
}
|
|
}
|
|
|
|
static void cli_mini_mode_uart_preamble_recved_state_recv(
|
|
void *buffer, uint16_t len)
|
|
{
|
|
(void)buffer;
|
|
cli_msg_hdr_t * hdr = NULL;
|
|
iot_printf("cli mini mode preamble state rx\n");
|
|
if ((CLI_MSG_HEADER_LEN - msg_data_recved) == len) {
|
|
hdr = (cli_msg_hdr_t *)cli_mini_uart_buffer;
|
|
msg_data_recved = CLI_MSG_HEADER_LEN;
|
|
if (cli_check_header_valid(hdr)) {
|
|
iot_printf("cli head valid, start read body\n");
|
|
mini_mode_state = CLI_MINI_UART_HEADER_RECVED;
|
|
msg_len = hdr->msg_len;
|
|
uart_dma_read(
|
|
cli_mini_uart_buffer + msg_data_recved,
|
|
msg_len + CLI_MSG_BACK_LEN,
|
|
cli_mini_mode_uart_rx,
|
|
NULL, 1);
|
|
} else {
|
|
iot_printf("cli head invalid\n");
|
|
cli_mini_mode_uart_find_next_msg();
|
|
}
|
|
} else {
|
|
cli_enable_mini_mode_uart_rx();
|
|
}
|
|
}
|
|
|
|
static void cli_mini_mode_uart_header_recved_state_recv(
|
|
void *buffer, uint16_t len)
|
|
{
|
|
(void)buffer;
|
|
iot_printf("cli mini mode header state rx\n");
|
|
if ((len + msg_data_recved) ==
|
|
(uint16_t)(CLI_MSG_HEADER_LEN + msg_len + CLI_MSG_BACK_LEN)) {
|
|
msg_data_recved = CLI_MSG_HEADER_LEN +
|
|
CLI_MSG_BACK_LEN + msg_len;
|
|
if (cli_check_pattern(
|
|
cli_mini_uart_buffer +
|
|
CLI_MSG_HEADER_LEN + msg_len,
|
|
CLI_MSG_BACK_LEN, CLI_BACK_CODE)) {
|
|
iot_printf("cli msg recved\n");
|
|
cli_uart_rx_frame(NULL, cli_mini_uart_buffer,
|
|
CLI_MSG_HEADER_LEN + msg_len, NULL);
|
|
cli_enable_mini_mode_uart_rx();
|
|
} else {
|
|
cli_mini_mode_uart_find_next_msg();
|
|
}
|
|
} else {
|
|
cli_enable_mini_mode_uart_rx();
|
|
}
|
|
}
|
|
|
|
static void cli_mini_mode_uart_rx(void *buffer, uint32_t len)
|
|
{
|
|
cli_mini_mode_data *data = NULL;
|
|
iot_pkt_t *pkt = iot_pkt_alloc(
|
|
sizeof(cli_mini_mode_data), IOT_CLI_MID);
|
|
iot_task_msg_t *msg =
|
|
iot_cli_create_cli_msg(IOT_CLI_MINI_UART_RECV, pkt);
|
|
|
|
data = (cli_mini_mode_data *)iot_pkt_data(pkt);
|
|
iot_pkt_put(pkt, sizeof(cli_mini_mode_data));
|
|
data->buffer = buffer;
|
|
data->len = len;
|
|
|
|
if (msg) {
|
|
iot_task_queue_msg(
|
|
host_info->host_task_h, msg, IOT_CLI_QUEUE_HOST);
|
|
} else if (pkt) {
|
|
iot_pkt_free(pkt);
|
|
}
|
|
}
|
|
|
|
static void cli_mini_mode_uart_tx(iot_pkt_t *pkt)
|
|
{
|
|
if (pkt) {
|
|
uart_dma_write(iot_pkt_data(pkt),
|
|
iot_pkt_data_len(pkt), NULL, NULL);
|
|
iot_pkt_free(pkt);
|
|
}
|
|
}
|
|
|
|
static void cli_handle_mini_mode_uart_msg(iot_pkt_t *pkt)
|
|
{
|
|
if (pkt) {
|
|
cli_mini_mode_data *msg =
|
|
(cli_mini_mode_data*)iot_pkt_data(pkt);
|
|
switch (mini_mode_state)
|
|
{
|
|
case CLI_MINI_UART_INIT:
|
|
cli_mini_mode_uart_init_state_recv(
|
|
msg->buffer, (uint16_t)msg->len);
|
|
break;
|
|
case CLI_MINI_UART_PREAMBLE_RECVED:
|
|
cli_mini_mode_uart_preamble_recved_state_recv(
|
|
msg->buffer, (uint16_t)msg->len);
|
|
break;
|
|
case CLI_MINI_UART_HEADER_RECVED:
|
|
cli_mini_mode_uart_header_recved_state_recv(
|
|
msg->buffer, (uint16_t)msg->len);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
iot_pkt_free(pkt);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
iot_task_msg_t *iot_cli_create_cli_msg(uint16_t id, iot_pkt_t *pkt)
|
|
{
|
|
iot_task_msg_t *msg;
|
|
iot_cli_msg_t *cli_msg;
|
|
|
|
msg = iot_task_alloc_msg(cli.cli_task_h);
|
|
if (msg) {
|
|
cli_msg = container_of(msg, iot_cli_msg_t, msg);
|
|
if (cli_msg) {
|
|
cli_msg->data = pkt;
|
|
}
|
|
msg->type = IOT_CLI_MSG_TYPE;
|
|
msg->id = id;
|
|
}
|
|
|
|
return msg;
|
|
}
|
|
|
|
static void iot_cli_task_msg_exe_func(iot_task_h task_h, iot_task_msg_t *t_msg)
|
|
{
|
|
iot_cli_msg_t *cli_msg = container_of(t_msg, iot_cli_msg_t, msg);
|
|
|
|
if (t_msg->type == IOT_CLI_MSG_TYPE)
|
|
{
|
|
switch (t_msg->id) {
|
|
case IOT_CLI_SEND_MSG:
|
|
{
|
|
if (cli.commu.type == COMMUNICATOR_BT) {
|
|
iot_cli_bt_communicator_send(cli_msg->data);
|
|
break;
|
|
}
|
|
#ifdef CLI_MINI_MODE_ENABLE
|
|
cli_mini_mode_uart_tx(cli_msg->data);
|
|
#else
|
|
package_send(&cli.commu, UDP_CLI_SEND_PORT, cli_msg->data);
|
|
#endif
|
|
break;
|
|
}
|
|
case IOT_CLI_REV_MSG:
|
|
{
|
|
cli_handle_msg(cli_msg);
|
|
break;
|
|
}
|
|
#ifdef CLI_MINI_MODE_ENABLE
|
|
case IOT_CLI_MINI_UART_RECV:
|
|
{
|
|
cli_handle_mini_mode_uart_msg(cli_msg->data);
|
|
break;
|
|
}
|
|
#endif
|
|
case IOT_CLI_RX_APP_DATA_MSG:
|
|
{
|
|
/* drop the data frame's preamble code and back code */
|
|
iot_cli_pre_handle_data(iot_pkt_data(cli_msg->data) +
|
|
IOT_CLI_UART_FRAME_PREAMBLE_LEN,
|
|
iot_pkt_data_len(cli_msg->data) -
|
|
IOT_CLI_UART_FRAME_HDR_TAIL_LEN, COMMUNICATOR_UART);
|
|
iot_pkt_free(cli_msg->data);
|
|
break;
|
|
}
|
|
default:
|
|
iot_cli_host_interface_handle_task_msg(cli_msg, t_msg->id);
|
|
break;
|
|
}
|
|
}
|
|
iot_task_free_msg(task_h, t_msg);
|
|
}
|
|
|
|
static void iot_cli_task_msg_cancel_func(iot_task_h task_h, iot_task_msg_t *t_msg)
|
|
{
|
|
iot_cli_msg_t *cli_msg = container_of(t_msg, iot_cli_msg_t, msg);
|
|
|
|
if (t_msg->type == IOT_CLI_MSG_TYPE)
|
|
{
|
|
switch (t_msg->id)
|
|
{
|
|
case IOT_CLI_SEND_MSG:
|
|
case IOT_CLI_REV_MSG:
|
|
#ifdef CLI_MINI_MODE_ENABLE
|
|
case IOT_CLI_MINI_UART_RECV:
|
|
#endif
|
|
case IOT_CLI_RX_APP_DATA_MSG:
|
|
if (cli_msg->data) {
|
|
iot_pkt_free(cli_msg->data);
|
|
}
|
|
break;
|
|
default:
|
|
iot_cli_host_interface_cancel_task_msg(cli_msg, t_msg->id);
|
|
break;
|
|
}
|
|
}
|
|
iot_task_free_msg(task_h, t_msg);
|
|
}
|
|
|
|
static void iot_cli_set_communicator(interface_type_t type)
|
|
{
|
|
if (type != cli.commu.type) {
|
|
cli.commu.type = type;
|
|
}
|
|
}
|
|
|
|
uint32_t iot_cli_pre_handle_data(void *buffer, uint32_t len,
|
|
interface_type_t type)
|
|
{
|
|
(void)type;
|
|
uint32_t ret = ERR_FAIL;
|
|
uint8_t *ptr = (uint8_t *)buffer;
|
|
uint8_t cli_msg_hdr_len;
|
|
cli_msg_hdr_t *hdr = (cli_msg_hdr_t *)buffer;
|
|
uint16_t crc;
|
|
cli_msg_ack_t ack = { 0 };
|
|
|
|
if (!buffer) {
|
|
iot_printf("Invalid cli msg buffer\n");
|
|
goto out;
|
|
}
|
|
|
|
cli_msg_hdr_len = sizeof(cli_msg_hdr_t);
|
|
if (len < cli_msg_hdr_len){
|
|
iot_printf("Invalid cli msg len\n");
|
|
goto out;
|
|
}
|
|
uint8_t xor_value = iot_chip_get_xor_value();
|
|
if (cli_ftm_mode == 0 && xor_value != 0) {
|
|
for (uint32_t i = 0; i < hdr->msg_len; i++) {
|
|
ptr[cli_msg_hdr_len + i] ^= xor_value;
|
|
}
|
|
}
|
|
/*check cli crc*/
|
|
if (hdr->cli_crc != 0){
|
|
crc = iot_getcrc32_h16(ptr + cli_msg_hdr_len, hdr->msg_len);
|
|
if (hdr->cli_crc != crc){
|
|
iot_printf("cli_crc fail,id=%d,mod=%d,len=%d, crc=%d\n", \
|
|
hdr->msg_id, hdr->module_id, hdr->msg_len, crc);
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
if (hdr->auto_ack) {
|
|
cli_send_module_msg_with_sn(
|
|
hdr->module_id, hdr->msg_id,
|
|
(uint8_t *)&ack, sizeof(ack), hdr->sn, NULL);
|
|
}
|
|
|
|
iot_cli_queue_data(buffer, len);
|
|
ret = ERR_OK;
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
#if(IOT_CLI_INF_MODE == IOT_CLI_INF_MODE_APP)
|
|
|
|
void iot_cli_recv_app_data(iot_pkt_t *pkt)
|
|
{
|
|
iot_task_msg_t *msg = NULL;
|
|
|
|
if (NULL == pkt) {
|
|
return;
|
|
}
|
|
msg = iot_cli_create_cli_msg(IOT_CLI_RX_APP_DATA_MSG, pkt);
|
|
|
|
if (msg) {
|
|
iot_task_queue_msg(cli.cli_task_h, msg, IOT_CLI_QUEUE_TX);
|
|
} else {
|
|
iot_pkt_free(pkt);
|
|
}
|
|
}
|
|
|
|
void iot_cli_recv_data_from_comm(void* pdev, void *buffer, uint32_t len)
|
|
{
|
|
iot_pkt_t *t_pkt = NULL;
|
|
uint8_t *data;
|
|
|
|
(void)pdev;
|
|
if ((NULL == buffer) || (0 == len)) {
|
|
return;
|
|
}
|
|
/* add preamble_code(2 bytes) and backcode(2 bytes) */
|
|
t_pkt = iot_pkt_alloc(len + IOT_CLI_UART_FRAME_HDR_TAIL_LEN,
|
|
IOT_CLI_MID);
|
|
|
|
if (NULL == t_pkt) {
|
|
return;
|
|
}
|
|
|
|
data = iot_pkt_data(t_pkt);
|
|
os_mem_cpy(data, "##", IOT_CLI_UART_FRAME_PREAMBLE_LEN);
|
|
data += IOT_CLI_UART_FRAME_PREAMBLE_LEN;
|
|
os_mem_cpy(data, buffer, len);
|
|
data += len;
|
|
os_mem_cpy(data, "@@", IOT_CLI_UART_FRAME_BACKCODE_LEN);
|
|
iot_pkt_put(t_pkt, len + IOT_CLI_UART_FRAME_HDR_TAIL_LEN);
|
|
if (NULL != cli_send_data_to_app) {
|
|
cli_send_data_to_app(t_pkt);
|
|
} else {
|
|
iot_pkt_free(t_pkt);
|
|
}
|
|
}
|
|
#else
|
|
|
|
void iot_cli_recv_app_data(iot_pkt_t *pkt)
|
|
{
|
|
if (pkt) {
|
|
iot_pkt_free(pkt);
|
|
}
|
|
}
|
|
|
|
void iot_cli_recv_data_from_comm(void* pdev, void *buffer, uint32_t len)
|
|
{
|
|
(void)pdev;
|
|
(void)buffer;
|
|
(void)len;
|
|
}
|
|
|
|
#endif /* end IOT_CLI_INF_MODE == IOT_CLI_INF_MODE_APP */
|
|
|
|
uint32_t iot_cli_init(uint8_t interface_type, uint8_t ftm_mode)
|
|
{
|
|
(void)interface_type;
|
|
uint32_t ret = ERR_OK;
|
|
iot_task_config_t task_cfg;
|
|
cli_ftm_mode = ftm_mode;
|
|
iot_oem_cfg_t *cfg;
|
|
|
|
// get module type
|
|
iot_oem_get_cfg(&cfg);
|
|
cli_module_type = cfg->base_cfg.module_type;
|
|
|
|
#ifdef CLI_MINI_MODE_ENABLE
|
|
uart_dma_init(1, 115200);
|
|
cli_enable_mini_mode_uart_rx();
|
|
#else
|
|
iot_cli_host_interface_init_uart(&cli.commu, interface_type);
|
|
commnuicator_register_callback_packet_recv(&cli.commu, cli_uart_rx_frame);
|
|
#endif
|
|
|
|
#if(IOT_CLI_INF_MODE == IOT_CLI_INF_MODE_APP)
|
|
commnuicator_register_cb_ext_tx_comp(&cli.commu,
|
|
iot_cli_recv_data_from_comm);
|
|
#endif
|
|
|
|
#if (PLC_SUPPORT_CCO_ROLE || IOT_STA_CONTROL_MODE)
|
|
cli.enable_commu = 1;
|
|
#else
|
|
cli.enable_commu = 0;
|
|
#endif
|
|
|
|
cli.need_download_cli_to_flash = required_to_write_to_flash();
|
|
|
|
iot_share_task_msg_register(IOT_SHARE_TASK_MT_CLI,
|
|
iot_cli_log_to_flash_msg_handle,
|
|
iot_cli_log_to_flash_msg_cancel_handle);
|
|
|
|
task_cfg.stack_size = IOT_CLI_TASK_STACK_SIZE;
|
|
task_cfg.task_prio = IOT_CLI_TASK_PRIO;
|
|
task_cfg.msg_size = sizeof(iot_cli_msg_t);
|
|
task_cfg.msg_cnt = IOT_CLI_MSG_POOL_SIZE;
|
|
task_cfg.queue_cnt = IOT_CLI_POOL_MAX_PRIO;
|
|
task_cfg.queue_cfg[IOT_CLI_QUEUE_TX].quota = 0;
|
|
task_cfg.queue_cfg[IOT_CLI_QUEUE_RX].quota = 0;
|
|
task_cfg.queue_cfg[IOT_CLI_QUEUE_HOST].quota = 0;
|
|
task_cfg.msg_exe_func = iot_cli_task_msg_exe_func;
|
|
task_cfg.msg_cancel_func = iot_cli_task_msg_cancel_func;
|
|
task_cfg.core_id = 0;
|
|
|
|
cli.cli_task_h = iot_task_create(IOT_DRIVER_MID, &task_cfg);
|
|
|
|
if (cli.cli_task_h == NULL)
|
|
{
|
|
iot_printf("cli start task fail!\n");
|
|
goto err_task;
|
|
}
|
|
//register modules here
|
|
cli.dbglog = get_dbglog_instance();
|
|
ret = register_dbglog_callback(cli_send_dbglog);
|
|
if (ret != ERR_OK)
|
|
{
|
|
goto err_log;
|
|
}
|
|
|
|
ret = iot_cli_host_interface_init(cli_send_module_msg_with_sn, cli.cli_task_h);
|
|
if (ret != ERR_OK)
|
|
{
|
|
goto err_host_interface;
|
|
}
|
|
|
|
iot_dbglog_input(IOT_CLI_MID, DBGLOG_INFO_LVL_2,
|
|
IOT_CLI_READY_INFO, 0);
|
|
|
|
if (ERR_OK == iot_cli_bt_communicator_init()) {
|
|
iot_cli_set_communicator(COMMUNICATOR_BT);
|
|
cli.enable_commu = 1;
|
|
}
|
|
goto out;
|
|
err_host_interface:
|
|
iot_cli_host_interface_deinit();
|
|
err_log:
|
|
iot_dbglog_deinit();
|
|
err_task:
|
|
if (cli.cli_task_h)
|
|
iot_task_delete(cli.cli_task_h);
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
uint32_t iot_cli_deinit()
|
|
{
|
|
iot_cli_host_interface_deinit();
|
|
iot_dbglog_deinit();
|
|
if (cli.cli_task_h) {
|
|
iot_task_delete(cli.cli_task_h);
|
|
cli.cli_task_h = NULL;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void register_ftm_recv_cb(FTM_MSG_HANDLER cb)
|
|
{
|
|
cli_ftm_func_p = cb;
|
|
}
|
|
|
|
void register_pd_board_recv_cb(PT_BOARD_MSG_HANDLER cb)
|
|
{
|
|
cli_pd_board_func_p = cb;
|
|
}
|
|
|
|
void register_app_recv_cli_data_cb(APP_CLI_MSG_HANDLER cb)
|
|
{
|
|
cli_send_data_to_app = cb;
|
|
}
|
|
|
|
#if IOT_CLI_IC_TOOL_EN
|
|
|
|
void register_ic_tool_recv_cb(IC_TOOL_MSG_HANDLER cb)
|
|
{
|
|
cli_ic_tool_func_p = cb;
|
|
}
|
|
|
|
void register_ic_rf_tool_recv_cb(IC_TOOL_MSG_HANDLER cb)
|
|
{
|
|
cli_ic_rf_tool_func_p = cb;
|
|
}
|
|
|
|
#endif
|
|
|
|
void cli_add_msg_header(void* input_buffer, uint32_t buffer_len,
|
|
uint32_t moduleid, uint32_t msgid, uint16_t sn,
|
|
uint8_t** output_buffer, uint32_t *out_len, uint8_t *src_mac)
|
|
{
|
|
if (!output_buffer) {
|
|
IOT_ASSERT(output_buffer);
|
|
return;
|
|
}
|
|
cli_msg_hdr_t *msg = (cli_msg_hdr_t *)*output_buffer;
|
|
msg->module_id = (cli_moduleid_t)moduleid;
|
|
msg->msg_id = (uint16_t)msgid;
|
|
msg->msg_len = (uint16_t)buffer_len;
|
|
msg->sn = sn;
|
|
if (cli_ftm_mode == 0) {
|
|
msg->cli_crc = iot_getcrc32_h16(input_buffer, buffer_len);
|
|
} else if (cli_ftm_mode == 1) {
|
|
msg->cli_crc = 0;
|
|
msg->sn = 0;
|
|
}
|
|
|
|
if (src_mac) {
|
|
iot_mac_addr_cpy(msg->src_mac, src_mac);
|
|
} else if (host_info) {
|
|
iot_mac_addr_cpy(msg->src_mac, host_info->mac_addr);
|
|
}
|
|
iot_mac_addr_cpy(msg->target_mac, host_info->mac_addr);
|
|
|
|
uint8_t xor_value = iot_chip_get_xor_value();
|
|
if (cli_ftm_mode == 0 && xor_value != 0) {
|
|
for (uint32_t i = 0; i < buffer_len; i++) {
|
|
(*output_buffer)[sizeof(cli_msg_hdr_t) + i] =
|
|
((uint8_t*)input_buffer)[i] ^ xor_value;
|
|
}
|
|
} else {
|
|
os_mem_cpy(&(*output_buffer)[sizeof(cli_msg_hdr_t)],
|
|
input_buffer, buffer_len);
|
|
}
|
|
*out_len = buffer_len + sizeof(cli_msg_hdr_t);
|
|
}
|
|
|
|
static iot_pkt_t* iot_cli_uart_create_cli_msg(uint32_t moduleid, uint32_t msgid,
|
|
uint8_t *buffer, uint32_t bufferlen, uint16_t sn, uint8_t *src_mac)
|
|
{
|
|
iot_pkt_t *data;
|
|
uint32_t datalen = 0;
|
|
uint8_t* data_ptr;
|
|
|
|
data = iot_pkt_alloc(bufferlen + sizeof(cli_msg_hdr_t)+
|
|
MAX_CLI_FRAME_HEAD+ MAX_CLI_FRAME_END, IOT_CLI_MID);
|
|
if (data == NULL) {
|
|
iot_printf("cli_send_module_msg iot_pkt_alloc fail\n");
|
|
#if PLC_HW_ISSUE_ASSERT_LEVEL <= PLC_HW_ISSUE_ASSERT_CRITICAL
|
|
//IOT_ASSERT(data);
|
|
#endif
|
|
return NULL;
|
|
}
|
|
|
|
if (iot_pkt_reserve(data, MAX_CLI_FRAME_HEAD) == NULL) {
|
|
iot_printf("cli_send_module_msg iot_pkt_reserve fail\n");
|
|
iot_pkt_free(data);
|
|
return NULL;
|
|
}
|
|
|
|
data_ptr = iot_pkt_data(data);
|
|
os_mem_set(data_ptr, 0, bufferlen + sizeof(cli_msg_hdr_t));
|
|
cli_add_msg_header(buffer, bufferlen,
|
|
moduleid, msgid, sn,
|
|
(uint8_t**)&data_ptr, &datalen, src_mac);
|
|
|
|
if (iot_pkt_set_tail(data, iot_pkt_data(data) + datalen) == NULL) {
|
|
iot_printf("cli_send_module_msg iot_pkt_set_tail fail\n");
|
|
iot_pkt_free(data);
|
|
return NULL;
|
|
}
|
|
return data;
|
|
}
|
|
|
|
void cli_send_module_msg_with_sn(uint32_t moduleid, uint32_t msgid,
|
|
uint8_t *buffer, uint32_t bufferlen, uint16_t sn, uint8_t *src_mac)
|
|
{
|
|
iot_pkt_t *data;
|
|
|
|
#ifdef CLI_MM_MODE_CHECK
|
|
// for mission mode sta
|
|
if ((MODULE_TYPE_CCO != cli_module_type) && (!cli_ftm_mode) &&
|
|
(cli.commu.type != COMMUNICATOR_BT)) {
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
if (cli.cli_task_h == NULL || ((bufferlen != 0) && (buffer == NULL))){
|
|
iot_printf("invalid param (%s)\n", __FUNCTION__);
|
|
return;
|
|
}
|
|
if (cli.commu.type == COMMUNICATOR_BT) {
|
|
data = iot_cli_bt_create_cli_msg(moduleid, msgid, buffer, bufferlen,
|
|
sn);
|
|
} else {
|
|
data = iot_cli_uart_create_cli_msg(moduleid, msgid, buffer, bufferlen,
|
|
sn, src_mac);
|
|
}
|
|
if (data) {
|
|
send_tx_msg_to_cli_task(data);
|
|
} else {
|
|
iot_printf("cli_send_module_msg create communicator data fail\n");
|
|
}
|
|
}
|
|
|
|
void cli_send_module_msg(uint32_t moduleid, uint32_t msgid,
|
|
uint8_t *buffer, uint32_t bufferlen)
|
|
{
|
|
cli_send_module_msg_with_sn(moduleid, msgid, buffer, bufferlen,
|
|
CLI_UL_BUF_IVALID_SN, NULL);
|
|
}
|
|
|
|
void send_tx_msg_to_cli_task(iot_pkt_t* data)
|
|
{
|
|
iot_task_msg_t *t_msg;
|
|
|
|
#ifdef CLI_MM_MODE_CHECK
|
|
/*for mission sta, should free iot_pkt here*/
|
|
if ((MODULE_TYPE_CCO != cli_module_type) && (!cli_ftm_mode) &&
|
|
(cli.commu.type != COMMUNICATOR_BT)) {
|
|
if (data) {
|
|
iot_pkt_free(data);
|
|
}
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
t_msg = iot_cli_create_cli_msg(IOT_CLI_SEND_MSG, data);
|
|
if (t_msg == NULL) {
|
|
iot_printf("send_tx_msg_to_cli_task iot_task_alloc_msg fail\n");
|
|
goto err_exit;
|
|
}
|
|
iot_task_queue_msg(cli.cli_task_h, t_msg, IOT_CLI_QUEUE_TX);
|
|
return;
|
|
err_exit:
|
|
if (data) {
|
|
iot_pkt_free(data);
|
|
}
|
|
}
|
|
|
|
static uint8_t iot_cli_mac_type(uint8_t *mac)
|
|
{
|
|
uint32_t cnt = 0;
|
|
for (int i = 0; i < 6; i++) {
|
|
cnt += mac[i];
|
|
}
|
|
if (cnt == 0) {
|
|
return IOT_CLI_INVALID_ADDR;
|
|
} else if (cnt == 6 * 0xff) {
|
|
return IOT_CLI_BROADCAST_ADDR;
|
|
}
|
|
return IOT_CLI_UNICAST_ADDR;
|
|
}
|
|
|
|
#if PLC_SUPPORT_CCO_ROLE
|
|
static uint8_t iot_cli_is_local_mac(uint8_t* mac)
|
|
{
|
|
//check if mac is local or not
|
|
uint8_t is_local = 1;
|
|
is_local = ((!mac) || MAC_IS_EMPTY(mac) ||
|
|
iot_mac_addr_cmp(mac, host_info->mac_addr));
|
|
return is_local;
|
|
}
|
|
#endif
|
|
|
|
void iot_cli_queue_data(void *buffer, uint32_t len)
|
|
{
|
|
cli_msg_hdr_t *hdr = (cli_msg_hdr_t *)buffer;
|
|
iot_cli_msg_t *cli_msg;
|
|
iot_task_msg_t *t_msg;
|
|
uint8_t mac_type;
|
|
int32_t buffer_len = (len - CLI_MSG_HEADER_LEN);
|
|
iot_pkt_t *data = NULL;
|
|
if (cli.cli_task_h == NULL || buffer == NULL) {
|
|
iot_printf("Invalid param (%s)\n", __FUNCTION__);
|
|
return;
|
|
}
|
|
|
|
mac_type = iot_cli_mac_type(hdr->target_mac);
|
|
if ((mac_type == IOT_CLI_UNICAST_ADDR) &&
|
|
(os_mem_cmp(host_info->mac_addr,
|
|
hdr->target_mac, CLI_MAC_ADDR_LEN) != 0)) {
|
|
iot_printf("cli tsf msg target=%.2x:%.2x:%.2x:%.2x:%.2x:%.2x,"\
|
|
"mod=%d,msg=%d,len=%d\n", hdr->target_mac[0],
|
|
hdr->target_mac[1],hdr->target_mac[2], hdr->target_mac[3],
|
|
hdr->target_mac[4],hdr->target_mac[5], hdr->module_id,
|
|
hdr->msg_id, hdr->msg_len);
|
|
iot_cli_send_data(CLI_UNICAST_SEND_TYPE, 0, hdr->module_id,
|
|
hdr->msg_id, hdr->src_mac, hdr->target_mac,
|
|
(uint8_t*)buffer + CLI_MSG_HEADER_LEN, buffer_len);
|
|
return;
|
|
} else if (mac_type == IOT_CLI_BROADCAST_ADDR) {
|
|
#if PLC_SUPPORT_CCO_ROLE
|
|
iot_printf("%s src node %02x:%02x:%02x:%02x:%02x broadcast cli data \n",
|
|
__FUNCTION__, hdr->src_mac[0], hdr->src_mac[1], hdr->src_mac[2],
|
|
hdr->src_mac[3], hdr->src_mac[4], hdr->src_mac[5]);
|
|
/* clr src addr, avoid broadcast storm for ckb, avoid rsp for sta */
|
|
os_mem_set(hdr->src_mac, 0 , CLI_MAC_ADDR_LEN);
|
|
iot_cli_send_data(CLI_BCAST_SEND_TYPE, 0, hdr->module_id, hdr->msg_id,
|
|
hdr->src_mac, hdr->target_mac,
|
|
(uint8_t*)buffer + CLI_MSG_HEADER_LEN, buffer_len);
|
|
return;
|
|
#elif (IOT_STA_CONTROL_MODE == IOT_STA_CONTROL_TYPE_STA)
|
|
if (os_mem_cmp(host_info->mac_addr, hdr->src_mac, CLI_MAC_ADDR_LEN)
|
|
!= 0) {
|
|
iot_printf("%s src add is invalid \n", __FUNCTION__);
|
|
return;
|
|
}
|
|
iot_cli_send_data(CLI_UNICAST_SEND_TYPE, 0, hdr->module_id, hdr->msg_id,
|
|
hdr->src_mac, hdr->target_mac,
|
|
(uint8_t*)buffer + CLI_MSG_HEADER_LEN, buffer_len);
|
|
return;
|
|
#endif
|
|
}
|
|
#if PLC_SUPPORT_CCO_ROLE
|
|
if (cli.enable_commu) {
|
|
if (iot_cli_is_local_mac(hdr->src_mac)) {
|
|
;
|
|
} else if (hdr->msg_id == CLI_MSGID_GET_TOPO) {
|
|
iot_printf("plc manager role is CKB\n");
|
|
// change plc mgr state to 0
|
|
cli_set_plc_mgr_state(0);
|
|
cli_chang_host_role(hdr->src_mac);
|
|
cli.enable_commu = 0;
|
|
}
|
|
} else if (!iot_cli_is_local_mac(hdr->src_mac)) {
|
|
;
|
|
} else if (hdr->msg_id != CLI_MSGID_ONLINE) {
|
|
return;
|
|
} else {
|
|
iot_printf("plc manager role is UART\n");
|
|
// change plc mgr state to 0
|
|
cli_set_plc_mgr_state(0);
|
|
cli_chang_host_role(hdr->src_mac);
|
|
cli.enable_commu = 1;
|
|
}
|
|
#endif
|
|
t_msg = iot_task_alloc_msg(cli.cli_task_h);
|
|
if (t_msg == NULL) {
|
|
iot_printf("iot_cli_queue_data iot_task_alloc_msg fail\n");
|
|
return;
|
|
}
|
|
cli_msg = container_of(t_msg, iot_cli_msg_t, msg);
|
|
//os_mem_set(cli_msg, 0, sizeof(iot_cli_msg_t));
|
|
|
|
if (buffer_len >0){
|
|
data = iot_pkt_alloc(buffer_len, IOT_CLI_MID);
|
|
if (!data){
|
|
iot_printf("iot_cli_queue_data alloc mem fail,len:%d\n", buffer_len);
|
|
iot_task_free_msg(cli.cli_task_h, t_msg);
|
|
return;
|
|
}
|
|
|
|
if (iot_pkt_set_tail(data, iot_pkt_data(data) + buffer_len) == NULL){
|
|
iot_printf("iot_cli_queue_data iot_pkt_set_tail fail\n");
|
|
iot_task_free_msg(cli.cli_task_h, t_msg);
|
|
iot_pkt_free(data);
|
|
return;
|
|
}
|
|
}
|
|
|
|
#if PLC_SUPPORT_UPGRADE_DEBUG
|
|
iot_printf("cli rev one msg(mdu=%d, msg=%d, len=%d)\n", hdr->module_id,
|
|
hdr->msg_id, buffer_len);
|
|
#endif
|
|
|
|
t_msg->id = IOT_CLI_REV_MSG;
|
|
t_msg->type = IOT_CLI_MSG_TYPE;
|
|
cli_msg->module_id = hdr->module_id;
|
|
cli_msg->msg_id = hdr->msg_id;
|
|
cli_msg->sn = hdr->sn;
|
|
os_mem_cpy(&(cli_msg->src_mac[0]), &(hdr->src_mac[0]), CLI_MAC_ADDR_LEN);
|
|
//msg->datalen = buffer_len;
|
|
cli_msg->data = data;
|
|
os_mem_cpy(iot_pkt_data(cli_msg->data),
|
|
(((uint8_t*)buffer) + CLI_MSG_HEADER_LEN),
|
|
buffer_len);
|
|
|
|
iot_task_queue_msg(cli.cli_task_h, t_msg, IOT_CLI_QUEUE_RX);
|
|
}
|
|
|
|
static void cli_uart_rx_frame(
|
|
void* pcli, void *buffer, uint32_t len, void* rxdesc)
|
|
{
|
|
(void)pcli;
|
|
(void)rxdesc;
|
|
iot_cli_pre_handle_data(buffer, len, COMMUNICATOR_UART);
|
|
}
|
|
|
|
static void cli_handle_undefined_msg(iot_cli_msg_t *msg)
|
|
{
|
|
if (msg->module_id == CLI_MODULEID_HOSTINTERFACE) {
|
|
iot_cli_module_send_to_host_with_retry(msg->msg_id,
|
|
iot_pkt_data(msg->data), iot_pkt_data_len(msg->data), msg->sn,
|
|
NULL, msg->src_mac);
|
|
} else if (msg->module_id == CLI_MODULEID_DEBUGLOG) {
|
|
cli_send_module_msg(CLI_MODULEID_DEBUGLOG,
|
|
msg->msg_id,
|
|
iot_pkt_data(msg->data),
|
|
iot_pkt_data_len(msg->data));
|
|
}
|
|
}
|
|
|
|
static void cli_handle_msg(iot_cli_msg_t *msg)
|
|
{
|
|
uint32_t msgid = msg->msg_id;
|
|
cli_moduleid_t moduleid = msg->module_id;
|
|
bool_t need_free = true;
|
|
#if IOT_CLI_IC_TOOL_EN
|
|
iot_printf("mod=%d,msg=%d\n", msg->module_id, msg->msg_id);
|
|
|
|
if (moduleid == CLI_MODULEID_MANUFACTURE_OP && cli_ic_tool_func_p) {
|
|
cli_ic_tool_func_p(msgid, msg->data, iot_pkt_data_len(msg->data));
|
|
goto exit;
|
|
} else if (moduleid == CLI_MODULEID_FTM && cli_ic_rf_tool_func_p) {
|
|
cli_ic_rf_tool_func_p(msgid, msg->data, iot_pkt_data_len(msg->data));
|
|
goto exit;
|
|
}
|
|
#elif IOT_PT_BOARD_SELECT
|
|
if (moduleid == CLI_MODULEID_MANUFACTURE_OP && cli_pd_board_func_p) {
|
|
cli_pd_board_func_p(msgid, msg->data);
|
|
goto exit;
|
|
}
|
|
#else
|
|
if (moduleid == CLI_MODULEID_FTM && cli_ftm_func_p) {
|
|
cli_ftm_func_p(msgid, msg->data, &need_free);
|
|
goto exit;
|
|
}
|
|
#endif
|
|
|
|
iot_printf(
|
|
"cli_handle_msg src=%.2x:%.2x:%.2x:%.2x:%.2x:%.2x,mod=%d,"\
|
|
"msg=%d,len=%d\n", msg->src_mac[0], msg->src_mac[1],
|
|
msg->src_mac[2], msg->src_mac[3], msg->src_mac[4],
|
|
msg->src_mac[5], msg->module_id, msg->msg_id,
|
|
iot_pkt_data_len(msg->data));
|
|
|
|
if (!iot_cli_host_interface_handle_msg(moduleid, msgid, msg)) {
|
|
cli_handle_undefined_msg(msg);
|
|
}
|
|
|
|
exit:
|
|
if (need_free && msg->data) {
|
|
iot_pkt_free(msg->data);
|
|
}
|
|
}
|
|
|