258 lines
8.3 KiB
C
258 lines
8.3 KiB
C
/*
|
|
* Copyright (c) CompanyNameMagicTag 2019-2020. All rights reserved.
|
|
* Description: MRS NDM 645 handle.
|
|
*/
|
|
|
|
#include "mrs_ndm_645.h"
|
|
#include "mrs_ndm_plc.h"
|
|
#include "mrs_msg.h"
|
|
#include "mrs_proto_645.h"
|
|
#include "mrs_common_tools.h"
|
|
#include "soc_mac_nv.h"
|
|
|
|
#if defined(PRODUCT_CFG_PRODUCT_TYPE_NDM)
|
|
#define MRS_DI_CCO_DUT_TRANS 0xE010
|
|
|
|
#define MRS_DI_NDM_SET_WORK_MDOE_TRANS 0xE001
|
|
#define MRS_DI_NDM_REQ_WORK_MDOE_TRANS 0xE002
|
|
|
|
|
|
td_void mrs_ndm_dut_cco_uart_rx(td_pbyte data, td_u16 data_len, td_pbyte addr, td_u8 addr_len);
|
|
td_bool mrs_ndm_dut_plc_frame_check(const mrs_plc_frame_data *plc);
|
|
td_void mrs_ndm_test_cmd_uart_rx(td_pbyte data, td_u16 data_len, td_pbyte addr, td_u8 addr_len);
|
|
|
|
/* processing for 645 frame recieving from serial ports */
|
|
td_void mrs_msg_on_app_frame_rx_645(EXT_CONST mrs_queue_msg *msg)
|
|
{
|
|
td_pbyte data = (td_pbyte)msg->param1;
|
|
td_u16 data_len = msg->param0;
|
|
td_u8 fn;
|
|
td_u8 is_no_mac_state;
|
|
|
|
mrs_proto_645_frame_inf frame = { { 0 }, 0, 0, TD_NULL };
|
|
|
|
if (mrs_proto_645_decode_frame(data, data_len, &frame) != EXT_ERR_SUCCESS) {
|
|
mrs_free(data);
|
|
return;
|
|
}
|
|
|
|
fn = frame.ctrl & MRS_DUT_645_CTRL_FN_MASK;
|
|
switch (fn) {
|
|
case MRS_DUT_645_CTRL_FN_CCO: /* CCO equip frame */
|
|
mrs_ndm_dut_cco_uart_rx(frame.data, frame.data_len, frame.addr, (td_u8)sizeof(frame.addr));
|
|
break;
|
|
|
|
case MRS_DUT_645_CTRL_FN_CIU:
|
|
is_no_mac_state = TD_TRUE;
|
|
uapi_p2p_set_ciu_no_mac_state_p1901(is_no_mac_state);
|
|
mrs_ndm_send_ciu_plc_frame(data, data_len, frame.addr, sizeof(frame.addr), is_no_mac_state);
|
|
break;
|
|
case MRS_DUT_645_CTRL_FN_NDM:
|
|
mrs_ndm_test_cmd_uart_rx(frame.data, frame.data_len, frame.addr, (td_u8)sizeof(frame.addr));
|
|
break;
|
|
case MRS_DUT_645_CTRL_FN_STA: /* STA equip frame */
|
|
default:
|
|
is_no_mac_state = TD_TRUE;
|
|
uapi_p2p_set_ciu_no_mac_state_p1901(is_no_mac_state);
|
|
mrs_ndm_send_sta_dut_plc_frame(data, data_len, frame.addr, (const td_u8)sizeof(frame.addr),
|
|
is_no_mac_state);
|
|
break;
|
|
}
|
|
|
|
mrs_free(data);
|
|
}
|
|
td_void mrs_ndm_set_work_mode_uart_frame(td_u8 result)
|
|
{
|
|
mrs_proto_645_frame_inf inf = { { 0 }, 0, 0, TD_NULL };
|
|
td_u32 ret;
|
|
td_u8 *frame = TD_NULL;
|
|
td_u16 frame_len;
|
|
|
|
inf.data_len = (td_u8)(3); /* 3: di (2B) + work_mode (1B) */
|
|
inf.data = (td_u8 *)mrs_malloc(inf.data_len);
|
|
if (inf.data == TD_NULL) {
|
|
return;
|
|
}
|
|
|
|
inf.data[0] = 0x01;
|
|
inf.data[1] = 0xE0; /* 0xE0 */
|
|
inf.data[2] = result; /* index 2: 0x01 */
|
|
|
|
inf.ctrl = MRS_DUT_645_CTRL_FN_NDM | 0x80; /* 0x80 */
|
|
|
|
ret = mrs_proto_645_create_frame(&inf, &frame, &frame_len);
|
|
mrs_free(inf.data);
|
|
if (ret == EXT_ERR_SUCCESS) {
|
|
mrs_uart_tx(frame, frame_len);
|
|
}
|
|
|
|
mrs_free(frame);
|
|
}
|
|
td_void mrs_ndm_req_work_mode_uart_frame(td_void)
|
|
{
|
|
mrs_proto_645_frame_inf inf = { { 0 }, 0, 0, TD_NULL };
|
|
td_u32 ret;
|
|
td_u8 *frame = TD_NULL;
|
|
td_u16 frame_len;
|
|
|
|
inf.data_len = (td_u8)(5); /* 5: di (2B) + tei(2B) + work_mode (1B) */
|
|
inf.data = (td_u8 *)mrs_malloc(inf.data_len);
|
|
if (inf.data == TD_NULL) {
|
|
return;
|
|
}
|
|
diag_cmd_config_ndm_connect_para_stru nv_para = {0};
|
|
|
|
ret = uapi_nv_read(ID_DIAG_CMD_CONFIG_NDM_CONNECT_PARA, (td_pvoid)&nv_para, sizeof(nv_para));
|
|
if (ret != EXT_ERR_SUCCESS) {
|
|
return;
|
|
}
|
|
|
|
inf.data[0] = 0x02; /* 0x02 */
|
|
inf.data[1] = 0xE0; /* 0xE0 */
|
|
inf.data[2] = nv_para.ndm_tei & EXT_U8_MAX; /* index 2: ndm_tei */
|
|
inf.data[3] = (nv_para.ndm_tei >> EXT_U8_BITS) & EXT_U8_MAX; /* index 3: ndm_tei */
|
|
inf.data[4] = nv_para.work_mode; /* index 4: work_mode */
|
|
|
|
inf.ctrl = MRS_DUT_645_CTRL_FN_NDM | 0x80; /* 0x80 */
|
|
|
|
ret = mrs_proto_645_create_frame(&inf, &frame, &frame_len);
|
|
mrs_free(inf.data);
|
|
if (ret == EXT_ERR_SUCCESS) {
|
|
mrs_uart_tx(frame, frame_len);
|
|
}
|
|
|
|
mrs_free(frame);
|
|
}
|
|
|
|
td_u32 mrs_ndm_set_ndm_info(td_u8 work_mode, td_u16 tei)
|
|
{
|
|
diag_cmd_config_ndm_connect_para_stru nv_para = {0};
|
|
|
|
if (!(work_mode <= EXT_NDM_SEARCH_NET_MODE_SWITCH_COM && work_mode > EXT_NDM_UNKNOWN_WORK_MODE)) {
|
|
return EXT_ERR_FAILURE;
|
|
}
|
|
|
|
if (!((tei) <= EXT_NDM_MAX_TEI && (tei) >= EXT_NDM_MIN_TEI)) {
|
|
return EXT_ERR_FAILURE;
|
|
}
|
|
|
|
td_u32 ret = uapi_nv_read(ID_DIAG_CMD_CONFIG_NDM_CONNECT_PARA, (td_pvoid)&nv_para, sizeof(nv_para));
|
|
if (ret != EXT_ERR_SUCCESS) {
|
|
return EXT_ERR_FAILURE;
|
|
}
|
|
|
|
nv_para.work_mode = work_mode;
|
|
nv_para.ndm_tei = tei;
|
|
if (uapi_nv_write(ID_DIAG_CMD_CONFIG_NDM_CONNECT_PARA, (td_pvoid)&nv_para, sizeof(nv_para)) != EXT_ERR_SUCCESS) {
|
|
return EXT_ERR_FAILURE;
|
|
}
|
|
|
|
return EXT_ERR_SUCCESS;
|
|
}
|
|
|
|
td_void mrs_ndm_test_cmd_uart_rx(td_pbyte data, td_u16 data_len, td_pbyte addr, td_u8 addr_len)
|
|
{
|
|
td_u16 di;
|
|
td_u8 work_mode;
|
|
td_u16 tei;
|
|
ext_unref_param(addr);
|
|
ext_unref_param(addr_len);
|
|
|
|
if (data_len < 2) { /* 2:di (2B) */
|
|
return;
|
|
}
|
|
mrs_proto_645_data_decode(data, data_len);
|
|
|
|
di = uapi_make_u16(data[0], data[1]);
|
|
if (di == MRS_DI_NDM_SET_WORK_MDOE_TRANS) {
|
|
if (data_len < 5) { /* 5:di (2B) + tei(2B) + work_mode (1B) */
|
|
return;
|
|
}
|
|
tei = uapi_make_u16(data[2], data[3]); /* index 2,3: tei */
|
|
work_mode = data[4]; /* index 4: work_mode */
|
|
td_u32 ret = mrs_ndm_set_ndm_info(work_mode, tei);
|
|
mrs_ndm_set_work_mode_uart_frame((td_u8)ret);
|
|
} else if (di == MRS_DI_NDM_REQ_WORK_MDOE_TRANS) {
|
|
mrs_ndm_req_work_mode_uart_frame();
|
|
}
|
|
}
|
|
|
|
td_void mrs_ndm_dut_cco_uart_rx(td_pbyte data, td_u16 data_len, td_pbyte addr, td_u8 addr_len)
|
|
{
|
|
td_u16 di;
|
|
td_u16 cmd;
|
|
td_u16 length;
|
|
|
|
if (data_len < 6) { /* 6:di (2B) + cmd id (2B) + length (2B) + data (length) */
|
|
return;
|
|
}
|
|
|
|
mrs_proto_645_data_decode(data, data_len);
|
|
|
|
di = uapi_make_u16(data[0], data[1]);
|
|
cmd = uapi_make_u16(data[2], data[3]); /* index 2&3: cmd */
|
|
length = uapi_make_u16(data[4], data[5]); /* index 4&5: length */
|
|
if ((di != MRS_DI_CCO_DUT_TRANS) || (cmd != PLC_CMD_ID_DUT_CCO_TEST) ||
|
|
(length < sizeof(mrs_dut_cco_frame)) || (length + 6 != data_len)) { /* 6:di (2B),cmd id (2B) ,length (2B) */
|
|
return;
|
|
}
|
|
|
|
mrs_ndm_send_cco_dut_plc_frame(data + EXT_METER_ADDR_LEN, data_len - EXT_METER_ADDR_LEN, addr, addr_len);
|
|
}
|
|
|
|
td_void mrs_ndm_cco_dut_uart_frame(td_pbyte data, td_u16 data_len, const td_pbyte addr, td_u8 addr_len)
|
|
{
|
|
mrs_proto_645_frame_inf inf = { { 0 }, 0, 0, TD_NULL };
|
|
errno_t err;
|
|
td_u32 ret;
|
|
td_u8 *frame = TD_NULL;
|
|
td_u16 frame_len;
|
|
|
|
inf.data_len = (td_u8)(data_len + 6); /* 6: di (2B) + cmd id (2B) + length (2B) + data (length) */
|
|
inf.data = (td_u8 *)mrs_malloc(inf.data_len);
|
|
if (inf.data == TD_NULL) {
|
|
return;
|
|
}
|
|
|
|
inf.data[0] = 0x10;
|
|
inf.data[1] = 0xE0;
|
|
inf.data[2] = 0x01; /* index 2: 0x01 */
|
|
inf.data[3] = 0xF0; /* index 3: 0xF0 */
|
|
inf.data[4] = (td_u8)(data_len & EXT_U8_MAX); /* index 4: data length low 8bits */
|
|
inf.data[5] = (td_u8)((data_len >> EXT_U8_BITS) & EXT_U8_MAX); /* index 5: data length high 8bits */
|
|
|
|
err = memcpy_s(inf.data + 6, inf.data_len - 6, data, data_len); /* 6:di (2B) + cmd id (2B) + length (2B) */
|
|
if (err != EOK) {
|
|
mrs_free(inf.data);
|
|
return;
|
|
}
|
|
|
|
err = memcpy_s(inf.addr, sizeof(inf.addr), addr, addr_len);
|
|
if (err != EOK) {
|
|
mrs_free(inf.data);
|
|
return;
|
|
}
|
|
|
|
mrs_hex_invert(inf.addr, sizeof(inf.addr));
|
|
inf.ctrl = MRS_DUT_645_CTRL_FN_CCO | 0x80;
|
|
|
|
ret = mrs_proto_645_create_frame(&inf, &frame, &frame_len);
|
|
mrs_free(inf.data);
|
|
if (ret == EXT_ERR_SUCCESS) {
|
|
mrs_uart_tx(frame, frame_len);
|
|
}
|
|
|
|
mrs_free(frame);
|
|
}
|
|
|
|
td_bool mrs_proto_is_rcv_p2p_pkt_by_dest_mac(EXT_CONST td_u8 *dest_mac, td_u8 mac_len)
|
|
{
|
|
if (dest_mac == TD_NULL || mac_len != EXT_PLC_MAC_ADDR_LEN) {
|
|
return TD_FALSE;
|
|
}
|
|
|
|
return mrs_is_wild_mac(dest_mac);
|
|
}
|
|
|
|
#endif /* defined(PRODUCT_CFG_PRODUCT_TYPE_NDM) */
|