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

1194 lines
39 KiB
C

/****************************************************************************
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
be copied by any method or incorporated into another program without
the express written consent of Aerospace C.Power. This Information or any portion
thereof remains the property of Aerospace C.Power. The Information contained herein
is believed to be accurate and Aerospace C.Power assumes no responsibility or
liability for its use in any way and conveys no license or title under
any patent or copyright and makes no representation or warranty that this
Information is free from patent or copyright infringement.
****************************************************************************/
#include "os_timer_api.h"
#include "os_utils_api.h"
#include "iot_app_api.h"
#include "iot_io_api.h"
#include "iot_task_api.h"
#include "iot_edge_compute.h"
#include "iot_proto_common.h"
#include "iot_proto_dl645.h"
#include "iot_proto_ge.h"
#include "iot_bitmap_api.h"
#include "iot_app_cus_flash.h"
#include "iot_flashinfo.h"
#pragma pack(push) // save the pack status
#pragma pack(1) // 1 byte align
/* edge inner message */
enum
{
EDGE_INTERNAL_NEXT_CACHE_ID = 0x1,
EDGE_INTERNAL_UART_IDLE_ID,
};
/* edg timer message */
enum
{
/* edge starting stopping timer */
EDGE_MONITOR_START_STOP_ID = 0x1,
/* edge wait for uart respond */
EDGE_TIMEROUT_UART_READ_ID,
/* interval between two cache */
EDGE_TIMEROUT_NEXT_CACHE_ID,
};
enum
{
/* get start msg from proto, go into starting state */
edge_state_idle = 0,
/* no uart msg during start_stop timer, go into stated state */
edge_state_starting,
/* polling all cache cmd one by one each time */
edge_state_started,
/* no uart msg during start_stop timer, go into stopped state */
edge_state_stopping,
/* return uart handle to proto and go into idle state */
edge_state_stopped,
};
typedef uint8_t(* EDGE_FN_HANDLE)(uint8_t msg, uint8_t msg_id, void *arg);
typedef struct _iot_edge_fnhdl_tbl_t
{
/* each code handler */
EDGE_FN_HANDLE cmd_handle_fn;
} iot_edge_fnhdl_tbl_t;
#pragma pack(pop)
void iot_common_bin_dump(uint8_t *data, uint32_t dlen);
static uint8_t
iot_edge_state_idle_handler(uint8_t msg, uint8_t msg_id, void *arg);
static uint8_t
iot_edge_state_starting_handler(uint8_t msg, uint8_t msg_id, void *arg);
static uint8_t
iot_edge_state_started_handler(uint8_t msg, uint8_t msg_id, void *arg);
static uint8_t
iot_edge_state_stopping_handler(uint8_t msg, uint8_t msg_id, void *arg);
static uint8_t
iot_edge_state_stopped_handler(uint8_t msg, uint8_t msg_id, void *arg);
static iot_edge_fnhdl_tbl_t edge_state_hdl_tbl[] = {
{iot_edge_state_idle_handler},
{iot_edge_state_starting_handler},
{iot_edge_state_started_handler},
{iot_edge_state_stopping_handler},
{iot_edge_state_stopped_handler},
};
void iot_os_stop_timer_handle(timer_id_t tmr, uint16_t msg, uint8_t msg_id)
{
os_stop_timer(tmr);
iot_task_clean_msg(prototask_contxt.task_handle, msg, msg_id);
}
/**
* @brief iot_edge_uart_send() - the edge send the data to uart
* @param p_pkt: the pkt of the data
* @retval: true or false
*/
static uint32_t iot_edge_uart_send(iot_pkt_t *p_pkt)
{
uint8_t ret = ERR_INVAL;
if (p_pkt != NULL) {
iot_cus_printf("[edge]send uart");
iot_common_bin_dump(iot_pkt_data(p_pkt), iot_pkt_data_len(p_pkt));
ret = iot_uart_send(prototask_contxt.edge_obj.uart_hdl, p_pkt, NULL);
}
return ret;
}
/**
* @brief iot_edge_pickup_a_cmd() - to pick up a edge cmd to send to uart
* @param idx: point to the index of the data
* @retval: the idx of the cmd in edgecom_cmd_t array
if the idx is >= EDGECOM_MAX_CMD, means no cmd to pick now
*/
static uint8_t iot_edge_pickup_a_cmd(uint8_t *idx)
{
uint8_t ret = true;
uint8_t index;
edge_obj_t *p_edge_obj = &prototask_contxt.edge_obj;
uint8_t *p_loop_cache_sign = (uint8_t*)&p_edge_obj->loop_cache_sign;
uint8_t *p_edge_cmd_sign = (uint8_t*)&p_edge_obj->cache_info.edge_cmd_sign;
for (index = 0; index < EDGECOM_MAX_CMD; index++) {
if ((iot_bitmap_is_set(p_loop_cache_sign, sizeof(uint32_t), index + 1)) &&
(iot_bitmap_is_set(p_edge_cmd_sign, sizeof(uint32_t), index + 1))) {
iot_bitmap_clear(p_loop_cache_sign, sizeof(uint32_t), index + 1);
break;
}
}
if(index >= EDGECOM_MAX_CMD) {
ret = false;
}
*idx = index;
return ret;
}
/* intercall */
static void edge_post_internal_msg_handle(uint8_t msg_id)
{
iot_proto_task_post_msg(EDGE_INTERNAL_MSG, msg_id, NULL, 0,
IOT_PROTO_TASK_QUEUE_LP);
}
/**
* @brief proto_post_data_to_edge_msg_handle() - to post msg data to edge
* @param msg_id: message id
* @param data: message data
* @param data_len: message data length
*/
void proto_post_data_to_edge_msg_handle(uint8_t msg_id, void *data,
uint16_t data_len)
{
uint8_t *pkt_data;
iot_pkt_t *pkt = NULL;
if (data != NULL && data_len) {
pkt = iot_pkt_alloc(data_len, IOT_GREE_APP_MID);
if (pkt == NULL) {
iot_cus_printf("[edge]alloc pkt size(%d) error\n", data_len);
IOT_ASSERT(0);
return;
}
pkt_data = iot_pkt_put(pkt, data_len);
os_mem_cpy(pkt_data, data, data_len);
}
iot_proto_task_post_msg(EDGE_INPUT_MSG, msg_id, pkt,
0, IOT_PROTO_TASK_QUEUE_LP);
}
/* timer */
/* for uart respond data time out */
static void post_uart_receive_timer_msg(timer_id_t timer_id, void * arg)
{
iot_proto_task_post_msg(EDGE_TIMER_MSG, EDGE_TIMEROUT_UART_READ_ID, arg,
0, IOT_PROTO_TASK_QUEUE_LP);
}
/* for edge in starting and stopping time out */
static void post_monitor_start_stop_timer_msg(timer_id_t timer_id, void * arg)
{
iot_proto_task_post_msg(EDGE_TIMER_MSG, EDGE_MONITOR_START_STOP_ID, arg,
0, IOT_PROTO_TASK_QUEUE_LP);
}
/* interval of two cache cmd */
static void post_next_cache_timer_msg(timer_id_t timer_id, void * arg)
{
iot_proto_task_post_msg(EDGE_TIMER_MSG, EDGE_TIMEROUT_NEXT_CACHE_ID, arg,
0, IOT_PROTO_TASK_QUEUE_LP);
}
/**
* @brief iot_load_edge_info_from_cus_flash() - load edge info from cus flash.
* @param edge_info: the edge info load from customer flash.
*/
static void iot_load_edge_info_from_cus_flash(edgecom_flash_info_t *edge_info)
{
uint8_t ret = 0;
ret = cus_app_flash_read(APP_FLASH_START_ADDR,
(uint8_t*)edge_info, sizeof(edgecom_flash_info_t));
if (ret == 0) {
// check magic
if ((edge_info->magic_start != IOT_PROTO_CUST_FLASHINFO_MAGIC1) ||
(edge_info->magic_end != IOT_PROTO_CUST_FLASHINFO_MAGIC2)) {
ret = ERR_FAIL;
}
}
if (ret) {
iot_cus_printf("reset edge flash info\n");
os_mem_set(edge_info, 0, sizeof(edgecom_flash_info_t));
edge_info->magic_start = IOT_PROTO_CUST_FLASHINFO_MAGIC1;
edge_info->magic_end = IOT_PROTO_CUST_FLASHINFO_MAGIC2;
edge_info->cmd_tol_tm = UART_MAX_TIMEOUT;
edge_info->cmd_each_tm = UART_RX_TIMEOUT;
edge_info->cmd_starting_stopping_tm = EDGE_STARTING_STOPPING_TIMEOUT;
edge_info->cmd_inverval = UART_NEXT_CACHE_TIMEOUT;
} else {
iot_cus_printf("load edge flash info success\n");
}
}
/**
* @brief iot_save_edge_info_to_cus_flash() - save edge info to cusom flash.
* @param edge_info: the edge info will save to customer flash.
* @retval: - success return 0.
*/
uint8_t iot_save_edge_info_to_cus_flash(edgecom_flash_info_t *edge_info)
{
uint8_t ret = 0;
ret = cus_app_flash_write(APP_FLASH_START_ADDR, (uint8_t*)edge_info,
sizeof(edgecom_flash_info_t));
if (ret) {
iot_cus_printf("save edge flash info err\n");
}
return ret;
}
uint8_t iot_edge_tmr_init(void)
{
uint8_t ret = 0;
edge_obj_t *p_edge_obj = &prototask_contxt.edge_obj;
p_edge_obj->edge_monitor_start_stop_tmr =
os_create_timer(IOT_GREE_APP_MID, false,
post_monitor_start_stop_timer_msg, NULL);
if (p_edge_obj->edge_monitor_start_stop_tmr == 0) {
ret = 1;
goto error_0;
}
p_edge_obj->next_cache_tmr =
os_create_timer(IOT_GREE_APP_MID, false,
post_next_cache_timer_msg, NULL);
if (p_edge_obj->next_cache_tmr == 0) {
ret = 2;
goto error_1;
}
p_edge_obj->uart_rx_tmr =
os_create_timer(IOT_GREE_APP_MID, false,
post_uart_receive_timer_msg, NULL);
if (p_edge_obj->uart_rx_tmr == 0) {
ret = 3;
goto error_2;
}
goto success;
error_2:
os_delete_timer(p_edge_obj->next_cache_tmr);
error_1:
os_delete_timer(p_edge_obj->edge_monitor_start_stop_tmr);
error_0:
success:
iot_cus_printf("edge timer create ret=%d\n", ret);
return ret;
}
uint8_t iot_edge_get_device_data(uint8_t *pdata, uint8_t **dev_data,
uint8_t *dev_data_len)
{
uint8_t ret = false;
uint32_t di = 0;
proto_645_header_t *dl645_frm;
ge_frame_data_send_set_subfn160_t *p_data;
p_data = (ge_frame_data_send_set_subfn160_t *)pdata;
if ((p_data->hdr.hdr.fn != PROTO_GE_PLC_SET_CMD) ||
(p_data->hdr.subfn != PROTO_GE_DATA_CMD)) {
goto out;
}
if (p_data->resv == DL645_07_RESV0_RESV) {
dl645_frm = (proto_645_header_t *)p_data->data;
iot_proto_645_ext_sub33_handle(dl645_frm->data, dl645_frm->len);
proto_645_2007_byte_to_di(dl645_frm->data, di);
iot_cus_printf("[edge]recv di=%08X\n", di);
if ((di == DL645_07_DI_DL645_TYPE) || (di == DL645_07_DI_MODBUS_TYPE)) {
/* extend */
*dev_data = &dl645_frm->data[DL645_DI_LEN];
*dev_data_len = dl645_frm->len - DL645_DI_LEN;
iot_cus_printf("[edge]dump 645\n");
iot_common_bin_dump(*dev_data, *dev_data_len);
ret = true;
}
}
out:
return ret;
}
/**
* @brief iot_edge_receive_data_handle() - to handle the data which received
from uart during edge running
* @param data: point to the data will send to PLC
* @param len length of the data
* @param idx the idx of the cmd in edgecom_cmd_t array, it means which
cmd is waiting for uart response
* @retval: true or false
*/
static uint8_t
iot_edge_receive_data_handle(uint8_t *data, uint8_t len, uint8_t idx)
{
uint8_t ret = false;
uint8_t *dev_data;
uint8_t dev_data_len;
/* point to data to check */
uint8_t *tmp_buf;
/* data cnt in each gree frame */
uint16_t data_len;
/* length of one gree frame */
uint16_t frame_len;
uint16_t cur_pos = 0;
uint32_t di;
iot_pkt_t *p_pkt = NULL;
edgecom_flash_info_t *p_cache_info =
&prototask_contxt.edge_obj.cache_info;
ge_frame_data_send_set_subfn160_t *p_ge_frame = NULL;
ge_frm_tail_t *p_ge_frame_tail = NULL;
proto_645_header_t *p_dl645_hdr = NULL;
proto_645_tailer_t *p_dl645_tail = NULL;
/* other cmd go to out */
do {
data_len = 0;
tmp_buf = data + cur_pos;
if (cur_pos >= (len - 1)) {
iot_cus_printf("[edge][err] pos=%d >= %d - 1\n", cur_pos, len);
break;
}
ret = ge_frame_data_len(tmp_buf, len - cur_pos, &data_len);
if (ret != ERR_OK) {
/* not get a complete frame */
iot_cus_printf("[edge][err] incomplete frame\n");
break;
}
frame_len = data_len + GE_FRM_MIN_LEN;
cur_pos += frame_len;
if (!iot_edge_get_device_data(tmp_buf, &dev_data, &dev_data_len)) {
continue;
}
if (iot_bitmap_is_set((uint8_t *)&p_cache_info->edge_cmd_sign,
sizeof(uint32_t), idx + 1)) {
if (os_mem_cmp(p_cache_info->cmd_list[idx].rx_buf, dev_data,
dev_data_len)) {
os_mem_cpy(p_cache_info->cmd_list[idx].rx_buf, dev_data,
dev_data_len);
p_cache_info->cmd_list[idx].rx_len = dev_data_len;
/* change 645 di */
proto_645_2007_byte_to_di(dev_data - DL645_DI_LEN, di);
if (di == DL645_07_DI_DL645_TYPE) {
di = idx + DL645_07_DI_EDGE_645_MIN_CMD;
} else {
di = idx + DL645_07_DI_EDGE_MODBUS_MIN_CMD;
}
p_ge_frame = (ge_frame_data_send_set_subfn160_t*)tmp_buf;
p_ge_frame_tail = (ge_frm_tail_t*)(tmp_buf + frame_len -
sizeof(ge_frm_tail_t));
p_dl645_hdr = (proto_645_header_t*)p_ge_frame->data;
proto_645_2007_di_to_byte(di, p_dl645_hdr->data);
iot_proto_645_ext_add33_handle(dev_data - DL645_DI_LEN,
dev_data_len + DL645_DI_LEN);
p_dl645_tail = (proto_645_tailer_t*)(p_dl645_hdr->data +
p_dl645_hdr->len);
/* change cs */
p_dl645_tail->cs =iot_proto_645_calc_cs(p_dl645_hdr);
/* change ge tail */
p_ge_frame_tail->check_sum = ge_frm_checksum_calc(tmp_buf,
frame_len- sizeof(ge_frm_tail_t));
ret = true;
} else {
iot_cus_printf("the cache data has not change\n");
continue;
}
} else {
iot_cus_printf("the cmd has been cancelled\n");
continue;
}
p_pkt = iot_pkt_alloc(frame_len, IOT_GREE_APP_MID);
if (p_pkt == NULL) {
iot_cus_printf("%s pkt Malloc Failed !!", __FUNCTION__);
goto out;
}
os_mem_cpy(iot_pkt_put(p_pkt, frame_len), tmp_buf, frame_len);
iot_edge_post_to_proto_msg_handle(p_pkt, EDGE_OUTPUT_DL645_PKT_ID);
} while (cur_pos < len);
out:
return ret;
}
/**
* @brief iot_edge_add_cache() - to add an edge cache cmd
* @param data: point to the data of cmd
* @param len length of the data
*/
static void iot_edge_add_cache(uint8_t *data, uint16_t len)
{
uint8_t idx;
uint8_t tx_len;
edge_cache_cmd_info_t *p_data = (edge_cache_cmd_info_t *)data;
edgecom_flash_info_t *flash_info = &prototask_contxt.edge_obj.cache_info;
idx = p_data->idx;
tx_len = (uint8_t)(len - sizeof(edge_cache_cmd_info_t));
iot_bitmap_set((uint8_t *)&flash_info->edge_cmd_sign, sizeof(uint32_t),
idx + 1);
os_mem_cpy(flash_info->cmd_list[idx].tx_buf, p_data->data, tx_len);
flash_info->cmd_list[idx].tx_len = tx_len;
iot_save_edge_info_to_cus_flash(flash_info);
}
/**
* @brief iot_edge_del_cache() - to cancel an edge cache cmd
* @param data: point to the data of cmd
* @param len length of the data
*/
static void iot_edge_del_cache(uint8_t *data, uint16_t len)
{
(void)len;
uint8_t idx;
edge_cache_cmd_info_t *p_data = (edge_cache_cmd_info_t *)data;
edgecom_flash_info_t *flash_info = &prototask_contxt.edge_obj.cache_info;
idx = p_data->idx;
iot_bitmap_clear((uint8_t *)&flash_info->edge_cmd_sign, sizeof(uint32_t),
idx + 1);
os_mem_set(&flash_info->cmd_list[idx], 0, sizeof(edgecom_cmd_t));
iot_save_edge_info_to_cus_flash(flash_info);
}
/**
* @brief iot_edge_query_cache_info_cache() - to get the information of
an edge cache cmd
* @param data: point to the data of cmd
* @param len length of the data
*/
static void iot_edge_query_cache_info_cache(uint8_t *data, uint16_t len)
{
uint8_t pkt_len;
edge_cache_cmd_info_t *p_query_info = (edge_cache_cmd_info_t *)data;
uint8_t type = p_query_info->cmd_type;
uint8_t idx = p_query_info->idx;
iot_pkt_t *p_pkt = NULL;
edgecom_flash_info_t *flash_info = &prototask_contxt.edge_obj.cache_info;
pkt_len = sizeof(edge_cache_cmd_info_t) + flash_info->cmd_list[idx].tx_len;
p_pkt = iot_pkt_alloc(pkt_len, IOT_GREE_APP_MID);
if (!p_pkt) {
iot_cus_printf("%s no pkt\n", __FUNCTION__);
goto out;
}
p_query_info = (edge_cache_cmd_info_t *)iot_pkt_put(p_pkt, pkt_len);
p_query_info->cmd_type = type;
p_query_info->idx = idx;
os_mem_cpy(p_query_info->data, flash_info->cmd_list[idx].tx_buf,
flash_info->cmd_list[idx].tx_len);
iot_edge_post_to_proto_msg_handle(p_pkt, EDGE_OUTPUT_RESP_CACHE_INFO_ID);
out:
return;
}
static void iot_edge_uart_rx_time_handle(edgecom_flash_info_t *cache_info)
{
if (cache_info->cmd_tol_tm < cache_info->cmd_each_tm) {
cache_info->cmd_each_tm = cache_info->cmd_tol_tm;
} else {
cache_info->cmd_tol_tm -= (cache_info->cmd_tol_tm %
cache_info->cmd_each_tm);
}
}
/* @brief iot_edge_delay_time_set_handle() - to set the information of
delay time
* @param data: point to the data of cmd
* @param len length of the data
* @retval: point to the information
*/
static iot_pkt_t *
iot_edge_delay_time_set_handle(uint8_t *data, uint16_t len)
{
edge_delay_time_info_t *p_data = (edge_delay_time_info_t *)data;
edge_obj_t *p_edge_obj = &prototask_contxt.edge_obj;
p_edge_obj->cache_info.cmd_inverval = p_data->cmd_inverval;
p_edge_obj->cache_info.cmd_tol_tm = p_data->cmd_tol_tm;
iot_edge_uart_rx_time_handle(&p_edge_obj->cache_info);
/* save to flash */
iot_save_edge_info_to_cus_flash(&p_edge_obj->cache_info);
return NULL;
}
/* @brief iot_edge_delay_time_inner_set_handle() - to set the inner delay time,
starting_stopping time and each overtime
* @param data: point to the data of cmd
* @param len length of the data
* @retval: point to the information
*/
static iot_pkt_t *
iot_edge_delay_time_inner_set_handle(uint8_t *data, uint16_t len)
{
edge_delay_time_info_inner_t *p_data = (edge_delay_time_info_inner_t *)data;
edge_obj_t *p_edge_obj = &prototask_contxt.edge_obj;
p_edge_obj->cache_info.cmd_starting_stopping_tm =
p_data->cmd_starting_stopping_tm;
p_edge_obj->cache_info.cmd_each_tm = p_data->cmd_each_tm;
iot_edge_uart_rx_time_handle(&p_edge_obj->cache_info);
/* save to flash */
iot_save_edge_info_to_cus_flash(&p_edge_obj->cache_info);
return NULL;
}
/* @brief iot_edge_baud_set_handle() - to set the edge command baud
* @param data: point to the data of cmd
* @param len length of the data
*/
static void iot_edge_baud_set_handle(uint8_t *data, uint16_t len)
{
uint8_t i, j;
uint8_t cnt = *data;
edge_baud_cmd_t *edge_cmd = (edge_baud_cmd_t *)(data + 1);
edgecom_flash_info_t *cache_info = &prototask_contxt.edge_obj.cache_info;
uint8_t need_save_flash = 0;
if (cnt == 0) {
return;
}
for (i = 0; i < cnt; i++) {
j = edge_cmd->index - 1;
if (j < EDGECOM_MAX_CMD &&
(edge_cmd->baud_info.baud_idx !=
cache_info->baud_info[j].baud_idx ||
edge_cmd->baud_info.parity != cache_info->baud_info[j].parity)) {
/* change param */
cache_info->baud_info[j].baud_idx = edge_cmd->baud_info.baud_idx;
cache_info->baud_info[j].parity = edge_cmd->baud_info.parity;
need_save_flash = 1;
}
edge_cmd++;
}
/* save to flash */
if (need_save_flash) {
iot_save_edge_info_to_cus_flash(cache_info);
}
return;
}
/**
* @brief iot_edge_delay_time_query_handle() - to get the information of
delay time
*/
static void iot_edge_delay_time_query_handle(void)
{
uint8_t pkt_len = sizeof(edge_delay_time_info_t);
edgecom_flash_info_t *p_edge_obj = &prototask_contxt.edge_obj.cache_info;
iot_pkt_t *p_pkt = NULL;
edge_delay_time_info_t *p_time_info;
p_pkt = iot_pkt_alloc(pkt_len, IOT_GREE_APP_MID);
if (!p_pkt) {
iot_cus_printf("%s no pkt\n", __FUNCTION__);
goto out;
}
p_time_info = (edge_delay_time_info_t *)iot_pkt_put(p_pkt, pkt_len);
p_time_info->cmd_inverval = p_edge_obj->cmd_inverval;
p_time_info->cmd_tol_tm = p_edge_obj->cmd_tol_tm;
iot_edge_post_to_proto_msg_handle(p_pkt, EDGE_OUTPUT_RESP_DELAY_TIME_ID);
out:
return;
}
/**
* @brief iot_edge_delay_time_inner_query_handle() - to get the information of
delay time
*/
static void iot_edge_delay_time_inner_query_handle(void)
{
uint8_t pkt_len = sizeof(edge_delay_time_info_inner_t);
edgecom_flash_info_t *p_edge_obj = &prototask_contxt.edge_obj.cache_info;
iot_pkt_t *p_pkt = NULL;
edge_delay_time_info_inner_t *p_time_info;
p_pkt = iot_pkt_alloc(pkt_len, IOT_GREE_APP_MID);
if (!p_pkt) {
iot_cus_printf("%s no pkt\n", __FUNCTION__);
goto out;
}
p_time_info = (edge_delay_time_info_inner_t *)iot_pkt_put(p_pkt, pkt_len);
p_time_info->cmd_starting_stopping_tm = p_edge_obj->cmd_starting_stopping_tm;
p_time_info->cmd_each_tm = p_edge_obj->cmd_each_tm;
iot_edge_post_to_proto_msg_handle(p_pkt, EDGE_OUTPUT_RESP_DELAY_TIME_INNER_ID);
out:
return;
}
/**
* @brief iot_edge_baud_query_handle() - to get the information of baud
*/
static void iot_edge_baud_query_handle(void)
{
uint8_t i;
uint16_t pkt_len;
uint8_t *pkt_data;
iot_pkt_t *p_pkt = NULL;
edge_baud_cmd_t *p_baud_cmd;
edgecom_flash_info_t *p_cache_info = &prototask_contxt.edge_obj.cache_info;
pkt_len = sizeof(edge_baud_cmd_t) * EDGECOM_MAX_CMD + sizeof(uint8_t);
p_pkt = iot_pkt_alloc(pkt_len, IOT_GREE_APP_MID);
if (!p_pkt) {
iot_cus_printf("%s no pkt\n", __FUNCTION__);
goto out;
}
pkt_data = iot_pkt_put(p_pkt, pkt_len);
*pkt_data = EDGECOM_MAX_CMD;
p_baud_cmd = (edge_baud_cmd_t *)(pkt_data + sizeof(uint8_t));
for (i = 0; i < EDGECOM_MAX_CMD; i++) {
p_baud_cmd->index = i + 1;
p_baud_cmd->baud_info.baud_idx = p_cache_info->baud_info[i].baud_idx;
p_baud_cmd->baud_info.parity = p_cache_info->baud_info[i].parity;
p_baud_cmd++;
}
iot_edge_post_to_proto_msg_handle(p_pkt, EDGE_OUTPUT_RESP_BAUD_ID);
out:
return;
}
/**
* @brief iot_edge_cache_cnt_query_handle() - to get the count of edge command
*/
static void iot_edge_cache_cnt_query_handle(void)
{
uint8_t pkt_len = sizeof(edge_cmd_cnt_t);
uint32_t edge_cmd_sign =
prototask_contxt.edge_obj.cache_info.edge_cmd_sign;
edge_cmd_cnt_t *cmd_cnt;
iot_pkt_t *p_pkt = NULL;
p_pkt = iot_pkt_alloc(pkt_len, IOT_GREE_APP_MID);
if (!p_pkt) {
iot_cus_printf("%s no pkt\n", __FUNCTION__);
goto out;
}
cmd_cnt = (edge_cmd_cnt_t *)iot_pkt_put(p_pkt, pkt_len);
cmd_cnt->cnt = (uint8_t)iot_bitmap_cbs((uint8_t *)&edge_cmd_sign,
sizeof(edge_cmd_sign));
iot_cus_printf("cache cnt = %d\n", cmd_cnt->cnt);
iot_edge_post_to_proto_msg_handle(p_pkt, EDGE_OUTPUT_RESP_CACHE_CNT_ID);
out:
return;
}
/**
* @brief iot_edge_input_cache_msg_id_handle() - to handle the message of edge
cmd
* @param msg_id: message id
* @param data: point to the data of cmd
* @param len length of the data
* @retval: true or false
*/
static uint8_t iot_edge_input_cache_msg_id_handle(uint8_t msg_id,
uint8_t *data, uint16_t len)
{
switch(msg_id) {
case EDGE_INPUT_ADD_CACHE_ID:
{
iot_edge_add_cache(data, len);
break;
}
case EDGE_INPUT_DEL_CACHE_ID:
{
/* to do */
iot_edge_del_cache(data, len);
break;
}
case EDGE_INPUT_QUERY_CACHE_INFO_ID:
{
/* to do */
iot_edge_query_cache_info_cache(data, len);
break;
}
case EDGE_INPUT_SET_DELAY_TIME_ID:
{
iot_edge_delay_time_set_handle(data, len);
break;
}
case EDGE_INPUT_QUERY_DELAY_TIME_ID:
{
iot_edge_delay_time_query_handle();
break;
}
case EDGE_INPUT_QUERY_CACHE_CNT_ID:
{
iot_edge_cache_cnt_query_handle();
break;
}
case EDGE_INPUT_SET_DELAY_TIME_INNER_ID:
{
iot_edge_delay_time_inner_set_handle(data, len);
break;
}
case EDGE_INPUT_QUERY_DELAY_TIME_INNER_ID:
{
iot_edge_delay_time_inner_query_handle();
break;
}
case EDGE_INPUT_SET_BAUD_ID:
{
iot_edge_baud_set_handle(data, len);
break;
}
case EDGE_INPUT_QUERY_BAUD_ID:
{
iot_edge_baud_query_handle();
break;
}
default:
break;
}
return true;
}
void iot_edge_init(void)
{
iot_load_edge_info_from_cus_flash(&prototask_contxt.edge_obj.cache_info);
}
void iot_edge_state_machine(uint8_t msg, uint8_t msg_id, void *arg)
{
uint8_t next_state;
uint8_t current_state = prototask_contxt.edge_obj.edge_state;
next_state = edge_state_hdl_tbl[current_state].cmd_handle_fn(msg, msg_id,
arg);
if (next_state != current_state) {
prototask_contxt.edge_obj.edge_state = next_state;
}
iot_cus_printf("[EDGE_SM]cur_state=%d, next_state=%d, msg=%d msg_id=%d\n",
current_state, next_state, msg, msg_id);
}
/**
* @brief iot_edge_state_idle_handler() - to handle the idle state of edge
* @param msg: message type
* @param msg_id: message id
* @param arg: point to the data
* @retval: the next state of edge state machine
*/
static uint8_t
iot_edge_state_idle_handler(uint8_t msg, uint8_t msg_id, void *arg)
{
uint8_t next_state = edge_state_idle;
uint8_t *p_input_data = NULL;
uint8_t input_len = 0;
void **pp_output_data = NULL;
iot_pkt_t *p_pkt = NULL;
edge_obj_t *p_edge_obj = &prototask_contxt.edge_obj;
if (arg != NULL) {
p_input_data = iot_pkt_data(arg);
input_len = iot_pkt_data_len(arg);
}
switch(msg)
{
case EDGE_INPUT_MSG:
{
if (msg_id == EDGE_INPUT_REQ_START_ID) {
if (p_edge_obj->cache_info.edge_cmd_sign) {
next_state = edge_state_starting;
p_edge_obj->uart_hdl = *(void**)p_input_data;
p_edge_obj->loop_cache_sign =
p_edge_obj->cache_info.edge_cmd_sign;
os_start_timer(p_edge_obj->edge_monitor_start_stop_tmr,
p_edge_obj->cache_info.cmd_starting_stopping_tm);
} else {
p_pkt = iot_pkt_alloc(sizeof(uint32_t), IOT_GREE_APP_MID);
if (p_pkt == NULL) {
iot_cus_printf("%s pkt Malloc Failed!\n", __FUNCTION__);
goto out;
}
pp_output_data = (void **)iot_pkt_put(p_pkt,
sizeof(uint32_t));
*pp_output_data = *(void **)iot_pkt_data(arg);
iot_edge_post_to_proto_msg_handle(p_pkt,
EDGE_OUTPUT_STOPPED_ID);
iot_cus_printf("[EDGE_SM_IDLE]edge no cache\n");
}
} else if (INPUT_PROTO_CHECK(msg_id)) {
iot_cus_printf("input_len= %d\n", input_len);
iot_common_bin_dump(p_input_data, input_len);
iot_edge_input_cache_msg_id_handle(msg_id, p_input_data,
input_len);
}
break;
}
default:
break;
}
if (arg != NULL) {
iot_pkt_free(arg);
}
out:
return next_state;
}
/**
* @brief iot_edge_state_starting_handler() - to handle the starting state of
edge
* @param msg: message type
* @param msg_id: message id
* @param arg: point to the data
* @retval: the next state of edge state machine
*/
static uint8_t
iot_edge_state_starting_handler(uint8_t msg, uint8_t msg_id, void *arg)
{
uint8_t next_state = edge_state_starting;
uint8_t *p_input_data = NULL;
uint8_t input_len = 0;
void **pp_output_data = NULL;
iot_pkt_t *p_pkt = NULL;
edge_obj_t *p_edge_obj = &prototask_contxt.edge_obj;
if (arg != NULL) {
p_input_data = iot_pkt_data(arg);
input_len = iot_pkt_data_len(arg);
}
switch(msg)
{
case EDGE_INPUT_MSG:
{
if (msg_id == EDGE_INPUT_REQ_STOPID_ID) {
p_pkt = iot_pkt_alloc(sizeof(uint32_t), IOT_GREE_APP_MID);
if (p_pkt == NULL) {
iot_cus_printf("%s pkt Malloc Failed!\n", __FUNCTION__);
goto out;
}
pp_output_data = (void **)iot_pkt_put(p_pkt, sizeof(uint32_t));
*pp_output_data = p_edge_obj->uart_hdl;
p_edge_obj->uart_hdl = NULL;
iot_edge_post_to_proto_msg_handle(p_pkt,
EDGE_OUTPUT_STOPPED_ID);
iot_os_stop_timer_handle(p_edge_obj->edge_monitor_start_stop_tmr,
EDGE_TIMER_MSG, EDGE_MONITOR_START_STOP_ID);
next_state = edge_state_idle;
} else if (INPUT_PROTO_CHECK(msg_id)) {
iot_edge_input_cache_msg_id_handle(msg_id, p_input_data,
input_len);
}
break;
}
case EDGE_TIMER_MSG:
{
if (msg_id == EDGE_MONITOR_START_STOP_ID) {
edge_post_internal_msg_handle(EDGE_INTERNAL_UART_IDLE_ID);
next_state = edge_state_started;
}
break;
}
case EDGE_UART_RX_MSG:
{
iot_os_stop_timer_handle(p_edge_obj->edge_monitor_start_stop_tmr,
EDGE_TIMER_MSG, EDGE_MONITOR_START_STOP_ID);
os_start_timer(p_edge_obj->edge_monitor_start_stop_tmr,
p_edge_obj->cache_info.cmd_starting_stopping_tm);
break;
}
default:
break;
}
if (arg != NULL) {
iot_pkt_free(arg);
}
out:
return next_state;
}
/**
* @brief iot_edge_state_started_handler() - to handle the started state of edge
* @param msg: message type
* @param msg_id: message id
* @param arg: point to the data
* @retval: the next state of edge state machine
*/
static uint8_t
iot_edge_state_started_handler(uint8_t msg, uint8_t msg_id, void *arg)
{
uint8_t next_state = edge_state_started;
uint8_t cmd_bit_idx;
uint8_t *p_input_data = NULL;
uint8_t input_len = 0;
iot_pkt_t *cmd_pkt = NULL;
/* point to the tx_buf of cmd */
uint8_t *tx_data;
/* length of tx_buf */
uint8_t tx_data_len;
edge_obj_t *p_edge_obj = &prototask_contxt.edge_obj;
edgecom_cmd_t *p_cmd_list = prototask_contxt.edge_obj.cache_info.cmd_list;
if (arg != NULL) {
p_input_data = iot_pkt_data(arg);
input_len = iot_pkt_data_len(arg);
}
switch(msg)
{
case EDGE_INTERNAL_MSG:
{
if (msg_id == EDGE_INTERNAL_UART_IDLE_ID) {
edge_post_internal_msg_handle(EDGE_INTERNAL_NEXT_CACHE_ID);
} else if (msg_id == EDGE_INTERNAL_NEXT_CACHE_ID) {
if (iot_edge_pickup_a_cmd(&cmd_bit_idx)) {
tx_data_len = p_cmd_list[cmd_bit_idx].tx_len;
tx_data = p_cmd_list[cmd_bit_idx].tx_buf;
cmd_pkt = iot_pkt_alloc(tx_data_len, IOT_GREE_APP_MID);
if (cmd_pkt == NULL) {
iot_cus_printf("%s pkt Malloc Failed!\n", __FUNCTION__);
goto out;
}
os_mem_cpy(iot_pkt_put(cmd_pkt, tx_data_len), tx_data,
tx_data_len);
p_edge_obj->cmd_bit_idx = cmd_bit_idx;
iot_edge_uart_send(cmd_pkt);
os_start_timer(p_edge_obj->uart_rx_tmr,
p_edge_obj->cache_info.cmd_each_tm);
p_edge_obj->uart_rx_total_time = 0;
} else {
iot_cus_printf("[EDGE_SM_STARTED][UART_RX_TIMEOUT]"
"from started to stopping\n");
next_state = edge_state_stopping;
os_start_timer(p_edge_obj->edge_monitor_start_stop_tmr,
p_edge_obj->cache_info.cmd_starting_stopping_tm);
}
}
break;
}
case EDGE_INPUT_MSG:
{
if (msg_id == EDGE_INPUT_REQ_STOPID_ID) {
if (os_is_timer_active(p_edge_obj->next_cache_tmr)) {
iot_os_stop_timer_handle(p_edge_obj->next_cache_tmr,
EDGE_TIMER_MSG, EDGE_TIMEROUT_NEXT_CACHE_ID);
}
if (os_is_timer_active(p_edge_obj->uart_rx_tmr)) {
iot_os_stop_timer_handle(p_edge_obj->uart_rx_tmr,
EDGE_TIMER_MSG, EDGE_TIMEROUT_UART_READ_ID);
}
os_start_timer(p_edge_obj->edge_monitor_start_stop_tmr,
p_edge_obj->cache_info.cmd_starting_stopping_tm);
iot_cus_printf("[EDGE_SM_STARTED]"
"[EDGE_STARTING_STOPPING_TIMEOUT]started to stopping\n");
next_state = edge_state_stopping;
} else if (INPUT_PROTO_CHECK(msg_id)) {
iot_edge_input_cache_msg_id_handle(msg_id, p_input_data,
input_len);
}
break;
}
case EDGE_TIMER_MSG:
{
cmd_bit_idx = p_edge_obj->cmd_bit_idx;
if (msg_id == EDGE_TIMEROUT_UART_READ_ID) {
p_edge_obj->uart_rx_total_time +=
p_edge_obj->cache_info.cmd_each_tm;
if (p_edge_obj->uart_rx_total_time >=
p_edge_obj->cache_info.cmd_tol_tm) {
os_start_timer(p_edge_obj->next_cache_tmr,
p_edge_obj->cache_info.cmd_inverval);
} else {
tx_data_len = p_cmd_list[cmd_bit_idx].tx_len;
tx_data = p_cmd_list[cmd_bit_idx].tx_buf;
cmd_pkt = iot_pkt_alloc(tx_data_len, IOT_GREE_APP_MID);
if (cmd_pkt == NULL) {
iot_cus_printf("%s pkt Malloc Failed!\n", __FUNCTION__);
goto out;
}
os_mem_cpy(iot_pkt_put(cmd_pkt, tx_data_len), tx_data,
tx_data_len);
iot_edge_uart_send(cmd_pkt);
os_start_timer(p_edge_obj->uart_rx_tmr,
p_edge_obj->cache_info.cmd_each_tm);
}
} else if (msg_id == EDGE_TIMEROUT_NEXT_CACHE_ID) {
edge_post_internal_msg_handle(EDGE_INTERNAL_NEXT_CACHE_ID);
}
break;
}
case EDGE_UART_RX_MSG:
{
iot_os_stop_timer_handle(p_edge_obj->uart_rx_tmr,
EDGE_TIMER_MSG, EDGE_TIMEROUT_UART_READ_ID);
cmd_bit_idx = p_edge_obj->cmd_bit_idx;
os_start_timer(p_edge_obj->next_cache_tmr,
p_edge_obj->cache_info.cmd_inverval);
iot_edge_receive_data_handle(p_input_data, input_len, cmd_bit_idx);
break;
}
default:
break;
}
if (arg != NULL) {
iot_pkt_free(arg);
}
out:
return next_state;
}
/**
* @brief iot_edge_state_stopping_handler() - to handle the stopping state of
edge
* @param msg: message type
* @param msg_id: message id
* @param arg: point to the data
* @retval: the next state of edge state machine
*/
static uint8_t
iot_edge_state_stopping_handler(uint8_t msg, uint8_t msg_id, void *arg)
{
uint8_t next_state = edge_state_stopping;
uint8_t *p_input_data = NULL;
uint8_t input_len = 0;
edge_obj_t *p_edge_obj = &prototask_contxt.edge_obj;
if (arg != NULL) {
p_input_data = iot_pkt_data(arg);
input_len = iot_pkt_data_len(arg);
}
switch(msg)
{
case EDGE_TIMER_MSG:
{
if (msg_id == EDGE_MONITOR_START_STOP_ID) {
edge_post_internal_msg_handle(EDGE_INTERNAL_UART_IDLE_ID);
iot_cus_printf("[EDGE_SM_STOPPING][EDGE_INTERNAL_UART_IDLE_ID]"
"from stopping to stopped\n");
next_state = edge_state_stopped;
}
break;
}
case EDGE_UART_RX_MSG:
{
iot_os_stop_timer_handle(p_edge_obj->edge_monitor_start_stop_tmr,
EDGE_TIMER_MSG, EDGE_MONITOR_START_STOP_ID);
os_start_timer(p_edge_obj->edge_monitor_start_stop_tmr,
p_edge_obj->cache_info.cmd_starting_stopping_tm);
p_edge_obj->debug_statistic_cnt.stopping_rxuart_cnt++;
iot_cus_printf("[EDGE_SM_STOPPING][EDGE_UART_RX_MSG]"
"receive data count %d\n",
p_edge_obj->debug_statistic_cnt.stopping_rxuart_cnt);
break;
}
case EDGE_INPUT_MSG:
{
if (INPUT_PROTO_CHECK(msg_id)) {
iot_edge_input_cache_msg_id_handle(msg_id, p_input_data,
input_len);
}
break;
}
default:
break;
}
if (arg != NULL) {
iot_pkt_free(arg);
}
return next_state;
}
/**
* @brief iot_edge_state_stopped_handler() - to handle the stopped state of edge
* @param msg: message type
* @param msg_id: message id
* @param arg: point to the data
* @retval: the next state of edge state machine
*/
static uint8_t
iot_edge_state_stopped_handler(uint8_t msg, uint8_t msg_id, void *arg)
{
uint8_t next_state = edge_state_stopped;
uint8_t *p_input_data = NULL;
uint8_t input_len = 0;
void **p_data;
iot_pkt_t *p_pkt = NULL;
edge_obj_t *p_edge_obj = &prototask_contxt.edge_obj;
if (arg != NULL) {
p_input_data = iot_pkt_data(arg);
input_len = iot_pkt_data_len(arg);
}
switch(msg)
{
case EDGE_INTERNAL_MSG:
{
if (msg_id == EDGE_INTERNAL_UART_IDLE_ID) {
p_pkt = iot_pkt_alloc(sizeof(uint32_t), IOT_GREE_APP_MID);
if (p_pkt == NULL) {
iot_cus_printf("%s pkt Malloc Failed!\n", __FUNCTION__);
goto out;
}
p_data = (void **)iot_pkt_put(p_pkt, sizeof(uint32_t));
*p_data = p_edge_obj->uart_hdl;
p_edge_obj->uart_hdl = NULL;
iot_edge_post_to_proto_msg_handle(p_pkt,
EDGE_OUTPUT_STOPPED_ID);
iot_cus_printf("[EDGE_SM_STOPPED][EDGE_OUTPUT_STOPPED_ID]"
"from stopped to idle\n");
next_state = edge_state_idle;
}
break;
}
case EDGE_INPUT_MSG:
{
if (INPUT_PROTO_CHECK(msg_id)) {
iot_edge_input_cache_msg_id_handle(msg_id, p_input_data,
input_len);
}
break;
}
default:
break;
}
if (arg != NULL) {
iot_pkt_free(arg);
}
out:
return next_state;
}