2024 lines
70 KiB
C
Executable File
2024 lines
70 KiB
C
Executable File
/****************************************************************************
|
|
|
|
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
|
|
|
|
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
|
|
be copied by any method or incorporated into another program without
|
|
the express written consent of Aerospace C.Power. This Information or any portion
|
|
thereof remains the property of Aerospace C.Power. The Information contained herein
|
|
is believed to be accurate and Aerospace C.Power assumes no responsibility or
|
|
liability for its use in any way and conveys no license or title under
|
|
any patent or copyright and makes no representation or warranty that this
|
|
Information is free from patent or copyright infringement.
|
|
|
|
****************************************************************************/
|
|
/* os_ship header files */
|
|
#include "os_timer_api.h"
|
|
#include "os_utils_api.h"
|
|
#include "iot_app_api.h"
|
|
#include "iot_gpio_api.h"
|
|
#include "iot_adc_api.h"
|
|
#include "iot_board_api.h"
|
|
#include "iot_io_api.h"
|
|
#include "iot_task_api.h"
|
|
#include "iot_proto_dl645.h"
|
|
#include "iot_proto_ge.h"
|
|
#include "iot_edge_compute.h"
|
|
#include "iot_proto_modbus.h"
|
|
#include "iot_plc_msg_cco_api.h"
|
|
|
|
mcu_data_handle_t mcu_data_dl645;
|
|
extern uint8_t ge_buf[];
|
|
uint8_t g_dl645_local_mode_state = DL645_LOCAL_MODE_INIT;
|
|
proto_645_localmode_data_cache_t g_local_dl645_cache;
|
|
static uint8_t proto_645_any_addr[IOT_MAC_ADDR_LEN] =
|
|
{0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA};
|
|
|
|
#if PLC_SUPPORT_STA_ROLE
|
|
static void iot_proto_645_handle_edge_resp(uint8_t *in_data,
|
|
uint16_t in_data_len, uint8_t type);
|
|
|
|
static uint8_t iot_edge_dl645_send_plc_msg(uint8_t *data, uint16_t len);
|
|
|
|
static uint8_t iot_sta_check_local_dl645_cmd(uint8_t *data_input,
|
|
uint32_t *di, uint8_t *mac);
|
|
|
|
static void iot_sta_handle_local_dl645_cmd(uint8_t *data_input,
|
|
uint16_t data_len, uint8_t fn, uint32_t di, uint8_t source,
|
|
uint8_t *req_mac);
|
|
|
|
#endif /* end PLC_SUPPORT_STA_ROLE */
|
|
|
|
extern void iot_common_bin_dump(uint8_t *data, uint32_t dlen);
|
|
|
|
/**
|
|
* @brief iot_proto_645_calc_cs() - To calculate a DL645 crc
|
|
* @param hdr: point to a proto_645_header_t struct
|
|
* @retval: the value of DL645 crc
|
|
*/
|
|
uint8_t iot_proto_645_calc_cs(proto_645_header_t *hdr)
|
|
{
|
|
uint8_t i, len, ret = 0;
|
|
uint8_t *data = (uint8_t *)hdr;
|
|
|
|
len = sizeof(*hdr) + hdr->len;
|
|
for (i = 0; i < len; i++){
|
|
ret += data[i];
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
void iot_proto_dl645_read_addr(uint8_t *data)
|
|
{
|
|
proto_645_header_t *hdr = (proto_645_header_t*)data;
|
|
proto_645_tailer_t *tail = NULL;
|
|
hdr->start_char_1 = PROTO_645_START_CHAR;
|
|
iot_mac_addr_cpy(hdr->addr, proto_645_any_addr);
|
|
hdr->control.fn = PROTO_645_2007_FN_READ_ADDR;
|
|
hdr->len = 0;
|
|
hdr->start_char_2 = PROTO_645_START_CHAR;
|
|
tail = (proto_645_tailer_t*)hdr->data;
|
|
tail->cs = iot_proto_645_calc_cs(hdr);
|
|
tail->end_char = PROTO_645_END_CHAR;
|
|
}
|
|
|
|
void iot_proto_645_ext_add33_handle(uint8_t *ds, uint32_t size)
|
|
{
|
|
uint8_t *ptr = ds;
|
|
while (size--)
|
|
{
|
|
(*ptr++) += 0x33;
|
|
}
|
|
return;
|
|
}
|
|
|
|
void iot_proto_645_ext_sub33_handle(uint8_t *ds, uint32_t size)
|
|
{
|
|
uint8_t *ptr = ds;
|
|
while (size--)
|
|
{
|
|
(*ptr++) -= 0x33;
|
|
}
|
|
return;
|
|
}
|
|
|
|
uint32_t iot_proto_645_get_di_by_sub33(uint8_t *data, uint8_t len, uint32_t *di)
|
|
{
|
|
uint8_t di_t[DL645_DI_LEN] = {0};
|
|
|
|
if (len < DL645_DI_LEN) {
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
os_mem_cpy(di_t, data, DL645_DI_LEN);
|
|
iot_proto_645_ext_sub33_handle(di_t, DL645_DI_LEN);
|
|
proto_645_2007_byte_to_di(di_t, *di);
|
|
|
|
return ERR_OK;
|
|
}
|
|
|
|
void iot_pack_dl645_to_ge(uint8_t *data_input, uint8_t *ge_data,
|
|
uint16_t *data_len, uint8_t *mac, bool_t b_conless)
|
|
{
|
|
uint16_t crc;
|
|
ge_frame_data_send_set_subfn160_t *data_frm;
|
|
|
|
ge_frm_tail_t *tail_frm;
|
|
|
|
data_frm = (ge_frame_data_send_set_subfn160_t *)ge_data;
|
|
data_frm->hdr.hdr.preamble = GE_FRM_PREAMBLE_CODE;
|
|
data_frm->hdr.hdr.data_len = *data_len + IOT_MAC_ADDR_LEN;
|
|
data_frm->hdr.hdr.fn = PROTO_GE_PLC_SET_CMD;
|
|
data_frm->hdr.subfn = PROTO_GE_DATA_CMD;
|
|
data_frm->force_tx_connless = b_conless;
|
|
data_frm->force_noaggr = 0;
|
|
data_frm->recv_connless = 0;
|
|
data_frm->resv = DL645_07_RESV0_RESV;
|
|
iot_mac_addr_cpy(&data_frm->dest_mac[0], mac);
|
|
if (data_input) {
|
|
os_mem_cpy(&data_frm->data[0], &data_input[0], *data_len);
|
|
}
|
|
crc = ge_frm_checksum_calc(ge_data, data_frm->hdr.hdr.data_len +
|
|
GE_FRM_CHECK_SUM_FIELD_POS);
|
|
tail_frm = (ge_frm_tail_t*)&data_frm->data[*data_len];
|
|
tail_frm->check_sum = crc;
|
|
tail_frm->tail = GE_FRM_TAIL_CODE;
|
|
*data_len = *data_len + sizeof(ge_frame_data_send_set_subfn160_t) +
|
|
sizeof(ge_frm_tail_t);
|
|
#if (IOT_GE_CKQ_MODE_ENABLE == 0)
|
|
iot_common_bin_dump(ge_data, *data_len);
|
|
#endif
|
|
}
|
|
|
|
/* init dl645 header, fill mac, ctrl ... */
|
|
void iot_proto_645_header_init(proto_645_header_t *hdr,
|
|
uint8_t *addr, uint8_t fn, uint8_t dir, uint8_t ack, uint8_t follow)
|
|
{
|
|
IOT_ASSERT(addr);
|
|
IOT_ASSERT(ack <= PROTO_645_2007_ERR_OTHER);
|
|
IOT_ASSERT(follow <= DL645_FOLLOW_AVAILABLE);
|
|
IOT_ASSERT(dir <= PROTO_645_DIR_SLAVE);
|
|
|
|
hdr->start_char_1 = PROTO_645_START_CHAR;
|
|
iot_mac_addr_cpy(hdr->addr, addr);
|
|
hdr->control.fn = fn;
|
|
hdr->control.dir = dir;
|
|
hdr->control.ack = ack;
|
|
hdr->control.follow = follow;
|
|
hdr->start_char_2 = PROTO_645_START_CHAR;
|
|
}
|
|
|
|
/* init dl645 tail, fill cs and end char */
|
|
void iot_proto_645_tail_init(proto_645_header_t *hdr)
|
|
{
|
|
uint8_t *data = hdr->data, len = hdr->len;
|
|
proto_645_tailer_t *tail = (proto_645_tailer_t*)(data + len);
|
|
|
|
tail->cs = iot_proto_645_calc_cs(hdr);
|
|
tail->end_char = PROTO_645_END_CHAR;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_proto_645_build_resp_msg() dl645 pack response frame.
|
|
* @param hdr: point to data which should pack a frame.
|
|
* @param in_data: to fill in the data of 645 fram
|
|
* @param len: in_data len
|
|
* @param reason: error reason, 0 is no error
|
|
* @param fn: function control code
|
|
*/
|
|
void iot_proto_645_build_resp_msg(proto_645_header_t *hdr,
|
|
uint8_t *in_data, uint8_t len, uint8_t reason, uint8_t fn)
|
|
{
|
|
proto_645_header_t *dl645_frm = hdr;
|
|
uint8_t revert_mac[IOT_MAC_ADDR_LEN];
|
|
|
|
if (dl645_frm == NULL) {
|
|
return;
|
|
}
|
|
|
|
iot_mac_addr_cpy(revert_mac, prototask_contxt.local_dev.mac);
|
|
iot_mac_addr_reverse(revert_mac);
|
|
iot_proto_645_header_init(dl645_frm, revert_mac, fn, PROTO_645_DIR_SLAVE,
|
|
(reason == 0 ? PROTO_645_2007_ERR_OK : PROTO_645_2007_ERR_OTHER),
|
|
DL645_FOLLOW_INVALID);
|
|
if ((in_data != NULL) && (len != 0)) {
|
|
os_mem_cpy(dl645_frm->data, in_data, len);
|
|
dl645_frm->len = len;
|
|
} else if (reason) {
|
|
dl645_frm->data[0] = reason;
|
|
dl645_frm->len = sizeof(reason);
|
|
} else {
|
|
dl645_frm->len = 0;
|
|
}
|
|
iot_proto_645_ext_add33_handle(dl645_frm->data, dl645_frm->len);
|
|
|
|
iot_proto_645_tail_init(dl645_frm);
|
|
}
|
|
|
|
uint8_t iot_proto_645_frm_format_check(uint8_t *data, uint16_t len,
|
|
uint8_t *integrity)
|
|
{
|
|
uint8_t test_crc;
|
|
uint8_t err_code = 0;
|
|
proto_645_header_t *hdr_645 = NULL;
|
|
proto_645_tailer_t *tail_645 = NULL;
|
|
uint16_t dl645_len = 0;
|
|
uint8_t frame_check_result = GET_NO_FRAME;
|
|
|
|
if (data[0] != PROTO_645_START_CHAR) {
|
|
err_code = 1;
|
|
goto out;
|
|
}
|
|
|
|
if (len < PROTO_645_SECOND_HEAD_POS + 1) {
|
|
err_code = 2;
|
|
frame_check_result = GET_HALF_FRAME;
|
|
goto out;
|
|
}
|
|
|
|
hdr_645 = (proto_645_header_t*)data;
|
|
if (hdr_645->start_char_2 != PROTO_645_START_CHAR) {
|
|
err_code = 3;
|
|
goto out;
|
|
}
|
|
|
|
dl645_len = hdr_645->len + DL645_PARSE_FRM_MIN_LEN;
|
|
if (len < dl645_len) {
|
|
err_code = 4;
|
|
frame_check_result = GET_HALF_FRAME;
|
|
goto out;
|
|
}
|
|
|
|
tail_645 = (proto_645_tailer_t*)(data + sizeof(proto_645_header_t) +
|
|
hdr_645->len);
|
|
if (tail_645->end_char != PROTO_645_END_CHAR) {
|
|
err_code = 5;
|
|
goto out;
|
|
}
|
|
|
|
test_crc = iot_proto_645_calc_cs(hdr_645);
|
|
if (tail_645->cs != test_crc) {
|
|
iot_cus_printf("[DL645] crc:%02x\n", test_crc);
|
|
err_code = 6;
|
|
goto out;
|
|
}
|
|
|
|
frame_check_result = GET_ONE_FRAME;
|
|
|
|
if (len > dl645_len) {
|
|
err_code = 7;
|
|
}
|
|
|
|
out:
|
|
if (err_code > 0) {
|
|
iot_cus_printf("645_frm_check err_code:%x\n", err_code);
|
|
}
|
|
|
|
if (NULL != integrity) {
|
|
*integrity = frame_check_result;
|
|
}
|
|
|
|
return err_code;
|
|
}
|
|
|
|
#if PLC_SUPPORT_STA_ROLE
|
|
|
|
void iot_proto_edge_msg_output_msg_handler(uint8_t msg_id, void *arg)
|
|
{
|
|
void **p_data = NULL;
|
|
uint16_t data_len = 0;
|
|
edge_inner_time_info_t time_info;
|
|
edge_delay_time_info_inner_t *p_edge_time_inner;
|
|
|
|
if (arg != NULL) {
|
|
p_data = (void **)iot_pkt_data(arg);
|
|
data_len = iot_pkt_data_len(arg);
|
|
}
|
|
switch(msg_id) {
|
|
case EDGE_OUTPUT_STOPPED_ID:
|
|
{
|
|
greeapp->uart_com = *p_data;
|
|
iot_proto_resume_pkt_2_mainboard();
|
|
os_start_timer(prototask_contxt.edge_monitor_start_tmr,
|
|
prototask_contxt.flashinfo.public.pub.edge_start_tm);
|
|
break;
|
|
}
|
|
case EDGE_OUTPUT_DL645_PKT_ID:
|
|
{
|
|
iot_edge_dl645_send_plc_msg((uint8_t *)p_data, data_len);
|
|
break;
|
|
}
|
|
case EDGE_OUTPUT_RESP_CACHE_INFO_ID:
|
|
{
|
|
iot_proto_645_handle_edge_resp((uint8_t *)p_data, data_len,
|
|
EDGE_RESP_EDGE_CMD_INFO);
|
|
break;
|
|
}
|
|
case EDGE_OUTPUT_RESP_CACHE_CNT_ID:
|
|
{
|
|
iot_proto_645_handle_edge_resp((uint8_t *)p_data, data_len,
|
|
EDGE_RESP_EDGE_CMD_CNT);
|
|
break;
|
|
}
|
|
case EDGE_OUTPUT_RESP_DELAY_TIME_ID:
|
|
{
|
|
iot_proto_645_handle_edge_resp((uint8_t *)p_data, data_len,
|
|
EDGE_RESP_TIME_PARAM);
|
|
break;
|
|
}
|
|
case EDGE_OUTPUT_RESP_DELAY_TIME_INNER_ID:
|
|
{
|
|
p_edge_time_inner = (edge_delay_time_info_inner_t *)p_data;
|
|
time_info.cmd_starting_stopping_tm =
|
|
p_edge_time_inner->cmd_starting_stopping_tm;
|
|
time_info.cmd_each_tm = p_edge_time_inner->cmd_each_tm;
|
|
time_info.edge_start_tm =
|
|
prototask_contxt.flashinfo.public.pub.edge_start_tm;
|
|
iot_proto_645_handle_edge_resp((uint8_t *)&time_info,
|
|
sizeof(time_info), EDGE_RESP_TIME_PARAM_INNER);
|
|
break;
|
|
}
|
|
case EDGE_OUTPUT_RESP_BAUD_ID:
|
|
{
|
|
iot_proto_645_handle_edge_resp((uint8_t *)p_data, data_len,
|
|
EDGE_RESP_CMD_BAUD);
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
if (arg != NULL) {
|
|
iot_pkt_free(arg);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief iot_edge_dl645_send_plc_msg() - dl645 send data to cco by PLC
|
|
* @param data: the data
|
|
* @param len: the len of the data
|
|
* @retval: true or false
|
|
*/
|
|
static uint8_t iot_edge_dl645_send_plc_msg(uint8_t *data, uint16_t len)
|
|
{
|
|
uint8_t ret = false;
|
|
protpkt_tx_info_t txinfo = { 0 };
|
|
|
|
if (data == NULL) {
|
|
ret = false;
|
|
goto out;
|
|
}
|
|
|
|
iot_proto_fill_txinfo(&txinfo, true, PLCTXRX_UNICAST, 0,
|
|
PROTO_UNICAST_RETRY_DEFAULT_INTVL, 1,
|
|
prototask_contxt.local_dev.mac, prototask_contxt.cco_dev.mac);
|
|
iot_proto_remote_cmd_send_to_plctxrx(data, len, &txinfo);
|
|
ret = true;
|
|
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
/* @brief iot_proto_send_dl645_ack() - send dl645 ack, from uart resp dl645,
|
|
* from plc resp ge + dl545
|
|
* @param fn: command ctrl
|
|
* @param reason error reason
|
|
* @param source source plc or uart
|
|
* @param dst_mac if plc resp dst mac
|
|
* @retval: success return 0, others error.
|
|
*/
|
|
static uint8_t iot_proto_send_dl645_ack(uint8_t fn, uint8_t reason,
|
|
uint8_t source, uint8_t *dst_mac)
|
|
{
|
|
uint8_t *pkt_data;
|
|
uint16_t pkt_len;
|
|
uint16_t dl645_len;
|
|
uint16_t fea0_hdr_len;
|
|
iot_pkt_t *pkt;
|
|
proto_645_header_t *dl645_frm;
|
|
protpkt_tx_info_t txinfo = { 0 };
|
|
|
|
fea0_hdr_len = sizeof(ge_frame_data_send_set_subfn160_t);
|
|
pkt_len = DL645_PARSE_FRM_MIN_LEN + (reason == 0 ? 0 : 1);
|
|
|
|
if (source == FROM_PLC) {
|
|
dl645_len = pkt_len;
|
|
pkt_len += sizeof(ge_frm_tail_t) + fea0_hdr_len;
|
|
}
|
|
|
|
pkt = iot_pkt_alloc(pkt_len, IOT_GREE_APP_MID);
|
|
if (!pkt) {
|
|
return 1;
|
|
}
|
|
pkt_data = iot_pkt_put(pkt, pkt_len);
|
|
if (source == FROM_PLC) {
|
|
dl645_frm = (proto_645_header_t *)(pkt_data + fea0_hdr_len);
|
|
iot_proto_645_build_resp_msg(dl645_frm, NULL, 0,
|
|
reason, fn);
|
|
iot_pack_dl645_to_ge(NULL, pkt_data, &dl645_len, dst_mac, false);
|
|
|
|
iot_proto_fill_txinfo(&txinfo, true, PLCTXRX_UNICAST, 0,
|
|
PROTO_UNICAST_RETRY_DEFAULT_INTVL, 1,
|
|
prototask_contxt.local_dev.mac, dst_mac);
|
|
|
|
iot_proto_remote_cmd_send_to_plctxrx(pkt_data, pkt_len, &txinfo);
|
|
iot_pkt_free(pkt);
|
|
} else {
|
|
iot_proto_645_build_resp_msg((proto_645_header_t *)pkt_data, NULL, 0,
|
|
reason, fn);
|
|
iot_proto_send_to_mainboard(pkt);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void iot_proto_pack_data_to_dl645(uint8_t *data_input, uint8_t *dl645_data,
|
|
uint16_t *data_len, uint32_t di, uint8_t *mac, uint8_t fn, uint8_t dir)
|
|
{
|
|
proto_645_header_t *dl645_frm = NULL;
|
|
|
|
if (data_input == NULL || dl645_data == NULL) {
|
|
iot_cus_printf("%s data err!\n", __FUNCTION__);
|
|
return;
|
|
}
|
|
|
|
if (*data_len + DL645_DI_LEN > DL645_FRM_DATA_MAX_LEN) {
|
|
iot_cus_printf("%s out of max length\n", __FUNCTION__);
|
|
return;
|
|
}
|
|
|
|
dl645_frm = (proto_645_header_t *)dl645_data;
|
|
iot_proto_645_header_init(dl645_frm, mac, fn, dir, PROTO_645_2007_ERR_OK,
|
|
DL645_FOLLOW_INVALID);
|
|
dl645_frm->len = *data_len + DL645_DI_LEN;
|
|
proto_645_2007_di_to_byte(di, dl645_frm->data);
|
|
os_mem_cpy(dl645_frm->data + DL645_DI_LEN, data_input, (*data_len));
|
|
iot_proto_645_ext_add33_handle(dl645_frm->data, dl645_frm->len);
|
|
iot_proto_645_tail_init(dl645_frm);
|
|
*data_len = dl645_frm->len + DL645_PARSE_FRM_MIN_LEN;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_proto_645_handle_edge_resp() - fill data to the data position
|
|
* of 645 frame,then packet into one ge frame, finally send the packet to PLC
|
|
* @param in_data: point to the data of the edge resp pkt
|
|
* @param in_data_len: the len of the in_data
|
|
* @param type: resp type
|
|
*/
|
|
static void iot_proto_645_handle_edge_resp(uint8_t *in_data,
|
|
uint16_t in_data_len, uint8_t type)
|
|
{
|
|
uint16_t pkt_len;
|
|
uint8_t ret = 0;
|
|
uint8_t *pkt_data, *dl645_data;
|
|
uint8_t dl645_data_len = 0;
|
|
uint16_t dl645_len, cmd_len;
|
|
uint32_t di;
|
|
iot_pkt_t *pkt = NULL;
|
|
uint8_t ge_data_pos = sizeof(ge_frame_data_send_set_subfn160_t);
|
|
proto_645_header_t *dl645_frm;
|
|
edge_cache_cmd_info_t *edge_cmd;
|
|
uint8_t revert_mac[IOT_MAC_ADDR_LEN];
|
|
|
|
dl645_data_len = DL645_DI_LEN + in_data_len;
|
|
if (type == EDGE_RESP_TIME_PARAM) {
|
|
di = DL645_07_DI_EDGE_TIME_PARAM;
|
|
} else if (type == EDGE_RESP_TIME_PARAM_INNER) {
|
|
di = DL645_07_DI_EDGE_TIME_PARAM_INNER;
|
|
} else if (type == EDGE_RESP_EDGE_CMD_CNT) {
|
|
di = DL645_07_DI_QUERY_EDGE_CMD_CNT;
|
|
} else if (type == EDGE_RESP_EDGE_CMD_INFO) {
|
|
dl645_data_len -= sizeof(edge_cache_cmd_info_t);
|
|
edge_cmd = (edge_cache_cmd_info_t *)in_data;
|
|
if (edge_cmd->cmd_type == EDGE_QUERY_EDGE_CMD_645) {
|
|
di = DL645_07_DI_EDGE_645_MIN_CMD + edge_cmd->idx;
|
|
} else if (edge_cmd->cmd_type == EDGE_QUERY_EDGE_CMD_MODBUS) {
|
|
di = DL645_07_DI_EDGE_MODBUS_MIN_CMD + edge_cmd->idx;
|
|
}
|
|
/* if edge response cmd data of the in_data, the dl645_data_len value
|
|
isn't only DL645_DI_LEN, otherwise only resp di */
|
|
if (dl645_data_len != DL645_DI_LEN) {
|
|
cmd_len = in_data_len - sizeof(edge_cache_cmd_info_t);
|
|
in_data += sizeof(edge_cache_cmd_info_t);
|
|
if (iot_proto_645_frm_format_check(edge_cmd->data, cmd_len, NULL) &&
|
|
iot_proto_modbus_frm_format_check(edge_cmd->data, cmd_len)) {
|
|
dl645_data_len = DL645_DI_LEN;
|
|
}
|
|
}
|
|
} else if (type == EDGE_RESP_CMD_BAUD) {
|
|
di = DL645_07_DI_EDGE_CMD_BAUD;
|
|
}
|
|
|
|
dl645_len = DL645_PARSE_FRM_MIN_LEN + dl645_data_len;
|
|
pkt_len = dl645_len + sizeof(ge_frm_tail_t) +
|
|
sizeof(ge_frame_data_send_set_subfn160_t);
|
|
pkt = iot_pkt_alloc(pkt_len, IOT_GREE_APP_MID);
|
|
if (!pkt) {
|
|
ret = 1;
|
|
goto out;
|
|
}
|
|
|
|
pkt_data = iot_pkt_put(pkt, pkt_len);
|
|
dl645_frm = (proto_645_header_t *)(pkt_data + ge_data_pos);
|
|
dl645_data = dl645_frm->data;
|
|
os_mem_cpy(dl645_data, &di, DL645_DI_LEN);
|
|
if (dl645_data_len > DL645_DI_LEN) {
|
|
os_mem_cpy(dl645_data + DL645_DI_LEN, in_data,
|
|
dl645_data_len - DL645_DI_LEN);
|
|
}
|
|
dl645_frm->len = dl645_data_len;
|
|
iot_mac_addr_cpy(revert_mac, prototask_contxt.local_dev.mac);
|
|
iot_mac_addr_reverse(revert_mac);
|
|
iot_proto_645_header_init(dl645_frm, revert_mac, PROTO_645_2007_FN_READ_DATA,
|
|
PROTO_645_DIR_SLAVE, PROTO_645_2007_ERR_OK, DL645_FOLLOW_INVALID);
|
|
iot_proto_645_ext_add33_handle(dl645_frm->data, dl645_frm->len);
|
|
iot_proto_645_tail_init(dl645_frm);
|
|
|
|
iot_pack_dl645_to_ge(NULL, pkt_data, &dl645_len,
|
|
prototask_contxt.cco_dev.mac, 0);
|
|
iot_edge_dl645_send_plc_msg(pkt_data, pkt_len);
|
|
iot_pkt_free(pkt);
|
|
|
|
out:
|
|
iot_cus_printf("645_handle_edge_resp ret:%x\n", ret);
|
|
}
|
|
|
|
/**
|
|
* @brief iot_resp_uart_mac_query() - To response the module read the mac
|
|
of device
|
|
* @param source: from uart or plc
|
|
* @param req_mac: the address represents where the cmd came from and the
|
|
* response data will be sent to
|
|
*/
|
|
static void iot_resp_uart_mac_query(uint8_t source, uint8_t *req_mac)
|
|
{
|
|
uint8_t revert_mac[IOT_MAC_ADDR_LEN], ret = 0;
|
|
uint16_t dl645_len = DL645_PARSE_FRM_MIN_LEN + IOT_MAC_ADDR_LEN;
|
|
uint8_t ge_data_pos = sizeof(ge_frame_data_send_set_subfn160_t);
|
|
iot_pkt_t *pkt;
|
|
uint8_t *pkt_data, data_pos = 0;
|
|
uint16_t pkt_len;
|
|
protpkt_tx_info_t txinfo = { 0 };
|
|
|
|
if ((source != FROM_PLC) && (source != FROM_UART)) {
|
|
ret = 1;
|
|
goto out;
|
|
}
|
|
|
|
if ((source == FROM_PLC) && (req_mac == NULL)) {
|
|
ret = 2;
|
|
goto out;
|
|
}
|
|
|
|
/* for cmd from uart pkt_len is dl645 frame length;
|
|
for cmd from plc, pkt_len is FEA0 length */
|
|
if (source == FROM_UART) {
|
|
pkt_len = dl645_len;
|
|
} else {
|
|
pkt_len = dl645_len + sizeof(ge_frm_tail_t) +
|
|
sizeof(ge_frame_data_send_set_subfn160_t);
|
|
data_pos = ge_data_pos;
|
|
}
|
|
|
|
pkt = iot_pkt_alloc(pkt_len, IOT_GREE_APP_MID);
|
|
if (!pkt) {
|
|
ret = 3;
|
|
goto out;
|
|
}
|
|
|
|
pkt_data = iot_pkt_put(pkt, pkt_len);
|
|
iot_mac_addr_cpy(revert_mac, prototask_contxt.local_dev.mac);
|
|
iot_mac_addr_reverse(revert_mac);
|
|
iot_proto_645_build_resp_msg((proto_645_header_t *)(pkt_data + data_pos),
|
|
revert_mac, IOT_MAC_ADDR_LEN, 0, PROTO_645_2007_FN_READ_ADDR);
|
|
if (source == FROM_UART) {
|
|
iot_proto_send_to_mainboard(pkt);
|
|
} else {
|
|
iot_pack_dl645_to_ge(NULL, pkt_data, &dl645_len, req_mac, false);
|
|
|
|
iot_proto_fill_txinfo(&txinfo, true, PLCTXRX_UNICAST, 0,
|
|
PROTO_UNICAST_RETRY_DEFAULT_INTVL, 1,
|
|
prototask_contxt.local_dev.mac, req_mac);
|
|
|
|
iot_proto_remote_cmd_send_to_plctxrx(pkt_data, pkt_len, &txinfo);
|
|
iot_pkt_free(pkt);
|
|
}
|
|
|
|
out:
|
|
iot_cus_printf("%s ret:%d\n", __FUNCTION__, ret);
|
|
}
|
|
|
|
/**
|
|
* @brief iot_proto_dl645_uart_set() - handle the uart set cmd from uart or plc
|
|
* @param dl645_data: point to the dl645 data field
|
|
* @param source: from uart or plc
|
|
* @param req_mac: the address represents where the cmd came from and the
|
|
* response data will be sent to
|
|
*/
|
|
static void iot_proto_dl645_uart_set(proto_645_set_uart_param_t *dl645_data,
|
|
uint8_t source, uint8_t *req_mac)
|
|
{
|
|
uint8_t ret = 0;
|
|
uint8_t reason = 0;
|
|
uint32_t baud_val[] = PROTO_GE_UART_BAUD_VALUE;
|
|
ge_app_pib_info_t *p_flash = &prototask_contxt.flashinfo;
|
|
|
|
if ((source != FROM_PLC) && (source != FROM_UART)) {
|
|
ret = 1;
|
|
goto out;
|
|
}
|
|
|
|
if ((source == FROM_PLC) && (req_mac == NULL)) {
|
|
ret = 2;
|
|
goto out;
|
|
}
|
|
|
|
if ((iot_proto_uart_param_check(dl645_data->baudrate, dl645_data->parity,
|
|
dl645_data->data_bit, dl645_data->stop_bit) == false) ||
|
|
(p_flash->public.pub.baudidx >= PROTO_GE_UART_BAUD_IDX_MAX)) {
|
|
ret = 3;
|
|
reason = DL645_ERR_PARAMETER_ERROR;
|
|
}
|
|
|
|
if (reason == 0) {
|
|
if ((baud_val[p_flash->public.pub.baudidx] != dl645_data->baudrate) ||
|
|
(p_flash->public.pub.parity != dl645_data->parity) ||
|
|
(p_flash->public.pub.data != dl645_data->data_bit) ||
|
|
(p_flash->public.pub.stop != dl645_data->stop_bit)) {
|
|
/* save uart param to flash */
|
|
p_flash->public.pub.baudidx =
|
|
uart_baud_find_index(dl645_data->baudrate);
|
|
p_flash->public.pub.parity = dl645_data->parity;
|
|
p_flash->public.pub.data = dl645_data->data_bit;
|
|
p_flash->public.pub.stop = dl645_data->stop_bit;
|
|
iot_proto_flashsave(p_flash);
|
|
}
|
|
}
|
|
|
|
if (iot_proto_send_dl645_ack(PROTO_645_2007_FN_WRITE_DATA, reason,
|
|
source, req_mac)) {
|
|
ret = 4;
|
|
}
|
|
|
|
out:
|
|
iot_cus_printf("%s ret:%d reason:%d\n", __FUNCTION__, ret, reason);
|
|
}
|
|
/**
|
|
* @brief iot_proto_dl645_resp_uart_param() - response uart param to plc
|
|
* @param di: dl645 DI
|
|
* @param source: from uart or plc
|
|
* @param req_mac: the address represents where the cmd came from and the
|
|
* response data will be sent to
|
|
*/
|
|
static void iot_proto_dl645_resp_uart_param(uint32_t di, uint8_t source,
|
|
uint8_t *req_mac)
|
|
{
|
|
uint8_t ret = 0;
|
|
uint16_t pkt_len;
|
|
uint8_t ge_data_pos = sizeof(ge_frame_data_send_set_subfn160_t);
|
|
uint16_t dl645_len = DL645_PARSE_FRM_MIN_LEN +
|
|
sizeof(proto_645_resp_uart_param_t);
|
|
uint8_t *pkt_data;
|
|
proto_645_header_t *dl645_frm;
|
|
iot_pkt_t *pkt;
|
|
protpkt_tx_info_t txinfo = { 0 };
|
|
uint32_t baud_val[] = PROTO_GE_UART_BAUD_VALUE;
|
|
ge_app_pib_info_t *p_flash = &prototask_contxt.flashinfo;
|
|
proto_645_resp_uart_param_t uart_param;
|
|
|
|
if ((source != FROM_PLC) || (NULL == req_mac)) {
|
|
ret = 1;
|
|
goto out;
|
|
}
|
|
|
|
pkt_len = dl645_len + sizeof(ge_frm_tail_t) +
|
|
sizeof(ge_frame_data_send_set_subfn160_t);
|
|
pkt = iot_pkt_alloc(pkt_len, IOT_GREE_APP_MID);
|
|
if (!pkt) {
|
|
ret = 2;
|
|
goto out;
|
|
}
|
|
|
|
uart_param.di = di;
|
|
uart_param.baudrate = baud_val[p_flash->public.pub.baudidx];
|
|
uart_param.parity = p_flash->public.pub.parity;
|
|
uart_param.data_bit = p_flash->public.pub.data;
|
|
uart_param.stop_bit = p_flash->public.pub.stop;
|
|
|
|
pkt_data = iot_pkt_put(pkt, pkt_len);
|
|
dl645_frm = (proto_645_header_t *)(pkt_data+ge_data_pos);
|
|
iot_proto_645_build_resp_msg(dl645_frm, (uint8_t *)&uart_param,
|
|
sizeof(uart_param), 0, PROTO_645_2007_FN_READ_DATA);
|
|
iot_pack_dl645_to_ge(NULL, pkt_data, &dl645_len, req_mac, 0);
|
|
|
|
iot_proto_fill_txinfo(&txinfo, true, PLCTXRX_UNICAST, 0,
|
|
PROTO_UNICAST_RETRY_DEFAULT_INTVL, 1,
|
|
prototask_contxt.local_dev.mac, req_mac);
|
|
|
|
iot_proto_remote_cmd_send_to_plctxrx(pkt_data, pkt_len, &txinfo);
|
|
iot_pkt_free(pkt);
|
|
|
|
out:
|
|
iot_cus_printf("%s ret:%d\n", __FUNCTION__, ret);
|
|
}
|
|
|
|
/**
|
|
* @brief iot_proto_dl645_write_vout() - handle the power ctrl set cmd from plc
|
|
* @param dl645_data: point to the dl645 data field
|
|
* @param source: from uart or plc
|
|
* @param req_mac: the address represents where the cmd came from and the
|
|
* response data will be sent to
|
|
*/
|
|
static void iot_proto_dl645_write_vout(proto_645_write_vout_param_t *dl645_data,
|
|
uint8_t source, uint8_t *req_mac)
|
|
{
|
|
uint8_t ret = 0;
|
|
uint8_t reason = 0;
|
|
|
|
if ((source != FROM_PLC) || (req_mac == NULL)) {
|
|
ret = 1;
|
|
goto out;
|
|
}
|
|
|
|
if (((dl645_data->v3p3_on_off == 0) && (dl645_data->v12_on_off == 0)) ||
|
|
((dl645_data->v3p3_on_off != HPLC_3P0_JY_VOUT_ON) &&
|
|
(dl645_data->v3p3_on_off != HPLC_3P0_JY_VOUT_OFF)) ||
|
|
((dl645_data->v12_on_off != HPLC_3P0_JY_VOUT_ON) &&
|
|
(dl645_data->v12_on_off != HPLC_3P0_JY_VOUT_OFF))) {
|
|
ret = 2;
|
|
reason = DL645_ERR_PARAMETER_ERROR;
|
|
}
|
|
|
|
if (!reason) {
|
|
if(dl645_data->v3p3_on_off == HPLC_3P0_JY_VOUT_ON) {
|
|
iot_gpio_value_set(HPLC_3P0_JY_EN_OUT3V3_PIN , 1);
|
|
iot_cus_printf("enable 3.3v output\n");
|
|
} else if (dl645_data->v3p3_on_off == HPLC_3P0_JY_VOUT_OFF) {
|
|
iot_gpio_value_set(HPLC_3P0_JY_EN_OUT3V3_PIN , 0);
|
|
iot_cus_printf("disable 3.3v output\n");
|
|
}
|
|
if (dl645_data->v12_on_off == HPLC_3P0_JY_VOUT_ON) {
|
|
iot_gpio_value_set(HPLC_3P0_JY_EN_OUT12V_PIN , 1);
|
|
iot_cus_printf("enable 12v output\n");
|
|
} else if (dl645_data->v12_on_off == HPLC_3P0_JY_VOUT_OFF) {
|
|
iot_gpio_value_set(HPLC_3P0_JY_EN_OUT12V_PIN , 0);
|
|
iot_cus_printf("disable 12v output\n");
|
|
}
|
|
}
|
|
|
|
if (iot_proto_send_dl645_ack(PROTO_645_2007_FN_WRITE_DATA, reason,
|
|
source, req_mac)) {
|
|
ret = 3;
|
|
}
|
|
|
|
out:
|
|
iot_cus_printf("%s ret:%d reason:%d\n", __FUNCTION__, ret, reason);
|
|
}
|
|
|
|
/**
|
|
* @brief iot_proto_dl645_resp_vout() - response power ctrl status to plc
|
|
* @param di: dl645 DI
|
|
* @param source: from uart or plc
|
|
* @param req_mac: the address represents where the cmd came from and the
|
|
* response data will be sent to
|
|
*/
|
|
static void iot_proto_dl645_resp_vout(uint32_t di, uint8_t source,
|
|
uint8_t *req_mac)
|
|
{
|
|
uint8_t ret = 0, err_3v3 = 0, err_12v = 0;
|
|
uint16_t pkt_len;
|
|
uint8_t ge_data_pos = sizeof(ge_frame_data_send_set_subfn160_t);
|
|
uint16_t dl645_len = DL645_PARSE_FRM_MIN_LEN +
|
|
sizeof(proto_645_resp_vol_info_t);
|
|
uint8_t *pkt_data;
|
|
proto_645_header_t *dl645_frm;
|
|
iot_pkt_t *pkt;
|
|
int v3p3_level = 0, v12_level = 0;
|
|
protpkt_tx_info_t txinfo = { 0 };
|
|
proto_645_resp_vol_info_t vol_info;
|
|
int32_t v3 = 0;
|
|
int32_t v12 = 0;
|
|
|
|
if ((source != FROM_PLC) || (NULL == req_mac)) {
|
|
ret = 1;
|
|
goto out;
|
|
}
|
|
|
|
pkt_len = dl645_len + sizeof(ge_frm_tail_t) +
|
|
sizeof(ge_frame_data_send_set_subfn160_t);
|
|
pkt = iot_pkt_alloc(pkt_len, IOT_GREE_APP_MID);
|
|
if (!pkt) {
|
|
ret = 2;
|
|
goto out;
|
|
}
|
|
|
|
vol_info.di = di;
|
|
iot_gpio_output_value_get(HPLC_3P0_JY_EN_OUT3V3_PIN, &v3p3_level);
|
|
vol_info.v3p3_on_off =
|
|
(v3p3_level == 0) ? HPLC_3P0_JY_VOUT_OFF : HPLC_3P0_JY_VOUT_ON;
|
|
v3 = iot_adc_poll_done(ADC_CHANNEL0, ADC_ACC16, ADC_GAIN_3V, &err_3v3);
|
|
|
|
iot_gpio_output_value_get(HPLC_3P0_JY_EN_OUT12V_PIN, &v12_level);
|
|
vol_info.v12_on_off =
|
|
(v12_level == 0) ? HPLC_3P0_JY_VOUT_OFF : HPLC_3P0_JY_VOUT_ON;
|
|
v12 = iot_adc_poll_done(ADC_CHANNEL4, ADC_ACC16, ADC_GAIN_3V, &err_12v);
|
|
|
|
iot_cus_printf("adc 3v3[%d %d] 12v[%d %d]\n", err_3v3, v3, err_12v, v12);
|
|
|
|
if (err_3v3 == 0) {
|
|
/* calc volt to 100mv */
|
|
v3 = v3 * HPLC_3P0_JY_VOUT3V3_RATE * 32 / 511;
|
|
/* for half adjusting */
|
|
vol_info.v3p3_vol = (uint8_t)(v3 + 0.5);
|
|
} else {
|
|
vol_info.v3p3_vol = HPLC_3P0_JY_INVALID_VOL;
|
|
}
|
|
|
|
if (err_12v == 0) {
|
|
/* calc volt to 100mv */
|
|
v12 = v12 * HPLC_3P0_JY_VOUT12V_RATE * 32 / 511;
|
|
/* for half adjusting */
|
|
vol_info.v12_vol = (uint8_t)(v12 + 0.5);
|
|
} else {
|
|
vol_info.v12_vol = HPLC_3P0_JY_INVALID_VOL;
|
|
}
|
|
|
|
iot_cus_printf("calc 3v3[%d %d %d] 12v[%d %d %d]\n", err_3v3, v3,
|
|
vol_info.v3p3_vol, err_12v, v12, vol_info.v12_vol);
|
|
|
|
pkt_data = iot_pkt_put(pkt, pkt_len);
|
|
dl645_frm = (proto_645_header_t *)(pkt_data+ge_data_pos);
|
|
iot_proto_645_build_resp_msg(dl645_frm, (uint8_t *)&vol_info,
|
|
sizeof(vol_info), 0, PROTO_645_2007_FN_READ_DATA);
|
|
iot_pack_dl645_to_ge(NULL, pkt_data, &dl645_len, req_mac, 0);
|
|
|
|
iot_proto_fill_txinfo(&txinfo, true, PLCTXRX_UNICAST, 0,
|
|
PROTO_UNICAST_RETRY_DEFAULT_INTVL, 1,
|
|
prototask_contxt.local_dev.mac, req_mac);
|
|
|
|
iot_proto_remote_cmd_send_to_plctxrx(pkt_data, pkt_len, &txinfo);
|
|
iot_pkt_free(pkt);
|
|
|
|
out:
|
|
iot_cus_printf("%s ret:%x\n", __FUNCTION__, ret);
|
|
}
|
|
|
|
/**
|
|
* @brief iot_proto_dl645_resp_boot_info() - response boot info to plc
|
|
* @param di: dl645 DI
|
|
* @param source: from uart or plc
|
|
* @param req_mac: the address represents where the cmd came from and the
|
|
* response data will be sent to
|
|
*/
|
|
static void iot_proto_dl645_resp_boot_info(uint32_t di, uint8_t source,
|
|
uint8_t *req_mac)
|
|
{
|
|
uint8_t ret = 0;
|
|
uint16_t pkt_len;
|
|
uint8_t ge_data_pos = sizeof(ge_frame_data_send_set_subfn160_t);
|
|
uint16_t dl645_len = DL645_PARSE_FRM_MIN_LEN +
|
|
sizeof(proto_645_resp_boot_info_t);
|
|
uint8_t *pkt_data;
|
|
proto_645_header_t *dl645_frm;
|
|
iot_pkt_t *pkt;
|
|
protpkt_tx_info_t txinfo = { 0 };
|
|
proto_645_resp_boot_info_t boot_info = { 0 };
|
|
|
|
if ((source != FROM_PLC) || (NULL == req_mac)) {
|
|
ret = 1;
|
|
goto out;
|
|
}
|
|
|
|
pkt_len = dl645_len + sizeof(ge_frm_tail_t) +
|
|
sizeof(ge_frame_data_send_set_subfn160_t);
|
|
pkt = iot_pkt_alloc(pkt_len, IOT_GREE_APP_MID);
|
|
if (!pkt) {
|
|
ret = 2;
|
|
goto out;
|
|
}
|
|
|
|
boot_info.di = di;
|
|
iot_board_get_boot_reason(&boot_info.last_reboot_reason);
|
|
boot_info.total_boot_cnt = iot_board_get_reset_count(SYSTEM_RESET_PWR) +
|
|
iot_board_get_reset_count(SYSTEM_RESET_WDT) +
|
|
iot_board_get_reset_count(SYSTEM_RESET_SOFT);
|
|
|
|
|
|
pkt_data = iot_pkt_put(pkt, pkt_len);
|
|
dl645_frm = (proto_645_header_t *)(pkt_data+ge_data_pos);
|
|
iot_proto_645_build_resp_msg(dl645_frm, (uint8_t *)&boot_info,
|
|
sizeof(boot_info), 0, PROTO_645_2007_FN_READ_DATA);
|
|
iot_pack_dl645_to_ge(NULL, pkt_data, &dl645_len, req_mac, 0);
|
|
|
|
iot_proto_fill_txinfo(&txinfo, true, PLCTXRX_UNICAST, 0,
|
|
PROTO_UNICAST_RETRY_DEFAULT_INTVL, 1,
|
|
prototask_contxt.local_dev.mac, req_mac);
|
|
|
|
iot_proto_remote_cmd_send_to_plctxrx(pkt_data, pkt_len, &txinfo);
|
|
iot_pkt_free(pkt);
|
|
|
|
out:
|
|
iot_cus_printf("%s ret:%x\n", __FUNCTION__, ret);
|
|
}
|
|
|
|
/**
|
|
* @brief iot_proto_dl645_resp_monitor_signal() - response monitor_signal to plc
|
|
* @param di: dl645 DI
|
|
* @param source: from uart or plc
|
|
* @param req_mac: the address represents where the cmd came from and the
|
|
* response data will be sent to
|
|
*/
|
|
static void iot_proto_dl645_resp_monitor_signal(uint32_t di, uint8_t source,
|
|
uint8_t *req_mac)
|
|
{
|
|
uint8_t ret = 0, level = 0;
|
|
uint16_t pkt_len;
|
|
uint8_t ge_data_pos = sizeof(ge_frame_data_send_set_subfn160_t);
|
|
uint16_t dl645_len = DL645_PARSE_FRM_MIN_LEN +
|
|
sizeof(proto_645_resp_monitor_signal_t);
|
|
uint8_t *pkt_data;
|
|
proto_645_header_t *dl645_frm;
|
|
iot_pkt_t *pkt;
|
|
protpkt_tx_info_t txinfo = { 0 };
|
|
proto_645_resp_monitor_signal_t monitor = { 0 };
|
|
|
|
if ((source != FROM_PLC) || (NULL == req_mac)) {
|
|
ret = 1;
|
|
goto out;
|
|
}
|
|
|
|
pkt_len = dl645_len + sizeof(ge_frm_tail_t) +
|
|
sizeof(ge_frame_data_send_set_subfn160_t);
|
|
pkt = iot_pkt_alloc(pkt_len, IOT_GREE_APP_MID);
|
|
if (!pkt) {
|
|
ret = 2;
|
|
goto out;
|
|
}
|
|
|
|
monitor.di = di;
|
|
level = iot_gpio_value_get(HPLC_3P0_JY_MONITOR_PIN);
|
|
monitor.signal =
|
|
(level == 0) ? HPLC_3P0_JY_MONITOR_CLOSE : HPLC_3P0_JY_MONITOR_OPEN;
|
|
|
|
pkt_data = iot_pkt_put(pkt, pkt_len);
|
|
dl645_frm = (proto_645_header_t *)(pkt_data+ge_data_pos);
|
|
iot_proto_645_build_resp_msg(dl645_frm, (uint8_t *)&monitor,sizeof(monitor),
|
|
0, PROTO_645_2007_FN_READ_DATA);
|
|
iot_pack_dl645_to_ge(NULL, pkt_data, &dl645_len, req_mac, 0);
|
|
|
|
iot_proto_fill_txinfo(&txinfo, true, PLCTXRX_UNICAST, 0,
|
|
PROTO_UNICAST_RETRY_DEFAULT_INTVL, 1,
|
|
prototask_contxt.local_dev.mac, req_mac);
|
|
|
|
iot_proto_remote_cmd_send_to_plctxrx(pkt_data, pkt_len, &txinfo);
|
|
iot_pkt_free(pkt);
|
|
|
|
out:
|
|
iot_cus_printf("%s ret:%d\n", __FUNCTION__, ret);
|
|
}
|
|
|
|
/**
|
|
* @brief iot_proto_dl645_close_hw_wdg() - disable hardware watchdog
|
|
* @param dl645_data: pointer of dlt645 data field
|
|
* @param source: from uart or plc
|
|
* @param req_mac: the address represents where the cmd came from and the
|
|
* response data will be sent to
|
|
*/
|
|
static void iot_proto_dl645_close_hw_wdg(proto_645_close_hw_wdg_t *dl645_data,
|
|
uint8_t source, uint8_t *req_mac)
|
|
{
|
|
uint8_t ret = 0;
|
|
uint8_t reason = 0;
|
|
|
|
if ((source != FROM_PLC) || (NULL == req_mac)) {
|
|
ret = 1;
|
|
goto out;
|
|
}
|
|
|
|
if (dl645_data->close_wdg != HPLC_3P0_JY_CLOSE_HW_WDG) {
|
|
reason = DL645_ERR_PARAMETER_ERROR;
|
|
} else {
|
|
prototask_contxt.hw_watchdog_en = 0;
|
|
}
|
|
|
|
|
|
if (iot_proto_send_dl645_ack(PROTO_645_2007_FN_WRITE_DATA, reason,
|
|
source, req_mac)) {
|
|
ret = 2;
|
|
}
|
|
|
|
out:
|
|
iot_cus_printf("%s ret:%d reason:%d\n", __FUNCTION__, ret, reason);
|
|
}
|
|
|
|
/**
|
|
* @brief iot_proto_dl645_set_edge_cmd_time() - dl645 set edge cmd inverval time
|
|
* and total time
|
|
* @param dl645_data: point to the 645 frame
|
|
* @param source: from uart or plc
|
|
* @param req_mac: the address represents where the cmd came from and the
|
|
* response data will be sent to
|
|
*/
|
|
static void iot_proto_dl645_set_edge_cmd_time(
|
|
proto_645_set_edge_time_t *dl645_data, uint8_t source, uint8_t *req_mac)
|
|
{
|
|
uint8_t ret = 0;
|
|
uint8_t reason = 0;
|
|
edge_delay_time_info_t time_info;
|
|
|
|
if ((source != FROM_PLC) || (NULL == req_mac)) {
|
|
ret = 1;
|
|
goto out;
|
|
}
|
|
|
|
if ((dl645_data->cmd_inverval >= EDGE_CMD_INTERVE_MIN) &&
|
|
(dl645_data->cmd_inverval <= EDGE_CMD_INTERVE_MAX) &&
|
|
(dl645_data->cmd_tol_tm >= UART_RX_MAX_TIMEOUT_MIN) &&
|
|
(dl645_data->cmd_tol_tm <= UART_RX_MAX_TIMEOUT_MAX)) {
|
|
time_info.cmd_inverval = dl645_data->cmd_inverval;
|
|
time_info.cmd_tol_tm = dl645_data->cmd_tol_tm;
|
|
} else {
|
|
ret = 2;
|
|
reason = DL645_ERR_PARAMETER_ERROR;
|
|
}
|
|
|
|
if (iot_proto_send_dl645_ack(PROTO_645_2007_FN_WRITE_DATA, reason,
|
|
source, req_mac)) {
|
|
ret = 3;
|
|
}
|
|
|
|
if (!reason) {
|
|
proto_post_data_to_edge_msg_handle(EDGE_INPUT_SET_DELAY_TIME_ID,
|
|
&time_info, sizeof(edge_delay_time_info_t));
|
|
}
|
|
|
|
out:
|
|
iot_cus_printf("%s ret:%d reason:%d\n", __FUNCTION__, ret, reason);
|
|
}
|
|
|
|
/**
|
|
* @brief iot_proto_dl645_set_edge_cmd_time_inner() - dl645 set edge start time、
|
|
* starting_stopping time and each rx timeout
|
|
* @param dl645_data: point to the 645 frame
|
|
* @param source: from uart or plc
|
|
* @param req_mac: the address represents where the cmd came from and the
|
|
* response data will be sent to
|
|
*/
|
|
static void iot_proto_dl645_set_edge_cmd_time_inner(
|
|
proto_645_set_edge_time_inner_t *dl645_data, uint8_t source,
|
|
uint8_t *req_mac)
|
|
{
|
|
uint8_t ret = 0, reason = 0;
|
|
edge_delay_time_info_inner_t time_info;
|
|
ge_app_pib_info_t *p_flash = &prototask_contxt.flashinfo;
|
|
|
|
if ((source != FROM_PLC) || (NULL == req_mac)) {
|
|
ret = 1;
|
|
goto out;
|
|
}
|
|
|
|
if ((dl645_data->time_info.edge_start_tm >= UART_MONITOR_START_MIN) &&
|
|
(dl645_data->time_info.edge_start_tm <= UART_MONITOR_START_MAX) &&
|
|
(dl645_data->time_info.cmd_starting_stopping_tm >=
|
|
EDGE_STARTING_STOPPING_MIN) &&
|
|
(dl645_data->time_info.cmd_starting_stopping_tm <=
|
|
EDGE_STARTING_STOPPING_MAX) &&
|
|
(dl645_data->time_info.cmd_each_tm >= UART_RX_TIMEOUT_MIN) &&
|
|
(dl645_data->time_info.cmd_each_tm <= UART_RX_TIMEOUT_MAX)) {
|
|
p_flash->public.pub.edge_start_tm =
|
|
dl645_data->time_info.edge_start_tm;
|
|
time_info.cmd_starting_stopping_tm =
|
|
dl645_data->time_info.cmd_starting_stopping_tm;
|
|
time_info.cmd_each_tm = dl645_data->time_info.cmd_each_tm;
|
|
} else {
|
|
ret = 2;
|
|
reason = DL645_ERR_PARAMETER_ERROR;
|
|
}
|
|
|
|
if (iot_proto_send_dl645_ack(PROTO_645_2007_FN_WRITE_DATA, reason,
|
|
source, req_mac)) {
|
|
ret = 3;
|
|
}
|
|
|
|
if (!reason) {
|
|
/* cmd_starting_stopping_tm and cmd_each_tm are send to edge,
|
|
edge_start_tm is saved in proto parameter list */
|
|
proto_post_data_to_edge_msg_handle(EDGE_INPUT_SET_DELAY_TIME_INNER_ID,
|
|
&time_info, sizeof(edge_delay_time_info_inner_t));
|
|
/* save edge_start_tm to pib */
|
|
iot_proto_flashsave(p_flash);
|
|
}
|
|
|
|
out:
|
|
iot_cus_printf("%s ret:%d reason:%d\n", __FUNCTION__, ret, reason);
|
|
}
|
|
|
|
/**
|
|
* @brief iot_proto_dl645_query_edge_cmd_time() - dl645 query edge cmd inverval
|
|
* time and total time
|
|
* @param source: from uart or plc
|
|
*/
|
|
static void iot_proto_dl645_query_edge_cmd_time(uint8_t source)
|
|
{
|
|
uint8_t ret = 0;
|
|
|
|
if (source != FROM_PLC) {
|
|
ret = 1;
|
|
goto out;
|
|
}
|
|
|
|
proto_post_data_to_edge_msg_handle(EDGE_INPUT_QUERY_DELAY_TIME_ID, NULL, 0);
|
|
|
|
out:
|
|
iot_cus_printf("query_edge_cmd_time ret:%x\n", ret);
|
|
}
|
|
|
|
/**
|
|
* @brief iot_proto_dl645_query_edge_cmd_time_inner() - dl645 query edge cmd
|
|
start time、starting stopping time
|
|
and each overtime
|
|
* @param source: from uart or plc
|
|
*/
|
|
static void iot_proto_dl645_query_edge_cmd_time_inner(uint8_t source)
|
|
{
|
|
uint8_t ret = 0;
|
|
|
|
if (source != FROM_PLC) {
|
|
ret = 1;
|
|
goto out;
|
|
}
|
|
|
|
proto_post_data_to_edge_msg_handle(EDGE_INPUT_QUERY_DELAY_TIME_INNER_ID, NULL, 0);
|
|
|
|
out:
|
|
iot_cus_printf("query_edge_cmd_time_inner ret:%x\n", ret);
|
|
}
|
|
|
|
static void iot_proto_dl645_query_edge_cmd_cnt(uint8_t source)
|
|
{
|
|
uint8_t ret = 0;
|
|
|
|
if (source != FROM_PLC) {
|
|
ret = 1;
|
|
goto out;
|
|
}
|
|
|
|
proto_post_data_to_edge_msg_handle(EDGE_INPUT_QUERY_CACHE_CNT_ID, NULL, 0);
|
|
|
|
out:
|
|
iot_cus_printf("query_edge_cmd_cnt ret:%x\n", ret);
|
|
}
|
|
|
|
/**
|
|
* @brief iot_proto_dl645_query_edge_cmd_baud() - dl645 query edge cmd baud
|
|
* @param source: from uart or plc
|
|
*/
|
|
static void iot_proto_dl645_query_edge_cmd_baud(uint8_t source)
|
|
{
|
|
uint8_t ret = 0;
|
|
|
|
if (source != FROM_PLC) {
|
|
/* only handle plc query command */
|
|
ret = 1;
|
|
goto out;
|
|
}
|
|
|
|
proto_post_data_to_edge_msg_handle(EDGE_INPUT_QUERY_BAUD_ID, NULL, 0);
|
|
|
|
out:
|
|
iot_cus_printf("query_edge_baud ret:%d\n", ret);
|
|
}
|
|
|
|
static void iot_proto_dl645_set_edge_cmd(proto_645_edge_dev_cmd_t *dl645_data,
|
|
uint16_t frm_len, uint32_t di, uint8_t source, uint8_t *req_mac)
|
|
{
|
|
uint8_t ret = 0, idx = 0;
|
|
uint8_t reason = 0;
|
|
uint16_t pkt_len, data_len;
|
|
int16_t cmd_len;
|
|
iot_pkt_t *cmd_pkt = NULL;
|
|
edge_cache_cmd_info_t *cmd_data;
|
|
|
|
if ((source != FROM_PLC) || (NULL == req_mac)) {
|
|
ret = 1;
|
|
goto out;
|
|
}
|
|
|
|
if ((di >= DL645_07_DI_EDGE_645_MIN_CMD) &&
|
|
(di <= DL645_07_DI_EDGE_645_MAX_CMD)) {
|
|
idx = di - DL645_07_DI_EDGE_645_MIN_CMD;
|
|
} else if ((di >= DL645_07_DI_EDGE_MODBUS_MIN_CMD) &&
|
|
(di <= DL645_07_DI_EDGE_MODBUS_MAX_CMD)) {
|
|
idx = di - DL645_07_DI_EDGE_MODBUS_MIN_CMD;
|
|
}
|
|
|
|
data_len = frm_len - DL645_PARSE_FRM_MIN_LEN;
|
|
cmd_len = data_len - sizeof(proto_645_edge_dev_cmd_t);
|
|
if (cmd_len < 0) {
|
|
reason = DL645_ERR_PARAMETER_ERROR;
|
|
} else if (cmd_len == 0) {
|
|
/* delete edge command */
|
|
proto_post_data_to_edge_msg_handle(EDGE_INPUT_DEL_CACHE_ID,
|
|
NULL, 0);
|
|
} else {
|
|
/* add edge command */
|
|
if (iot_proto_645_frm_format_check(&dl645_data->data[0], cmd_len, NULL) &&
|
|
iot_proto_modbus_frm_format_check(&dl645_data->data[0], cmd_len)) {
|
|
/* modbus or dl645 format error */
|
|
ret = 2;
|
|
reason = DL645_ERR_PARAMETER_ERROR;
|
|
} else {
|
|
pkt_len = cmd_len + sizeof(edge_cache_cmd_info_t);
|
|
cmd_pkt = iot_pkt_alloc(pkt_len, IOT_GREE_APP_MID);
|
|
if (!cmd_pkt) {
|
|
ret = 3;
|
|
goto out;
|
|
}
|
|
cmd_data = (edge_cache_cmd_info_t *)iot_pkt_put(cmd_pkt, pkt_len);
|
|
cmd_data->idx = idx;
|
|
os_mem_cpy(cmd_data->data, &dl645_data->data[0], cmd_len);
|
|
proto_post_data_to_edge_msg_handle(EDGE_INPUT_ADD_CACHE_ID,
|
|
cmd_data, pkt_len);
|
|
|
|
iot_pkt_free(cmd_pkt);
|
|
}
|
|
}
|
|
|
|
if (iot_proto_send_dl645_ack(PROTO_645_2007_FN_WRITE_DATA,
|
|
reason, source, req_mac)) {
|
|
ret = 4;
|
|
}
|
|
|
|
out:
|
|
iot_cus_printf("%s ret:%d reason:%d\n", __FUNCTION__, ret, reason);
|
|
}
|
|
|
|
static void iot_proto_dl645_query_edge_cmd(uint32_t di, uint8_t source)
|
|
{
|
|
uint8_t ret = 0;
|
|
edge_cache_cmd_info_t cmd_data;
|
|
|
|
if (source != FROM_PLC) {
|
|
ret = 1;
|
|
goto out;
|
|
}
|
|
|
|
if ((di >= DL645_07_DI_EDGE_645_MIN_CMD) &&
|
|
(di <= DL645_07_DI_EDGE_645_MAX_CMD)) {
|
|
cmd_data.cmd_type = EDGE_QUERY_EDGE_CMD_645;
|
|
cmd_data.idx = di - DL645_07_DI_EDGE_645_MIN_CMD;
|
|
} else if ((di >= DL645_07_DI_EDGE_MODBUS_MIN_CMD) &&
|
|
(di <= DL645_07_DI_EDGE_MODBUS_MAX_CMD)) {
|
|
cmd_data.cmd_type = EDGE_QUERY_EDGE_CMD_MODBUS;
|
|
cmd_data.idx = di - DL645_07_DI_EDGE_MODBUS_MIN_CMD;
|
|
}
|
|
|
|
proto_post_data_to_edge_msg_handle(EDGE_INPUT_QUERY_CACHE_INFO_ID,
|
|
&cmd_data, sizeof(edge_cache_cmd_info_t));
|
|
|
|
out:
|
|
iot_cus_printf("%s ret:%d\n", __FUNCTION__, ret);
|
|
}
|
|
|
|
/**
|
|
* @brief iot_proto_dl645_set_edge_cmd_baud() - dl645 set edge cmd baud
|
|
* @param dl645_data: point to the 645 frame
|
|
* @param source: from uart or plc
|
|
* @param req_mac: the address represents where the cmd came from and the
|
|
* response data will be sent to
|
|
*/
|
|
static void iot_proto_dl645_set_edge_cmd_baud(
|
|
proto_645_edge_dev_cmd_t *dl645_data, uint16_t cmd_len,
|
|
uint8_t source, uint8_t *req_mac)
|
|
{
|
|
uint8_t i;
|
|
uint8_t cnt;
|
|
uint8_t ret = 0;
|
|
uint8_t reason = 0;
|
|
edge_baud_cmd_t *edge_cmd;
|
|
|
|
cnt = (uint8_t)(*dl645_data->data);
|
|
|
|
if ((source != FROM_PLC) || (NULL == req_mac)) {
|
|
ret = 1;
|
|
goto out;
|
|
}
|
|
|
|
cmd_len -= sizeof(proto_645_edge_dev_cmd_t);
|
|
|
|
if (cnt == 0 || cnt > EDGECOM_MAX_CMD) {
|
|
reason = DL645_ERR_PARAMETER_ERROR;
|
|
goto err;
|
|
}
|
|
|
|
if (cmd_len != cnt * sizeof(edge_baud_cmd_t) + sizeof(uint8_t)) {
|
|
iot_cus_printf("%s length error cnt:%d\n", __FUNCTION__, cnt);
|
|
reason = DL645_ERR_PARAMETER_ERROR;
|
|
goto err;
|
|
}
|
|
|
|
edge_cmd = (edge_baud_cmd_t*)(dl645_data->data + sizeof(uint8_t));
|
|
/* check param */
|
|
for (i = 0; i < cnt; i++) {
|
|
if (edge_cmd->index == 0 || edge_cmd->index > EDGECOM_MAX_CMD) {
|
|
/* check cmd index */
|
|
reason = DL645_ERR_PARAMETER_ERROR;
|
|
break;
|
|
}
|
|
if (edge_cmd->baud_info.baud_idx >= EDGE_BAUD_IDX_CNT) {
|
|
/* check cmd baud */
|
|
reason = DL645_ERR_PARAMETER_ERROR;
|
|
break;
|
|
}
|
|
if (edge_cmd->baud_info.parity > IOT_UART_PARITY_SPACE) {
|
|
/* check cmd parity */
|
|
reason = DL645_ERR_PARAMETER_ERROR;
|
|
break;
|
|
}
|
|
edge_cmd++;
|
|
}
|
|
|
|
err:
|
|
if (iot_proto_send_dl645_ack(PROTO_645_2007_FN_WRITE_DATA,
|
|
reason, source, req_mac)) {
|
|
ret = 2;
|
|
}
|
|
|
|
if (!reason) {
|
|
proto_post_data_to_edge_msg_handle(EDGE_INPUT_SET_BAUD_ID,
|
|
dl645_data->data, cmd_len);
|
|
}
|
|
|
|
out:
|
|
iot_cus_printf("%s ret:%d reason:%d\n", __FUNCTION__, ret, reason);
|
|
}
|
|
|
|
static uint8_t iot_proto_645_local_mode_cache(proto_645_header_t *data_645)
|
|
{
|
|
uint32_t di;
|
|
uint8_t revert_mac[IOT_MAC_ADDR_LEN];
|
|
uint8_t pos;
|
|
uint16_t dl645_len;
|
|
|
|
iot_mac_addr_cpy(revert_mac, data_645->addr);
|
|
iot_mac_addr_reverse(revert_mac);
|
|
proto_645_2007_byte_to_di(data_645->data, di);
|
|
dl645_len = data_645->len + DL645_PARSE_FRM_MIN_LEN;
|
|
|
|
/* tail +1 to get memory before storage the input data */
|
|
g_local_dl645_cache.tail++;
|
|
if (g_local_dl645_cache.tail >= DL645_LOCALMODE_CACHE_MAX_NUM) {
|
|
g_local_dl645_cache.tail = 0;
|
|
}
|
|
/* when tail equal to head means the cache is full, head +1 to free the
|
|
earliest data*/
|
|
if (g_local_dl645_cache.tail == g_local_dl645_cache.head) {
|
|
g_local_dl645_cache.head++;
|
|
if (g_local_dl645_cache.head >= DL645_LOCALMODE_CACHE_MAX_NUM) {
|
|
g_local_dl645_cache.head = 0;
|
|
}
|
|
}
|
|
/* cache the 645 data on tail */
|
|
pos = g_local_dl645_cache.tail;
|
|
iot_cus_printf("meter data save to pos[%d], di=%08X, "
|
|
"mac=[%02x%02x%02x%02x%02x%02x]\n", pos, di, revert_mac[0],
|
|
revert_mac[1], revert_mac[2], revert_mac[3], revert_mac[4],
|
|
revert_mac[5]);
|
|
g_local_dl645_cache.meter_data[pos].di = di;
|
|
iot_mac_addr_cpy(g_local_dl645_cache.meter_data[pos].mac, revert_mac);
|
|
iot_proto_645_ext_add33_handle(data_645->data, data_645->len);
|
|
os_mem_cpy(g_local_dl645_cache.meter_data[pos].data, data_645, dl645_len);
|
|
|
|
return ERR_OK;
|
|
}
|
|
|
|
static uint8_t* iot_proto_645_local_mode_lookup(uint32_t di, uint8_t *mac)
|
|
{
|
|
uint8_t i;
|
|
uint8_t cache_size;
|
|
uint8_t pos;
|
|
|
|
iot_cus_printf("look for meter data: di=%08X, "
|
|
"mac=[%02x%02x%02x%02x%02x%02x]\n", di, mac[0], mac[1], mac[2], mac[3],
|
|
mac[4], mac[5]);
|
|
/* to get the size of used cache, the array is regard as a circular fifo */
|
|
if (g_local_dl645_cache.tail >= g_local_dl645_cache.head) {
|
|
cache_size = g_local_dl645_cache.tail - g_local_dl645_cache.head;
|
|
} else {
|
|
cache_size = g_local_dl645_cache.tail + DL645_LOCALMODE_CACHE_MAX_NUM -
|
|
g_local_dl645_cache.head;
|
|
}
|
|
/* we should look up the cache from head to tail */
|
|
for (i = 0; i < (cache_size + 1); i++) {
|
|
pos = g_local_dl645_cache.head + i;
|
|
if (pos >= DL645_LOCALMODE_CACHE_MAX_NUM) {
|
|
pos -= DL645_LOCALMODE_CACHE_MAX_NUM;
|
|
}
|
|
if (di == g_local_dl645_cache.meter_data[pos].di &&
|
|
iot_mac_addr_cmp(mac, g_local_dl645_cache.meter_data[pos].mac)) {
|
|
iot_cus_printf("meter data found in pos[%d]\n", pos);
|
|
return (uint8_t *)g_local_dl645_cache.meter_data[pos].data;;
|
|
}
|
|
}
|
|
iot_cus_printf("local meter data not found\n");
|
|
return NULL;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_proto_645_local_mode_cmd_start() - handle the local read mode
|
|
entry cmd
|
|
*/
|
|
static void iot_proto_645_local_mode_cmd_start(void)
|
|
{
|
|
g_dl645_local_mode_state = DL645_LOCAL_MODE_STARTED;
|
|
iot_cus_printf("dl645_local_read_mode[%d]\n",
|
|
g_dl645_local_mode_state);
|
|
os_start_timer(prototask_contxt.dl645_localmode_tmr,
|
|
PROTO_TMR_645_LOCAL_READ_MODE_INTVL);
|
|
}
|
|
|
|
/**
|
|
* @brief iot_proto_645_ckq_req_handle() - handle the meter read cmd where
|
|
* came frome ckq in local read mode
|
|
* @param hdr: pointer to the integral 645 frame
|
|
*/
|
|
static void iot_proto_645_ckq_req_handle(proto_645_header_t *hdr)
|
|
{
|
|
proto_645_header_t *ext_645_hdr = hdr;
|
|
proto_645_header_t *cmd_645_hdr = NULL;
|
|
proto_645_header_t *local_645 = NULL;
|
|
proto_645_header_t *ind_645 = NULL;
|
|
uint16_t frm_645_len = 0;
|
|
uint8_t dst_mac[IOT_MAC_ADDR_LEN];
|
|
uint32_t cmd_di = 0;
|
|
uint8_t cmd_mac[IOT_MAC_ADDR_LEN];
|
|
iot_pkt_t *pkt = NULL;
|
|
uint16_t pkt_len = 0;
|
|
uint8_t *pkt_data = NULL;
|
|
protpkt_tx_info_t txinfo = { 0 };
|
|
|
|
if (ext_645_hdr->len < (DL645_PARSE_FRM_MIN_LEN + DL645_DI_LEN)) {
|
|
iot_cus_printf("%s length of cmd err!\n", __FUNCTION__);
|
|
return;
|
|
}
|
|
|
|
iot_mac_addr_cpy(dst_mac, ext_645_hdr->addr);
|
|
iot_mac_addr_reverse(dst_mac);
|
|
cmd_645_hdr = (proto_645_header_t *)(ext_645_hdr->data + DL645_DI_LEN);
|
|
iot_mac_addr_cpy(cmd_mac, cmd_645_hdr->addr);
|
|
iot_mac_addr_reverse(cmd_mac);
|
|
iot_proto_645_ext_sub33_handle(cmd_645_hdr->data, cmd_645_hdr->len);
|
|
proto_645_2007_byte_to_di(cmd_645_hdr->data, cmd_di);
|
|
|
|
if (iot_sta_check_local_dl645_cmd((uint8_t *)cmd_645_hdr, &cmd_di,
|
|
cmd_mac)) {
|
|
/* handle the local dl645 cmd from ckq */
|
|
iot_cus_printf("handle local cmd from ckq[%02x:%02x:%02x:%02x:%02x:"
|
|
"%02x]\n", cmd_mac[0], cmd_mac[1], cmd_mac[2], cmd_mac[3],
|
|
cmd_mac[4], cmd_mac[5]);
|
|
iot_sta_handle_local_dl645_cmd((uint8_t *)cmd_645_hdr,
|
|
ext_645_hdr->len - DL645_DI_LEN, cmd_645_hdr->control.fn, cmd_di,
|
|
FROM_PLC, dst_mac);
|
|
return;
|
|
}
|
|
/* handle all the dl645 cmd except local dl645 cmd from ckq */
|
|
local_645 = (proto_645_header_t *)iot_proto_645_local_mode_lookup(cmd_di,
|
|
cmd_mac);
|
|
if (local_645 != NULL) {
|
|
frm_645_len = local_645->len + DL645_PARSE_FRM_MIN_LEN;
|
|
pkt_len = frm_645_len + sizeof(ge_frm_tail_t) +
|
|
sizeof(ge_frame_data_send_set_subfn160_t);
|
|
if (pkt_len > GE_FRM_MAX_LEN) {
|
|
iot_cus_printf("%s out of max length of ge frame!\n", __FUNCTION__);
|
|
return;
|
|
}
|
|
pkt = iot_pkt_alloc(pkt_len, IOT_GREE_APP_MID);
|
|
if (pkt == NULL) {
|
|
iot_cus_printf("%s pkt alloc err!\n", __FUNCTION__);
|
|
return;
|
|
}
|
|
pkt_data = iot_pkt_put(pkt, pkt_len);
|
|
iot_pack_dl645_to_ge((uint8_t *)local_645, pkt_data, &frm_645_len,
|
|
dst_mac, true);
|
|
} else {
|
|
frm_645_len = DL645_NACK_FRM_LEN;
|
|
pkt_len = frm_645_len + sizeof(ge_frm_tail_t) +
|
|
sizeof(ge_frame_data_send_set_subfn160_t);
|
|
pkt = iot_pkt_alloc(pkt_len, IOT_GREE_APP_MID);
|
|
if (pkt == NULL) {
|
|
iot_cus_printf("%s pkt alloc err!\n", __FUNCTION__);
|
|
return;
|
|
}
|
|
pkt_data = iot_pkt_put(pkt, pkt_len);
|
|
ind_645 = (proto_645_header_t *)(pkt_data +
|
|
sizeof(ge_frame_data_send_set_subfn160_t));
|
|
iot_proto_645_build_resp_msg(ind_645, NULL, 0 ,DL645_ERR_NO_REQ_DATA,
|
|
PROTO_645_2007_FN_READ_DATA);
|
|
iot_pack_dl645_to_ge(NULL, pkt_data, &frm_645_len, dst_mac, true);
|
|
}
|
|
if (pkt) {
|
|
iot_proto_fill_txinfo(&txinfo, true, PLCTXRX_UNICAST,
|
|
PROTO_UNICAST_RETRY_DEFAULT_CNT,
|
|
PROTO_UNICAST_RETRY_DEFAULT_INTVL, 1,
|
|
prototask_contxt.local_dev.mac, dst_mac);
|
|
txinfo.force_tx_connless = true;
|
|
iot_proto_remote_cmd_send_to_plctxrx(pkt_data, pkt_len, &txinfo);
|
|
iot_pkt_free(pkt);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief iot_sta_check_local_dl645_cmd() - check it is a local cmd or not
|
|
* @param data_input: point to the dl645 data
|
|
* @param di: point to the dl645 di and get it out if it exist
|
|
* @param mac: point to the mac of dl645 cmd
|
|
* @retval: local or not
|
|
*/
|
|
static uint8_t iot_sta_check_local_dl645_cmd(uint8_t *data_input,
|
|
uint32_t *di, uint8_t *mac)
|
|
{
|
|
uint8_t ret = false;
|
|
proto_645_header_t *hdr_645 = ( proto_645_header_t *)data_input;
|
|
iot_cus_printf("local hdr_645->control.fn = %x\n", hdr_645->control.fn);
|
|
switch (hdr_645->control.fn) {
|
|
case PROTO_645_2007_FN_READ_DATA:
|
|
{
|
|
proto_645_2007_byte_to_di(hdr_645->data, *di);
|
|
iot_cus_printf("local check di = %x\n", *di);
|
|
if ((iot_sta_check_local_645_di(*di) &&
|
|
iot_mac_addr_cmp(mac, prototask_contxt.local_dev.mac)) ||
|
|
iot_sta_check_local_mode_645_di(*di)) {
|
|
ret = true;
|
|
}
|
|
break;
|
|
}
|
|
case PROTO_645_2007_FN_READ_ADDR:
|
|
{
|
|
if (iot_mac_addr_cmp(mac, proto_645_any_addr) ||
|
|
iot_mac_addr_cmp(mac, prototask_contxt.local_dev.mac)) {
|
|
ret = true;
|
|
}
|
|
if (hdr_645->control.dir == PROTO_645_DIR_SLAVE &&
|
|
!prototask_contxt.macaddr_set) {
|
|
/* set module mac after recv response mac */
|
|
ret = true;
|
|
}
|
|
break;
|
|
}
|
|
case PROTO_645_2007_FN_WRITE_DATA:
|
|
{
|
|
proto_645_2007_byte_to_di(hdr_645->data, *di);
|
|
iot_cus_printf("local write data di = %x\n", *di);
|
|
if (iot_sta_check_local_645_di(*di) &&
|
|
iot_mac_addr_cmp(mac, prototask_contxt.local_dev.mac)) {
|
|
ret = true;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
/* TO DO */
|
|
break;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_sta_handle_local_dl645_cmd() - handle the local sta cmd
|
|
* @param data_input: point to the dl645 data
|
|
* @param data_len: length of the dl645 frame
|
|
* @param fn: control.fn of dl645 cmd
|
|
* @param di: the dl645 di if it exist
|
|
* @param source: from uart or plc
|
|
* @param req_mac: the address represents where the cmd came from and the
|
|
* response data will be sent to
|
|
*/
|
|
static void iot_sta_handle_local_dl645_cmd(uint8_t *data_input,
|
|
uint16_t data_len, uint8_t fn, uint32_t di, uint8_t source, uint8_t *req_mac)
|
|
{
|
|
proto_645_header_t *hdr_645;
|
|
uint8_t *dst_mac = req_mac;
|
|
|
|
if ((FROM_UART == source) && (NULL != dst_mac) ){
|
|
dst_mac = NULL;
|
|
}
|
|
if (NULL != dst_mac) {
|
|
iot_cus_printf("Response DI[0x%08X] fn[0x%02x] will be sent "
|
|
"to[%02x:%02x:%02x:%02x:%02x:%02x]\n", di, fn, req_mac[0],
|
|
req_mac[1], req_mac[2], req_mac[3], req_mac[4], req_mac[5]);
|
|
}
|
|
|
|
switch (fn) {
|
|
case PROTO_645_2007_FN_READ_DATA:
|
|
{
|
|
hdr_645 = (proto_645_header_t *)data_input;
|
|
if (di == DL645_07_DI_CKQ_MODE_READ) {
|
|
iot_proto_645_ckq_req_handle(hdr_645);
|
|
} else if (DL645_07_DI_UART_PARAM == di) {
|
|
iot_proto_dl645_resp_uart_param(di, source, dst_mac);
|
|
} else if (DL645_07_DI_QUERY_BOOT_INFO == di) {
|
|
iot_proto_dl645_resp_boot_info(di, source, dst_mac);
|
|
}
|
|
if (CUS_BOARD_ID_LEDC_V3_0 == iot_board_get_board_id() &&
|
|
iot_hwver_is_ledc_v3_0_jy()) {
|
|
if (DL645_07_DI_CTRL_VOUT == di) {
|
|
iot_proto_dl645_resp_vout(di, source, dst_mac);
|
|
} else if (DL645_07_DI_READ_MONITOR_SIGNAL == di) {
|
|
iot_proto_dl645_resp_monitor_signal(di, source, dst_mac);
|
|
} else if (DL645_07_DI_EDGE_TIME_PARAM == di) {
|
|
iot_proto_dl645_query_edge_cmd_time(source);
|
|
} else if (DL645_07_DI_QUERY_EDGE_CMD_CNT == di) {
|
|
iot_proto_dl645_query_edge_cmd_cnt(source);
|
|
} else if (((di >= DL645_07_DI_EDGE_645_MIN_CMD) &&
|
|
(di <= DL645_07_DI_EDGE_645_MAX_CMD)) ||
|
|
((di >= DL645_07_DI_EDGE_MODBUS_MIN_CMD) &&
|
|
(di <= DL645_07_DI_EDGE_MODBUS_MAX_CMD))) {
|
|
iot_proto_dl645_query_edge_cmd(di, source);
|
|
} else if (DL645_07_DI_EDGE_TIME_PARAM_INNER == di) {
|
|
iot_proto_dl645_query_edge_cmd_time_inner(source);
|
|
} else if (DL645_07_DI_EDGE_CMD_BAUD == di) {
|
|
iot_proto_dl645_query_edge_cmd_baud(source);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case PROTO_645_2007_FN_READ_ADDR:
|
|
{
|
|
hdr_645 = (proto_645_header_t *)data_input;
|
|
if (hdr_645->control.dir == PROTO_645_DIR_MASTER) {
|
|
iot_resp_uart_mac_query(source, dst_mac);
|
|
} else {
|
|
if (!prototask_contxt.macaddr_set) {
|
|
/* moudle has already got the meter's addres by this frame
|
|
set moudle address same as meter's */
|
|
iot_mac_addr_reverse(hdr_645->addr);
|
|
iot_proto_set_mac(hdr_645->addr, 0, false);
|
|
iot_proto_boot_ready_ind(hdr_645->addr);
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
case PROTO_645_2007_FN_WRITE_DATA:
|
|
{
|
|
hdr_645 = (proto_645_header_t *)data_input;
|
|
if (di == DL645_07_DI_UART_PARAM) {
|
|
iot_proto_dl645_uart_set((proto_645_set_uart_param_t *)hdr_645->data,
|
|
source, dst_mac);
|
|
}
|
|
if (CUS_BOARD_ID_LEDC_V3_0 == iot_board_get_board_id() &&
|
|
iot_hwver_is_ledc_v3_0_jy()) {
|
|
if (DL645_07_DI_CTRL_VOUT == di) {
|
|
iot_proto_dl645_write_vout((proto_645_write_vout_param_t *)
|
|
hdr_645->data, source, dst_mac);
|
|
} else if (DL645_07_DI_CLOSE_HW_WATCHDOG == di) {
|
|
iot_proto_dl645_close_hw_wdg((proto_645_close_hw_wdg_t *)
|
|
hdr_645->data, source, dst_mac);
|
|
} else if (DL645_07_DI_EDGE_TIME_PARAM == di) {
|
|
iot_proto_dl645_set_edge_cmd_time((proto_645_set_edge_time_t *)
|
|
hdr_645->data, source, dst_mac);
|
|
} else if (((di >= DL645_07_DI_EDGE_645_MIN_CMD) &&
|
|
(di <= DL645_07_DI_EDGE_645_MAX_CMD)) ||
|
|
((di >= DL645_07_DI_EDGE_MODBUS_MIN_CMD) &&
|
|
(di <= DL645_07_DI_EDGE_MODBUS_MAX_CMD))) {
|
|
iot_proto_dl645_set_edge_cmd((proto_645_edge_dev_cmd_t *)
|
|
hdr_645->data, data_len, di, source, dst_mac);
|
|
} else if (DL645_07_DI_EDGE_TIME_PARAM_INNER == di) {
|
|
iot_proto_dl645_set_edge_cmd_time_inner(
|
|
(proto_645_set_edge_time_inner_t *)hdr_645->data,
|
|
source, dst_mac);
|
|
} else if (DL645_07_DI_EDGE_CMD_BAUD == di) {
|
|
iot_proto_dl645_set_edge_cmd_baud(
|
|
(proto_645_edge_dev_cmd_t *)hdr_645->data, hdr_645->len,
|
|
source, dst_mac);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
/* TO DO */
|
|
break;
|
|
}
|
|
}
|
|
|
|
uint8_t iot_handle_ge_to_dl645(uint8_t *data_input, uint8_t *data_output)
|
|
{
|
|
ge_frame_data_send_set_subfn160_t *data_hdr =
|
|
(ge_frame_data_send_set_subfn160_t *)data_input;
|
|
proto_645_header_t *hdr_645 = (proto_645_header_t *)data_hdr->data;
|
|
/* the start position of dl645 data in the ge frame */
|
|
uint8_t dl645_data_pos = sizeof(ge_frame_data_send_set_subfn160_t) +
|
|
sizeof(proto_645_header_t) + DL645_DI_LEN;
|
|
/* length of ge data */
|
|
uint8_t ge_data_len = data_hdr->hdr.hdr.data_len - IOT_MAC_ADDR_LEN;
|
|
/* length of dl645 data */
|
|
uint8_t dl645_data_len = hdr_645->len - DL645_DI_LEN;
|
|
uint32_t di = 0;
|
|
uint8_t revert_mac[IOT_MAC_ADDR_LEN];
|
|
uint8_t *dst = prototask_contxt.cco_dev.mac;
|
|
|
|
if (hdr_645->control.dir == PROTO_645_DIR_SLAVE) {
|
|
dl645_data_len = 0;
|
|
iot_cus_printf("the dir of cmd is error, the cmd wont be handled\n");
|
|
goto out;
|
|
}
|
|
|
|
iot_mac_addr_cpy(revert_mac, hdr_645->addr);
|
|
iot_mac_addr_reverse(revert_mac);
|
|
iot_proto_645_ext_sub33_handle(hdr_645->data, hdr_645->len);
|
|
if (iot_sta_check_local_dl645_cmd((uint8_t *)hdr_645, &di, revert_mac)) {
|
|
iot_sta_handle_local_dl645_cmd((uint8_t *)hdr_645, ge_data_len,
|
|
hdr_645->control.fn, di, FROM_PLC, dst);
|
|
dl645_data_len = 0;
|
|
} else if ((iot_mac_addr_cmp(revert_mac, prototask_contxt.local_dev.mac)) &&
|
|
((hdr_645->control.fn == PROTO_645_2007_FN_READ_DATA)) &&
|
|
iot_sta_check_extend_645_di(di)) {
|
|
os_mem_cpy(data_output, &data_input[dl645_data_pos],
|
|
dl645_data_len);
|
|
} else if ((hdr_645->control.fn == PROTO_645_2007_FN_READ_DATA) &&
|
|
di == DL645_07_DI_CKQ_READ_MODE_EN) {
|
|
os_mem_cpy(data_output, &data_input[dl645_data_pos],
|
|
dl645_data_len);
|
|
iot_proto_645_local_mode_cmd_start();
|
|
} else {
|
|
iot_proto_645_ext_add33_handle(hdr_645->data, hdr_645->len);
|
|
os_mem_cpy(data_output, data_hdr->data, ge_data_len);
|
|
dl645_data_len = ge_data_len;
|
|
}
|
|
out:
|
|
return dl645_data_len;
|
|
}
|
|
|
|
uint8_t iot_sta_pack_extend_dl645_to_ge(uint8_t *data_input,
|
|
uint8_t *ge_data, uint16_t *data_len, uint8_t protcotype)
|
|
{
|
|
uint8_t dl645_frame_len;
|
|
uint8_t dl645_crc;
|
|
uint8_t addr_reverse[IOT_MAC_ADDR_LEN];
|
|
uint16_t ge_crc;
|
|
proto_645_header_t *dl645_frm =
|
|
(proto_645_header_t *)&ge_data[GE_FEA0_HEAD_LEN];
|
|
ge_frame_data_send_set_subfn160_t *ge_frm;
|
|
ge_frm_tail_t *tail_frm;
|
|
|
|
iot_mac_addr_cpy(addr_reverse, prototask_contxt.local_dev.mac);
|
|
iot_mac_addr_reverse(addr_reverse);
|
|
dl645_frm->start_char_1 = PROTO_645_START_CHAR;
|
|
dl645_frm->start_char_2 = PROTO_645_START_CHAR;
|
|
iot_mac_addr_cpy(dl645_frm->addr, addr_reverse);
|
|
dl645_frm->control.fn = PROTO_645_2007_FN_READ_DATA;
|
|
dl645_frm->control.dir = PROTO_645_DIR_SLAVE;
|
|
dl645_frm->len = *data_len + DL645_DI_LEN;
|
|
dl645_frame_len = dl645_frm->len + DL645_PARSE_FRM_MIN_LEN;
|
|
if (protcotype == MODBUS_TYPE) {
|
|
proto_645_2007_di_to_byte(DL645_07_DI_MODBUS_TYPE, dl645_frm->data);
|
|
} else if (protcotype == DL645_TYPE) {
|
|
proto_645_2007_di_to_byte(DL645_07_DI_DL645_TYPE, dl645_frm->data);
|
|
} else {
|
|
iot_cus_printf("%s:the protcotype is not support:\n", __FUNCTION__);
|
|
return 1;
|
|
}
|
|
|
|
os_mem_cpy(dl645_frm->data + DL645_DI_LEN, data_input, *data_len);
|
|
iot_proto_645_ext_add33_handle(dl645_frm->data, dl645_frm->len);
|
|
dl645_crc = iot_proto_645_calc_cs(dl645_frm);
|
|
dl645_frm->data[dl645_frm->len] = dl645_crc;
|
|
dl645_frm->data[dl645_frm->len + 1] = PROTO_645_END_CHAR;
|
|
|
|
ge_frm = (ge_frame_data_send_set_subfn160_t *)ge_data;
|
|
ge_frm->hdr.hdr.preamble = GE_FRM_PREAMBLE_CODE;
|
|
ge_frm->hdr.hdr.data_len = dl645_frame_len + IOT_MAC_ADDR_LEN;
|
|
ge_frm->hdr.hdr.fn = PROTO_GE_PLC_SET_CMD;
|
|
ge_frm->hdr.subfn = PROTO_GE_DATA_CMD;
|
|
ge_frm->force_tx_connless = 0;
|
|
ge_frm->force_noaggr = 0;
|
|
ge_frm->recv_connless = 0;
|
|
ge_frm->resv = DL645_07_RESV0_RESV;
|
|
|
|
iot_mac_addr_cpy(&ge_frm->dest_mac[0], prototask_contxt.cco_dev.mac);
|
|
ge_crc = ge_frm_checksum_calc(ge_data, dl645_frame_len +
|
|
sizeof(ge_frame_data_send_set_subfn160_t));
|
|
tail_frm = (ge_frm_tail_t*)&ge_frm->data[dl645_frame_len];
|
|
tail_frm->check_sum = ge_crc;
|
|
tail_frm->tail = GE_FRM_TAIL_CODE;
|
|
*data_len = dl645_frame_len + sizeof(ge_frame_data_send_set_subfn160_t) +
|
|
sizeof(ge_frm_tail_t);
|
|
iot_cus_printf("iot_sta_pack_extend_dl645_to_ge:\n");
|
|
iot_common_bin_dump(ge_data, dl645_frame_len +
|
|
sizeof(ge_frame_data_send_set_subfn160_t) + sizeof(ge_frm_tail_t));
|
|
return 0;
|
|
}
|
|
|
|
#else
|
|
|
|
uint8_t iot_handle_cco_delay_tm_pack_ge_to_dl645(uint8_t *data_input,
|
|
uint8_t *data_output)
|
|
{
|
|
ge_frame_delay_time_subfn166_t *frame =
|
|
(ge_frame_delay_time_subfn166_t *)data_input;
|
|
proto_645_header_t * dl645_frm = (proto_645_header_t *)data_output;
|
|
uint8_t revert_mac[IOT_MAC_ADDR_LEN], dl645_frm_len;
|
|
ge_delay_tm_test_t tm_test;
|
|
|
|
if (data_input == NULL || data_output == NULL) {
|
|
iot_cus_printf("[err]%s data ptr is null\n", "delay tm");
|
|
return 0;
|
|
}
|
|
iot_mac_addr_cpy(revert_mac, frame->dest_mac);
|
|
iot_mac_addr_reverse(revert_mac);
|
|
tm_test = frame->tm_test;
|
|
dl645_frm->len = sizeof(ge_delay_tm_test_t) + DL645_DI_LEN;
|
|
dl645_frm_len = dl645_frm->len + sizeof(proto_645_header_t) +
|
|
sizeof(proto_645_tailer_t);
|
|
proto_645_2007_di_to_byte(DL645_07_DI_DELAYTIME, dl645_frm->data);
|
|
os_mem_cpy(dl645_frm->data + DL645_DI_LEN, (uint8_t *)&tm_test,
|
|
sizeof(ge_delay_tm_test_t));
|
|
iot_proto_645_header_init((proto_645_header_t *)dl645_frm, revert_mac,
|
|
PROTO_645_2007_FN_READ_DATA, PROTO_645_DIR_SLAVE, PROTO_645_2007_ERR_OK,
|
|
DL645_FOLLOW_INVALID);
|
|
iot_proto_645_ext_add33_handle(dl645_frm->data, dl645_frm->len);
|
|
iot_proto_645_tail_init(dl645_frm);
|
|
return dl645_frm_len;
|
|
}
|
|
|
|
void iot_proto_edge_msg_output_msg_handler(uint8_t msg_id, void *arg)
|
|
{
|
|
(void)msg_id;
|
|
|
|
if (arg != NULL) {
|
|
iot_pkt_free(arg);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief dl645_resp_cmd_ack() - dl645 query err、set cmd ack
|
|
* @param ctrl: read or write cmd
|
|
* @param err: error number,see DL645_ERR_XXX
|
|
*/
|
|
void dl645_resp_cmd_ack(uint8_t ctrl, uint8_t err)
|
|
{
|
|
uint8_t *send_cmd;
|
|
uint8_t data_len = DL645_PARSE_FRM_MIN_LEN;
|
|
iot_pkt_t *pkt = NULL;
|
|
|
|
if (err > 0) {
|
|
data_len += 1;
|
|
}
|
|
|
|
pkt = iot_pkt_alloc(data_len, IOT_GREE_APP_MID);
|
|
if (pkt == NULL) {
|
|
iot_cus_printf("[err]cctt pkt alloc fail\n");
|
|
return ;
|
|
}
|
|
send_cmd = iot_pkt_put(pkt, data_len);
|
|
iot_proto_645_build_resp_msg((proto_645_header_t *)send_cmd, NULL, 0,
|
|
err, ctrl);
|
|
|
|
iot_proto_send_to_mainboard(pkt);
|
|
}
|
|
|
|
#endif /* PLC_SUPPORT_STA_ROLE */
|
|
|
|
uint8_t iot_proto_645_format_check(mcu_data_handle_t *recv_data,
|
|
uint8_t *pdata, uint16_t *ret_size, uint16_t *ge_len_out)
|
|
{
|
|
uint8_t test_crc;
|
|
uint8_t err_code;
|
|
uint8_t frame_check_result = GET_NO_FRAME;
|
|
uint8_t *data = &recv_data->data[recv_data->data_pos];
|
|
uint16_t ge_len = 0;
|
|
uint16_t dl645_len;
|
|
uint16_t len = recv_data->total_len - recv_data->data_pos;
|
|
proto_645_header_t *hdr_645 = NULL;
|
|
proto_645_tailer_t *tail_645 = NULL;
|
|
uint8_t revert_mac[IOT_MAC_ADDR_LEN];
|
|
uint32_t di = 0;
|
|
|
|
err_code = 0;
|
|
if (data[0] != PROTO_645_START_CHAR) {
|
|
err_code = 1;
|
|
goto out;
|
|
}
|
|
|
|
if (recv_data->data_pos == recv_data->total_len - 1) {
|
|
err_code = 2;
|
|
goto out;
|
|
}
|
|
|
|
if (len < PROTO_645_SECOND_HEAD_POS + 1) {
|
|
err_code = 3;
|
|
frame_check_result = GET_HALF_FRAME;
|
|
goto out;
|
|
}
|
|
|
|
hdr_645 = (proto_645_header_t*)data;
|
|
if (hdr_645->start_char_2 != PROTO_645_START_CHAR) {
|
|
err_code = 4;
|
|
goto out;
|
|
}
|
|
|
|
dl645_len = hdr_645->len + DL645_PARSE_FRM_MIN_LEN;
|
|
if (len < dl645_len) {
|
|
err_code = 5;
|
|
frame_check_result = GET_HALF_FRAME;
|
|
goto out;
|
|
}
|
|
|
|
tail_645 = (proto_645_tailer_t*)(data + sizeof(proto_645_header_t) +
|
|
hdr_645->len);
|
|
if (tail_645->end_char != PROTO_645_END_CHAR) {
|
|
err_code = 6;
|
|
goto out;
|
|
}
|
|
|
|
test_crc = iot_proto_645_calc_cs(hdr_645);
|
|
if (tail_645->cs != test_crc) {
|
|
iot_cus_printf("[glpr DL645] crc:%x", test_crc);
|
|
err_code = 7;
|
|
goto out;
|
|
}
|
|
|
|
/* here, the frame is ok */
|
|
ge_len = dl645_len;
|
|
iot_mac_addr_cpy(revert_mac, hdr_645->addr);
|
|
iot_mac_addr_reverse(revert_mac);
|
|
iot_proto_645_ext_sub33_handle(hdr_645->data, hdr_645->len);
|
|
#if PLC_SUPPORT_STA_ROLE
|
|
if (iot_sta_check_local_dl645_cmd((uint8_t *)hdr_645, &di, revert_mac)) {
|
|
iot_sta_handle_local_dl645_cmd((uint8_t *)hdr_645, dl645_len,
|
|
hdr_645->control.fn, di, FROM_UART, NULL);
|
|
ge_len = 0;
|
|
} else if (g_dl645_local_mode_state == DL645_LOCAL_MODE_STARTED) {
|
|
iot_proto_645_local_mode_cache(hdr_645);
|
|
ge_len = 0;
|
|
} else {
|
|
if (!iot_ge_buf_overflow_test(*ret_size, dl645_len +
|
|
sizeof(ge_frame_data_send_set_subfn160_t) +
|
|
sizeof(ge_frm_tail_t) + DL645_PARSE_FRM_MIN_LEN + DL645_DI_LEN)) {
|
|
frame_check_result = GET_OVERFLOW;
|
|
goto out;
|
|
}
|
|
|
|
if (!is_edge_running() &&
|
|
iot_mac_addr_cmp(revert_mac, prototask_contxt.local_dev.mac)) {
|
|
iot_proto_645_ext_add33_handle(hdr_645->data, hdr_645->len);
|
|
iot_pack_dl645_to_ge((uint8_t *)hdr_645, &pdata[*ret_size],
|
|
&ge_len, prototask_contxt.cco_dev.mac, false);
|
|
} else {
|
|
iot_proto_645_ext_add33_handle(hdr_645->data, hdr_645->len);
|
|
iot_sta_pack_extend_dl645_to_ge((uint8_t *)hdr_645,
|
|
&pdata[*ret_size], &ge_len, DL645_TYPE);
|
|
}
|
|
}
|
|
#else
|
|
(void)di;
|
|
if (iot_mac_addr_cmp(revert_mac, prototask_contxt.local_dev.mac)) {
|
|
// post msg to task handle
|
|
iot_proto_post_dl645_cmd_msg(data, dl645_len);
|
|
ge_len = 0;
|
|
} else {
|
|
proto_645_2007_byte_to_di(hdr_645->data, di);
|
|
if ((di == DL645_07_DI_DELAYTIME) &&
|
|
(hdr_645->control.fn == PROTO_645_2007_FN_READ_DATA)) {
|
|
iot_proto_post_dl645_cmd_msg(data, dl645_len);
|
|
ge_len = 0;
|
|
} else if (iot_ge_buf_overflow_test(*ret_size, dl645_len +
|
|
sizeof(ge_frame_data_send_set_subfn160_t) +
|
|
sizeof(ge_frm_tail_t))) {
|
|
iot_proto_645_ext_add33_handle(hdr_645->data, hdr_645->len);
|
|
iot_pack_dl645_to_ge((uint8_t *)hdr_645, &pdata[*ret_size],
|
|
&ge_len, revert_mac, false);
|
|
} else {
|
|
frame_check_result = GET_OVERFLOW;
|
|
goto out;
|
|
}
|
|
}
|
|
#endif /* PLC_SUPPORT_STA_ROLE */
|
|
*ret_size += ge_len;
|
|
*ge_len_out = dl645_len;
|
|
frame_check_result = GET_ONE_FRAME;
|
|
out:
|
|
|
|
if (err_code > 0) {
|
|
iot_cus_printf("err_code:%x\n", err_code);
|
|
}
|
|
|
|
if (frame_check_result == GET_OVERFLOW) {
|
|
iot_cus_printf("ge_buf is overflow, dl645, di = %d\n mac:\n", di);
|
|
iot_common_bin_dump(revert_mac, IOT_MAC_ADDR_LEN);
|
|
}
|
|
|
|
return frame_check_result;
|
|
}
|
|
|
|
#if PLC_SUPPORT_STA_ROLE
|
|
|
|
void iot_proto_645_local_mode_timer_handler(void)
|
|
{
|
|
g_dl645_local_mode_state = DL645_LOCAL_MODE_INIT;
|
|
iot_cus_printf("dl645_local_read_mode[%d]\n", g_dl645_local_mode_state);
|
|
/* clear the 645 cache */
|
|
os_mem_set(&g_local_dl645_cache, 0, sizeof(g_local_dl645_cache));
|
|
}
|
|
|
|
#endif /* PLC_SUPPORT_STA_ROLE */
|