Files
kunlun/cli/cli/iot_cli.c
2024-09-28 14:24:04 +08:00

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