Files
kunlun/app/iot_cus_at_app/proto/app_proto_proc.c
2024-09-28 14:24:04 +08:00

992 lines
34 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 "app_main.h"
#include "app_uart.h"
#include "app_proto_proc.h"
#include "app_proto_proc_cco.h"
#include "app_cus_task.h"
#include "iot_app_pib_sta_api.h"
#include "iot_plc_sync_api.h"
#include "app_upg.h"
#if APP_IO_OPERATION_ENABLE
#include "app_gpio.h"
#endif /* end APP_IO_OPERATION_ENABLE */
uint16_t g_proto_frame_seq = 0;
uint16_t g_proto_sysctrl_frame_seq = 0;
static uint16_t g_proto_delay_seq = 0;
uint16_t app_proto_frame_dispatch(app_proto_frame_head *frame, uint8_t * out_buffer, uint16_t *length);
uint16_t app_proto_frame_tx(uint8_t * data, uint16_t data_length, app_source_e source, uint8_t * dst_addr);
uint16_t app_proto_get_version(app_proto_frame_head *frame, uint8_t * out_buffer, uint16_t *length);
uint16_t app_proto_get_mac_addr(app_proto_frame_head *frame, uint8_t * out_buffer, uint16_t *length);
uint16_t app_proto_get_dev_addr(app_proto_frame_head *frame, uint8_t * out_buffer, uint16_t *length);
uint16_t app_proto_set_dev_addr(app_proto_frame_head *frame, uint8_t * out_buffer, uint16_t *length);
uint16_t app_proto_reboot_module(app_proto_frame_head *frame, uint8_t * out_buffer, uint16_t *length);
uint16_t app_proto_data_trans_tx(app_proto_frame_head *frame, uint8_t * out_buffer, uint16_t *length);
uint16_t app_proto_data_trans_rx(app_proto_frame_head *frame, uint8_t * out_buffer, uint16_t *length);
uint16_t app_proto_qry_on_power_time(app_proto_frame_head *frame, uint8_t * out_buffer, uint16_t *length);
uint16_t app_proto_get_scan_band(app_proto_frame_head *frame, uint8_t * out_buffer, uint16_t *length);
uint16_t app_proto_set_scan_band(app_proto_frame_head *frame, uint8_t * out_buffer, uint16_t *length);
#if APP_IO_OPERATION_ENABLE
uint16_t app_proto_set_gpio(app_proto_frame_head *frame, uint8_t * out_buffer, uint16_t *length);
uint16_t app_proto_get_gpio(app_proto_frame_head *frame, uint8_t * out_buffer, uint16_t *length);
#endif /* end APP_IO_OPERATION_ENABLE */
uint16_t app_proto_get_calc_validity(app_proto_frame_head *frame, uint8_t * out_buffer, uint16_t *length);
uint16_t app_proto_get_uart_param(app_proto_frame_head *frame, uint8_t * out_buffer, uint16_t *length);
uint16_t app_proto_set_uart_param(app_proto_frame_head *frame, uint8_t * out_buffer, uint16_t *length);
uint16_t app_proto_sysctrl_data_to_plc(app_proto_frame_head *frame, uint8_t * out_buffer, uint16_t *length);
typedef uint16_t (*proto_proc_fn)(app_proto_frame_head *frame, uint8_t * out_buffer, uint16_t *length);
typedef struct {
uint16_t id;
uint16_t pad;
proto_proc_fn func;
} proto_proc_func_pair;
proto_proc_func_pair g_proto_proc_pair[] = {
{ ID_PROTO_CMD_GET_VERSION, 0, app_proto_get_version },
{ ID_PROTO_CMD_GET_MAC_ADDR, 0, app_proto_get_mac_addr },
{ ID_PROTO_CMD_GET_DEV_ADDR, 0, app_proto_get_dev_addr },
{ ID_PROTO_CMD_SET_DEV_ADDR, 0, app_proto_set_dev_addr },
{ ID_PROTO_CMD_REBOOT_MODULE, 0, app_proto_reboot_module },
{ ID_PROTO_CMD_QRY_ONPOWER_TIME, 0, app_proto_qry_on_power_time},
#if PLC_SUPPORT_STA_ROLE
{ ID_PROTO_CMD_GET_SCAN_BAND, 0, app_proto_get_scan_band },
{ ID_PROTO_CMD_SET_SCAN_BAND, 0, app_proto_set_scan_band },
//{ ID_PROTO_CMD_TRANS_FILE, 0, app_mcu_transfile_frame_rx },
#endif
#if PLC_SUPPORT_CCO_ROLE
{ ID_PROTO_CMD_TRANS_FILE, 0, app_proto_trans_file },
{ ID_PROTO_CMD_GET_WLIST_NUM, 0, app_proto_get_whitelist_num },
{ ID_PROTO_CMD_GET_WLIST_INFO, 0, app_proto_get_whitelist_info },
{ ID_PROTO_CMD_ADD_WLIST_NODE, 0, app_proto_add_whitelist_node },
{ ID_PROTO_CMD_DEL_WLIST_NODE, 0, app_proto_del_whitelist_node },
{ ID_PROTO_CMD_CLEAR_WLIST, 0, app_proto_clear_whitelist },
{ ID_PROTO_CMD_ENABLE_SELF_IDY, 0, app_proto_enable_network_identify_state },
{ ID_PROTO_CMD_SET_WLIST_STATE, 0, app_proto_set_whitelist_state },
{ ID_PROTO_CMD_GET_WLIST_STATE, 0, app_proto_get_whitelist_state },
{ ID_PROTO_CMD_GET_TOPO_NUM, 0, app_proto_get_topo_num },
{ ID_PROTO_CMD_GET_TOPO_INFO, 0, app_proto_get_topo_info },
{ ID_PROTO_CMD_GET_WORK_BAND, 0, app_proto_get_work_band },
{ ID_PROTO_CMD_SET_WORK_BAND, 0, app_proto_set_work_band },
//{ ID_PROTO_CMD_GET_TOPO_INO_EX, 0, app_proto_get_topo_info_ex },
#endif
#if APP_IO_OPERATION_ENABLE
{ ID_PROTO_CMD_SET_GPIO, 0, app_proto_set_gpio },
{ ID_PROTO_CMD_GET_GPIO, 0, app_proto_get_gpio },
#endif /* end APP_IO_OPERATION_ENABLE */
{ ID_PROTO_CMD_GET_NBNET_INFO, 0, app_proto_get_nbnet_info },
{ ID_PROTO_CMD_GET_CALC_VALI, 0, app_proto_get_calc_validity },
{ ID_PROTO_CMD_GET_UART_PARAM, 0, app_proto_get_uart_param },
{ ID_PROTO_CMD_SET_UART_PARAM, 0, app_proto_set_uart_param },
{ ID_PROTO_CMD_DATA_TRANS_TX, 0, app_proto_data_trans_tx },
{ ID_PROTO_CMD_DATA_TRANS_RX, 0, app_proto_data_trans_rx },
#if PLC_SUPPORT_CCO_ROLE
{ ID_PROTO_CMD_REMOTE_CMD_TX, 0, app_proto_remote_cmd_tx },
{ ID_PROTO_CMD_REMOTE_CMD_RX, 0, app_proto_remote_cmd_rx },
#endif
{ ID_PROTO_CMD_SYSCTRL_DATA_TRANS, 0, app_proto_sysctrl_data_to_plc},
//{ ID_PROTO_CMD_GET_NV_MAC_ADDR, 0, app_proto_get_nv_mac_addr },
//{ ID_PROTO_CMD_SET_NV_MAC_ADDR, 0, app_proto_set_nv_mac_addr },
};
void fill_proto_frame_fixed_info(app_proto_frame_head *head, uint16_t cmd, uint16_t seq, uint16_t data_length)
{
uint16_t crc = 0;
uint16_t length = sizeof(app_proto_frame_head) + data_length;
uint8_t *payload;
if (head == NULL) {
return;
}
head->head = APP_FRAME_HEAD_BYTE;
head->ctrl = PROTO_CTRL_RESPONSE;
head->cmd = cmd;
head->seq = seq;
head->length = data_length;
payload = (uint8_t *)head;
crc = iot_getcrc16(payload, length, IOT_CRC16_TYPE_XMODEM);
payload[length++] = (uint8_t)(crc >> PROTO_CRC_HIGH_BIT_OFFSET);
payload[length++] = (uint8_t)crc;
}
uint16_t app_proto_get_version(app_proto_frame_head *frame, uint8_t * out_buffer, uint16_t *length)
{
app_user_info_t user_info = {0};
proto_get_version_ind *ind = NULL;
uint8_t * payload;
uint16_t payload_length = APP_FRAME_MIN_LEN + sizeof(proto_get_version_ind);
if (frame == NULL || out_buffer == NULL || length == NULL) {
return ERR_FAIL;
}
payload = out_buffer;
os_mem_set(payload, 0, payload_length);
app_get_user_info(&user_info);
ind = (proto_get_version_ind *)(payload + sizeof(app_proto_frame_head));
(void) os_mem_cpy(ind->manu_code, user_info.manu_code, sizeof(user_info.manu_code));
(void) os_mem_cpy(ind->chip_type, user_info.chip_code, sizeof(user_info.chip_code));
ind->version = user_info.sw_ver;
iot_cus_printf("[proto]get version: version[0x%04x]\n", ind->version);
fill_proto_frame_fixed_info((app_proto_frame_head *)payload, frame->cmd, frame->seq,
sizeof(proto_get_version_ind));
*length = payload_length;
return ERR_OK;
}
uint16_t app_proto_get_mac_addr(app_proto_frame_head *frame, uint8_t * out_buffer, uint16_t *length)
{
proto_get_mac_addr_ind *ind = NULL;
uint8_t * payload;
uint16_t payload_length;
payload_length = APP_FRAME_MIN_LEN + sizeof(proto_get_mac_addr_ind);
if (frame == NULL || out_buffer == NULL || length == NULL) {
return ERR_FAIL;
}
payload = out_buffer;
os_mem_set(payload, 0, payload_length);
ind = (proto_get_mac_addr_ind *)(payload + sizeof(app_proto_frame_head));
iot_mac_addr_cpy(ind->addr, app_get_mac_addr());
fill_proto_frame_fixed_info((app_proto_frame_head *)payload, frame->cmd, frame->seq,
sizeof(proto_get_mac_addr_ind));
*length = payload_length;
return ERR_OK;
}
uint16_t app_proto_get_dev_addr(app_proto_frame_head *frame, uint8_t * out_buffer, uint16_t *length)
{
proto_get_mac_addr_ind *ind = NULL;
uint8_t * payload;
uint16_t payload_length;
payload_length = APP_FRAME_MIN_LEN + sizeof(proto_get_mac_addr_ind);
if (frame == NULL || out_buffer == NULL || length == NULL) {
return ERR_FAIL;
}
payload = out_buffer;
os_mem_set(payload, 0, payload_length);
ind = (proto_get_mac_addr_ind *)(payload + sizeof(app_proto_frame_head));
iot_mac_addr_cpy(ind->addr, app_get_mac_addr());
fill_proto_frame_fixed_info((app_proto_frame_head *)payload, frame->cmd, frame->seq,
sizeof(proto_get_mac_addr_ind));
*length = payload_length;
return ERR_OK;
}
uint16_t app_proto_set_dev_addr(app_proto_frame_head *frame, uint8_t * out_buffer, uint16_t *length)
{
app_proto_frame_head *head = NULL;
proto_set_dev_addr_ind *ind = NULL;
iot_oem_base_cfg_t * oem_cfg;
uint8_t * payload;
uint16_t payload_length;
app_entity_t *app_entry = NULL;
app_entry = app_get_main_entry();
payload_length = APP_FRAME_MIN_LEN + sizeof(proto_set_dev_addr_ind);
payload = out_buffer;
(void) os_mem_set(payload, 0, payload_length);
head = (app_proto_frame_head *)payload;
ind = (proto_set_dev_addr_ind *)head->data;
ind->ret_code = PROTO_RET_CODE_FAILED;
ind->reason = PROTO_REASON_FORMAT;
if (frame->length != (IOT_MAC_ADDR_LEN + PROTO_PAD_LEN1) ||
0 == iot_mac_addr_valid(frame->data)) {
return ERR_FAIL;
}
iot_oem_get_base_cfg(&oem_cfg);
iot_mac_addr_cpy(oem_cfg->module_mac, frame->data);
if (ERR_OK != iot_oem_set_base_cfg(oem_cfg)) {
return ERR_FAIL;
}
iot_mac_addr_cpy(app_entry->dev.mac_addr, frame->data);
#if PLC_SUPPORT_CCO_ROLE
app_set_mac_addr(frame->data);
#else
app_timer_start(APP_TIMER_ID_SET_MAC, PROTO_DELAY_MIN_TIME_MS, TIMER_TYPE_ONCE);
#endif
ind->ret_code = PROTO_RET_CODE_SUCCESS;
ind->reason = PROTO_REASON_NORMAL;
fill_proto_frame_fixed_info((app_proto_frame_head *)payload, frame->cmd, frame->seq,
sizeof(proto_set_dev_addr_ind));
*length = payload_length;
return ERR_OK;
}
uint16_t app_proto_reboot_module(app_proto_frame_head *frame, uint8_t * out_buffer, uint16_t *length)
{
proto_module_reboot_req *req = (proto_module_reboot_req *)(((uint8_t *)frame) + sizeof(app_proto_frame_head));
proto_module_reboot_ind *ind = NULL;
uint8_t * payload;
uint16_t payload_length = APP_FRAME_MIN_LEN + sizeof(proto_module_reboot_ind);
uint32_t delay = 0;
if (frame == NULL || out_buffer == NULL || length == NULL) {
return ERR_FAIL;
}
payload = out_buffer;
(void) os_mem_set(payload, 0, payload_length);
ind = (proto_module_reboot_ind *)(payload + sizeof(app_proto_frame_head));
if (frame->length == sizeof(proto_module_reboot_req)) {
static uint8_t flag = false;
if (flag == false) {
delay = req->delay; /* second */
delay *= PROTO_1S_CONVERT_MS; /* millisecond */
if (delay <= PROTO_DELAY_MIN_TIME_MS) { /* delay at least 500ms */
delay = PROTO_DELAY_MIN_TIME_MS;
}
app_timer_start(APP_TIMER_ID_REBOOT, delay, TIMER_TYPE_ONCE);
flag = true;
}
} else {
ind->ret_code = PROTO_RET_CODE_FAILED;
ind->reason = PROTO_REASON_FORMAT;
}
fill_proto_frame_fixed_info((app_proto_frame_head *)payload, frame->cmd, frame->seq,
sizeof(proto_module_reboot_ind));
*length = payload_length;
return ERR_OK;
}
uint16_t app_proto_qry_on_power_time(app_proto_frame_head *frame, uint8_t * out_buffer, uint16_t *length)
{
proto_qry_on_power_time_ind *ind = NULL;
uint8_t * payload;
uint16_t payload_length;
payload_length = APP_FRAME_MIN_LEN + sizeof(proto_qry_on_power_time_ind);
if (frame == NULL || out_buffer == NULL || length == NULL) {
return ERR_FAIL;
}
payload = out_buffer;
os_mem_set(payload, 0, payload_length);
ind = (proto_qry_on_power_time_ind *)(payload + sizeof(app_proto_frame_head));
iot_mac_addr_cpy(ind->addr, app_get_mac_addr());
ind->on_power_ms_time = os_boot_time32();
#if PLC_SUPPORT_CCO_ROLE
ind->frame_index = 0;
#else
os_mem_cpy(&ind->frame_index, frame->data, sizeof(uint16_t)) ;
#endif
APP_PRINTF("send indx %d", ind->frame_index);
fill_proto_frame_fixed_info((app_proto_frame_head *)payload, frame->cmd, frame->seq,
sizeof(proto_qry_on_power_time_ind));
*length = payload_length;
return ERR_OK;
}
uint16_t app_proto_get_scan_band(app_proto_frame_head *frame, uint8_t * out_buffer, uint16_t *length)
{
proto_get_fb_bitmap_ind *ind = NULL;
uint8_t *payload;
uint8_t *fb_bitmap;
uint16_t payload_length = APP_FRAME_MIN_LEN + sizeof(proto_get_fb_bitmap_ind);
if (frame == NULL || out_buffer == NULL || length == NULL) {
return ERR_FAIL;
}
if (0 == iot_app_get_scan_band_in_pib(&fb_bitmap)) {
return ERR_FAIL;
}
payload = out_buffer;
os_mem_set(payload, 0, payload_length);
ind = (proto_get_fb_bitmap_ind *)(payload + sizeof(app_proto_frame_head));
os_mem_cpy(ind->fb_bitmap, fb_bitmap, IOT_PLC_BAND_BITMAP_SIZE);
fill_proto_frame_fixed_info((app_proto_frame_head *)payload, frame->cmd,
frame->seq, sizeof(proto_get_fb_bitmap_ind));
*length = payload_length;
return ERR_OK;
}
uint16_t app_proto_set_scan_band(app_proto_frame_head *frame, uint8_t * out_buffer, uint16_t *length)
{
proto_set_fb_bitmap_req *req = NULL;
proto_set_fb_bitmap_ind *ind = NULL;
uint8_t *payload;
uint16_t payload_length = APP_FRAME_MIN_LEN + sizeof(proto_set_fb_bitmap_ind);
if (frame == NULL || out_buffer == NULL || length == NULL) {
return ERR_FAIL;
}
if (frame->length != sizeof(proto_set_fb_bitmap_req)) {
return ERR_FAIL;
}
req = (proto_set_fb_bitmap_req *)frame->data;
payload = out_buffer;
os_mem_set(payload, 0, payload_length);
ind = (proto_set_fb_bitmap_ind *)(payload + sizeof(app_proto_frame_head));
ind->ret_code = PROTO_RET_CODE_SUCCESS;
app_set_scan_band_bitmap(req->fb_bitmap);
iot_app_save_scan_band_to_pib(req->fb_bitmap, IOT_PLC_BAND_BITMAP_SIZE);
fill_proto_frame_fixed_info((app_proto_frame_head *)payload, frame->cmd,
frame->seq, sizeof(proto_set_fb_bitmap_ind));
*length = payload_length;
return ERR_OK;
}
uint16_t app_proto_get_calc_validity(app_proto_frame_head *frame, uint8_t * out_buffer, uint16_t *length)
{
proto_get_calc_vali_ind *ind = NULL;
uint8_t * payload;
uint16_t payload_length = APP_FRAME_MIN_LEN + sizeof(proto_get_calc_vali_ind);
if (frame == NULL || out_buffer == NULL || length == NULL) {
return ERR_FAIL;
}
payload = out_buffer;
os_mem_set(payload, 0, payload_length);
ind = (proto_get_calc_vali_ind *)(payload + sizeof(app_proto_frame_head));
ind->state = iot_board_calc_data_check();
fill_proto_frame_fixed_info((app_proto_frame_head *)payload, frame->cmd, frame->seq,
sizeof(proto_get_calc_vali_ind));
*length = payload_length;
return ERR_OK;
}
uint16_t app_proto_get_uart_param(app_proto_frame_head *frame,
uint8_t * out_buffer, uint16_t *length)
{
proto_get_uart_param_ind *ind = NULL;
uint8_t * payload;
uint16_t payload_length = APP_FRAME_MIN_LEN + sizeof(proto_get_uart_param_ind);
uart_cfg_t uart_para = {0};
if (frame == NULL || out_buffer == NULL || length == NULL) {
return ERR_FAIL;
}
if (frame->length != 0) {
APP_PRINTF("[ERR]%s Data length mismatch!", __FUNCTION__);
return ERR_FAIL;
}
payload = out_buffer;
os_mem_set(payload, 0, payload_length);
ind = (proto_get_uart_param_ind *)(payload + sizeof(app_proto_frame_head));
if (iot_app_get_uart_cfg_in_pib(&uart_para) != ERR_OK) {
APP_PRINTF("[ERR]%s Get uart config failed!", __FUNCTION__);
return ERR_FAIL;
}
if (0 == uart_para.uart_conf_vaild) {
ind->baudrate = APP_DEFAULT_BAUND_RATE;
ind->data_bits = APP_DEFAULT_DATA_BITS;
ind->stop_bits = APP_DEFAULT_STOP_BITS;
ind->parity = APP_DEFAULT_PARITY;
ind->threshold_value = APP_DEFAULT_THDVALUE;
} else {
ind->baudrate = uart_para.baud_rate;
ind->data_bits = uart_para.data_bits;
ind->stop_bits = uart_para.stop_bits;
ind->parity = uart_para.parity;
ind->threshold_value = uart_para.threshold_value;
}
fill_proto_frame_fixed_info((app_proto_frame_head *)payload, frame->cmd,
frame->seq, sizeof(proto_get_uart_param_ind));
*length = payload_length;
return ERR_OK;
}
uint16_t app_proto_set_uart_param(app_proto_frame_head *frame,
uint8_t * out_buffer, uint16_t *length)
{
proto_set_uart_param_req *req = NULL;
proto_set_uart_param_ind *ind = NULL;
uint8_t *payload;
uint16_t payload_length = APP_FRAME_MIN_LEN + sizeof(proto_set_uart_param_ind);
uart_cfg_t uart_para = {0};
if (frame == NULL || out_buffer == NULL || length == NULL) {
return ERR_FAIL;
}
if (frame->length != sizeof(proto_set_uart_param_req)) {
APP_PRINTF("[ERR]%s Data length mismatch!", __FUNCTION__);
return ERR_FAIL;
}
req = (proto_set_uart_param_req *)frame->data;
payload = out_buffer;
os_mem_set(payload, 0, payload_length);
ind = (proto_set_uart_param_ind *)(payload + sizeof(app_proto_frame_head));
ind->ret_code = PROTO_RET_CODE_SUCCESS;
uart_para.baud_rate = req->baudrate;
uart_para.data_bits = req->data_bits;
uart_para.stop_bits = req->stop_bits;
uart_para.parity = req->parity;
uart_para.threshold_value = req->threshold_value;
if (false == app_uart_is_valid(uart_para.baud_rate, uart_para.data_bits,
uart_para.stop_bits, uart_para.parity, uart_para.threshold_value)) {
ind->ret_code = PROTO_RET_CODE_FAILED;
} else if (ERR_OK != iot_app_save_uart_cfg_to_pib(&uart_para)) {
ind->ret_code = PROTO_RET_CODE_FAILED;
}
fill_proto_frame_fixed_info((app_proto_frame_head *)payload, frame->cmd,
frame->seq, sizeof(proto_set_uart_param_ind));
*length = payload_length;
return ERR_OK;
}
uint16_t app_proto_data_trans_tx(app_proto_frame_head *frame, uint8_t *out_buffer, uint16_t *length)
{
app_proto_frame_head *head = NULL;
proto_data_transmit_tx_req *req = NULL;
proto_data_transmit_tx_ind *ind = NULL;
uint16_t payload_length = APP_FRAME_MIN_LEN + sizeof(proto_data_transmit_tx_ind);
uint32_t ret = ERR_OK;
uint8_t *payload;
if (frame == NULL || frame->data == NULL ||
out_buffer == NULL || length == NULL) {
return ERR_FAIL;
}
req = (proto_data_transmit_tx_req *)frame->data;
payload = out_buffer;
(void) os_mem_set(payload, 0, payload_length);
head = (app_proto_frame_head *)payload;
ind = (proto_data_transmit_tx_ind *)head->data;
ind->ret_code = PROTO_RET_CODE_FAILED;
ind->reason = PROTO_REASON_FORMAT;
if ((frame->length > sizeof(proto_data_transmit_tx_req)) &&
(frame->length == sizeof(proto_data_transmit_tx_req) + req->data_length)) {
ret = app_plc_tx(req->data, req->data_length, req->dst_addr,
ID_PLC_DATA_TRANSMIT, NULL);
if (ret != ERR_OK) {
return ERR_FAIL;
} else if (ret == ERR_OK) {
ind->ret_code = PROTO_RET_CODE_SUCCESS;
ind->reason = PROTO_REASON_NORMAL;
} else {
ind->reason = PROTO_REASON_BUSY;
}
}
fill_proto_frame_fixed_info(head, frame->cmd, frame->seq,
sizeof(proto_data_transmit_tx_ind));
*length = payload_length;
return ERR_OK;
}
uint16_t app_proto_data_trans_rx(app_proto_frame_head *frame, uint8_t * out_buffer, uint16_t *length)
{
//fl_unref_param(frame);
//fl_unref_param(out_buffer);
//fl_unref_param(length);
return ERR_OK;
}
#if APP_IO_OPERATION_ENABLE
uint16_t app_proto_set_gpio(app_proto_frame_head *frame,
uint8_t *out_buffer, uint16_t *length)
{
proto_pin_info *req = NULL;
proto_set_gpio_ind *ind = NULL;
app_io_state io_state;
uint8_t *payload;
uint16_t payload_length = APP_FRAME_MIN_LEN + sizeof(proto_set_gpio_ind);
if (frame->length != sizeof(proto_pin_info)) {
return ERR_FAIL;
}
req = (proto_pin_info *)frame->data;
payload = out_buffer;
os_mem_set(payload, 0, payload_length);
io_state.pin_num = req->pin_num;
io_state.type = req->type;
io_state.state = req->state;
io_state.pwm_freq = req->pwm_freq;
io_state.pwm_ctl_mode = req->pwm_ctl_mode;
io_state.pwm_adjust_time = req->pwm_adjust_time;
io_state.init_state = 0;
ind = (proto_set_gpio_ind *)(payload + sizeof(app_proto_frame_head));
ind->ret_code = PROTO_RET_CODE_SUCCESS;
ind->reason = 0;
if (app_check_io_state_param(&io_state) != false) {
app_set_gpio_state(&io_state, STATE_SAVE_FLASH);
} else {
ind->ret_code = PROTO_RET_CODE_FAILED;
ind->reason = 1;
}
fill_proto_frame_fixed_info((app_proto_frame_head *)payload, frame->cmd,
frame->seq, sizeof(proto_set_gpio_ind));
*length = payload_length;
return ERR_OK;
}
uint16_t app_proto_get_gpio(app_proto_frame_head *frame,
uint8_t *out_buffer, uint16_t *length)
{
proto_get_gpio_ind *ind = NULL;
uint8_t *payload, num;
app_io_state io_state;
uint16_t data_len, payload_length;
uint8_t i, io_pin[APP_IO_PIN_MAX_NUM] = {0};
payload = out_buffer;
num = app_get_io_num(io_pin, sizeof(io_pin));
data_len = sizeof(proto_get_gpio_ind) + num * sizeof(proto_pin_info);
payload_length = APP_FRAME_MIN_LEN + data_len;
os_mem_set(payload, 0, payload_length);
ind = (proto_get_gpio_ind *)(payload + sizeof(app_proto_frame_head));
ind->cnt = num;
for (i = 0; i < num; i++) {
io_state.pin_num = io_pin[i];
if (ERR_FAIL == app_get_gpio_state(&io_state)) {
return ERR_FAIL;
}
ind->gpio_info[i].pin_num = io_state.pin_num;
ind->gpio_info[i].type = io_state.type;
ind->gpio_info[i].state = io_state.state;
ind->gpio_info[i].pwm_freq = io_state.pwm_freq;
ind->gpio_info[i].pwm_ctl_mode = io_state.pwm_ctl_mode;
ind->gpio_info[i].pwm_adjust_time = io_state.pwm_adjust_time;
}
fill_proto_frame_fixed_info((app_proto_frame_head *)payload, frame->cmd,
frame->seq, data_len);
*length = payload_length;
return ERR_OK;
}
#endif /* end APP_IO_OPERATION_ENABLE */
uint16_t app_proto_data_transmit(uint8_t * data, uint16_t data_length, uint8_t * src_addr)
{
uint32_t ret;
app_proto_frame_head *head = NULL;
proto_data_transmit_rx_req *req = NULL;
uint8_t * payload;
uint16_t payload_length = APP_FRAME_MIN_LEN + sizeof(proto_data_transmit_rx_req) + data_length;
iot_pkt_t *pkt_buf;
#if 0
#if PLC_SUPPORT_STA_ROLE
app_proto_hwctrl_proc(data, data_length, src_addr);
#endif
#endif
pkt_buf = iot_pkt_alloc(payload_length, IOT_APP_DEMO_MID);
if (NULL == pkt_buf) {
APP_PRINTF("[ERR] %s Packet Alloc Failed !!", __FUNCTION__);
return ERR_FAIL;
}
payload = iot_pkt_put(pkt_buf, payload_length);
head = (app_proto_frame_head *)payload;
req = (proto_data_transmit_rx_req *)head->data;
os_mem_cpy(req->src_addr, src_addr, IOT_MAC_ADDR_LEN);
req->data_length = data_length;
if (req->data_length > 0 && data != NULL) {
os_mem_cpy(req->data, data, data_length);
}
fill_proto_frame_fixed_info(head, ID_PROTO_CMD_DATA_TRANS_RX, g_proto_frame_seq++,
sizeof(proto_data_transmit_rx_req) + data_length);
ret = app_tx_to_cus_uart_msg(payload, payload_length);
iot_pkt_free(pkt_buf);
payload = NULL;
return ret;
}
uint16_t app_proto_sysctrl_data_to_plc(app_proto_frame_head *frame,
uint8_t *out_buffer, uint16_t *length)
{
APP_PRINTF("%s %d\n",__FUNCTION__,__LINE__);
uint32_t ret = ERR_OK;
proto_sysctrl_data_from_uart *req = NULL;
proto_sysctrl_data_header *reqdata = NULL;
if (frame == NULL || frame->data == NULL ||
out_buffer == NULL || length == NULL) {
return ERR_FAIL;
}
req = (proto_sysctrl_data_from_uart *)frame->data;
reqdata = (proto_sysctrl_data_header *)req->data;
if (reqdata->fun_code == INFO_DELAY_TEST) {
#if PLC_SUPPORT_CCO_ROLE
g_proto_delay_seq = frame->seq;
delay_timer_get(reqdata->data, CCO_TX_TIME, 0);
#endif
}
g_proto_sysctrl_frame_seq = frame->seq;
if ((frame->length > sizeof(proto_sysctrl_data_from_uart)) &&
(frame->length == sizeof(proto_sysctrl_data_from_uart) + req->data_length)) {
ret = app_plc_tx(req->data, req->data_length, req->dst_addr,
ID_PLC_SYSCTRL_DATA, NULL);
}
*length = 0;
return ret;
}
uint16_t app_proto_sysctrl_data_process(uint8_t *data, uint16_t data_length,
uint8_t *src_addr, uint8_t *dst_addr)
{
uint8_t *payload;
uint16_t ret;
uint16_t payload_length;
app_proto_frame_head *head = NULL;
proto_sysctrl_data_to_uart *req = NULL;
proto_sysctrl_data_header *reqdata = NULL;
app_entity_t *app_entry = NULL;
iot_pkt_t *pkt_buf;
app_entry = app_get_main_entry();
payload_length = APP_FRAME_MIN_LEN + sizeof(proto_sysctrl_data_to_uart) + data_length;
reqdata = (proto_sysctrl_data_header *)data;
#if PLC_SUPPORT_CCO_ROLE
if( reqdata->fun_code == INFO_FORWARD_DATA) {
return app_plc_tx(data, data_length, (uint8_t *)BROADCAST_MAC_ADDR,
ID_PLC_SYSCTRL_DATA, NULL);
}
if (reqdata->fun_code == INFO_DELAY_TEST) {
delay_timer_get(reqdata->data, CCO_RX_TIME, app_entry->receivetime);
app_ntb_to_us(reqdata->data);
}
#endif
#if PLC_SUPPORT_STA_ROLE
if (reqdata->fun_code == INFO_DELAY_TEST) {
delay_timer_get(reqdata->data, STA_RX_TIME, app_entry->receivetime);
delay_timer_get(reqdata->data, STA_TX_TIME, 0);
app_plc_tx(data, data_length, app_entry->dev.rmt_addr,
ID_PLC_SYSCTRL_DATA, NULL);
return ERR_OK;
}
#endif
pkt_buf = iot_pkt_alloc(payload_length, IOT_APP_DEMO_MID);
if (NULL == pkt_buf) {
APP_PRINTF("[ERR] %s Packet Alloc Failed !!", __FUNCTION__);
return ERR_FAIL;
}
payload = iot_pkt_put(pkt_buf, payload_length);
head = (app_proto_frame_head *)payload;
req = (proto_sysctrl_data_to_uart *)head->data;
req->data_length = data_length;
if (req->data_length > 0 && data != NULL) {
os_mem_cpy(req->data, data, data_length);
}
if (reqdata->fun_code == INFO_DELAY_TEST) {
iot_mac_addr_cpy(req->src_addr, dst_addr);
fill_proto_frame_fixed_info(head, ID_PROTO_CMD_SYSCTRL_DATA_TRANS,
g_proto_delay_seq, sizeof(proto_sysctrl_data_to_uart) + data_length);
} else {
iot_mac_addr_cpy(req->src_addr, src_addr);
fill_proto_frame_fixed_info(head, ID_PROTO_CMD_SYSCTRL_DATA_TRANS,
g_proto_sysctrl_frame_seq, sizeof(proto_sysctrl_data_to_uart) +
data_length);
}
ret = app_tx_to_cus_uart_msg(payload, payload_length);
iot_pkt_free(pkt_buf);
payload = NULL;
return ret;
}
uint16_t app_proto_get_nbnet_info(app_proto_frame_head *frame, uint8_t * out_buffer, uint16_t *length)
{
proto_get_nbnet_info_ind *ind = NULL;
iot_plc_nbnet_info *ninfo = NULL;
uint8_t *payload = out_buffer, i;
uint16_t payload_length;
ind = (proto_get_nbnet_info_ind *)(payload + sizeof(app_proto_frame_head));
iot_plc_query_nbnet(&ninfo);
payload_length = sizeof(proto_get_nbnet_info_ind) +
ninfo->count * sizeof(iot_plc_nb_info);
(void) os_mem_set(payload, 0, payload_length + APP_FRAME_MIN_LEN);
ind->nb_num = ninfo->count;
for (i = 0; i < ind->nb_num; i++) {
iot_mac_addr_cpy(ind->data[i].cco_mac, ninfo->nbnet_info[i].cco_mac);
ind->data[i].nid = ninfo->nbnet_info[i].nid;
ind->data[i].snr[0] = ninfo->nbnet_info[i].snr[0];
ind->data[i].snr[1] = ninfo->nbnet_info[i].snr[1];
ind->data[i].snr[2] = ninfo->nbnet_info[i].snr[2];
}
fill_proto_frame_fixed_info((app_proto_frame_head *)payload, frame->cmd,
frame->seq, payload_length);
*length = payload_length + APP_FRAME_MIN_LEN;
return ERR_OK;
}
uint16_t app_proto_frame_dispatch(app_proto_frame_head *frame, uint8_t * out_buffer, uint16_t *length)
{
uint32_t i = 0;
for (i = 0; i < APP_ARRAY_COUNT(g_proto_proc_pair); i++) {
if (frame->cmd == g_proto_proc_pair[i].id) {
if (g_proto_proc_pair[i].func != NULL) {
APP_PRINTF("[INF] handle Cmd: %04xH", frame->cmd);
return g_proto_proc_pair[i].func(frame, out_buffer, length);
}
}
}
APP_PRINTF("[INF] %s Invalid Protocol Cmd: %d", __FUNCTION__, frame->cmd);
return ERR_NOSUPP;
}
uint16_t app_proto_frame_tx(uint8_t *data, uint16_t data_length, app_source_e source, uint8_t *dst_addr)
{
switch (source) {
case APP_SOURCE_UART:
return app_tx_to_cus_uart_msg(data, data_length);
case APP_SOURCE_PLC:
return app_plc_tx(data, data_length, dst_addr,
ID_PLC_REMOTE_CMD, NULL);
default:
break;
}
return ERR_NOSUPP;
}
uint16_t app_proto_frame_rx(uint8_t * data, uint16_t data_length, app_source_e source, uint8_t * src_addr)
{
uint32_t ret;
uint16_t out_length = 0;
uint8_t *pdata;
uint16_t total_len;
uint16_t i = 0;
uint16_t frame_length;
app_proto_frame_head *frame;
uint16_t calc_crc;
uint16_t hd_index = 0xFFFF;
app_entity_t *app_entry = NULL;
uart_handle_buffer *uart_buffer;
app_entry = app_get_main_entry();
uart_buffer = app_get_uart_buf_info();
/* 断帧数据清除 */
app_uart_buf_clear(source);
total_len = uart_buffer->buff_len + data_length;
iot_pkt_t *pkt = iot_pkt_alloc(total_len, IOT_APP_DEMO_MID);
if (NULL == pkt) {
APP_PRINTF("[ERR] %s Packet Alloc Failed !!", __FUNCTION__);
return ERR_FAIL;
}
pdata = iot_pkt_put(pkt, total_len);
/* 合并存储的半帧数据和串口新输入的数据到一个pkt中 */
if (uart_buffer->buff_len > 0) {
os_mem_cpy(pdata, uart_buffer->buff_tmp, uart_buffer->buff_len);
os_mem_set(uart_buffer->buff_tmp, 0, uart_buffer->buff_len);
}
os_mem_cpy(pdata + uart_buffer->buff_len, data, data_length);
for (i = 0; i < total_len; i++) {
if (APP_FRAME_HEAD_BYTE == pdata[i]) {
/* 记录帧头位置 */
hd_index = i;
/* 剩余长度小于帧的最小长度,判断为半帧 */
if (i + APP_FRAME_MIN_LEN > total_len) {
goto half_frame;
}
frame = (app_proto_frame_head *)&pdata[i];
frame_length = sizeof(app_proto_frame_head) + frame->length + PROTO_CRC_SIZE;
/* 帧长度大于剩余长度并且小于帧的最大长度,判断为半帧 */
if (frame_length > (total_len - i)) {
if (frame_length < APP_FRAME_MAX_LEN) {
goto half_frame;
} else {
continue;
}
}
calc_crc = iot_getcrc16(&pdata[i], frame_length, IOT_CRC16_TYPE_XMODEM);
if (calc_crc != 0) {
APP_PRINTF("[ERR] Check Frame Faild with crc_err\n");
hd_index = 0xFFFF;
continue;
}
/* 帧长度等于剩余长度,则判断为没有半帧 */
if (frame_length == total_len - i) {
hd_index = 0xFFFF;
}
/* 处理得到的帧数据 */
ret = app_proto_frame_dispatch(frame, app_entry->out_buf, &out_length);
if (ret == ERR_OK) {
app_proto_frame_tx(app_entry->out_buf, out_length, source, src_addr);
} else {
APP_PRINTF("[ERR] %s Dispatch Frame Failed !!", __FUNCTION__);
}
i += (frame_length - 1);
}
}
/* 分析结束,判断是否有半帧 */
if (total_len > hd_index) {
if ((total_len - hd_index) < APP_FRAME_MAX_LEN) {
goto half_frame;
}
}
iot_pkt_free(pkt);
return ERR_OK;
/* 存储半帧到全局buffer */
half_frame:
uart_buffer->buff_len = total_len - hd_index;
os_mem_cpy(uart_buffer->buff_tmp, &pdata[hd_index], uart_buffer->buff_len);
APP_PRINTF(" half frame, buff len=%d\n", uart_buffer->buff_len);
iot_pkt_free(pkt);
return ERR_OK;
}
uint16_t app_proto_onoffline_report(uint8_t *mac, uint8_t flag)
{
uint16_t ret = ERR_FAIL;
uint8_t * payload;
proto_onoffline_info *data = NULL;
uint16_t payload_length = APP_FRAME_MIN_LEN + sizeof(proto_onoffline_info);
iot_pkt_t *pkt_buf;
pkt_buf = iot_pkt_alloc(payload_length, IOT_APP_DEMO_MID);
if (NULL == pkt_buf) {
APP_PRINTF("[ERR] %s Packet Alloc Failed !!", __FUNCTION__);
goto out;
}
payload = iot_pkt_put(pkt_buf, payload_length);
os_mem_set(payload, 0, payload_length);
data = (proto_onoffline_info *)(payload + sizeof(app_proto_frame_head));
os_mem_cpy(data->dev_addr, mac, IOT_MAC_ADDR_LEN);
data->status = flag;
fill_proto_frame_fixed_info((app_proto_frame_head *)payload,
ID_PROTO_CMD_REPORT_ONOFFLINE, 0, sizeof(proto_onoffline_info));
ret = app_tx_to_cus_uart_msg(payload, payload_length);
iot_pkt_free(pkt_buf);
payload = NULL;
out:
return ret;
}