418 lines
13 KiB
C
418 lines
13 KiB
C
/*
|
|
* Copyright (c) CompanyNameMagicTag 2019-2020. All rights reserved.
|
|
* Description: MRS CAPTURE FUN handle.(Development of Tested Module Based on 1901.1 Test System)
|
|
*/
|
|
|
|
#include "mrs_common_capture.h"
|
|
#include "mrs_common_tools.h"
|
|
#include "mrs_common_uart.h"
|
|
#include "dfx_app.h"
|
|
|
|
td_bool g_test_mode_enable;
|
|
ext_uart_port g_mrs_default_port = EXT_UART_0;
|
|
ext_uart_port g_mrs_diag_port = EXT_UART_1;
|
|
diag_cmd_test_mode_info_ind g_dfx_test_mode_info;
|
|
td_void mrs_handle_set_tone_mask(td_u16 test_duration, td_u8 pre_mode);
|
|
td_void mrs_handle_set_freq(td_u16 test_duration, td_u8 pre_mode);
|
|
static td_void mrs_set_test_mode_enable(td_bool enable);
|
|
static td_u32 mrs_check_msdu_to_com(EXT_CONST ext_capture_msdu_info *data);
|
|
static td_void mrs_dfx_enter_test_mode(td_u8 mode, td_u8 pre_mode);
|
|
static td_void mrs_config_uart_param(td_u32 rate, td_u32 parity);
|
|
static td_u32 mrs_check_phy_tans_test_to_com(EXT_CONST td_u8 *fc, EXT_CONST td_u8 *data, td_u16 pb_size);
|
|
static td_void mrs_dfx_test_mode_cnt(td_u8 test_mode);
|
|
static td_u32 mrs_change_baud_rate(td_u32 rate, td_u32 parity);
|
|
static td_void mrs_dfx_test_mode_err_frame_info(td_u8 pb_type);
|
|
|
|
td_void mrs_common_capture_init(td_void)
|
|
{
|
|
mrs_set_test_mode_enable(TD_FALSE);
|
|
|
|
#if defined(PRODUCT_CFG_PRODUCT_TYPE_CCO)
|
|
/* Time of parsing test packet, 35s */
|
|
mrs_timer_start(MRS_TIMER_ID_CCO_ENTER_TESTMODE, MRS_PARSE_TEST_PACKET_TIME * MRS_SEC_TO_MS, EXT_TIMER_TYPE_ONCE);
|
|
#endif
|
|
|
|
#if defined(PRODUCT_CFG_PRODUCT_TYPE_STA)
|
|
mrs_timer_start(MRS_TIMER_ID_STA_ENTER_TESTMODE, MRS_PARSE_TEST_PACKET_TIME * MRS_SEC_TO_MS, EXT_TIMER_TYPE_ONCE);
|
|
#endif
|
|
|
|
/* Register capture packet fun */
|
|
uapi_register_capture_packet_function(mrs_capture_fun);
|
|
uapi_mdm_register_test_mode(PHYSICAL_TEST_MODE_APP_TO_COM_LOOP, mrs_handle_app_to_com_loop_mode);
|
|
uapi_mdm_register_test_mode(PHYSICAL_TEST_MODE_APP_TO_PLC_LOOP, mrs_handle_app_to_plc_loop_mode);
|
|
uapi_mdm_register_test_mode(PHYSICAL_TEST_MODE_EXIT, mrs_handle_msdu_to_com_mode);
|
|
uapi_mdm_register_test_mode(PHYSICAL_TEST_MODE_SET_FREQ, mrs_handle_set_freq);
|
|
uapi_mdm_register_test_mode(PHYSICAL_TEST_MODE_SET_TONE_MASK_MODE, mrs_handle_set_tone_mask);
|
|
/* Set capture mode */
|
|
uapi_mdm_set_capture_mode(EXT_MAC_CAPTURE_SINGLE_PB_MODE);
|
|
}
|
|
|
|
td_void mrs_common_capture_deinit(td_void)
|
|
{
|
|
/* Deregisters the MSDU interface */
|
|
uapi_register_capture_msdu_function(TD_NULL);
|
|
|
|
if (uapi_mdm_get_phy_test_mode() == PHYSICAL_TEST_MODE_NONE) {
|
|
uapi_mdm_set_capture_mode(EXT_MAC_NO_CAPTURE_MODE);
|
|
/* This command is used to restore the MSDU flag, which is not intercepted */
|
|
uapi_set_intercept_msdu_enable(TD_FALSE);
|
|
}
|
|
|
|
uapi_register_capture_packet_function(TD_NULL);
|
|
}
|
|
|
|
static td_u32 mrs_check_phy_tans_test_to_com(EXT_CONST td_u8 *fc, EXT_CONST td_u8 *data, td_u16 pb_size)
|
|
{
|
|
td_u32 ret = EXT_ERR_FAILURE;
|
|
td_u16 total_len;
|
|
td_u16 length;
|
|
td_u8 *payload = TD_NULL;
|
|
td_u16 paylaod_len;
|
|
|
|
if (fc == TD_NULL) {
|
|
return ret;
|
|
}
|
|
|
|
/* The beacon frame is not sent to the serial port channel */
|
|
if ((fc[0] & 0x07) == 0) { /* 7 is DT MASK */
|
|
return ret;
|
|
}
|
|
|
|
g_dfx_test_mode_info.check_phy_tans_test_cnt++;
|
|
|
|
paylaod_len = pb_size;
|
|
total_len = MRS_FC_SIZE + paylaod_len;
|
|
|
|
payload = mrs_malloc(total_len);
|
|
if (payload == TD_NULL) {
|
|
return EXT_ERR_MALLOC_FAILUE;
|
|
}
|
|
|
|
if (memset_s(payload, total_len, 0, total_len) != EXT_ERR_SUCCESS) {
|
|
return EXT_ERR_FAILURE;
|
|
}
|
|
|
|
if (memcpy_s(payload, total_len, fc, MRS_FC_SIZE) != EXT_ERR_SUCCESS) {
|
|
return EXT_ERR_FAILURE;
|
|
}
|
|
|
|
if (data != TD_NULL) {
|
|
if (memcpy_s(payload + MRS_FC_SIZE, total_len - MRS_FC_SIZE, data, paylaod_len) != EXT_ERR_SUCCESS) {
|
|
return EXT_ERR_FAILURE;
|
|
}
|
|
}
|
|
|
|
if (total_len > EXT_DMS_FRM_MAX_PAYLOAD_SIZE) {
|
|
length = total_len - EXT_DMS_FRM_MAX_PAYLOAD_SIZE;
|
|
ret = mrs_uart_tx(payload, EXT_DMS_FRM_MAX_PAYLOAD_SIZE);
|
|
if (ret == EXT_ERR_SUCCESS) {
|
|
ret = mrs_uart_tx(payload + EXT_DMS_FRM_MAX_PAYLOAD_SIZE, length);
|
|
}
|
|
} else {
|
|
ret = mrs_uart_tx(payload, total_len);
|
|
}
|
|
|
|
mrs_free(payload);
|
|
|
|
return ret;
|
|
}
|
|
|
|
td_u32 mrs_capture_fun(ext_mdm_capture_packet_pbb_type state, EXT_CONST td_u8 *fc, EXT_CONST td_u8 *payload,
|
|
td_u16 pb_size)
|
|
{
|
|
td_u8 test_mode = uapi_mdm_get_phy_test_mode();
|
|
|
|
/* The current mode is the MAC layer transparent transmission test mode,exit */
|
|
if (test_mode == PHYSICAL_TEST_MODE_EXIT) {
|
|
return EXT_ERR_SKIP;
|
|
}
|
|
|
|
/* Processing After Entering the physical layer transparent transmission test mode */
|
|
if (test_mode == PHYSICAL_TEST_MODE_APP_TO_COM_LOOP) {
|
|
return mrs_check_phy_tans_test_to_com(fc, payload, pb_size);
|
|
}
|
|
|
|
mrs_dfx_test_mode_cnt(test_mode);
|
|
if (state != PBB_CORRECT_TYPE || fc == TD_NULL || payload == TD_NULL) {
|
|
mrs_dfx_test_mode_err_frame_info((td_u8)state);
|
|
return EXT_ERR_SKIP;
|
|
}
|
|
|
|
return EXT_ERR_SUCCESS;
|
|
}
|
|
|
|
/* Enter the physical layer transparent transmission test mode */
|
|
td_void mrs_handle_app_to_com_loop_mode(td_u16 test_duration, td_u8 pre_mode)
|
|
{
|
|
uapi_mdm_enter_phy_test_mode(PHYSICAL_TEST_MODE_APP_TO_COM_LOOP);
|
|
|
|
mrs_dfx_enter_test_mode(PHYSICAL_TEST_MODE_APP_TO_COM_LOOP, pre_mode);
|
|
|
|
mrs_config_uart_param(BR115200, MRS_SRV_UART_PARITY_NONE);
|
|
/* Setting the Packet Capture Mode */
|
|
uapi_mdm_set_capture_mode(EXT_MAC_INTERCEPT_SINGLE_PB_MODE);
|
|
#if defined(PRODUCT_CFG_PRODUCT_TYPE_CCO)
|
|
/* test mode duration£¬min */
|
|
mrs_timer_start(MRS_TIMER_ID_CCO_PHY_TRANS_TESTMODE, mrs_min_to_ms(test_duration), EXT_TIMER_TYPE_ONCE);
|
|
#endif
|
|
|
|
#if defined(PRODUCT_CFG_PRODUCT_TYPE_STA)
|
|
mrs_timer_start(MRS_TIMER_ID_STA_PHY_TRANS_TESTMODE, mrs_min_to_ms(test_duration), EXT_TIMER_TYPE_ONCE);
|
|
#endif
|
|
|
|
#if defined(PRODUCT_CFG_PRODUCT_TYPE_NDM)
|
|
ext_unref_param(test_duration);
|
|
#endif
|
|
}
|
|
|
|
/* Enter the physical layer return test mode */
|
|
td_void mrs_handle_app_to_plc_loop_mode(td_u16 test_duration, td_u8 pre_mode)
|
|
{
|
|
uapi_mdm_enter_phy_test_mode(PHYSICAL_TEST_MODE_APP_TO_PLC_LOOP);
|
|
|
|
mrs_dfx_enter_test_mode(PHYSICAL_TEST_MODE_APP_TO_PLC_LOOP, pre_mode);
|
|
/* Setting the Packet Capture Mode */
|
|
uapi_mdm_set_capture_mode(EXT_MAC_INTERCEPT_LOOP_MODE);
|
|
|
|
#if defined(PRODUCT_CFG_PRODUCT_TYPE_CCO)
|
|
/* test mode duration£¬min */
|
|
mrs_timer_start(MRS_TIMER_ID_CCO_PHY_LOOP_TESTMODE, mrs_min_to_ms(test_duration), EXT_TIMER_TYPE_ONCE);
|
|
#endif
|
|
|
|
#if defined(PRODUCT_CFG_PRODUCT_TYPE_STA)
|
|
mrs_timer_start(MRS_TIMER_ID_STA_PHY_LOOP_TESTMODE, mrs_min_to_ms(test_duration), EXT_TIMER_TYPE_ONCE);
|
|
#endif
|
|
|
|
#if defined(PRODUCT_CFG_PRODUCT_TYPE_NDM)
|
|
ext_unref_param(test_duration);
|
|
#endif
|
|
}
|
|
|
|
/* Enter the MAC layer transparent transmission test mode */
|
|
td_void mrs_handle_msdu_to_com_mode(td_u16 test_duration, td_u8 pre_mode)
|
|
{
|
|
uapi_mdm_enter_phy_test_mode(PHYSICAL_TEST_MODE_EXIT);
|
|
|
|
mrs_dfx_enter_test_mode(PHYSICAL_TEST_MODE_EXIT, pre_mode);
|
|
/* Register and capture MSDU packets to the serial port channel. */
|
|
uapi_register_capture_msdu_function(mrs_capture_msdu_fun);
|
|
/* Intercepts MSDU and does not report it to the application layer and network management layer */
|
|
uapi_set_intercept_msdu_enable(TD_TRUE);
|
|
|
|
mrs_config_uart_param(BR115200, MRS_SRV_UART_PARITY_NONE);
|
|
|
|
#if defined(PRODUCT_CFG_PRODUCT_TYPE_CCO)
|
|
/* test mode duration£¬min */
|
|
mrs_timer_start(MRS_TIMER_ID_CCO_MAC_MSDU_TESTMODE, mrs_min_to_ms(test_duration), EXT_TIMER_TYPE_ONCE);
|
|
#endif
|
|
|
|
#if defined(PRODUCT_CFG_PRODUCT_TYPE_STA)
|
|
mrs_timer_start(MRS_TIMER_ID_STA_MAC_MSDU_TESTMODE, mrs_min_to_ms(test_duration), EXT_TIMER_TYPE_ONCE);
|
|
#endif
|
|
|
|
#if defined(PRODUCT_CFG_PRODUCT_TYPE_NDM)
|
|
ext_unref_param(test_duration);
|
|
#endif
|
|
}
|
|
|
|
td_void mrs_handle_set_freq(td_u16 test_duration, td_u8 pre_mode)
|
|
{
|
|
uapi_mdm_set_work_freq((td_u8)(test_duration));
|
|
mrs_dfx_enter_test_mode(PHYSICAL_TEST_MODE_SET_FREQ, pre_mode);
|
|
}
|
|
|
|
td_void mrs_handle_set_tone_mask(td_u16 test_duration, td_u8 pre_mode)
|
|
{
|
|
uapi_mdm_set_tone_mask_mode((td_u8)(test_duration));
|
|
mrs_dfx_enter_test_mode(PHYSICAL_TEST_MODE_SET_TONE_MASK_MODE, pre_mode);
|
|
}
|
|
|
|
td_void mrs_capture_msdu_fun(EXT_CONST ext_capture_msdu_info *data)
|
|
{
|
|
td_u8 mode = uapi_mdm_get_phy_test_mode();
|
|
|
|
if (mode == PHYSICAL_TEST_MODE_EXIT) {
|
|
mrs_check_msdu_to_com(data);
|
|
}
|
|
}
|
|
|
|
static td_u32 mrs_check_msdu_to_com(EXT_CONST ext_capture_msdu_info *data)
|
|
{
|
|
td_u32 ret;
|
|
td_u16 total_length;
|
|
td_u16 length;
|
|
td_u8 *payload = TD_NULL;
|
|
|
|
if (data == TD_NULL || data->msdu_size == 0 || data->msdu_data == TD_NULL) {
|
|
return EXT_ERR_FAILURE;
|
|
}
|
|
|
|
g_dfx_test_mode_info.check_msdu_test_cnt++;
|
|
|
|
total_length = data->msdu_size;
|
|
payload = data->msdu_data;
|
|
if (total_length > EXT_DMS_FRM_MAX_PAYLOAD_SIZE) {
|
|
length = total_length - EXT_DMS_FRM_MAX_PAYLOAD_SIZE;
|
|
ret = mrs_uart_tx(payload, EXT_DMS_FRM_MAX_PAYLOAD_SIZE);
|
|
if (ret == EXT_ERR_SUCCESS) {
|
|
ret = mrs_uart_tx(payload + EXT_DMS_FRM_MAX_PAYLOAD_SIZE, length);
|
|
}
|
|
} else {
|
|
ret = mrs_uart_tx(payload, total_length);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
td_void mrs_set_work_freq_mode(td_u8 freq_mode)
|
|
{
|
|
uapi_mdm_set_work_freq(freq_mode);
|
|
}
|
|
|
|
static td_void mrs_set_test_mode_enable(td_bool enable)
|
|
{
|
|
g_test_mode_enable = enable;
|
|
}
|
|
|
|
td_bool mrs_get_test_mode_enable(td_void)
|
|
{
|
|
return g_test_mode_enable;
|
|
}
|
|
|
|
td_u32 mrs_parse_app_data(EXT_CONST td_u8 *pbdata, td_u8 **pdata)
|
|
{
|
|
td_u8 msdu_type;
|
|
td_u8 is_mac_exist;
|
|
td_u8 *buf = (td_u8 *)(pbdata + MRS_PBH_SIZE_P1901);
|
|
td_u8 app_offset;
|
|
|
|
msdu_type = buf[MRS_HEAD_MSDU_TYPE_OFFSET_P1901];
|
|
if (msdu_type != MRS_MSDU_TYPE_APP_P1901) {
|
|
return EXT_ERR_FAILURE;
|
|
}
|
|
|
|
is_mac_exist = buf[MRS_MAC_EXIST_FLAG_OFFSET_P1901] & 0x08;
|
|
if (is_mac_exist == TD_TRUE) {
|
|
app_offset = MRS_LONG_HEAD_SIZE_P1901;
|
|
} else {
|
|
app_offset = MRS_SHORT_HEAD_SIZE_P1901;
|
|
}
|
|
|
|
*pdata = buf + app_offset;
|
|
|
|
return EXT_ERR_SUCCESS;
|
|
}
|
|
|
|
static td_void mrs_config_uart_param(td_u32 rate, td_u32 parity)
|
|
{
|
|
mrs_change_baud_rate(rate, parity);
|
|
}
|
|
|
|
static td_u32 mrs_change_baud_rate(td_u32 rate, td_u32 parity)
|
|
{
|
|
td_u32 ret;
|
|
ext_uart_init_type uart_param = {BR115200, MRS_SRV_UART_DATABITS, MRS_SRV_UART_STOPBITS, MRS_SRV_UART_PARITY_NONE};
|
|
uart_param.baud_rate = rate;
|
|
uart_param.parity = parity;
|
|
|
|
(td_void) uapi_uart_close(g_mrs_default_port);
|
|
ret = uapi_uart_open(g_mrs_default_port);
|
|
if (ret != EXT_ERR_SUCCESS) {
|
|
return ret;
|
|
}
|
|
|
|
ret = uapi_uart_ioctl(g_mrs_default_port, UART_CFG_SET_ATTR, (uintptr_t)&uart_param);
|
|
if (ret != EXT_ERR_SUCCESS) {
|
|
return ret;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
td_void mrs_restore_uart_config(td_u32 rate, td_u32 parity)
|
|
{
|
|
mrs_change_baud_rate(rate, parity);
|
|
}
|
|
|
|
#if defined(PRODUCT_CFG_PRODUCT_TYPE_CCO) || defined(PRODUCT_CFG_PRODUCT_TYPE_STA)
|
|
td_void mrs_enter_test_mode(td_void)
|
|
{
|
|
if (uapi_mdm_get_phy_test_mode() == PHYSICAL_TEST_MODE_APP_TO_COM_LOOP ||
|
|
uapi_mdm_get_phy_test_mode() == PHYSICAL_TEST_MODE_EXIT) {
|
|
return;
|
|
}
|
|
|
|
mrs_common_capture_deinit();
|
|
}
|
|
|
|
td_void mrs_exit_phy_tans_test_mode(td_void)
|
|
{
|
|
td_u8 mode = uapi_mdm_get_phy_test_mode();
|
|
if (mode == PHYSICAL_TEST_MODE_APP_TO_COM_LOOP) {
|
|
uapi_mdm_exit_phy_test_mode();
|
|
}
|
|
}
|
|
|
|
td_void mrs_exit_phy_loop_test_mode(td_void)
|
|
{
|
|
uapi_mdm_exit_phy_test_mode();
|
|
}
|
|
|
|
td_void mrs_exit_mac_msdu_test_mode(td_void)
|
|
{
|
|
td_u8 mode = uapi_mdm_get_phy_test_mode();
|
|
if (mode == PHYSICAL_TEST_MODE_EXIT) {
|
|
uapi_mdm_exit_phy_test_mode();
|
|
}
|
|
}
|
|
#endif
|
|
|
|
static td_void mrs_dfx_test_mode_err_frame_info(td_u8 pb_type)
|
|
{
|
|
g_dfx_test_mode_info.rcv_frame_err_cnt++;
|
|
g_dfx_test_mode_info.payload_type = pb_type;
|
|
g_dfx_test_mode_info.rcv_frame_err_time = uapi_get_seconds();
|
|
}
|
|
|
|
static td_void mrs_dfx_test_mode_cnt(td_u8 test_mode)
|
|
{
|
|
g_dfx_test_mode_info.count++;
|
|
g_dfx_test_mode_info.mode = test_mode;
|
|
g_dfx_test_mode_info.latest_report_time = uapi_get_seconds();
|
|
}
|
|
|
|
td_void mrs_dfx_test_mode_invalid_frame(td_u8 port, td_u8 test_id)
|
|
{
|
|
g_dfx_test_mode_info.invalid_port = port;
|
|
g_dfx_test_mode_info.invalid_test_id = test_id;
|
|
}
|
|
|
|
static td_void mrs_dfx_enter_test_mode(td_u8 mode, td_u8 pre_mode)
|
|
{
|
|
diag_cmd_phy_test_mode_inf *p_mode = &(g_dfx_test_mode_info.mode_info[mode]);
|
|
|
|
p_mode->enter_test_mode_time = uapi_get_seconds();
|
|
p_mode->test_mode_flag = TD_TRUE;
|
|
p_mode->pre_mode = pre_mode;
|
|
}
|
|
|
|
td_void mrs_dfx_exit_test_mode(td_u8 mode, td_u8 cur_mode)
|
|
{
|
|
diag_cmd_phy_test_mode_inf *p_mode = &(g_dfx_test_mode_info.mode_info[mode]);
|
|
|
|
p_mode->exit_test_mode_time = uapi_get_seconds();
|
|
p_mode->test_mode_flag = TD_FALSE;
|
|
p_mode->pre_mode = cur_mode;
|
|
}
|
|
|
|
td_u32 mrs_cmd_query_test_mode_info(td_u16 id, td_pvoid cmd, td_u16 cmd_size, td_u8 option)
|
|
{
|
|
diag_cmd_test_mode_info_ind *ind = &g_dfx_test_mode_info;
|
|
|
|
ext_unref_param(cmd_size);
|
|
ext_unref_param(cmd);
|
|
|
|
return uapi_diag_report_packet(id, option, (td_pbyte)ind, sizeof(diag_cmd_test_mode_info_ind), TD_FALSE);
|
|
}
|
|
|