inwudriver-weibo/app/mrs/ndm/mrs_ndm_645.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) */