3373 lines
		
	
	
		
			114 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			3373 lines
		
	
	
		
			114 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_task_api.h"
 | 
						|
#include "os_event_api.h"
 | 
						|
#include "os_timer_api.h"
 | 
						|
#include "os_utils_api.h"
 | 
						|
 | 
						|
/* iot common header files */
 | 
						|
#include "iot_plc_api.h"
 | 
						|
#include "iot_module_api.h"
 | 
						|
#include "iot_queue_api.h"
 | 
						|
#include "iot_config_api.h"
 | 
						|
#include "iot_plc_msg_api.h"
 | 
						|
#include "iot_board_api.h"
 | 
						|
 | 
						|
#include "iot_mem_pool_api.h"
 | 
						|
#include "iot_config_api.h"
 | 
						|
#include "iot_app_api.h"
 | 
						|
#include "iot_errno_api.h"
 | 
						|
#include "iot_sg_drv_api.h"
 | 
						|
#include "iot_pib_api.h"
 | 
						|
#include "iot_ntoh_api.h"
 | 
						|
#include "iot_oem_api.h"
 | 
						|
 | 
						|
#include "proto_645.h"
 | 
						|
#include "proto_645_vendor.h"
 | 
						|
#include "proto_69845.h"
 | 
						|
#include "proto_69845_vendor.h"
 | 
						|
#include "proto_crc16.h"
 | 
						|
#include "proto_conn_less.h"
 | 
						|
#include "iot_frame_parse_api.h"
 | 
						|
#include "proto_dlms.h"
 | 
						|
#include "proto_qsxj.h"
 | 
						|
#include "proto_gw_app.h"
 | 
						|
 | 
						|
#include "iot_io_api.h"
 | 
						|
#include "iot_dbglog_api.h"
 | 
						|
#include "iot_uart_api.h"
 | 
						|
#include "iot_utils_api.h"
 | 
						|
#include "iot_dev_test.h"
 | 
						|
#include "iot_proto_dev_test.h"
 | 
						|
 | 
						|
/* define the length of the packet used for ppm detect */
 | 
						|
#define IOT_DEV_TEST_PPM_DETCT_PKG_LEN          400
 | 
						|
 | 
						|
#if IOT_DEV_TEST_BROADCAST_MODD_CFG
 | 
						|
 | 
						|
/* ppm detect function switch,  for the normal controller, this is always off */
 | 
						|
#define IOT_DEV_TEST_PPM_DETECT_EN              0
 | 
						|
 | 
						|
#else
 | 
						|
 | 
						|
/* ppm detect function switch, for HX applications, turn on this function when
 | 
						|
 * ppm detect is needed.
 | 
						|
 * for example, some CIU factories have problems in production test, you can
 | 
						|
 * try to open this function
 | 
						|
 */
 | 
						|
#define IOT_DEV_TEST_PPM_DETECT_EN              0
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
 | 
						|
#if (IOT_STA_CONTROL_MODE == 2) || (IOT_DEV_TEST_CCO_MODE)
 | 
						|
 | 
						|
static iot_dev_test_task_data_t *dev_test_task_data;
 | 
						|
 | 
						|
static uint8_t iot_dev_test_send_mode_config(uint8_t *dst_mac);
 | 
						|
 | 
						|
static void iot_dev_test_flash_info_init(void);
 | 
						|
 | 
						|
static void iot_dev_test_close_uart(iot_uart_h uart);
 | 
						|
 | 
						|
static bool_t iot_dev_test_set_uart_config(iot_uart_h uart);
 | 
						|
 | 
						|
static uint8_t iot_dev_test_flash_save(iot_dev_test_pib_t *p_info);
 | 
						|
 | 
						|
#if (IOT_DEV_TEST_DEBUG_EN == 1)
 | 
						|
 | 
						|
static char dev_test_log_buf[IOT_DEV_TEST_LOG_BUF_LEN] = { 0 };
 | 
						|
 | 
						|
void iot_dev_test_data_print(const char* str, uint8_t* buf, uint16_t len)
 | 
						|
{
 | 
						|
    uint32_t offset = 0;
 | 
						|
 | 
						|
    offset = iot_sprintf(dev_test_log_buf, "%s[len:%d]", str, len);
 | 
						|
    for (uint32_t i = 0; i < len; ++i) {
 | 
						|
        offset += iot_sprintf(dev_test_log_buf + offset, "%02X ", buf[i]);
 | 
						|
        if (IOT_DEV_TEST_LOG_BUF_LEN <= offset + 4) {
 | 
						|
            break;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    dev_test_log_buf[offset] = 0;
 | 
						|
    iot_cus_printf("%s\n", dev_test_log_buf);
 | 
						|
}
 | 
						|
 | 
						|
#else /* IOT_DEV_TEST_DEBUG_EN == 1 */
 | 
						|
 | 
						|
void iot_dev_test_data_print(const char* str, uint8_t* buf, uint16_t len)
 | 
						|
{
 | 
						|
    (void)str;
 | 
						|
    (void)buf;
 | 
						|
    (void)len;
 | 
						|
    return;
 | 
						|
}
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
#if IOT_STA_CONTROL_MODE == IOT_STA_CONTROL_TYPE_METER
 | 
						|
 | 
						|
/* mac addr of CIU TESTER */
 | 
						|
static const uint8_t ciu_tester_mac[IOT_MAC_ADDR_LEN] =
 | 
						|
    { 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x01 };
 | 
						|
 | 
						|
/* UART baudrate lookup table */
 | 
						|
static const uint32_t baud_tbl[SUPPORTED_BAUD_CNT] = {
 | 
						|
    2400,        // baudidx 0
 | 
						|
    4800,        // baudidx 1
 | 
						|
    9600,        // baudidx 2
 | 
						|
    115200,      // baudidx 3
 | 
						|
};
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
static void iot_dev_test_post_task_msg(uint16_t msg_type, uint16_t msg_id,
 | 
						|
    void *data)
 | 
						|
{
 | 
						|
    iot_task_msg_t *msg;
 | 
						|
    iot_dev_test_task_msg_t *task_msg;
 | 
						|
    iot_task_h task_hdl = dev_test_task_data->task_handle;
 | 
						|
 | 
						|
    msg = iot_task_alloc_msg_with_reserved(task_hdl, 0);
 | 
						|
    if (!msg) {
 | 
						|
        IOT_ASSERT(0);
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    task_msg = (iot_dev_test_task_msg_t*)msg;
 | 
						|
    task_msg->msg.type = msg_type;
 | 
						|
    task_msg->msg.id = msg_id;
 | 
						|
    task_msg->data = data;
 | 
						|
    iot_task_queue_msg(dev_test_task_data->task_handle, &task_msg->msg, 1);
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
/* send mode config to all the sta and lock the stas' band */
 | 
						|
static void iot_dev_test_config_all_sta_test_mode(void)
 | 
						|
{
 | 
						|
    static uint8_t check_cnt = IOT_DEV_TEST_BCAST_TIMER_CNT;
 | 
						|
 | 
						|
    check_cnt++;
 | 
						|
    if (check_cnt >= IOT_DEV_TEST_BCAST_TIMER_CNT) {
 | 
						|
        iot_dev_test_send_mode_config((uint8_t *)bcast_mac);
 | 
						|
        check_cnt = 0;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
#if (IOT_STA_CONTROL_MODE == IOT_STA_CONTROL_TYPE_METER)
 | 
						|
 | 
						|
/* define the max tool ppm value, which the tool may config */
 | 
						|
#define IOT_DEV_TEST_MAX_TOOL_PPM       15
 | 
						|
 | 
						|
static uint8_t spec_mac[IOT_MAC_ADDR_LEN] = {0xAA, 0xBB,0xCC, 0xCC,0xBB, 0xAA};
 | 
						|
 | 
						|
static void iot_dev_test_uart_send(iot_pkt_t *pkt);
 | 
						|
static bool_t iot_dev_test_frame_rpt_check(uint8_t *mac, uint16_t sn);
 | 
						|
static uint16_t iot_dev_test_app_get_sn(void);
 | 
						|
 | 
						|
static iot_uart_h iot_dev_test_open_uart(uint8_t port);
 | 
						|
 | 
						|
static void iot_dev_test_set_mac(uint8_t *mac);
 | 
						|
 | 
						|
static bool_t iot_dev_test_app_pkt_report_check(uint8_t *mac, uint32_t in_sn) {
 | 
						|
    bool_t need_rpt = false;
 | 
						|
 | 
						|
    iot_cus_printf("dst mac[%02x:%02x:%02x:%02x:%02x:%02x], stored sn[%lu], "
 | 
						|
        "recv sn[%lu]\n", mac[0],mac[1],mac[2],mac[3],mac[4],mac[5],
 | 
						|
        dev_test_task_data->stored_app_sn, in_sn);
 | 
						|
 | 
						|
    iot_cus_printf("local mac[%02x:%02x:%02x:%02x:%02x:%02x]\n",
 | 
						|
        dev_test_task_data->mac_addr[0], dev_test_task_data->mac_addr[1],
 | 
						|
        dev_test_task_data->mac_addr[2], dev_test_task_data->mac_addr[3],
 | 
						|
        dev_test_task_data->mac_addr[4], dev_test_task_data->mac_addr[5]);
 | 
						|
 | 
						|
    if (iot_mac_addr_cmp(mac, dev_test_task_data->mac_addr)
 | 
						|
            || iot_mac_is_bcast(mac)) {
 | 
						|
        need_rpt = true;
 | 
						|
        if (dev_test_task_data->stored_app_sn != in_sn) {
 | 
						|
//            need_rpt = true;
 | 
						|
            dev_test_task_data->stored_app_sn = in_sn;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
 | 
						|
    return need_rpt;
 | 
						|
}
 | 
						|
 | 
						|
static uint8_t iot_dev_test_fullfil_rsp_snr_cmd(uint8_t *data, uint16_t len,
 | 
						|
    int8_t snr, int8_t rssi)
 | 
						|
{
 | 
						|
    proto_645_header_t *hdr_645 = NULL;
 | 
						|
    uint8_t *t_ptr;
 | 
						|
    uint32_t di = 0;
 | 
						|
    uint8_t reason = 0;
 | 
						|
    uint8_t ret = ERR_FAIL;
 | 
						|
    proto_645_07_ext_signal_resp_t *signal_attr;
 | 
						|
    proto_645_tailer_t *tail;
 | 
						|
    proto_69845_frame_head_info_t *hdr_698;
 | 
						|
    proto_dlms_hdlc_head_t *hdr_dlms;
 | 
						|
    proto_dlms_hdlc_cache_t cache_dlms;
 | 
						|
 | 
						|
    hdr_645 = proto_645_format_check(data, len, PROTO_645_DIR_SLAVE);
 | 
						|
    if (NULL == hdr_645) {
 | 
						|
        hdr_698 = proto_69845_sanity_check(data, len);
 | 
						|
        if (NULL != hdr_698) {
 | 
						|
            iot_cus_printf("RECV_PLC_69845 frame, fn 0x%04x, "
 | 
						|
                "data_len %lu\n", hdr_698->len, hdr_698->ctrl.fn);
 | 
						|
        } else {
 | 
						|
            hdr_dlms = proto_dlms_hdlc_parse(data, len, &cache_dlms);
 | 
						|
            if (hdr_dlms) {
 | 
						|
                iot_cus_printf("RECV_PLC_DLMS frame, type %lu, \n",
 | 
						|
                    hdr_dlms->frame_format.bit.frame_type);
 | 
						|
            } else {
 | 
						|
                iot_cus_printf("RECV_PLC_unknown frame, len %lu\n", len);
 | 
						|
            }
 | 
						|
        }
 | 
						|
        reason = 1;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
 | 
						|
    if (ERR_OK != proto_645_get_di_by_sub33(hdr_645->data,
 | 
						|
        PROTO_645_2007_DI_LEN, PROTO_645_2007_ID, &di)) {
 | 
						|
        iot_cus_printf("RECV_PLC_645 frame, di 0x%04x, data_len %lu\n", di,
 | 
						|
            hdr_645->len);
 | 
						|
        reason = 2;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
 | 
						|
    if (di != PROTO_645_2007_EXT_QUERY_SIGNAL_ID) {
 | 
						|
        reason = 3;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
 | 
						|
    iot_cus_printf("uplink snr %d, rssi %lu\n", snr, rssi);
 | 
						|
 | 
						|
    t_ptr = &hdr_645->data[PROTO_645_2007_DI_LEN];
 | 
						|
    signal_attr = (proto_645_07_ext_signal_resp_t *)t_ptr;
 | 
						|
    signal_attr->ul_rssi = rssi + 0x33;
 | 
						|
    signal_attr->ul_snr = snr + 0x33;
 | 
						|
    tail = (proto_645_tailer_t *)&hdr_645->data[hdr_645->len];
 | 
						|
    tail->cs = proto_645_calc_cs(hdr_645);
 | 
						|
    ret = ERR_OK;
 | 
						|
out:
 | 
						|
    if (reason != 0) {
 | 
						|
        iot_cus_printf("fuillfil frame failed for reason %lu\n", reason);
 | 
						|
    }
 | 
						|
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
/* get the address from the response message, until now, dev_test app only
 | 
						|
 * support DL/T 645-2007, DL/T 698.45 and dlms
 | 
						|
 */
 | 
						|
static uint8_t iot_dev_test_addr_in_data_check(uint8_t *data, uint32_t len,
 | 
						|
    uint16_t sn)
 | 
						|
{
 | 
						|
    uint8_t ret = ERR_FAIL;
 | 
						|
    uint8_t addr[IOT_MAC_ADDR_LEN] = {0};
 | 
						|
    proto_645_header_t *hdr_645;
 | 
						|
    proto_69845_frame_head_info_t *hdr_698;
 | 
						|
    proto_dlms_hdlc_head_t *hdr_dlms;
 | 
						|
    proto_dlms_hdlc_cache_t cache_dlms;
 | 
						|
 | 
						|
    if (!data || !len) {
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    hdr_645 = proto_645_format_check_ext(data, len, PROTO_645_DIR_SLAVE);
 | 
						|
    if (hdr_645) {
 | 
						|
        iot_mac_addr_cpy(addr, hdr_645->addr);
 | 
						|
    } else {
 | 
						|
        hdr_698 = proto_69845_sanity_check_ext(data, (uint16_t)len);
 | 
						|
        if (hdr_698) {
 | 
						|
            iot_mac_addr_cpy(addr, proto_69845_get_ser_addr(hdr_698));
 | 
						|
        } else {
 | 
						|
            hdr_dlms = proto_dlms_hdlc_parse(data, len, &cache_dlms);
 | 
						|
            if (hdr_dlms) {
 | 
						|
                if (cache_dlms.dest_addr.type != PROTO_DLMS_HDLC_ADD_TYPE_4) {
 | 
						|
                    goto out;
 | 
						|
                }
 | 
						|
                proto_dlms_hdlc_type_4_addr_to_bcd_addr(addr,
 | 
						|
                    &cache_dlms.dest_addr);
 | 
						|
            } else {
 | 
						|
                goto out;
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
    iot_mac_addr_reverse(addr);
 | 
						|
    if (iot_dev_test_frame_rpt_check(addr, sn)) {
 | 
						|
        ret = ERR_OK;
 | 
						|
    }
 | 
						|
out:
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
/* update the collector's mac */
 | 
						|
static void iot_dev_test_update_collector_mac(uint8_t *mac)
 | 
						|
{
 | 
						|
#if IOT_DEV_TEST_SUPPORT_CT_MR_EN
 | 
						|
 | 
						|
    if (!dev_test_task_data->collector_vaild) {
 | 
						|
        if (!iot_mac_addr_valid(mac) || iot_mac_is_bcast(mac)) {
 | 
						|
            return;
 | 
						|
        }
 | 
						|
        iot_mac_addr_cpy(dev_test_task_data->collector, mac);
 | 
						|
        dev_test_task_data->collector_vaild = 1;
 | 
						|
        iot_cus_printf("%s: collector mac[%02x:%02x:%02x:%02x:%02x:"
 | 
						|
            "%02x] updated\n", __FUNCTION__,
 | 
						|
             mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
 | 
						|
    }
 | 
						|
    /* clear the cnt for expand the span of collector's address */
 | 
						|
    dev_test_task_data->collector_vaild_cnt = 0;
 | 
						|
 | 
						|
#else
 | 
						|
 | 
						|
    (void)mac;
 | 
						|
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
static uint8_t iot_dev_test_handle_normal_data(iot_pkt_t *pkt)
 | 
						|
{
 | 
						|
    uint8_t consumed = 0;
 | 
						|
    uint8_t *ptr = NULL;
 | 
						|
    iot_plc_msdu_recv_t *msdu = NULL;
 | 
						|
    proto_conn_less_mr_t *meter;
 | 
						|
    uint8_t *mac;
 | 
						|
    uint16_t app_sn;
 | 
						|
    uint16_t offset_sz;
 | 
						|
 | 
						|
    iot_plc_msg_header_t *hdr =
 | 
						|
        (iot_plc_msg_header_t*)iot_pkt_block_ptr(pkt, IOT_PKT_BLOCK_DATA);
 | 
						|
    msdu = (iot_plc_msdu_recv_t*)(hdr + 1);
 | 
						|
 | 
						|
    ptr = msdu->data;
 | 
						|
 | 
						|
    meter = (proto_conn_less_mr_t *)(ptr + sizeof(proto_conn_less_hdr_t));
 | 
						|
    app_sn = meter->seq;
 | 
						|
    if (dev_test_task_data->m2m_sub_mode == IOT_DEV_TEST_M2M_SUBMODE_CIU
 | 
						|
        && meter->m2m_switch_mode == IOT_DEV_TEST_M2M_MODE_SWITCH_ENABLE
 | 
						|
        && dev_test_task_data->dev_mode == IOT_DEV_TEST_APP_MODE_M2S) {
 | 
						|
        dev_test_task_data->dev_mode = IOT_DEV_TEST_APP_MODE_M2M;
 | 
						|
        iot_cus_printf("%s: set dev mode from M2S to M2M\n", __FUNCTION__);
 | 
						|
        /* If M2M CIU mode, need to query addr from CIU */
 | 
						|
        os_start_timer(dev_test_task_data->query_addr_tm,
 | 
						|
            IOT_DEV_TEST_QUERY_ADDR_TIMER_INTERVAL);
 | 
						|
    }
 | 
						|
 | 
						|
    if (dev_test_task_data->dev_mode == IOT_DEV_TEST_APP_MODE_M2S) {
 | 
						|
        /* data direction must: slave->master */
 | 
						|
        if (meter->dir != CONN_LESS_APP_DIR_SLAVE) {
 | 
						|
            iot_cus_printf("%s:M2S MODE -- invalid direction\n", __FUNCTION__);
 | 
						|
            return consumed;
 | 
						|
        }
 | 
						|
        /* when conditions satisfied, send the response data to UART:
 | 
						|
         * rule 1: the msdu source address is matched with the address
 | 
						|
         *         stored in the frame data infor pool;
 | 
						|
         * rule 2: the address field of the response message is same as
 | 
						|
                   the address stored in the frame data infor pool.
 | 
						|
         * any one of the rule 1 and rule 2 is effective, together with the
 | 
						|
         * sequnce number matched, the reponse message should be reported.
 | 
						|
         */
 | 
						|
        mac = msdu->src;
 | 
						|
        if (iot_dev_test_frame_rpt_check(mac, app_sn)
 | 
						|
            || (iot_dev_test_addr_in_data_check(meter->data, meter->data_len,
 | 
						|
            app_sn) == ERR_OK)) {
 | 
						|
            iot_cus_printf("%s: rpt condition satisfied, sn %lu,"
 | 
						|
                "mac[%02x:%02x:%02x:%02x:%02x:%02x]\n", __FUNCTION__, app_sn,
 | 
						|
                mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
 | 
						|
            offset_sz = sizeof(*msdu) + sizeof(*hdr) + sizeof(*meter) +
 | 
						|
                sizeof(proto_conn_less_hdr_t);
 | 
						|
            iot_pkt_pull(pkt, offset_sz);
 | 
						|
            /* update the collector'a address if neccessory */
 | 
						|
            iot_dev_test_update_collector_mac(mac);
 | 
						|
 | 
						|
            /* check the frame is a signal attr response command or not */
 | 
						|
            iot_dev_test_fullfil_rsp_snr_cmd(iot_pkt_data(pkt),
 | 
						|
                iot_pkt_data_len(pkt), msdu->snr, msdu->rssi);
 | 
						|
 | 
						|
            iot_dev_test_data_print("m2s msdu recv", iot_pkt_data(pkt),
 | 
						|
                (uint16_t)iot_pkt_data_len(pkt));
 | 
						|
 | 
						|
            iot_dev_test_uart_send(pkt);
 | 
						|
            consumed = 1;
 | 
						|
        } else {
 | 
						|
            iot_cus_printf("%s: pkt dropped for info mismatch, sn %lu, mac"
 | 
						|
                "[%02x:%02x:%02x:%02x:%02x:%02x]\n", __FUNCTION__, app_sn,
 | 
						|
                mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
 | 
						|
        }
 | 
						|
    } else if (dev_test_task_data->dev_mode == IOT_DEV_TEST_APP_MODE_M2M) {
 | 
						|
        if (IOT_DEV_TEST_BROADCAST_MODD_CFG) {
 | 
						|
            if (meter->dir != CONN_LESS_APP_DIR_M2M) {
 | 
						|
                iot_cus_printf("%s:M2M MODE -- invalid direction\n",
 | 
						|
                    __FUNCTION__);
 | 
						|
                return consumed;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        mac = msdu->dst;
 | 
						|
        if (iot_dev_test_app_pkt_report_check(mac, app_sn))  {
 | 
						|
            iot_cus_printf("%s: received master -> master pkt from"
 | 
						|
                "[%02x:%02x:%02x:%02x:%02x:%02x]\n", __FUNCTION__,
 | 
						|
                mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
 | 
						|
            offset_sz = sizeof(*msdu) + sizeof(*hdr) + sizeof(*meter) +
 | 
						|
                sizeof(proto_conn_less_hdr_t);
 | 
						|
            iot_pkt_pull(pkt, offset_sz);
 | 
						|
            iot_dev_test_uart_send(pkt);
 | 
						|
            consumed = 1;
 | 
						|
        } else {
 | 
						|
            iot_cus_printf("%s: pkt drooped for local addr is set "
 | 
						|
                "and dst addr is not matched with local addr", __FUNCTION__);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    return consumed;
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
static int8_t iot_dev_test_get_fix_ppm(void)
 | 
						|
{
 | 
						|
    iot_dev_test_pib_t *pib = &dev_test_task_data->flashinfo;
 | 
						|
    iot_dev_test_ppm_detec_desc_t * ppm_desc = &dev_test_task_data->ppm_desc;
 | 
						|
    int8_t ppm = ppm_desc->fix_ppm;
 | 
						|
 | 
						|
    if (pib->tool_ppm_valid) {
 | 
						|
        ppm = ppm_desc->fix_ppm - pib->tool_ppm;
 | 
						|
    }
 | 
						|
    return ppm;
 | 
						|
}
 | 
						|
 | 
						|
#if (IOT_DEV_TEST_HANDLE_PUSH_DATA_EN == 1) || (IOT_DEV_TEST_BROADCAST_MODD_CFG == 0)
 | 
						|
 | 
						|
/* ask for mac to indicate the modual is ready to handle cmd from CIU */
 | 
						|
static void iot_dev_test_send_bootup_indication(void)
 | 
						|
{
 | 
						|
 | 
						|
    iot_pkt_t *pkt = NULL;
 | 
						|
    static uint8_t boot_ind_cnt = 0;
 | 
						|
    static uint8_t intvl_cnt = 0;
 | 
						|
 | 
						|
    if (dev_test_task_data->boot_ind_en) {
 | 
						|
        intvl_cnt++;
 | 
						|
        if (intvl_cnt >= IOT_DEV_TEST_BOOT_IND_RETRY_INTV) {
 | 
						|
            pkt = proto_645_2007_build_ra_msg();
 | 
						|
 | 
						|
            if (NULL != pkt) {
 | 
						|
                iot_dev_test_data_print("send bootup indicatio: ",
 | 
						|
                    iot_pkt_data(pkt), (uint16_t)iot_pkt_data_len(pkt));
 | 
						|
                iot_dev_test_uart_send(pkt);
 | 
						|
                boot_ind_cnt++;
 | 
						|
                if (boot_ind_cnt > IOT_DEV_TEST_BOOT_IND_RETRY_MAX_CNT) {
 | 
						|
                    dev_test_task_data->boot_ind_en = 0;
 | 
						|
                }
 | 
						|
                intvl_cnt = 0;
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
    return;
 | 
						|
}
 | 
						|
 | 
						|
/* stop sending indication after received the response from CIU */
 | 
						|
static void iot_dev_test_stop_send_bootup_ind(void)
 | 
						|
{
 | 
						|
    if (dev_test_task_data->boot_ind_en == 1) {
 | 
						|
        dev_test_task_data->boot_ind_en = 0;
 | 
						|
        iot_cus_printf("stop sending the ind\n", __FUNCTION__);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static uint8_t iot_dev_test_pushed_data_rpt_check(uint8_t *mac, uint16_t seq)
 | 
						|
{
 | 
						|
    uint8_t ret = 0;
 | 
						|
    uint8_t *match_mac = dev_test_task_data->flashinfo.match_mac;
 | 
						|
    if (iot_mac_addr_cmp(mac, match_mac)
 | 
						|
        && (seq != dev_test_task_data->pushed_seq) && (seq != 0)) {
 | 
						|
        /* update pushed-data's seq */
 | 
						|
        dev_test_task_data->pushed_seq = seq;
 | 
						|
        ret = 1;
 | 
						|
    }
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
/* handle pushed-data from PLC */
 | 
						|
static uint8_t iot_dev_test_handle_pushed_data(iot_pkt_t *pkt)
 | 
						|
{
 | 
						|
    uint8_t consumed = 0;
 | 
						|
    uint8_t *ptr = NULL;
 | 
						|
    iot_plc_msdu_recv_t *msdu = NULL;
 | 
						|
    proto_conn_less_push_data_t *p_data;
 | 
						|
    uint8_t *mac;
 | 
						|
    uint16_t seq;
 | 
						|
    uint16_t offset_sz;
 | 
						|
 | 
						|
    iot_plc_msg_header_t *hdr =
 | 
						|
        (iot_plc_msg_header_t*)iot_pkt_block_ptr(pkt, IOT_PKT_BLOCK_DATA);
 | 
						|
    msdu = (iot_plc_msdu_recv_t*)(hdr + 1);
 | 
						|
 | 
						|
    ptr = msdu->data;
 | 
						|
 | 
						|
    p_data =
 | 
						|
        (proto_conn_less_push_data_t *)(ptr + sizeof(proto_conn_less_hdr_t));
 | 
						|
    seq = p_data->seq;
 | 
						|
 | 
						|
    iot_dev_test_data_print("pushed msdu recv all", iot_pkt_data(pkt),
 | 
						|
        (uint16_t)iot_pkt_data_len(pkt));
 | 
						|
 | 
						|
    if (dev_test_task_data->dev_mode == IOT_DEV_TEST_APP_MODE_M2S) {
 | 
						|
        /* data direction must: master->slave */
 | 
						|
        if (p_data->dir != CONN_LESS_APP_DIR_SLAVE) {
 | 
						|
            iot_cus_printf("%s:invalid direction\n", __FUNCTION__);
 | 
						|
            return consumed;
 | 
						|
        }
 | 
						|
 | 
						|
        mac = p_data->addr;
 | 
						|
        iot_mac_addr_reverse(mac);
 | 
						|
        if (iot_dev_test_pushed_data_rpt_check(mac, seq)) {
 | 
						|
            iot_cus_printf("%s: pushed data rpt condition satisfied, seq %lu,"
 | 
						|
                "mac[%02x:%02x:%02x:%02x:%02x:%02x]\n", __FUNCTION__, seq,
 | 
						|
                mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
 | 
						|
            offset_sz = sizeof(*msdu) + sizeof(*hdr) + sizeof(*p_data) +
 | 
						|
                sizeof(proto_conn_less_hdr_t);
 | 
						|
            iot_pkt_pull(pkt, offset_sz);
 | 
						|
 | 
						|
            iot_dev_test_data_print("pushed msdu recv", iot_pkt_data(pkt),
 | 
						|
                (uint16_t)iot_pkt_data_len(pkt));
 | 
						|
 | 
						|
            iot_dev_test_uart_send(pkt);
 | 
						|
            consumed = 1;
 | 
						|
        } else {
 | 
						|
            iot_cus_printf("%s: pkt dropped for info mismatch: seq[%lu], from"
 | 
						|
                "[%02x:%02x:%02x:%02x:%02x:%02x]\n", __FUNCTION__, seq,
 | 
						|
                mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    return consumed;
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
/* handle pushed-data's ack from CIU */
 | 
						|
static uint8_t iot_dev_test_handle_ack_data_from_host(
 | 
						|
    proto_645_header_t *hdr_645)
 | 
						|
{
 | 
						|
    uint16_t total_sz, payload_sz;
 | 
						|
    proto_conn_less_hdr_t *hdr;
 | 
						|
    proto_conn_less_push_data_t *p_data;
 | 
						|
    iot_pkt_t *msdu_pkt;
 | 
						|
    uint8_t dst_mac[IOT_MAC_ADDR_LEN] = { 0 };
 | 
						|
    uint8_t *ptr = NULL;
 | 
						|
    uint8_t ret = ERR_FAIL;
 | 
						|
    uint8_t reason = 0;
 | 
						|
 | 
						|
    if (0 == dev_test_task_data->collector_vaild) {
 | 
						|
        iot_mac_addr_cpy(dst_mac,(uint8_t *)bcast_mac);
 | 
						|
    } else {
 | 
						|
        iot_mac_addr_cpy(dst_mac, dev_test_task_data->collector);
 | 
						|
    }
 | 
						|
 | 
						|
    if (!iot_mac_addr_valid(dst_mac)) {
 | 
						|
        reason = 1;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
 | 
						|
    payload_sz = sizeof(*hdr_645) + hdr_645->len + sizeof(proto_645_tailer_t);
 | 
						|
    total_sz = sizeof(*hdr) + sizeof(*p_data) + payload_sz;
 | 
						|
 | 
						|
    msdu_pkt = iot_plc_alloc_conn_less_msdu(dev_test_task_data->app_handle,
 | 
						|
        IOT_PLC_MSG_TYPE_CONN_LESS_DATA, dst_mac, dev_test_task_data->mac_addr,
 | 
						|
        CONN_LESS_APP_PRIO_METER_READ, total_sz, IOT_PLC_MAX_RETRY_CNT);
 | 
						|
    if (msdu_pkt) {
 | 
						|
        ptr = iot_pkt_block_ptr(msdu_pkt, IOT_PKT_BLOCK_TAIL);
 | 
						|
        /* fill in header */
 | 
						|
        hdr = (proto_conn_less_hdr_t *)ptr;
 | 
						|
        hdr->id = CONN_LESS_APP_ID_DATA_PUSH;
 | 
						|
        hdr->port = CONN_LESS_APP_PORT;
 | 
						|
 | 
						|
        p_data = (proto_conn_less_push_data_t *)(hdr + 1);
 | 
						|
        p_data->seq = iot_dev_test_app_get_sn();
 | 
						|
        p_data->data_len = payload_sz;
 | 
						|
        p_data->dir = CONN_LESS_APP_DIR_MASTER;
 | 
						|
        /* fill in payload */
 | 
						|
        os_mem_cpy(p_data->data, hdr_645, payload_sz);
 | 
						|
        iot_pkt_put(msdu_pkt, total_sz);
 | 
						|
        iot_plc_send_msdu(dev_test_task_data->app_handle, msdu_pkt);
 | 
						|
        ret = ERR_OK;
 | 
						|
    } else {
 | 
						|
        reason = 2;
 | 
						|
    }
 | 
						|
 | 
						|
out:
 | 
						|
    iot_cus_printf("%s result %lu, reason %lu\n", __FUNCTION__, ret, reason);
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
/* set module address once the meter address changed */
 | 
						|
static void iot_dev_test_config_mac(uint8_t *mac)
 | 
						|
{
 | 
						|
    iot_plc_cfg_set_req_t cfg = {0};
 | 
						|
    iot_plc_app_h app_hdl = dev_test_task_data->app_handle;
 | 
						|
 | 
						|
    if (!iot_mac_addr_valid(mac) || iot_mac_is_bcast(mac)) {
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    iot_mac_addr_cpy(cfg.addr, mac);
 | 
						|
    cfg.addr_valid = 1;
 | 
						|
    cfg.reset = 1;
 | 
						|
    cfg.dev_type_valid = 1;
 | 
						|
    cfg.dev_type = IOT_PLC_DEV_TYPE_METER_CONTROLLER;
 | 
						|
    iot_plc_set_cfg(app_hdl, IOT_PLC_API_REQ_ID_DEFAULT, &cfg);
 | 
						|
    iot_cus_printf("%s: config local mac[%02x:%02x:%02x:%02x:%02x:%02x] "
 | 
						|
        "successfully\n", __FUNCTION__, cfg.addr[0], cfg.addr[1],
 | 
						|
        cfg.addr[2], cfg.addr[3], cfg.addr[4], cfg.addr[5]);
 | 
						|
    os_delay (500);
 | 
						|
 | 
						|
    /* here, update the local MAC in advance to avoid dropping the
 | 
						|
     * first packet.
 | 
						|
     */
 | 
						|
    iot_mac_addr_cpy(dev_test_task_data->mac_addr, mac);
 | 
						|
 | 
						|
        /* set default frequnce band */
 | 
						|
#if (IOT_DEV_TEST_SUPPORT_MUTIBAND == 1)
 | 
						|
    iot_plc_set_freq_band(app_hdl, IOT_PLC_API_REQ_ID_DEFAULT,
 | 
						|
        PLC_LIB_FREQ_BAND_MULTI_1_2);
 | 
						|
#else
 | 
						|
    iot_plc_set_freq_band(app_hdl, IOT_PLC_API_REQ_ID_DEFAULT,
 | 
						|
        dev_test_task_data->band_id);
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
/* update the matching mac when a new cmd received */
 | 
						|
static void iot_dev_test_update_match_mac(uint8_t *mac)
 | 
						|
{
 | 
						|
    uint8_t reason = 0;
 | 
						|
    iot_dev_test_pib_t *p_info = &dev_test_task_data->flashinfo;
 | 
						|
 | 
						|
    if (!iot_mac_addr_valid(mac) || iot_mac_is_bcast(mac)) {
 | 
						|
        reason = 1;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    if (iot_mac_addr_cmp(mac, p_info->match_mac)) {
 | 
						|
        reason = 2;
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
 | 
						|
    iot_mac_addr_cpy(p_info->match_mac, mac);
 | 
						|
    iot_dev_test_flash_save(p_info);
 | 
						|
    iot_dev_test_config_mac(mac);
 | 
						|
    dev_test_task_data->collector_vaild = 0;
 | 
						|
 | 
						|
    iot_cus_printf("%s: matching mac[%02x:%02x:%02x:%02x:%02x:%02x] "
 | 
						|
        "successfully, collector address vaild: %d\n", __FUNCTION__, mac[0],
 | 
						|
        mac[1], mac[2],mac[3], mac[4], mac[5],
 | 
						|
        dev_test_task_data->collector_vaild);
 | 
						|
out:
 | 
						|
    iot_cus_printf("%s reason %lu\n", __FUNCTION__, reason);
 | 
						|
}
 | 
						|
 | 
						|
#else /* IOT_DEV_TEST_HANDLE_PUSH_DATA_EN == 1 */
 | 
						|
 | 
						|
static void iot_dev_test_send_bootup_indication(void)
 | 
						|
{
 | 
						|
    return;
 | 
						|
}
 | 
						|
 | 
						|
static void iot_dev_test_stop_send_bootup_ind(void)
 | 
						|
{
 | 
						|
    return;
 | 
						|
}
 | 
						|
 | 
						|
static uint8_t iot_dev_test_handle_pushed_data(iot_pkt_t *pkt)
 | 
						|
{
 | 
						|
    (void)pkt;
 | 
						|
    return ERR_OK;
 | 
						|
}
 | 
						|
 | 
						|
static uint8_t iot_dev_test_handle_ack_data_from_host(
 | 
						|
    proto_645_header_t *hdr_645)
 | 
						|
{
 | 
						|
    (void)hdr_645;
 | 
						|
    return ERR_OK;
 | 
						|
}
 | 
						|
 | 
						|
static void iot_dev_test_update_match_mac(uint8_t *mac)
 | 
						|
{
 | 
						|
    (void)mac;
 | 
						|
}
 | 
						|
 | 
						|
#endif /* IOT_DEV_TEST_HANDLE_PUSH_DATA_EN == 0 */
 | 
						|
 | 
						|
static uint8_t iot_dev_test_config_data_hdl_check(uint8_t *mac, uint16_t seq)
 | 
						|
{
 | 
						|
    uint8_t ret = 0;
 | 
						|
    uint8_t *local_mac = dev_test_task_data->mac_addr;
 | 
						|
 | 
						|
    if (!mac || !seq) {
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    if (seq == dev_test_task_data->config_seq) {
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    if (iot_mac_addr_cmp(mac, local_mac)) {
 | 
						|
        dev_test_task_data->config_seq = seq;
 | 
						|
        ret = 1;
 | 
						|
    }
 | 
						|
out:
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
static uint8_t iot_dev_test_config_pack_plc_rsp_data(uint8_t *dst, uint16_t sn,
 | 
						|
    uint8_t *data, uint16_t len)
 | 
						|
{
 | 
						|
    uint32_t buflen = 0;
 | 
						|
    uint8_t *ptr = NULL;
 | 
						|
    iot_pkt_t *msdu_pkt;
 | 
						|
    proto_conn_less_hdr_t  *proto_hdr;
 | 
						|
    proto_conn_less_mr_t *meter;
 | 
						|
    iot_dev_test_task_data_t *dev_glb = dev_test_task_data;
 | 
						|
    int8_t fix_ppm;
 | 
						|
 | 
						|
    if(!dst || !data || !len) {
 | 
						|
        return ERR_FAIL;
 | 
						|
    }
 | 
						|
 | 
						|
    fix_ppm = iot_dev_test_get_fix_ppm();
 | 
						|
    buflen = sizeof(proto_conn_less_hdr_t) + sizeof(proto_conn_less_mr_t) + len;
 | 
						|
    msdu_pkt = iot_plc_alloc_conn_less_msdu_ext(dev_glb->app_handle,
 | 
						|
        IOT_PLC_MSG_TYPE_CONN_LESS_DATA, dst, dev_glb->mac_addr,
 | 
						|
        dev_glb->link_id, (uint16_t)buflen, IOT_PLC_MAX_RETRY_CNT,
 | 
						|
        fix_ppm, 0, dev_glb->tx_link_type);
 | 
						|
 | 
						|
    if (msdu_pkt == NULL) {
 | 
						|
        iot_cus_printf("allocate msdu fail\n");
 | 
						|
        return ERR_FAIL;
 | 
						|
    }
 | 
						|
 | 
						|
    ptr = iot_pkt_block_ptr(msdu_pkt, IOT_PKT_BLOCK_TAIL);
 | 
						|
    iot_pkt_put(msdu_pkt, buflen);
 | 
						|
    proto_hdr = (proto_conn_less_hdr_t *)ptr;
 | 
						|
    proto_hdr->id = CONN_LESS_APP_ID_CONFIG;
 | 
						|
    proto_hdr->port = CONN_LESS_APP_PORT;
 | 
						|
 | 
						|
    ptr += sizeof(proto_conn_less_hdr_t);
 | 
						|
    meter = (proto_conn_less_mr_t *)ptr;
 | 
						|
    meter->data_len = len;
 | 
						|
    meter->mr_timeout = IOT_DEV_TEST_CFG_MR_TIMEOUT;
 | 
						|
 | 
						|
    meter->seq = sn;
 | 
						|
    meter->dir = CONN_LESS_APP_DIR_SLAVE;
 | 
						|
    meter->option.dl_ppm_desc.value = 0;
 | 
						|
    meter->data_type = GW_APP_DATA_TYPE_645_2007;
 | 
						|
    meter->retry_cnt = 0;
 | 
						|
    os_mem_cpy(meter->data, data, len);
 | 
						|
 | 
						|
    iot_cus_printf("app conn_less send to[%02x:%02x:%02x:%02x:%02x:%02x]"
 | 
						|
        ", sn %lu, len %lu, fix ppm %d\n", dst[0], dst[1],
 | 
						|
        dst[2], dst[3], dst[4], dst[5], sn, buflen, fix_ppm);
 | 
						|
    iot_plc_send_msdu(dev_test_task_data->app_handle, msdu_pkt);
 | 
						|
 | 
						|
    return ERR_OK;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * @brief: creat a rsponse frame based on 645 protocal.
 | 
						|
 * @param  rsp_fn:  response Fn code
 | 
						|
 * @param  data:    pointer to data that fullfiled into the frame's data field
 | 
						|
 * @param  len:     data lenth that fullfiled into the frame's data field
 | 
						|
 * @retval: 0      --   success
 | 
						|
 * @retval: others --   failed
 | 
						|
 */
 | 
						|
static uint8_t iot_dev_test_form_rsp_data_frame(uint8_t rsp_fn, uint8_t *data,
 | 
						|
    uint8_t len)
 | 
						|
{
 | 
						|
    iot_pkt_t *pkt = NULL;
 | 
						|
    proto_645_header_t *hdr_645;
 | 
						|
    proto_645_tailer_t *tail_645;
 | 
						|
    uint8_t pkt_len;
 | 
						|
    uint8_t *ptr = NULL;
 | 
						|
    uint8_t ret = ERR_OK;
 | 
						|
 | 
						|
    pkt_len = IOT_DEV_TEST_RSP_FRAME_LEN_MIN + len;
 | 
						|
    pkt = iot_pkt_alloc(pkt_len, IOT_APP_DEV_TEST_MID);
 | 
						|
    if (pkt != NULL) {
 | 
						|
        ptr = iot_pkt_data(pkt);
 | 
						|
        hdr_645 = (proto_645_header_t *)ptr;
 | 
						|
 | 
						|
        hdr_645->start_char_1 = PROTO_645_START_CHAR;
 | 
						|
        iot_mac_addr_cpy(hdr_645->addr, spec_mac);
 | 
						|
        iot_mac_addr_reverse(hdr_645->addr);
 | 
						|
        hdr_645->len = len;
 | 
						|
        hdr_645->control.fn  = rsp_fn;
 | 
						|
        hdr_645->control.dir = PROTO_645_DIR_SLAVE;
 | 
						|
        hdr_645->control.ack = PROTO_645_ACK_NORMAL;
 | 
						|
        hdr_645->control.follow = PROTO_645_FOLLOW_INVALID;
 | 
						|
        hdr_645->start_char_2 = PROTO_645_START_CHAR;
 | 
						|
        os_mem_cpy(hdr_645->data, data, len);
 | 
						|
        proto_645_add33_handle(hdr_645->data, len);
 | 
						|
        ptr += sizeof(proto_645_header_t) + len;
 | 
						|
        tail_645 = (proto_645_tailer_t *)ptr;
 | 
						|
        tail_645->cs = proto_645_calc_cs(hdr_645);
 | 
						|
        tail_645->end_char = PROTO_645_END_CHAR;
 | 
						|
        iot_pkt_put (pkt, (sizeof(*hdr_645) + len + sizeof(*tail_645)));
 | 
						|
        iot_dev_test_uart_send(pkt);
 | 
						|
    } else {
 | 
						|
        iot_cus_printf("%s: alloc pkt failed!\n", __FUNCTION__);
 | 
						|
        ret = ERR_FAIL;
 | 
						|
    }
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * @brief: creat a confirm frame based on 645 protocal.
 | 
						|
 * @param  result:  0-no error, 1-error
 | 
						|
 * @param  reason:  error reason
 | 
						|
 * @param  len:     data lenth that fullfiled into the frame's data field
 | 
						|
 * @retval: 0   --   success
 | 
						|
 * @retval: others  --   failed
 | 
						|
 */
 | 
						|
static uint8_t iot_dev_test_form_rsp_cfm_frame(uint8_t fn, uint8_t result,
 | 
						|
    uint8_t reason)
 | 
						|
{
 | 
						|
    iot_pkt_t *pkt = NULL;
 | 
						|
    proto_645_header_t *hdr_645;
 | 
						|
    proto_645_tailer_t *tail_645;
 | 
						|
    uint8_t pkt_len;
 | 
						|
    uint8_t *ptr = NULL;
 | 
						|
    uint8_t ret = ERR_OK;
 | 
						|
 | 
						|
    if (result != 0) {
 | 
						|
        pkt_len = IOT_DEV_TEST_RSP_FRAME_LEN_MIN + 1;
 | 
						|
    } else {
 | 
						|
        pkt_len = IOT_DEV_TEST_RSP_FRAME_LEN_MIN;
 | 
						|
    }
 | 
						|
 | 
						|
    pkt = iot_pkt_alloc(pkt_len, IOT_APP_DEV_TEST_MID);
 | 
						|
    if (pkt != NULL) {
 | 
						|
        ptr = iot_pkt_data(pkt);
 | 
						|
        hdr_645 = (proto_645_header_t *)ptr;
 | 
						|
        hdr_645->control.fn  = fn;
 | 
						|
        hdr_645->start_char_1 = PROTO_645_START_CHAR;
 | 
						|
        iot_mac_addr_cpy(hdr_645->addr, spec_mac);
 | 
						|
        iot_mac_addr_reverse(hdr_645->addr);
 | 
						|
        hdr_645->control.dir = PROTO_645_DIR_SLAVE;
 | 
						|
        hdr_645->control.follow = PROTO_645_FOLLOW_INVALID;
 | 
						|
        hdr_645->start_char_2 = PROTO_645_START_CHAR;
 | 
						|
 | 
						|
        if (result == 0) {
 | 
						|
            /* ack normal */
 | 
						|
            hdr_645->len = 0;
 | 
						|
            hdr_645->control.ack = PROTO_645_ACK_NORMAL;
 | 
						|
        } else {
 | 
						|
            hdr_645->len = 1;
 | 
						|
            hdr_645->control.ack = PROTO_645_ACK_ABNORMAL;
 | 
						|
            hdr_645->data[0] = reason + 0x33;
 | 
						|
        }
 | 
						|
 | 
						|
        ptr += sizeof(proto_645_header_t) + hdr_645->len;
 | 
						|
        tail_645 = (proto_645_tailer_t *)ptr;
 | 
						|
        tail_645->cs = proto_645_calc_cs(hdr_645);
 | 
						|
        tail_645->end_char = PROTO_645_END_CHAR;
 | 
						|
        iot_pkt_put (pkt, (sizeof(*hdr_645) + hdr_645->len +
 | 
						|
            sizeof(*tail_645)));
 | 
						|
        iot_dev_test_data_print("SEND_UART frame:", iot_pkt_data(pkt),
 | 
						|
            (uint16_t)iot_pkt_data_len(pkt));
 | 
						|
 | 
						|
        iot_cus_printf("SEND_UART_CMD_RSP frame: fn 0x%02x, result 0x%02x\n",
 | 
						|
            fn, result);
 | 
						|
 | 
						|
        iot_dev_test_uart_send(pkt);
 | 
						|
    } else {
 | 
						|
        iot_cus_printf("%s: alloc pkt failed!\n", __FUNCTION__);
 | 
						|
        ret = ERR_FAIL;
 | 
						|
    }
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * @brief: set frequnce band
 | 
						|
 * @param  bandid:  band index
 | 
						|
 */
 | 
						|
static void iot_dev_test_set_band(uint8_t bandid)
 | 
						|
{
 | 
						|
    if (bandid > IOT_DEV_TEST_MAX_BAND) {
 | 
						|
        iot_dev_test_form_rsp_cfm_frame(IOT_DEV_TEST_FN_SET_BAND,
 | 
						|
            IOT_DEV_TEST_RSP_ERR, IOT_DEV_TEST_REASON_OUT_RNG);
 | 
						|
        iot_cus_printf("%s [err]band setting out of range\n", __FUNCTION__);
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    if (dev_test_task_data->band_id == bandid) {
 | 
						|
        iot_dev_test_form_rsp_cfm_frame(IOT_DEV_TEST_FN_SET_BAND,
 | 
						|
            IOT_DEV_TEST_RSP_ERR, IOT_DEV_TEST_REASON_DUP_SET);
 | 
						|
        iot_cus_printf("%s [err]Already in band-%lu\n", __FUNCTION__, bandid);
 | 
						|
        return;
 | 
						|
    }
 | 
						|
    dev_test_task_data->band_id = bandid;
 | 
						|
    iot_plc_set_freq_band(dev_test_task_data->app_handle,
 | 
						|
        IOT_PLC_API_REQ_ID_DEFAULT, bandid);
 | 
						|
    iot_printf("%s set freq-band to band-%lu ok\n",__FUNCTION__, bandid);
 | 
						|
    iot_dev_test_form_rsp_cfm_frame(IOT_DEV_TEST_FN_SET_BAND,
 | 
						|
        IOT_DEV_TEST_RSP_OK, IOT_DEV_TEST_REASON_OK);
 | 
						|
}
 | 
						|
 | 
						|
/* get the band's ID and creat a respons frame then send to mointor */
 | 
						|
static void iot_dev_test_querry_band_handle(void)
 | 
						|
{
 | 
						|
    uint8_t rsp_data[IOT_DEV_TEST_DATA_FIELD_LEN] = { 0 };
 | 
						|
    rsp_data[0] = dev_test_task_data->band_id;
 | 
						|
    iot_cus_printf("%s rsponse band id: %lu\n", __FUNCTION__, rsp_data[0]);
 | 
						|
    iot_dev_test_form_rsp_data_frame(IOT_DEV_TEST_FN_QUERRY_BAND_RSP,
 | 
						|
        rsp_data, IOT_DEV_TEST_DATA_FIELD_LEN);
 | 
						|
}
 | 
						|
 | 
						|
/* get the software version and creat a respons frame then send  to mointor */
 | 
						|
static void iot_dev_test_querry_ver_handle(void)
 | 
						|
{
 | 
						|
    uint32_t ver = 0;
 | 
						|
    uint8_t rsp_data[IOT_DEV_TEST_DATA_FIELD_LEN] = { 0 };
 | 
						|
    ver = iot_version_hex();
 | 
						|
    rsp_data[0] = ver & 0xFF;
 | 
						|
    rsp_data[1] = (ver >> 8) & 0xFF;
 | 
						|
    rsp_data[2] = (ver >> 16) & 0xFF;
 | 
						|
    rsp_data[3] = (ver >> 24) & 0xFF;
 | 
						|
    iot_cus_printf("%s software verison: 0x%x\n", __FUNCTION__, ver);
 | 
						|
    iot_dev_test_form_rsp_data_frame(IOT_DEV_TEST_FN_QUERRY_VER_RSP,
 | 
						|
        rsp_data, IOT_DEV_TEST_DATA_FIELD_LEN);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * @brief: set mac address
 | 
						|
 * @param  mac:  pointer to mac address which will be set
 | 
						|
 */
 | 
						|
static void iot_dev_test_set_mac(uint8_t *mac)
 | 
						|
{
 | 
						|
    iot_plc_cfg_set_req_t cfg;
 | 
						|
    iot_plc_app_h app_hdl = dev_test_task_data->app_handle;
 | 
						|
 | 
						|
    if (!iot_mac_addr_valid(mac) || iot_mac_is_bcast(mac)) {
 | 
						|
        iot_dev_test_form_rsp_cfm_frame(IOT_DEV_TEST_FN_SET_MAC,
 | 
						|
            IOT_DEV_TEST_RSP_ERR, IOT_DEV_TEST_REASON_MAC_INVALID);
 | 
						|
        iot_cus_printf("%s [err]mac invalid, all zero or boardcast mac will "
 | 
						|
            "not be set!\n", __FUNCTION__);
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    if (iot_mac_addr_cmp(dev_test_task_data->mac_addr, mac))
 | 
						|
    {
 | 
						|
        iot_dev_test_form_rsp_cfm_frame(IOT_DEV_TEST_FN_SET_MAC,
 | 
						|
            IOT_DEV_TEST_RSP_ERR, IOT_DEV_TEST_REASON_DUP_SET);
 | 
						|
        iot_cus_printf("%s [err]new mac is same as the using one\n",
 | 
						|
            __FUNCTION__);
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    os_mem_set(&cfg, 0, sizeof(cfg));
 | 
						|
    cfg.addr_valid = 1;
 | 
						|
    cfg.addr_type = IOT_PLC_MAC_ADDR_TYPE_METER;
 | 
						|
    iot_mac_addr_cpy(cfg.addr, mac);
 | 
						|
    cfg.reset = 1;
 | 
						|
    cfg.dev_type_valid = 1;
 | 
						|
    cfg.dev_type = IOT_PLC_DEV_TYPE_METER_CONTROLLER;
 | 
						|
    iot_plc_set_cfg(app_hdl, IOT_PLC_API_REQ_ID_DEFAULT, &cfg);
 | 
						|
 | 
						|
    iot_printf("%s set mac to [%02x:%02x:%02x:%02x:%02x:%02x] successfully\n",
 | 
						|
        __FUNCTION__, mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);
 | 
						|
    dev_test_task_data->m2m_check_addr = IOT_DEV_TEST_ADDR_SET;
 | 
						|
    iot_dev_test_form_rsp_cfm_frame(IOT_DEV_TEST_FN_SET_MAC,
 | 
						|
        IOT_DEV_TEST_RSP_OK, IOT_DEV_TEST_REASON_OK);
 | 
						|
}
 | 
						|
 | 
						|
/* get the local mac address and creat a respons frame then send to mointor */
 | 
						|
static void iot_dev_test_querry_mac_handle(void)
 | 
						|
{
 | 
						|
    uint8_t rsp_data[IOT_DEV_TEST_DATA_FIELD_LEN + 2] = { 0 };
 | 
						|
    iot_mac_addr_cpy(rsp_data, dev_test_task_data->mac_addr);
 | 
						|
    iot_cus_printf("%s rsponse local mac:[%02x:%02x:%02x:%02x:%02x:%02x]\n",
 | 
						|
        __FUNCTION__, rsp_data[0], rsp_data[1], rsp_data[2], rsp_data[3],
 | 
						|
        rsp_data[4], rsp_data[5]);
 | 
						|
    iot_mac_addr_reverse (rsp_data);
 | 
						|
    iot_dev_test_form_rsp_data_frame(IOT_DEV_TEST_FN_QUERRY_MAC_RSP,
 | 
						|
        rsp_data, IOT_DEV_TEST_DATA_FIELD_LEN + 2);
 | 
						|
}
 | 
						|
 | 
						|
/* set dev test op mode and creat a respons frame then send to mointor */
 | 
						|
static void iot_dev_test_set_op_mode(uint8_t op_mode)
 | 
						|
{
 | 
						|
    if (op_mode >= IOT_DEV_TEST_APP_MODE_MAX) {
 | 
						|
        iot_dev_test_form_rsp_cfm_frame(IOT_DEV_TEST_FN_SET_OP_MODE,
 | 
						|
            IOT_DEV_TEST_RSP_ERR, IOT_DEV_TEST_REASON_OUT_RNG);
 | 
						|
        iot_cus_printf("%s [err]invalid op mode\n", __FUNCTION__);
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    if (dev_test_task_data->dev_mode == op_mode) {
 | 
						|
        iot_dev_test_form_rsp_cfm_frame(IOT_DEV_TEST_FN_SET_OP_MODE,
 | 
						|
            IOT_DEV_TEST_RSP_ERR, IOT_DEV_TEST_REASON_DUP_SET);
 | 
						|
        iot_cus_printf("%s [err]new op mode is same as the using one\n",
 | 
						|
            __FUNCTION__);
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    dev_test_task_data->dev_mode = op_mode;
 | 
						|
    iot_dev_test_form_rsp_cfm_frame(IOT_DEV_TEST_FN_SET_OP_MODE,
 | 
						|
        IOT_DEV_TEST_RSP_OK, IOT_DEV_TEST_REASON_OK);
 | 
						|
}
 | 
						|
 | 
						|
/* query CKQ current operation mode */
 | 
						|
static void iot_dev_test_query_op_mode()
 | 
						|
{
 | 
						|
    uint8_t rsp_data[IOT_DEV_TEST_DATA_FIELD_LEN] = { 0 };
 | 
						|
    /* rsp_data is a 4-byte array, refer to 645 frame format */
 | 
						|
    rsp_data[0] = dev_test_task_data->dev_mode;
 | 
						|
    iot_dev_test_form_rsp_data_frame(IOT_DEV_TEST_FN_QUERY_OP_MODE_RSP,
 | 
						|
        rsp_data, IOT_DEV_TEST_DATA_FIELD_LEN);
 | 
						|
}
 | 
						|
 | 
						|
/* set the compensation ppm value, */
 | 
						|
static uint32_t proto_handle_645_set_tool_ppm(uint8_t *in_data,
 | 
						|
    uint8_t in_len, uint8_t* out_buf, uint8_t *out_len)
 | 
						|
{
 | 
						|
    iot_dev_test_pib_t *pib = &dev_test_task_data->flashinfo;
 | 
						|
    int8_t tool_ppm;
 | 
						|
    uint8_t *ptr = NULL;
 | 
						|
    uint32_t di = PROTO_645_2007_EXT_WRITE_TOOL_PPM;
 | 
						|
 | 
						|
    ptr =  in_data + PROTO_645_2007_DI_LEN;
 | 
						|
    tool_ppm = (int8_t)*ptr;
 | 
						|
    if (IOT_ABS(tool_ppm) > IOT_DEV_TEST_MAX_TOOL_PPM) {
 | 
						|
        iot_cus_printf("%s invalid tool_ppm %d\n", __FUNCTION__, tool_ppm);
 | 
						|
        return PROTO_645_2007_ERR_OTHER;
 | 
						|
    }
 | 
						|
 | 
						|
    if ((tool_ppm != pib->tool_ppm) || !pib->tool_ppm_valid) {
 | 
						|
        pib->tool_ppm = tool_ppm;
 | 
						|
        pib->tool_ppm_valid = 1;
 | 
						|
        iot_dev_test_flash_save(pib);
 | 
						|
        iot_cus_printf("tool ppm %d saved into PIB\n", tool_ppm);
 | 
						|
    } else {
 | 
						|
        iot_cus_printf("Duplicated ppm %d setting, skip saving\n", tool_ppm);
 | 
						|
 | 
						|
    }
 | 
						|
 | 
						|
    proto_645_2007_di_to_byte(di, out_buf);
 | 
						|
    *out_len = PROTO_645_2007_DI_LEN;
 | 
						|
 | 
						|
    return PROTO_645_2007_ERR_OK;
 | 
						|
}
 | 
						|
 | 
						|
static uint32_t proto_handle_645_read_pt_info(uint8_t *in_data,
 | 
						|
    uint8_t in_len, uint8_t* out_buf, uint8_t *out_len)
 | 
						|
{
 | 
						|
    proto_645_ext_read_pt_info_rsp_t *rsp_info = NULL;
 | 
						|
    iot_dev_test_pib_t *pib = &dev_test_task_data->flashinfo;
 | 
						|
    iot_dev_test_ppm_detec_desc_t *ppm_desc = &dev_test_task_data->ppm_desc;
 | 
						|
    iot_board_pt_info_t pt_info = {0};
 | 
						|
 | 
						|
    iot_board_get_pt_info(&pt_info);
 | 
						|
 | 
						|
    rsp_info = (proto_645_ext_read_pt_info_rsp_t *)(out_buf);
 | 
						|
    os_mem_set(rsp_info, 0, sizeof(*rsp_info));
 | 
						|
 | 
						|
    /* production test ppm */
 | 
						|
    if (pt_info.ppm_valid) {
 | 
						|
        rsp_info->local_pt_ppm_valid = 1;
 | 
						|
        rsp_info->local_pt_ppm = pt_info.ppm;
 | 
						|
    }
 | 
						|
    /* compensation ppm, configured by the tool */
 | 
						|
    if (pib->tool_ppm_valid) {
 | 
						|
        rsp_info->local_tool_ppm_valid = 1;
 | 
						|
        rsp_info->local_tool_ppm = pib->tool_ppm;
 | 
						|
    }
 | 
						|
    /* basic production test info */
 | 
						|
    if (pt_info.basic_info_valid) {
 | 
						|
        rsp_info->basic_data_valid = 1;
 | 
						|
        iot_mac_addr_cpy(rsp_info->basic_data.golden_mac,
 | 
						|
            pt_info.basic_info.golden_mac);
 | 
						|
        rsp_info->basic_data.year = pt_info.basic_info.year;
 | 
						|
        rsp_info->basic_data.month = pt_info.basic_info.month;
 | 
						|
        rsp_info->basic_data.day = pt_info.basic_info.day;
 | 
						|
        rsp_info->basic_data.hour = pt_info.basic_info.hour;
 | 
						|
        rsp_info->basic_data.min = pt_info.basic_info.min;
 | 
						|
        rsp_info->basic_data.golden_fw_ver = pt_info.basic_info.golden_fw_ver;
 | 
						|
        rsp_info->basic_data.pt_tool_ver = pt_info.basic_info.pt_tool_ver;
 | 
						|
        rsp_info->basic_data.pt_board_ver = pt_info.basic_info.pt_board_ver;
 | 
						|
    }
 | 
						|
    /* the dut firmware version, which supported the production test */
 | 
						|
    if (pt_info.pt_dut_ver_valid) {
 | 
						|
        rsp_info->pt_dut_fw_valid = 1;
 | 
						|
        rsp_info->pt_dut_fw_ver = pt_info.pt_dut_ver;
 | 
						|
    }
 | 
						|
    /* fix ppm */
 | 
						|
    rsp_info->local_fix_ppm = ppm_desc->fix_ppm;
 | 
						|
    rsp_info->local_fix_ppm_valid = 1;
 | 
						|
 | 
						|
    *out_len = sizeof(*rsp_info);
 | 
						|
 | 
						|
    return PROTO_645_2007_ERR_OK;
 | 
						|
}
 | 
						|
 | 
						|
 static iot_pkt_t *iot_dev_test_config_cmd_handle(proto_645_header_t *hdr)
 | 
						|
{
 | 
						|
    uint8_t fn, err_code = 0;
 | 
						|
    uint32_t len;
 | 
						|
    uint8_t out_len;
 | 
						|
    iot_pkt_t *pkt_645 = NULL;
 | 
						|
    uint32_t pkt_len, di;
 | 
						|
    uint8_t *out_ds, *out_buf;
 | 
						|
    uint8_t follow = PROTO_645_FOLLOW_INVALID;
 | 
						|
    uint8_t addr[IOT_MAC_ADDR_LEN] = {0};
 | 
						|
 | 
						|
    if (!hdr ) {
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
    proto_645_get_di_by_sub33(hdr->data, PROTO_645_2007_DI_LEN,
 | 
						|
        PROTO_645_2007_ID, &di);
 | 
						|
    proto_645_sub33_handle(hdr->data, hdr->len);
 | 
						|
    pkt_len = PROTO_645_READ_DATA_MAX_LEN + sizeof(hdr)
 | 
						|
        + sizeof(proto_645_tailer_t);
 | 
						|
    pkt_645 = iot_pkt_alloc(pkt_len, IOT_APP_DEV_TEST_MID);
 | 
						|
    out_ds = iot_pkt_data(pkt_645);
 | 
						|
    os_mem_set(dev_test_task_data->data_buf, 0, IOT_DEV_TEST_DATA_BUFF_LEN);
 | 
						|
    out_buf = dev_test_task_data->data_buf;
 | 
						|
    out_len = IOT_DEV_TEST_DATA_BUFF_LEN;
 | 
						|
    fn = hdr->control.fn;
 | 
						|
    iot_mac_addr_cpy(addr, hdr->addr);
 | 
						|
 | 
						|
    switch (fn) {
 | 
						|
    case PROTO_645_2007_FN_READ_DATA:
 | 
						|
    {
 | 
						|
        switch (di) {
 | 
						|
        case PROTO_645_2007_EXT_QUERY_PT_INFO:
 | 
						|
        {
 | 
						|
            err_code = proto_handle_645_read_pt_info(hdr->data,
 | 
						|
                hdr->len, out_buf, &out_len);
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        default:
 | 
						|
            err_code = PROTO_645_2007_ERR_NO_REQ_DATA;
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case PROTO_645_2007_FN_WRITE_DATA:
 | 
						|
    {
 | 
						|
        switch (di) {
 | 
						|
        case PROTO_645_2007_EXT_WRITE_TOOL_PPM:
 | 
						|
        {
 | 
						|
            err_code = proto_handle_645_set_tool_ppm(hdr->data,
 | 
						|
                hdr->len, out_buf, &out_len);
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        default:
 | 
						|
            err_code = PROTO_645_2007_ERR_NO_REQ_DATA;
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    default:
 | 
						|
        err_code = PROTO_645_2007_ERR_NO_REQ_DATA;
 | 
						|
        break;
 | 
						|
    }
 | 
						|
 | 
						|
    if (err_code) {
 | 
						|
        len = proto_645_fill_frame(out_ds, PROTO_645_2007_ID,
 | 
						|
            addr, PROTO_645_DIR_SLAVE, PROTO_645_ACK_ABNORMAL,
 | 
						|
            follow, fn, PROTO_645_INVALID_DI, 1, &err_code);
 | 
						|
    } else {
 | 
						|
        iot_cus_printf("di 0x%04x, out len %d\n", di, out_len);
 | 
						|
        len = proto_645_fill_frame(out_ds, PROTO_645_2007_ID,
 | 
						|
            addr, PROTO_645_DIR_SLAVE, PROTO_645_ACK_NORMAL,
 | 
						|
            follow, fn, di, out_len, out_buf);
 | 
						|
    }
 | 
						|
    iot_pkt_put(pkt_645, len);
 | 
						|
 | 
						|
    iot_dev_test_data_print("uplink 645: ", iot_pkt_data(pkt_645),
 | 
						|
        iot_pkt_data_len(pkt_645));
 | 
						|
out:
 | 
						|
    return pkt_645;
 | 
						|
}
 | 
						|
 | 
						|
/* set UART baudrate */
 | 
						|
static void iot_dev_test_set_baudrate(uint8_t baud_index)
 | 
						|
{
 | 
						|
    iot_dev_test_pib_t *p_info = &dev_test_task_data->flashinfo;
 | 
						|
    iot_uart_h uart_hdl = NULL;
 | 
						|
 | 
						|
    if (baud_index >= SUPPORTED_BAUD_CNT) {
 | 
						|
        iot_dev_test_form_rsp_cfm_frame(IOT_DEV_TEST_FN_SET_UART_BAUDRATE,
 | 
						|
            IOT_DEV_TEST_RSP_ERR, IOT_DEV_TEST_REASON_OUT_RNG);
 | 
						|
        iot_cus_printf("%s [err]invalid input val\n", __FUNCTION__);
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    if (p_info->baud_index == baud_index) {
 | 
						|
        iot_dev_test_form_rsp_cfm_frame(IOT_DEV_TEST_FN_SET_UART_BAUDRATE,
 | 
						|
            IOT_DEV_TEST_RSP_ERR, IOT_DEV_TEST_REASON_DUP_SET);
 | 
						|
        iot_cus_printf("%s [err]new baudrate is same as the using one\n",
 | 
						|
            __FUNCTION__);
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    p_info->baud_index = baud_index;
 | 
						|
    if (iot_dev_test_flash_save(p_info)) {
 | 
						|
        iot_dev_test_form_rsp_cfm_frame(IOT_DEV_TEST_FN_SET_UART_BAUDRATE,
 | 
						|
            IOT_DEV_TEST_RSP_OK, IOT_DEV_TEST_REASON_OK);
 | 
						|
    } else {
 | 
						|
        iot_dev_test_form_rsp_cfm_frame(IOT_DEV_TEST_FN_SET_UART_BAUDRATE,
 | 
						|
            IOT_DEV_TEST_RSP_ERR, IOT_DEV_TEST_REASON_SAVE_ERR);
 | 
						|
    }
 | 
						|
 | 
						|
    os_delay (2000);
 | 
						|
 | 
						|
    iot_dev_test_close_uart(dev_test_task_data->host_com);
 | 
						|
 | 
						|
    os_delay (1000);
 | 
						|
    uart_hdl = iot_dev_test_open_uart(iot_board_get_uart(UART_METER_PORT));
 | 
						|
    if (uart_hdl == NULL) {
 | 
						|
        iot_cus_printf("open uart meter port failed!\n");
 | 
						|
    } else {
 | 
						|
        if (iot_dev_test_set_uart_config(uart_hdl)) {
 | 
						|
            iot_cus_printf("open uart meter port successfully!\n");
 | 
						|
        }
 | 
						|
    }
 | 
						|
    dev_test_task_data->host_com = uart_hdl;
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
/* query UART baudrate */
 | 
						|
static void iot_dev_test_query_baudrate()
 | 
						|
{
 | 
						|
    uint8_t rsp_data[IOT_DEV_TEST_DATA_FIELD_LEN] = { 0 };
 | 
						|
    /* rsp_data is a 4-byte array, refer to 645 frame format */
 | 
						|
    rsp_data[0] = dev_test_task_data->flashinfo.baud_index;
 | 
						|
    iot_dev_test_form_rsp_data_frame(IOT_DEV_TEST_FN_QUERY_BAUD_RSP,
 | 
						|
        rsp_data, IOT_DEV_TEST_DATA_FIELD_LEN);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * @brief: set rf
 | 
						|
 * @param rf_option:  rf option
 | 
						|
 * @param rf_channel:  rf channel
 | 
						|
 * @param need_rsp:  if need to response
 | 
						|
 */
 | 
						|
static void iot_dev_test_set_rf(uint8_t rf_option, uint8_t rf_channel,
 | 
						|
    uint8_t need_rsp)
 | 
						|
{
 | 
						|
    uint8_t rf_valid = 0;
 | 
						|
 | 
						|
    if (rf_option == IOT_PLC_RF_OPTION_1) {
 | 
						|
        rf_valid = (rf_channel < IOT_PLC_OPTION1_CHANNEL_ID_MAX);
 | 
						|
    } else if (rf_option == IOT_PLC_RF_OPTION_2) {
 | 
						|
        rf_valid = (rf_channel < IOT_PLC_OPTION2_CHANNEL_ID_MAX);
 | 
						|
    } else if (rf_option == IOT_PLC_RF_OPTION_3) {
 | 
						|
        rf_valid = (rf_channel < IOT_PLC_OPTION3_CHANNEL_ID_MAX);
 | 
						|
    }
 | 
						|
 | 
						|
    if (!rf_valid) {
 | 
						|
        iot_dev_test_form_rsp_cfm_frame(IOT_DEV_TEST_FN_SET_RF,
 | 
						|
            IOT_DEV_TEST_RSP_ERR, IOT_DEV_TEST_REASON_OUT_RNG);
 | 
						|
        iot_cus_printf("%s [err]rf setting out of range\n", __FUNCTION__);
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    if (dev_test_task_data->ext_cfg.rf_valid &&
 | 
						|
        dev_test_task_data->ext_cfg.rf_option == rf_option &&
 | 
						|
        dev_test_task_data->ext_cfg.rf_channel == rf_channel) {
 | 
						|
        iot_dev_test_form_rsp_cfm_frame(IOT_DEV_TEST_FN_SET_RF,
 | 
						|
            IOT_DEV_TEST_RSP_OK, IOT_DEV_TEST_REASON_DUP_SET);
 | 
						|
        iot_cus_printf("%s already in option-%lu channel-%lu\n",
 | 
						|
            __FUNCTION__, rf_option, rf_channel);
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    dev_test_task_data->ext_cfg.rf_valid = 1;
 | 
						|
    dev_test_task_data->ext_cfg.rf_option = rf_option;
 | 
						|
    dev_test_task_data->ext_cfg.rf_channel = rf_channel;
 | 
						|
    iot_plc_set_rf_channel(dev_test_task_data->app_handle,
 | 
						|
        IOT_PLC_API_REQ_ID_DEFAULT, rf_option, rf_channel, 0);
 | 
						|
    iot_printf("%s set option to %lu channel to %lu ok\n", __FUNCTION__,
 | 
						|
        rf_option, rf_channel);
 | 
						|
    if (need_rsp) {
 | 
						|
        iot_dev_test_form_rsp_cfm_frame(IOT_DEV_TEST_FN_SET_RF,
 | 
						|
            IOT_DEV_TEST_RSP_OK, IOT_DEV_TEST_REASON_OK);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * @brief: set rf tx power
 | 
						|
 * @param rf_power:  rf tx power
 | 
						|
 */
 | 
						|
static void iot_dev_test_set_rf_tx_power(int8_t rf_power)
 | 
						|
{
 | 
						|
    if (!(rf_power >= IOT_PLC_RF_TX_POWER_MIN_DBM &&
 | 
						|
        rf_power <= IOT_PLC_RF_TX_POWER_MAX_DBM)) {
 | 
						|
        iot_dev_test_form_rsp_cfm_frame(IOT_DEV_TEST_FN_SET_RF_TX_POWER,
 | 
						|
            IOT_DEV_TEST_RSP_ERR, IOT_DEV_TEST_REASON_OUT_RNG);
 | 
						|
        iot_cus_printf("%s [err]rf tx power setting out of range\n",
 | 
						|
            __FUNCTION__);
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    if (dev_test_task_data->ext_cfg.rf_power_valid &&
 | 
						|
        dev_test_task_data->ext_cfg.rf_tx_power == rf_power) {
 | 
						|
        iot_dev_test_form_rsp_cfm_frame(IOT_DEV_TEST_FN_SET_RF_TX_POWER,
 | 
						|
            IOT_DEV_TEST_RSP_OK, IOT_DEV_TEST_REASON_DUP_SET);
 | 
						|
        iot_cus_printf("%s already in rf tx power-%d\n", __FUNCTION__,
 | 
						|
            rf_power);
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    dev_test_task_data->ext_cfg.rf_power_valid = 1;
 | 
						|
    dev_test_task_data->ext_cfg.rf_tx_power = rf_power;
 | 
						|
    iot_plc_set_tx_power_cap(dev_test_task_data->app_handle,
 | 
						|
        IOT_PLC_API_REQ_ID_DEFAULT, NULL,
 | 
						|
        &dev_test_task_data->ext_cfg.rf_tx_power);
 | 
						|
    iot_printf("%s set to rf tx power: %d ok\n", __FUNCTION__, rf_power);
 | 
						|
    iot_dev_test_form_rsp_cfm_frame(IOT_DEV_TEST_FN_SET_RF_TX_POWER,
 | 
						|
        IOT_DEV_TEST_RSP_OK, IOT_DEV_TEST_REASON_OK);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * @brief: set hplc tx power
 | 
						|
 * @param hplc_power:  hplc tx power
 | 
						|
 */
 | 
						|
static void iot_dev_test_set_hplc_tx_power(uint8_t hplc_power)
 | 
						|
{
 | 
						|
    if (!(hplc_power >= IOT_PLC_HPLC_TX_POWER_MIN_DBUV &&
 | 
						|
        hplc_power <= IOT_PLC_HPLC_TX_POWER_MAX_DBUV)) {
 | 
						|
        iot_dev_test_form_rsp_cfm_frame(IOT_DEV_TEST_FN_SET_HPLC_TX_POWER,
 | 
						|
            IOT_DEV_TEST_RSP_ERR, IOT_DEV_TEST_REASON_OUT_RNG);
 | 
						|
        iot_cus_printf("%s [err]hplc tx power setting out of range\n",
 | 
						|
            __FUNCTION__);
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    if (dev_test_task_data->ext_cfg.hplc_power_valid &&
 | 
						|
        dev_test_task_data->ext_cfg.hplc_tx_power == hplc_power) {
 | 
						|
        iot_dev_test_form_rsp_cfm_frame(IOT_DEV_TEST_FN_SET_HPLC_TX_POWER,
 | 
						|
            IOT_DEV_TEST_RSP_OK, IOT_DEV_TEST_REASON_DUP_SET);
 | 
						|
        iot_cus_printf("%s already in hplc tx power-%lu\n", __FUNCTION__,
 | 
						|
            hplc_power);
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    dev_test_task_data->ext_cfg.hplc_power_valid = 1;
 | 
						|
    dev_test_task_data->ext_cfg.hplc_tx_power = hplc_power;
 | 
						|
    iot_plc_set_tx_power_cap(dev_test_task_data->app_handle,
 | 
						|
        IOT_PLC_API_REQ_ID_DEFAULT, &dev_test_task_data->ext_cfg.hplc_tx_power,
 | 
						|
        NULL);
 | 
						|
    iot_printf("%s set to hplc tx power: %lu ok\n", __FUNCTION__, hplc_power);
 | 
						|
    iot_dev_test_form_rsp_cfm_frame(IOT_DEV_TEST_FN_SET_HPLC_TX_POWER,
 | 
						|
        IOT_DEV_TEST_RSP_OK, IOT_DEV_TEST_REASON_OK);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * @brief: set tx link type
 | 
						|
 * @param link_type: link type, see IOT_DEV_TEST_LINK_TYPE_XXX.
 | 
						|
 * @param need_rsp:  if need to response
 | 
						|
 */
 | 
						|
static void iot_dev_test_set_tx_link_type(uint8_t link_type, uint8_t need_rsp)
 | 
						|
{
 | 
						|
    if (link_type > IOT_PLC_TX_LINK_TYPE_MAX) {
 | 
						|
        iot_dev_test_form_rsp_cfm_frame(IOT_DEV_TEST_FN_SET_TX_LINK_TYPE,
 | 
						|
            IOT_DEV_TEST_RSP_ERR, IOT_DEV_TEST_REASON_OUT_RNG);
 | 
						|
        iot_cus_printf("%s [err]link type setting out of range\n",
 | 
						|
            __FUNCTION__);
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    if ((link_type == IOT_PLC_TX_LINK_TYPE_RF ||
 | 
						|
        link_type == IOT_PLC_TX_LINK_TYPE_DUAL) &&
 | 
						|
        (!dev_test_task_data->ext_cfg.rf_valid ||
 | 
						|
        !dev_test_task_data->ext_cfg_en)) {
 | 
						|
        iot_dev_test_form_rsp_cfm_frame(IOT_DEV_TEST_FN_SET_TX_LINK_TYPE,
 | 
						|
            IOT_DEV_TEST_RSP_ERR, IOT_DEV_TEST_REASON_CFG_INVALID);
 | 
						|
        iot_cus_printf("%s [err]invalid configuration for link type setting\n",
 | 
						|
            __FUNCTION__);
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    dev_test_task_data->tx_link_type = link_type;
 | 
						|
    iot_printf("%s set to link type: %lu ok\n", __FUNCTION__, link_type);
 | 
						|
    if (need_rsp) {
 | 
						|
        iot_dev_test_form_rsp_cfm_frame(IOT_DEV_TEST_FN_SET_TX_LINK_TYPE,
 | 
						|
            IOT_DEV_TEST_RSP_OK, IOT_DEV_TEST_REASON_OK);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static int8_t iot_dev_test_info_buf_find_slot(uint8_t *mac)
 | 
						|
{
 | 
						|
    int8_t index;
 | 
						|
    info_pool_t *pool = &dev_test_task_data->info_pool;
 | 
						|
    uint8_t slot_found = 0;
 | 
						|
    int8_t found_indx = -1;
 | 
						|
    /* rule 1: frames' infor stored in the buffer should have different dst
 | 
						|
     * address, if one frame has same dst address with others, the new one
 | 
						|
     * should replace the old one.
 | 
						|
     * rule 2: if the flag -- send_cnt is 0, that means slot found!
 | 
						|
     */
 | 
						|
    for (index = 0; index < IOT_DEV_TEST_POOL_NUM; index++) {
 | 
						|
        if (pool->frm_info[index].send_cnt != 0) {
 | 
						|
            if (iot_mac_addr_cmp(pool->frm_info[index].frm.dst_mac, mac)) {
 | 
						|
                found_indx = index;
 | 
						|
                iot_cus_printf("duplicated frame found, mac[%02x:%02x:%02x:"
 | 
						|
                    "%02x:%02x:%02x], stored sn %lu!\n", mac[0], mac[1], mac[2],
 | 
						|
                    mac[3], mac[4], mac[5], pool->frm_info[index].frm.app_sn);
 | 
						|
                break;
 | 
						|
            }
 | 
						|
        } else {
 | 
						|
            if (slot_found == 0) {
 | 
						|
                slot_found = 1;
 | 
						|
                found_indx = index;
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    return found_indx;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * @brief: send pkt at M2M mode.
 | 
						|
 * @param  frm_pkt: pkt for fullfil the msdu pkt
 | 
						|
 * @retval: 0      --   success
 | 
						|
 * @retval: others --   failed
 | 
						|
 */
 | 
						|
static uint8_t iot_dev_test_msdu_m2m_send(frame_pkt_t* frm_pkt)
 | 
						|
{
 | 
						|
    uint32_t buflen = 0;
 | 
						|
    uint8_t *ptr = NULL;
 | 
						|
    iot_pkt_t *msdu_pkt;
 | 
						|
    proto_conn_less_hdr_t  *proto_hdr;
 | 
						|
    proto_conn_less_mr_t *meter;
 | 
						|
    uint8_t dst_mac[IOT_MAC_ADDR_LEN] = { 0 };
 | 
						|
 | 
						|
    buflen = sizeof(proto_conn_less_hdr_t) + sizeof(proto_conn_less_mr_t)
 | 
						|
        + iot_pkt_data_len(frm_pkt->data);
 | 
						|
 | 
						|
    if (IOT_DEV_TEST_M2M_SUBMODE_CIU == dev_test_task_data->m2m_sub_mode) {
 | 
						|
        iot_mac_addr_cpy(dst_mac, (uint8_t *)ciu_tester_mac);
 | 
						|
    } else {
 | 
						|
        if (iot_mac_addr_cmp(frm_pkt->dst_mac, proto_645_any_addr)) {
 | 
						|
            iot_set_bcast_mac(dst_mac);
 | 
						|
        } else {
 | 
						|
            iot_mac_addr_cpy(dst_mac, frm_pkt->dst_mac);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    msdu_pkt = iot_plc_alloc_conn_less_msdu_ext(dev_test_task_data->app_handle,
 | 
						|
        IOT_PLC_MSG_TYPE_CONN_LESS_DATA, dst_mac, dev_test_task_data->mac_addr,
 | 
						|
        dev_test_task_data->link_id, (uint16_t)buflen, 0, 0, 0,
 | 
						|
        dev_test_task_data->tx_link_type);
 | 
						|
 | 
						|
    if (msdu_pkt == NULL) {
 | 
						|
        iot_cus_printf("allocate msdu fail\n");
 | 
						|
        return ERR_FAIL;
 | 
						|
    }
 | 
						|
 | 
						|
    ptr = iot_pkt_block_ptr(msdu_pkt, IOT_PKT_BLOCK_TAIL);
 | 
						|
    iot_pkt_put(msdu_pkt, buflen);
 | 
						|
    proto_hdr = (proto_conn_less_hdr_t *)ptr;
 | 
						|
    proto_hdr->id = CONN_LESS_APP_ID_METER_R;
 | 
						|
    proto_hdr->port = CONN_LESS_APP_PORT;
 | 
						|
 | 
						|
    ptr += sizeof(proto_conn_less_hdr_t);
 | 
						|
    meter = (proto_conn_less_mr_t *)ptr;
 | 
						|
    meter->data_len = iot_pkt_data_len(frm_pkt->data);
 | 
						|
    meter->mr_timeout = IOT_DEV_TEST_CFG_MR_TIMEOUT;
 | 
						|
    meter->seq = iot_dev_test_app_get_sn();
 | 
						|
    /* Check the dev operation mode to set DIR */
 | 
						|
    meter->dir = CONN_LESS_APP_DIR_M2M;
 | 
						|
    if (dev_test_task_data->m2m_sub_mode ==IOT_DEV_TEST_M2M_SUBMODE_CIUTESTER) {
 | 
						|
        meter->m2m_switch_mode = IOT_DEV_TEST_M2M_MODE_SWITCH_ENABLE;
 | 
						|
    }
 | 
						|
    meter->option.dl_ppm_desc.value = 0;
 | 
						|
 | 
						|
    if (frm_pkt->data) {
 | 
						|
        ptr = iot_pkt_data(frm_pkt->data);
 | 
						|
        os_mem_cpy(meter->data, ptr, iot_pkt_data_len(frm_pkt->data));
 | 
						|
        iot_pkt_free(frm_pkt->data);
 | 
						|
    }
 | 
						|
 | 
						|
    iot_cus_printf("%s: app conn_less send to[%02x:%02x:%02x:%02x:%02x:%02x],"
 | 
						|
        " len %lu, link_type %lu\n", __FUNCTION__, frm_pkt->dst_mac[0],
 | 
						|
        frm_pkt->dst_mac[1], frm_pkt->dst_mac[2], frm_pkt->dst_mac[3],
 | 
						|
        frm_pkt->dst_mac[4], frm_pkt->dst_mac[5], buflen,
 | 
						|
        dev_test_task_data->tx_link_type);
 | 
						|
    iot_plc_send_msdu(dev_test_task_data->app_handle, msdu_pkt);
 | 
						|
 | 
						|
    return ERR_OK;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * @brief: send pkt at m2s mode.
 | 
						|
 * @param  frm_pkt: pkt for fullfil the msdu pkt
 | 
						|
 * @retval: 0      --   success
 | 
						|
 * @retval: others --   failed
 | 
						|
 */
 | 
						|
static uint8_t iot_dev_test_msdu_m2s_send(frame_pkt_t* frm_pkt)
 | 
						|
{
 | 
						|
    uint32_t buflen = 0;
 | 
						|
    uint8_t *ptr = NULL;
 | 
						|
    iot_pkt_t *msdu_pkt;
 | 
						|
    proto_conn_less_hdr_t  *proto_hdr;
 | 
						|
    proto_conn_less_mr_t *meter;
 | 
						|
    uint8_t *dst_mac = NULL;
 | 
						|
    iot_dev_test_task_data_t *dev_glb = dev_test_task_data;
 | 
						|
    iot_dev_test_ppm_detec_desc_t *ppm_desc = &dev_glb->ppm_desc;
 | 
						|
    int8_t fix_ppm, temp;
 | 
						|
 | 
						|
    if (IOT_DEV_TEST_SUPPORT_CT_MR_EN) {
 | 
						|
        if (0 == dev_glb->collector_vaild) {
 | 
						|
            dst_mac = (uint8_t *)bcast_mac;
 | 
						|
        } else {
 | 
						|
            dst_mac = dev_glb->collector;
 | 
						|
        }
 | 
						|
    } else {
 | 
						|
        dst_mac = frm_pkt->dst_mac;
 | 
						|
    }
 | 
						|
 | 
						|
    buflen = sizeof(proto_conn_less_hdr_t) + sizeof(proto_conn_less_mr_t)
 | 
						|
        + iot_pkt_data_len(frm_pkt->data);
 | 
						|
    if (frm_pkt->ppm_detect) {
 | 
						|
        if (buflen < IOT_DEV_TEST_PPM_DETCT_PKG_LEN) {
 | 
						|
            buflen = IOT_DEV_TEST_PPM_DETCT_PKG_LEN;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    if (frm_pkt->ppm_detect) {
 | 
						|
        temp = ppm_desc->ppm_detect_cnt + 1;
 | 
						|
        fix_ppm = (temp >> 1) * PPM_DETECT_STEP_VALUE;
 | 
						|
        fix_ppm *=  (temp & 0x01 ? 1 : -1);
 | 
						|
        ppm_desc->fix_ppm = fix_ppm;
 | 
						|
        ppm_desc->ppm_detect_cnt++;
 | 
						|
        if (ppm_desc->ppm_detect_cnt >= ((PPM_DETECT_STEP_MAX_CNT * 2) + 1))
 | 
						|
            ppm_desc->ppm_detect_cnt = 0;
 | 
						|
    }
 | 
						|
    fix_ppm = iot_dev_test_get_fix_ppm();
 | 
						|
 | 
						|
    msdu_pkt = iot_plc_alloc_conn_less_msdu_ext(dev_glb->app_handle,
 | 
						|
        IOT_PLC_MSG_TYPE_CONN_LESS_DATA, dst_mac, dev_glb->mac_addr,
 | 
						|
        dev_glb->link_id, (uint16_t)buflen, IOT_PLC_MAX_RETRY_CNT,
 | 
						|
        fix_ppm, 0, dev_glb->tx_link_type);
 | 
						|
 | 
						|
    if (msdu_pkt == NULL) {
 | 
						|
        iot_cus_printf("allocate msdu fail\n");
 | 
						|
        return ERR_FAIL;
 | 
						|
    }
 | 
						|
 | 
						|
    ptr = iot_pkt_block_ptr(msdu_pkt, IOT_PKT_BLOCK_TAIL);
 | 
						|
    iot_pkt_put(msdu_pkt, buflen);
 | 
						|
    proto_hdr = (proto_conn_less_hdr_t *)ptr;
 | 
						|
    proto_hdr->id = CONN_LESS_APP_ID_METER_R;
 | 
						|
    proto_hdr->port = CONN_LESS_APP_PORT;
 | 
						|
 | 
						|
    ptr += sizeof(proto_conn_less_hdr_t);
 | 
						|
    meter = (proto_conn_less_mr_t *)ptr;
 | 
						|
    meter->data_len = iot_pkt_data_len(frm_pkt->data);
 | 
						|
    meter->mr_timeout = IOT_DEV_TEST_CFG_MR_TIMEOUT;
 | 
						|
 | 
						|
    if (!frm_pkt->sn_valid || frm_pkt->ppm_detect) {
 | 
						|
        frm_pkt->app_sn = iot_dev_test_app_get_sn();
 | 
						|
        frm_pkt->sn_valid = 1;
 | 
						|
    }
 | 
						|
 | 
						|
    meter->seq = frm_pkt->app_sn;
 | 
						|
    meter->dir = CONN_LESS_APP_DIR_MASTER;
 | 
						|
    meter->option.dl_ppm_desc.value = 0;
 | 
						|
    meter->data_type = frm_pkt->p_type;
 | 
						|
    meter->retry_cnt = 1;
 | 
						|
 | 
						|
    ptr = iot_pkt_data(frm_pkt->data);
 | 
						|
    os_mem_cpy(meter->data, ptr, iot_pkt_data_len(frm_pkt->data));
 | 
						|
 | 
						|
    if (frm_pkt->ppm_detect) {
 | 
						|
        ppm_desc->ppm_detect_rec[ppm_desc->ppm_detect_rec_idx].sn =
 | 
						|
            frm_pkt->app_sn;
 | 
						|
        ppm_desc->ppm_detect_rec[ppm_desc->ppm_detect_rec_idx].fix_ppm =
 | 
						|
            fix_ppm;
 | 
						|
        ppm_desc->ppm_detect_rec_idx++;
 | 
						|
        if (ppm_desc->ppm_detect_rec_idx >= IOT_DEV_TEST_PPM_DETECT_REC_MAX) {
 | 
						|
            ppm_desc->ppm_detect_rec_idx = 0;
 | 
						|
        }
 | 
						|
        if (ppm_desc->ppm_detect_rec_cnt < IOT_DEV_TEST_PPM_DETECT_REC_MAX)
 | 
						|
            ppm_desc->ppm_detect_rec_cnt++;
 | 
						|
    }
 | 
						|
 | 
						|
    iot_cus_printf("app conn_less send to[%02x:%02x:%02x:%02x:%02x:%02x], sn "
 | 
						|
        "%lu, len %lu, link_type %lu, fix ppm %d\n", frm_pkt->dst_mac[0],
 | 
						|
        frm_pkt->dst_mac[1], frm_pkt->dst_mac[2], frm_pkt->dst_mac[3],
 | 
						|
        frm_pkt->dst_mac[4], frm_pkt->dst_mac[5], frm_pkt->app_sn, buflen,
 | 
						|
        dev_glb->tx_link_type, fix_ppm);
 | 
						|
    iot_plc_send_msdu(dev_glb->app_handle, msdu_pkt);
 | 
						|
 | 
						|
    return ERR_OK;
 | 
						|
}
 | 
						|
 | 
						|
static uint16_t iot_dev_test_app_get_sn(void)
 | 
						|
{
 | 
						|
    dev_test_task_data->app_sn++;
 | 
						|
    if (dev_test_task_data->app_sn == 0) {
 | 
						|
        dev_test_task_data->app_sn = 1;
 | 
						|
    }
 | 
						|
    return dev_test_task_data->app_sn;
 | 
						|
}
 | 
						|
 | 
						|
static void iot_dev_test_fullfill_info_buf(uint8_t index, frame_pkt_t *frm)
 | 
						|
{
 | 
						|
    info_pool_t *pool = &dev_test_task_data->info_pool;
 | 
						|
 | 
						|
    /* if the send_cnt is none-zero, that means, a duplicated frame is
 | 
						|
     * found, the remain_cnt should not be updated.
 | 
						|
     */
 | 
						|
 | 
						|
    if (pool->frm_info[index].send_cnt == 0) {
 | 
						|
        pool->remain_cnt--;
 | 
						|
    }
 | 
						|
    /* if the old data would be replaced by new one, free the pkt first, just in
 | 
						|
     * case of memory leakage.
 | 
						|
     */
 | 
						|
    if (pool->frm_info[index].frm.data) {
 | 
						|
        iot_pkt_free(pool->frm_info[index].frm.data);
 | 
						|
    }
 | 
						|
 | 
						|
    os_mem_set(&pool->frm_info[index], 0, sizeof(frame_info_t));
 | 
						|
    os_mem_cpy(&pool->frm_info[index].frm, frm, sizeof(frame_pkt_t));
 | 
						|
    pool->frm_info[index].send_cnt++;
 | 
						|
}
 | 
						|
 | 
						|
void iot_dev_test_buf_info_del(frame_info_t *frame)
 | 
						|
{
 | 
						|
    info_pool_t *pool = &dev_test_task_data->info_pool;
 | 
						|
    frame_pkt_t *frm = &frame->frm;
 | 
						|
    if (frm->data) {
 | 
						|
       iot_pkt_free(frm->data);
 | 
						|
    }
 | 
						|
    os_mem_set(frame, 0, sizeof(*frame));
 | 
						|
    if (pool->remain_cnt < IOT_DEV_TEST_POOL_NUM) {
 | 
						|
        pool->remain_cnt++;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void iot_dev_tset_buf_info_clean()
 | 
						|
{
 | 
						|
    iot_dev_test_task_data_t *dev_glb = dev_test_task_data;
 | 
						|
    info_pool_t *info_pool = &dev_glb->info_pool;
 | 
						|
    uint8_t i;
 | 
						|
    if (info_pool->remain_cnt == IOT_DEV_TEST_POOL_NUM) {
 | 
						|
        return;
 | 
						|
    }
 | 
						|
    for (i = 0; i < IOT_DEV_TEST_POOL_NUM; i++) {
 | 
						|
         if (iot_mac_addr_valid(info_pool->frm_info[i].frm.dst_mac)) {
 | 
						|
             iot_dev_test_buf_info_del(&info_pool->frm_info[i]);
 | 
						|
         }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * 1. allocate a msdu SN for all frame stored in sending pool.
 | 
						|
 * 2. find slot to cache the frame info in sending pool
 | 
						|
 * 3. copy the frame info into the sending pool.
 | 
						|
 * 4. send the frame data to plc
 | 
						|
 */
 | 
						|
static uint32_t iot_dev_test_msdu_send_handle(frame_pkt_t *frm)
 | 
						|
{
 | 
						|
    int8_t index;
 | 
						|
    uint32_t ret = ERR_OK;
 | 
						|
    if (dev_test_task_data->dev_mode == IOT_DEV_TEST_APP_MODE_M2M) {
 | 
						|
        /* In M2M mode, no retry, so no need app_sn from slot  */
 | 
						|
        if (ERR_OK != iot_dev_test_msdu_m2m_send(frm)) {
 | 
						|
            ret = ERR_FAIL;
 | 
						|
        }
 | 
						|
    } else if (dev_test_task_data->dev_mode == IOT_DEV_TEST_APP_MODE_M2S) {
 | 
						|
        index = iot_dev_test_info_buf_find_slot(frm->dst_mac);
 | 
						|
        if (index >= 0) {
 | 
						|
            iot_dev_test_send_mode_config(frm->dst_mac);// send mode config
 | 
						|
            if (!iot_dev_test_msdu_m2s_send(frm)) {
 | 
						|
                iot_dev_test_fullfill_info_buf(index, frm);
 | 
						|
            }
 | 
						|
        } else {
 | 
						|
            iot_cus_printf("NO buffer slot, frame sent to [%02x:%02x:%02x:%02x:"
 | 
						|
                "%02x:%02x]failed!\n", frm->dst_mac[0], frm->dst_mac[1],
 | 
						|
                frm->dst_mac[2], frm->dst_mac[3], frm->dst_mac[4],
 | 
						|
                frm->dst_mac[5]);
 | 
						|
            ret = ERR_FAIL;
 | 
						|
        }
 | 
						|
    } else {
 | 
						|
        iot_cus_printf("%s: invalid dev_mode[%d]\n", __FUNCTION__,
 | 
						|
            dev_test_task_data->dev_mode);
 | 
						|
        ret = ERR_FAIL;
 | 
						|
    }
 | 
						|
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
static void iot_dev_test_ppm_detect_done_handle(int8_t *fix_ppm)
 | 
						|
{
 | 
						|
    iot_dev_test_pib_t *pib = &dev_test_task_data->flashinfo;
 | 
						|
    iot_dev_test_ppm_detec_desc_t *ppm_desc = &dev_test_task_data->ppm_desc;
 | 
						|
    if (!IOT_DEV_TEST_PPM_DETECT_EN) {
 | 
						|
        return;
 | 
						|
    }
 | 
						|
    ppm_desc->ppm_detect_rec_idx = 0;
 | 
						|
    ppm_desc->ppm_detect_rec_cnt = 0;
 | 
						|
    if (fix_ppm) {
 | 
						|
        ppm_desc->ppm_detect_state = PPM_DETECT_STATE_DONE;
 | 
						|
        ppm_desc->fix_ppm = *fix_ppm;
 | 
						|
        pib->fix_ppm = ppm_desc->fix_ppm;
 | 
						|
        pib->ppm_valid = 1;
 | 
						|
        iot_mac_addr_cpy(pib->ppm_target_mac, ppm_desc->ppm_target_mac);
 | 
						|
        iot_dev_test_flash_save(pib);
 | 
						|
        iot_cus_printf("%s ok, ppm value %d\n", __FUNCTION__,
 | 
						|
            ppm_desc->fix_ppm);
 | 
						|
    } else {
 | 
						|
        ppm_desc->ppm_detect_state = PPM_DETECT_STATE_IDLE;
 | 
						|
        ppm_desc->fix_ppm = 0;
 | 
						|
        iot_cus_printf("%s fail\n", __FUNCTION__);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void iot_dev_test_ppm_detect_restart(void)
 | 
						|
{
 | 
						|
    iot_dev_test_ppm_detec_desc_t *ppm_desc = &dev_test_task_data->ppm_desc;
 | 
						|
 | 
						|
    if ((!IOT_DEV_TEST_PPM_DETECT_EN) ||
 | 
						|
        (PPM_DETECT_STATE_DONE != ppm_desc->ppm_detect_state)){
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    ppm_desc->ppm_detect_state = PPM_DETECT_STATE_IDLE;
 | 
						|
}
 | 
						|
 | 
						|
static void iot_dev_test_ppm_detect_load(uint8_t *addr)
 | 
						|
{
 | 
						|
     iot_dev_test_ppm_detec_desc_t *ppm_desc = &dev_test_task_data->ppm_desc;
 | 
						|
     if (!IOT_DEV_TEST_PPM_DETECT_EN) {
 | 
						|
        return;
 | 
						|
     }
 | 
						|
     if (!iot_mac_addr_cmp(ppm_desc->ppm_target_mac, addr)) {
 | 
						|
        /* if the target address changes, PPM needs to be
 | 
						|
         * detected again.
 | 
						|
         */
 | 
						|
        iot_mac_addr_cpy(ppm_desc->ppm_target_mac, addr);
 | 
						|
        iot_dev_tset_buf_info_clean();
 | 
						|
        ppm_desc->ppm_detect_state = PPM_DETECT_STATE_IDLE;
 | 
						|
        ppm_desc->ppm_detect_rec_idx = 0;
 | 
						|
        ppm_desc->ppm_detect_rec_cnt = 0;
 | 
						|
        ppm_desc->ppm_detect_cnt = 0;
 | 
						|
        ppm_desc->fix_ppm = 0;
 | 
						|
     }
 | 
						|
}
 | 
						|
 | 
						|
static void iot_dev_test_ppm_detect_init(void)
 | 
						|
{
 | 
						|
    iot_dev_test_ppm_detec_desc_t *ppm_desc = &dev_test_task_data->ppm_desc;
 | 
						|
    iot_dev_test_pib_t *pib = &dev_test_task_data->flashinfo;
 | 
						|
    os_mem_set(ppm_desc, 0x0, sizeof(*ppm_desc));
 | 
						|
    if (!IOT_DEV_TEST_PPM_DETECT_EN) {
 | 
						|
        ppm_desc->ppm_detect_state = PPM_DETECT_STATE_DONE;
 | 
						|
        ppm_desc->fix_ppm = 0;
 | 
						|
    } else if (pib->ppm_valid) {
 | 
						|
        ppm_desc->ppm_detect_state = PPM_DETECT_STATE_DONE;
 | 
						|
        iot_mac_addr_cpy(ppm_desc->ppm_target_mac,
 | 
						|
            pib->ppm_target_mac);
 | 
						|
        ppm_desc->fix_ppm = pib->fix_ppm;
 | 
						|
    }
 | 
						|
    iot_cus_printf("%s en %lu, ppm_detect_state %lu, ppm %d\n",
 | 
						|
        __FUNCTION__, IOT_DEV_TEST_PPM_DETECT_EN,
 | 
						|
        ppm_desc->ppm_detect_state, ppm_desc->fix_ppm);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * @brief:  check if the mac and sn are both in the same queue node, if so,
 | 
						|
 *          return true if not, return false.
 | 
						|
 * @param   mac: mac address of meter who sent the msdu pkt
 | 
						|
 * @param   sn:  meter sent back, originally assigned by sta control
 | 
						|
 * @retval: true  --   sn and mac both matched
 | 
						|
 * @retval: false --   info mismached
 | 
						|
 */
 | 
						|
static bool_t iot_dev_test_frame_rpt_check(uint8_t *mac, uint16_t sn)
 | 
						|
{
 | 
						|
    bool_t ret = false;
 | 
						|
    uint8_t i, j;
 | 
						|
    iot_dev_test_task_data_t *dev_glb = dev_test_task_data;
 | 
						|
    iot_dev_test_ppm_detec_desc_t *ppm_desc = &dev_glb->ppm_desc;
 | 
						|
    info_pool_t *info_pool = &dev_glb->info_pool;
 | 
						|
 | 
						|
    if (info_pool->remain_cnt != IOT_DEV_TEST_POOL_NUM) {
 | 
						|
        for (i = 0; i < IOT_DEV_TEST_POOL_NUM; i++) {
 | 
						|
            if (iot_mac_is_bcast(info_pool->frm_info[i].frm.dst_mac) ||
 | 
						|
                iot_mac_addr_cmp(mac, info_pool->frm_info[i].frm.dst_mac)) {
 | 
						|
                if (info_pool->frm_info[i].frm.ppm_detect) {
 | 
						|
                    for (j = 0; j < ppm_desc->ppm_detect_rec_cnt; j ++) {
 | 
						|
                        if (ppm_desc->ppm_detect_rec[j].sn == sn) {
 | 
						|
                            iot_dev_test_ppm_detect_done_handle(
 | 
						|
                                &ppm_desc->ppm_detect_rec[j].fix_ppm);
 | 
						|
                            ret = true;
 | 
						|
                            goto done;
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                } else if (sn == info_pool->frm_info[i].frm.app_sn) {
 | 
						|
                    ret = true;
 | 
						|
                    break;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
done:
 | 
						|
    if (ret) {
 | 
						|
        iot_dev_test_buf_info_del(&info_pool->frm_info[i]);
 | 
						|
    }
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
uint16_t iot_dev_get_mr_retry_intval(frame_info_t *frame)
 | 
						|
{
 | 
						|
    if (frame->frm.ppm_detect) {
 | 
						|
        return 8;
 | 
						|
    } else {
 | 
						|
        return IOT_DEV_TEST_APP_MAX_RETRY_INTV_CNT;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
uint16_t iot_dev_get_mr_max_age(frame_info_t *frame)
 | 
						|
{
 | 
						|
    if (frame->frm.ppm_detect) {
 | 
						|
        return ((PPM_DETECT_STEP_MAX_CNT * 2 + 1) *
 | 
						|
            iot_dev_get_mr_retry_intval(frame));
 | 
						|
    } else {
 | 
						|
        return IOT_DEV_TEST_MAX_LIFE_SPAN_CNT;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/* once the periodicly timer is fired up, we should check the frame's
 | 
						|
 * life-span counter, if the counter reaches the limit, the stored info
 | 
						|
 * should be wiped out.
 | 
						|
 */
 | 
						|
static void iot_dev_test_buf_refresh(void)
 | 
						|
{
 | 
						|
    uint8_t i;
 | 
						|
    info_pool_t *pool = &dev_test_task_data->info_pool;
 | 
						|
    iot_dev_test_ppm_detec_desc_t *ppm_desc = &dev_test_task_data->ppm_desc;
 | 
						|
    frame_pkt_t *frm = NULL;
 | 
						|
    uint16_t intval, max_age;
 | 
						|
 | 
						|
    if ((dev_test_task_data->collector_vaild) &&
 | 
						|
        IOT_DEV_TEST_SUPPORT_CT_MR_EN &&
 | 
						|
        IOT_DEV_TEST_COLLECTOR_AUTO_CLR) {
 | 
						|
        dev_test_task_data->collector_vaild_cnt++;
 | 
						|
        if (dev_test_task_data->collector_vaild_cnt >=
 | 
						|
            IOT_DEV_TEST_COLLECTOR_VAILID_CNT) {
 | 
						|
            dev_test_task_data->collector_vaild = 0;
 | 
						|
            dev_test_task_data->collector_vaild_cnt = 0;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    if (pool->remain_cnt != IOT_DEV_TEST_POOL_NUM) {
 | 
						|
        for (i = 0; i < IOT_DEV_TEST_POOL_NUM; i++) {
 | 
						|
            if (pool->frm_info[i].send_cnt != 0) {
 | 
						|
                intval = iot_dev_get_mr_retry_intval(&pool->frm_info[i]);
 | 
						|
                max_age = iot_dev_get_mr_max_age(&pool->frm_info[i]);
 | 
						|
                frm = &pool->frm_info[i].frm;
 | 
						|
                pool->frm_info[i].span_cnt++;
 | 
						|
                if (pool->frm_info[i].span_cnt >= max_age) {
 | 
						|
                    iot_cus_printf("%s: frame mac[%02x:%02x:%02x:%02x:%02x:%02x"
 | 
						|
                        "], app_sn %lu is dropped for timeout\n", __FUNCTION__,
 | 
						|
                        frm->dst_mac[0], frm->dst_mac[1], frm->dst_mac[2],
 | 
						|
                        frm->dst_mac[3], frm->dst_mac[4], frm->dst_mac[5],
 | 
						|
                        frm->app_sn);
 | 
						|
                    if (PPM_DETECT_STATE_DOING == ppm_desc->ppm_detect_state) {
 | 
						|
                        iot_dev_test_ppm_detect_done_handle(NULL);
 | 
						|
                    } else if (PPM_DETECT_STATE_DONE == ppm_desc->ppm_detect_state) {
 | 
						|
                        iot_dev_test_ppm_detect_restart();
 | 
						|
                    }
 | 
						|
                    iot_dev_test_buf_info_del(&pool->frm_info[i]);
 | 
						|
                    continue;
 | 
						|
                } else if ((pool->frm_info[i].span_cnt % intval) == 0) {
 | 
						|
                    if (!iot_dev_test_msdu_m2s_send(frm)) {
 | 
						|
                        pool->frm_info[i].send_cnt++;
 | 
						|
                        iot_cus_printf("%s: sending retry, app_sn %lu, "
 | 
						|
                            "retry cnt %lu\n", __FUNCTION__, frm->app_sn,
 | 
						|
                            pool->frm_info[i].send_cnt - 1);
 | 
						|
                    }
 | 
						|
                }
 | 
						|
                /* send the mode config to sta at every 750ms in unicast way */
 | 
						|
                if (pool->frm_info[i].span_cnt %
 | 
						|
                    (IOT_DEV_TEST_APP_MAX_RETRY_INTV_CNT - 1) == 0) {
 | 
						|
                    iot_dev_test_send_mode_config(frm->dst_mac);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/* once received a uart data, allocate a pkt, then post a msg to handle
 | 
						|
 * the data
 | 
						|
 */
 | 
						|
static void iot_dev_test_uart_meter_port_func(uint8_t* buffer,
 | 
						|
    uint32_t buffer_len, bool_t is_full_frame,uint32_t invalid_data_len)
 | 
						|
{
 | 
						|
    iot_pkt_t *pkt;
 | 
						|
 | 
						|
    (void)invalid_data_len;
 | 
						|
    (void)is_full_frame;
 | 
						|
 | 
						|
    if (dev_test_task_data->dev_ready == 0) {
 | 
						|
        iot_cus_printf("%s: Device is not ready, pkt dropped!\n", __FUNCTION__);
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    pkt = iot_pkt_alloc(buffer_len, IOT_APP_DEV_TEST_MID);
 | 
						|
    if (pkt) {
 | 
						|
        os_mem_cpy(iot_pkt_put(pkt, buffer_len), buffer, buffer_len);
 | 
						|
        iot_dev_test_post_task_msg(IOT_DEV_TEST_UART_RECV_MSG, 0, pkt);
 | 
						|
    } else {
 | 
						|
        iot_cus_printf("%s: alloc failed\n", __FUNCTION__);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void iot_dev_test_handle_mr_req(uint8_t proto_type,
 | 
						|
    uint8_t *ds, uint32_t len, uint8_t *dst)
 | 
						|
{
 | 
						|
    frame_pkt_t frm = { 0 };
 | 
						|
    iot_pkt_t *buf;
 | 
						|
    uint8_t *data;
 | 
						|
    iot_dev_test_ppm_detec_desc_t * ppm_desc = &dev_test_task_data->ppm_desc;
 | 
						|
    iot_mac_addr_cpy(frm.dst_mac, dst);
 | 
						|
    iot_dev_test_ppm_detect_load(dst);
 | 
						|
    frm.p_type = proto_type;
 | 
						|
 | 
						|
    if ((NULL == ds) || (!len)) {
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    if (ppm_desc->ppm_detect_state != PPM_DETECT_STATE_DONE) {
 | 
						|
        frm.ppm_detect = 1;
 | 
						|
        ppm_desc->ppm_detect_state = PPM_DETECT_STATE_DOING;
 | 
						|
    }
 | 
						|
 | 
						|
    buf = iot_pkt_alloc(len, IOT_APP_DEV_TEST_MID);
 | 
						|
    if (buf == NULL) {
 | 
						|
        IOT_ASSERT(0);
 | 
						|
    }
 | 
						|
    data = iot_pkt_data(buf);
 | 
						|
    os_mem_cpy(data, ds, len);
 | 
						|
    iot_pkt_put(buf, len);
 | 
						|
    frm.data = buf;
 | 
						|
    if (ERR_OK != iot_dev_test_msdu_send_handle(&frm)) {
 | 
						|
        iot_pkt_free(buf);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/* handle config data from PLC */
 | 
						|
static uint8_t iot_dev_test_handle_config_data(iot_pkt_t *pkt)
 | 
						|
{
 | 
						|
    uint8_t *ptr = NULL;
 | 
						|
    iot_plc_msdu_recv_t *msdu = NULL;
 | 
						|
    proto_conn_less_mr_t *meter;
 | 
						|
    uint8_t *mac;
 | 
						|
    uint16_t app_sn;
 | 
						|
    uint16_t offset_sz;
 | 
						|
    proto_645_header_t *hdr_645 = NULL;
 | 
						|
    uint8_t t_mac[IOT_MAC_ADDR_LEN];
 | 
						|
    iot_pkt_t *msg_645 = NULL;
 | 
						|
 | 
						|
    iot_plc_msg_header_t *hdr = (iot_plc_msg_header_t*)iot_pkt_data(pkt);
 | 
						|
    msdu = (iot_plc_msdu_recv_t*)(hdr + 1);
 | 
						|
 | 
						|
    ptr = msdu->data;
 | 
						|
    iot_dev_test_data_print("msdu data", msdu->data, msdu->len);
 | 
						|
    meter = (proto_conn_less_mr_t *)(ptr + sizeof(proto_conn_less_hdr_t));
 | 
						|
    app_sn = meter->seq;
 | 
						|
 | 
						|
    /* data direction must: master ->slave */
 | 
						|
    if (meter->dir != CONN_LESS_APP_DIR_MASTER) {
 | 
						|
        iot_cus_printf("%s: invalid direction\n", __FUNCTION__);
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
 | 
						|
    mac = msdu->src;
 | 
						|
    offset_sz = sizeof(*msdu) + sizeof(*hdr) + sizeof(*meter) +
 | 
						|
        sizeof(proto_conn_less_hdr_t);
 | 
						|
    iot_pkt_pull(pkt, offset_sz);
 | 
						|
 | 
						|
    hdr_645 = proto_645_format_check(iot_pkt_data(pkt),
 | 
						|
        iot_pkt_data_len(pkt), PROTO_645_DIR_MASTER);
 | 
						|
    if (NULL == hdr_645) {
 | 
						|
        goto out;
 | 
						|
    }
 | 
						|
 | 
						|
    iot_mac_addr_cpy(t_mac, hdr_645->addr);
 | 
						|
    iot_mac_addr_reverse(t_mac);
 | 
						|
 | 
						|
    if (iot_dev_test_config_data_hdl_check(t_mac, app_sn)) {
 | 
						|
        iot_cus_printf("Received config data, sn %lu, mac[%02x:%02x:"
 | 
						|
            "%02x:%02x:%02x:%02x]\n", app_sn, t_mac[0], t_mac[1],
 | 
						|
            t_mac[2], t_mac[3], t_mac[4], t_mac[5]);
 | 
						|
        iot_dev_test_data_print("dlt645 data:", iot_pkt_data(pkt),
 | 
						|
            (uint16_t)iot_pkt_data_len(pkt));
 | 
						|
 | 
						|
        msg_645 = iot_dev_test_config_cmd_handle(hdr_645);
 | 
						|
        if (NULL !=  msg_645) {
 | 
						|
            iot_dev_test_config_pack_plc_rsp_data(mac, app_sn,
 | 
						|
                iot_pkt_data(msg_645), iot_pkt_data_len(msg_645));
 | 
						|
            iot_pkt_free(msg_645);
 | 
						|
        }
 | 
						|
    } else {
 | 
						|
        iot_cus_printf("config data dropped, sn %lu, mac"
 | 
						|
            "[%02x:%02x:%02x:%02x:%02x:%02x]\n", app_sn,
 | 
						|
            mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
 | 
						|
    }
 | 
						|
out:
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
static
 | 
						|
uint8_t iot_dev_test_check_addr_set_condition(proto_645_header_t *hdr_645)
 | 
						|
{
 | 
						|
    if (!hdr_645) {
 | 
						|
        iot_cus_printf("%s invalid hdr_645\n", __FUNCTION__);
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
 | 
						|
    return (dev_test_task_data->dev_mode == IOT_DEV_TEST_APP_MODE_M2M
 | 
						|
        && dev_test_task_data->m2m_sub_mode == IOT_DEV_TEST_M2M_SUBMODE_CIU
 | 
						|
        && dev_test_task_data->m2m_ciu_query_addr !=
 | 
						|
        IOT_DEV_TEST_QUERY_CIU_ADDR_SUCC
 | 
						|
        && (hdr_645->control.fn == PROTO_645_2007_FN_READ_ADDR)
 | 
						|
        && (hdr_645->control.ack == PROTO_645_ACK_NORMAL)
 | 
						|
        && (hdr_645->control.dir == PROTO_645_DIR_SLAVE));
 | 
						|
}
 | 
						|
 | 
						|
static void iot_dev_test_uart_qsxj_hw_ver_resp()
 | 
						|
{
 | 
						|
    uint16_t pkt_len, i, hw_ver_hex;
 | 
						|
    iot_pkt_t *pkt, *resp_pkt;
 | 
						|
    proto_qsxj_data_t *qsxj_data;
 | 
						|
    proto_qsxj_hw_ver_t *hw_ver;
 | 
						|
    iot_oem_hw_ver_info_t hw_ver_info = { 0 };
 | 
						|
 | 
						|
    pkt_len = sizeof(*qsxj_data) + sizeof(*hw_ver);
 | 
						|
    pkt = iot_pkt_alloc(pkt_len, IOT_APP_DEV_TEST_MID);
 | 
						|
    if (!pkt) {
 | 
						|
        return;
 | 
						|
    }
 | 
						|
    qsxj_data = (proto_qsxj_data_t *)iot_pkt_put(pkt, pkt_len);
 | 
						|
    proto_qsxj_di_to_byte(PROTO_QSXJ_DI_HARDWARE_VER, &qsxj_data->di);
 | 
						|
    qsxj_data->len = PROTO_QSXJ_MODE_INFO_LEN_HW_VER;
 | 
						|
    hw_ver = (proto_qsxj_hw_ver_t *)qsxj_data->data;
 | 
						|
    iot_oem_get_hw_ver_info(&hw_ver_info);
 | 
						|
    hw_ver_hex = hw_ver_info.module_version[1];
 | 
						|
    hw_ver_hex = hw_ver_hex << 8;
 | 
						|
    hw_ver_hex |= hw_ver_info.module_version[0];
 | 
						|
    for (i = 0; i < PROTO_QSXJ_MODE_INFO_LEN_HW_VER; i++) {
 | 
						|
        hw_ver->hw_ver[i] = iot_byte_to_ascii(hw_ver_hex & 0x0f, 1);
 | 
						|
        hw_ver_hex >>= 4;
 | 
						|
    }
 | 
						|
    iot_data_reverse(hw_ver->hw_ver, PROTO_QSXJ_MODE_INFO_LEN_HW_VER);
 | 
						|
    /* ver/flag_follow/channel fields is meaningless for qsxj dev_test proto */
 | 
						|
    resp_pkt = proto_qsxj_build_msg((uint8_t *)qsxj_data, pkt_len,
 | 
						|
        PROTO_QSXJ_COMMAND_SET_RESP, PROTO_QSXJ_VER_SX_V04, 0,
 | 
						|
        PROTO_QSXJ_CHANNEL_NUM0);
 | 
						|
    if (resp_pkt) {
 | 
						|
        iot_dev_test_uart_send(resp_pkt);
 | 
						|
    }
 | 
						|
    if (pkt) {
 | 
						|
        iot_pkt_free(pkt);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void iot_dev_test_uart_qsxj_sw_ver_resp()
 | 
						|
{
 | 
						|
    uint16_t pkt_len, sw_ver_hex, i;
 | 
						|
    iot_pkt_t *pkt, *resp_pkt;
 | 
						|
    proto_qsxj_data_t *qsxj_data;
 | 
						|
    proto_qsxj_sw_ver_t *sw_ver;
 | 
						|
    iot_build_info_t build_info = { 0 };
 | 
						|
 | 
						|
    pkt_len = sizeof(*qsxj_data) + sizeof(*sw_ver);
 | 
						|
    pkt = iot_pkt_alloc(pkt_len, IOT_APP_DEV_TEST_MID);
 | 
						|
    if (!pkt) {
 | 
						|
        return;
 | 
						|
    }
 | 
						|
    qsxj_data = (proto_qsxj_data_t *)iot_pkt_put(pkt, pkt_len);
 | 
						|
    proto_qsxj_di_to_byte(PROTO_QSXJ_DI_SOFTWARE_VER, &qsxj_data->di);
 | 
						|
    qsxj_data->len = PROTO_QSXJ_MODE_INFO_LEN_SW_VER_FIX +
 | 
						|
        PROTO_QSXJ_MODE_INFO_LEN_SW_VER_FILL;
 | 
						|
    sw_ver = (proto_qsxj_sw_ver_t *)qsxj_data->data;
 | 
						|
    os_mem_cpy(sw_ver->ver_fix, fixed_ver, PROTO_QSXJ_MODE_INFO_LEN_SW_VER_FIX);
 | 
						|
    iot_version_get_user_build_info(&build_info);
 | 
						|
    sw_ver_hex = build_info.sw_ver;
 | 
						|
    for (i = 0; i < PROTO_QSXJ_MODE_INFO_LEN_SW_VER_FILL; i++) {
 | 
						|
        if (i == 2) {
 | 
						|
            sw_ver->ver_fill[i] = '.';
 | 
						|
            continue;
 | 
						|
        }
 | 
						|
        sw_ver->ver_fill[i] = iot_byte_to_ascii(sw_ver_hex & 0x0f, 1);
 | 
						|
        sw_ver_hex >>= 4;
 | 
						|
    }
 | 
						|
    iot_data_reverse(sw_ver->ver_fill, PROTO_QSXJ_MODE_INFO_LEN_SW_VER_FILL);
 | 
						|
    /* ver/flag_follow/channel fields is meaningless for qsxj dev_test proto */
 | 
						|
    resp_pkt = proto_qsxj_build_msg((uint8_t *)qsxj_data, pkt_len,
 | 
						|
        PROTO_QSXJ_COMMAND_SET_RESP, PROTO_QSXJ_VER_SX_V04, 0,
 | 
						|
        PROTO_QSXJ_CHANNEL_NUM0);
 | 
						|
    if (resp_pkt) {
 | 
						|
        iot_dev_test_uart_send(resp_pkt);
 | 
						|
    }
 | 
						|
    if (pkt) {
 | 
						|
        iot_pkt_free(pkt);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void iot_dev_test_uart_qsxj_data_handle(iot_pkt_t *pkt)
 | 
						|
{
 | 
						|
    uint8_t *data, flag_nack = 0, addr_len, i;
 | 
						|
    uint8_t di_data_len, addr, meter_addr[IOT_MAC_ADDR_LEN] = { 0 };
 | 
						|
    uint16_t di, data_len;
 | 
						|
    uint32_t len;
 | 
						|
    proto_qsxj_head_t *head;
 | 
						|
    proto_qsxj_data_t *qsxj_data;
 | 
						|
    iot_pkt_t *resp_pkt;
 | 
						|
    frame_pkt_t frm = {0};
 | 
						|
 | 
						|
    data = iot_pkt_data(pkt);
 | 
						|
    len = iot_pkt_data_len(pkt);
 | 
						|
    iot_cus_printf("%s received uart data, len %lu\n", __FUNCTION__, len);
 | 
						|
    iot_dev_test_data_print("uart recv", data, len);
 | 
						|
    head = proto_qsxj_sanity_check(data, (uint16_t)len);
 | 
						|
    if (head) {
 | 
						|
        if (head->command != PROTO_QSXJ_COMMAND_SET_REQ) {
 | 
						|
            flag_nack = 1;
 | 
						|
            goto ack;
 | 
						|
        }
 | 
						|
        data_len = proto_qsxj_len_get(head) - sizeof(head->command) -
 | 
						|
            PROTO_QSXJ_CRC16_LEN;
 | 
						|
        if (data_len < sizeof(di)) {
 | 
						|
            flag_nack = 1;
 | 
						|
            goto ack;
 | 
						|
        }
 | 
						|
        di = iot_bytes_to_uint16(head->data, 1);
 | 
						|
        switch (di) {
 | 
						|
        case PROTO_QSXJ_DI_METER_NUM:
 | 
						|
        {
 | 
						|
            if (data_len < sizeof(*qsxj_data)) {
 | 
						|
                flag_nack = 1;
 | 
						|
                goto ack;
 | 
						|
            }
 | 
						|
            data_len -= sizeof(*qsxj_data);
 | 
						|
            qsxj_data = (proto_qsxj_data_t *)head->data;
 | 
						|
            di_data_len = qsxj_data->len;
 | 
						|
            if (data_len < di_data_len) {
 | 
						|
                flag_nack = 1;
 | 
						|
                goto ack;
 | 
						|
            }
 | 
						|
            addr_len = min(di_data_len, IOT_MAC_ADDR_LEN * 2);
 | 
						|
            for (i = 0; i < addr_len; i++) {
 | 
						|
                addr = iot_ascii_to_byte(qsxj_data->data[addr_len - 1 - i]) &
 | 
						|
                    0x0f;
 | 
						|
                if (i % 2) {
 | 
						|
                    meter_addr[i / 2] |= (addr << 4);
 | 
						|
                } else {
 | 
						|
                    meter_addr[i / 2] |= addr;
 | 
						|
                }
 | 
						|
            }
 | 
						|
            if (!iot_mac_addr_valid(meter_addr) ||
 | 
						|
                iot_mac_is_bcast(meter_addr)) {
 | 
						|
                flag_nack = 1;
 | 
						|
                goto ack;
 | 
						|
            }
 | 
						|
            iot_mac_addr_reverse(meter_addr);
 | 
						|
            iot_mac_addr_cpy(dev_test_task_data->qsxj_addr, meter_addr);
 | 
						|
            goto ack;
 | 
						|
        }
 | 
						|
        case PROTO_QSXJ_DI_HARDWARE_VER:
 | 
						|
        {
 | 
						|
            iot_dev_test_uart_qsxj_hw_ver_resp();
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        case PROTO_QSXJ_DI_SOFTWARE_VER:
 | 
						|
        {
 | 
						|
            iot_dev_test_uart_qsxj_sw_ver_resp();
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        default:
 | 
						|
            flag_nack = 1;
 | 
						|
            goto ack;
 | 
						|
        }
 | 
						|
    } else {
 | 
						|
        if (iot_mac_addr_valid(dev_test_task_data->qsxj_addr) &&
 | 
						|
            !iot_mac_is_bcast(dev_test_task_data->qsxj_addr)) {
 | 
						|
            frm.data = pkt;
 | 
						|
            frm.p_type = CONN_LESS_PROTO_TYPE_TRANSPARENT;
 | 
						|
            iot_mac_addr_cpy(frm.dst_mac, dev_test_task_data->qsxj_addr);
 | 
						|
            if (ERR_OK == iot_dev_test_msdu_send_handle(&frm)) {
 | 
						|
                return;
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
    goto out;
 | 
						|
ack:
 | 
						|
    resp_pkt = proto_qsxj_build_ack(PROTO_QSXJ_VER_SX_V04,
 | 
						|
        PROTO_QSXJ_COMMAND_SET_RESP, flag_nack);
 | 
						|
    if (resp_pkt) {
 | 
						|
        iot_dev_test_uart_send(resp_pkt);
 | 
						|
    }
 | 
						|
out:
 | 
						|
    if (pkt) {
 | 
						|
        iot_pkt_free(pkt);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static uint32_t iot_dev_test_69845_control_cmd(proto_69845_frame_head_info_t *hdr_698)
 | 
						|
{
 | 
						|
    uint8_t reason;
 | 
						|
    uint32_t ret = ERR_OK;
 | 
						|
    apdu_info_t apdu = {0};
 | 
						|
    proto_69845_apdu_t *req_apdu;
 | 
						|
    proto_69845_app_set_req_t *set;
 | 
						|
    proto_69845_app_set_req_normal_t *normal_data;
 | 
						|
    uint32_t oad_value;
 | 
						|
    proto_69845_app_ele_data_t *ele_data;
 | 
						|
    proto_69845_ext_rf_param_t *rf_param;
 | 
						|
    proto_69845_ext_work_mode_t *control_mode;
 | 
						|
    addr_info_t addr_info = {0};
 | 
						|
    iot_pkt_t *pkt;
 | 
						|
    proto_69845_app_oad_t app_oad = {0};
 | 
						|
 | 
						|
    if (hdr_698->ctrl.fn != PROTO_69845_FN_USER_DATA) {
 | 
						|
        reason = 1;
 | 
						|
        ret = ERR_INVAL;
 | 
						|
        goto err;
 | 
						|
    }
 | 
						|
    if (hdr_698->ctrl.dir_prm != PROTO_69845_D_P_CLIENT_RESPONSE
 | 
						|
        && hdr_698->ctrl.dir_prm != PROTO_69845_D_P_CLIENT_REQUEST) {
 | 
						|
        reason = 2;
 | 
						|
        ret = ERR_INVAL;
 | 
						|
        goto err;
 | 
						|
    }
 | 
						|
 | 
						|
    if (proto_69845_get_apdu(hdr_698, hdr_698->len + PROTO_69845_START_END_LEN,
 | 
						|
        &apdu) != ERR_OK) {
 | 
						|
        reason = 3;
 | 
						|
        ret = ERR_INVAL;
 | 
						|
        goto err;
 | 
						|
    }
 | 
						|
 | 
						|
    req_apdu = (proto_69845_apdu_t *)apdu.ptr;
 | 
						|
    if (req_apdu->type != PROTO_69845_C_APP_SET_REQ) {
 | 
						|
        reason = 4;
 | 
						|
        ret = ERR_INVAL;
 | 
						|
        goto err;
 | 
						|
    }
 | 
						|
 | 
						|
    set = (proto_69845_app_set_req_t *)req_apdu->data;
 | 
						|
    if (set->data_type != PROTO_69845_APP_SET_NORMAL) {
 | 
						|
        reason = 5;
 | 
						|
        ret = ERR_INVAL;
 | 
						|
        goto err;
 | 
						|
    }
 | 
						|
 | 
						|
    normal_data = (proto_69845_app_set_req_normal_t *)set->data;
 | 
						|
    oad_value = iot_bytes_to_uint32((uint8_t *)&normal_data->oad.oi, 1);
 | 
						|
    ele_data = (proto_69845_app_ele_data_t *)(&normal_data->data);
 | 
						|
    if (ele_data->data_type != PROTO_69845_APP_DATA_OCTET_STRING) {
 | 
						|
        reason = 6;
 | 
						|
        ret = ERR_INVAL;
 | 
						|
        goto err;
 | 
						|
    }
 | 
						|
 | 
						|
    switch (oad_value) {
 | 
						|
    case PROTO_69845_EXT_APP_OAD_BROADCAST_RF_PARAM:
 | 
						|
    {
 | 
						|
        rf_param = (proto_69845_ext_rf_param_t *)ele_data->data;
 | 
						|
        iot_dev_test_set_rf(rf_param->option, rf_param->channel, 0);
 | 
						|
        ret = ERR_EXIST;
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case PROTO_69845_EXT_APP_OAD_HRF_MODE:
 | 
						|
    {
 | 
						|
        uint8_t link_type;
 | 
						|
        control_mode = (proto_69845_ext_work_mode_t *)ele_data->data;
 | 
						|
        if (control_mode->mode == PROTO_69845_CONTROLLER_MODE_HPLC) {
 | 
						|
            link_type = IOT_PLC_TX_LINK_TYPE_HPLC;
 | 
						|
        } else {
 | 
						|
            link_type = IOT_PLC_TX_LINK_TYPE_RF;
 | 
						|
        }
 | 
						|
        iot_dev_test_set_tx_link_type(link_type, 0);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    default:
 | 
						|
        reason = 7;
 | 
						|
        ret = ERR_INVAL;
 | 
						|
        goto err;
 | 
						|
    }
 | 
						|
 | 
						|
    addr_info.ser_info.type = PROTO_69845_SA_TYPE_SIG;
 | 
						|
    addr_info.ser_info.len = IOT_MAC_ADDR_LEN;
 | 
						|
    addr_info.ser_info.logical_addr = 0;
 | 
						|
    iot_mac_addr_cpy(addr_info.ser_info.addr, dev_test_task_data->mac_addr);
 | 
						|
    addr_info.cli_addr = PROTO_69845_CA_INVAILD_ADD;
 | 
						|
    app_oad.oi = iot_bytes_to_uint16((uint8_t *)&normal_data->oad.oi, 1);
 | 
						|
    app_oad.attribute_id = normal_data->oad.attribute_id;
 | 
						|
    app_oad.attribute_char = normal_data->oad.attribute_char;
 | 
						|
    app_oad.element_index = normal_data->oad.element_index;
 | 
						|
 | 
						|
    pkt = proto_69845_set_normal_ack(&addr_info, &normal_data->piid,
 | 
						|
        &app_oad, PROTO_69845_APP_DAR_SUCCESS);
 | 
						|
    if (pkt == NULL) {
 | 
						|
        reason = 8;
 | 
						|
        ret = ERR_INVAL;
 | 
						|
        goto err;
 | 
						|
    }
 | 
						|
    iot_dev_test_uart_send(pkt);
 | 
						|
    goto out;
 | 
						|
err:
 | 
						|
    if (reason >= 7) {
 | 
						|
        iot_cus_printf("%s error reason:%lu", __FUNCTION__, reason);
 | 
						|
    }
 | 
						|
out:
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
static void iot_dev_test_uart_data_handle(iot_pkt_t *pkt)
 | 
						|
{
 | 
						|
    uint16_t len = 0;
 | 
						|
    proto_645_header_t *hdr_645;
 | 
						|
    proto_69845_frame_head_info_t *hdr_698;
 | 
						|
    proto_dlms_hdlc_head_t *hdr_dlms;
 | 
						|
    proto_dlms_hdlc_cache_t cache_dlms;
 | 
						|
    union proto_dlms_hdlc_format frame_format = {0};
 | 
						|
    addr_info_t svr_info = {0};
 | 
						|
    uint8_t *data;
 | 
						|
    uint16_t  fe_cnt = 0;
 | 
						|
    uint16_t pkt_len;
 | 
						|
    uint8_t band_id;
 | 
						|
    uint8_t op_mode;
 | 
						|
    uint8_t baud_index;
 | 
						|
    uint8_t t_mac[IOT_MAC_ADDR_LEN] = { 0 };
 | 
						|
    uint8_t dst_mac[IOT_MAC_ADDR_LEN] = { 0 };
 | 
						|
    uint32_t di;
 | 
						|
    uint8_t rf_option, rf_channel;
 | 
						|
    int8_t rf_tx_power;
 | 
						|
    uint8_t hplc_tx_power, link_type;
 | 
						|
 | 
						|
    len = (uint16_t)iot_pkt_block_len(pkt, IOT_PKT_BLOCK_DATA);
 | 
						|
    data = iot_pkt_block_ptr(pkt, IOT_PKT_BLOCK_DATA);
 | 
						|
 | 
						|
    iot_cus_printf("%s received uart data, len %lu\n", __FUNCTION__, len);
 | 
						|
    iot_dev_test_data_print("uart recv", data, len);
 | 
						|
 | 
						|
again:
 | 
						|
    if (dev_test_task_data->m2m_sub_mode == IOT_DEV_TEST_M2M_SUBMODE_CIU
 | 
						|
        && dev_test_task_data->dev_mode == IOT_DEV_TEST_APP_MODE_M2M) {
 | 
						|
        hdr_645 = proto_645_format_check(data, len, PROTO_645_DIR_SLAVE);
 | 
						|
    } else {
 | 
						|
        hdr_645 = proto_645_format_check(data, len, PROTO_645_DIR_MASTER);
 | 
						|
    }
 | 
						|
 | 
						|
    if (hdr_645) {
 | 
						|
        pkt_len = sizeof(*hdr_645) + hdr_645->len + sizeof(proto_645_tailer_t);
 | 
						|
        if (iot_mac_addr_cmp(hdr_645->addr, spec_mac)) {
 | 
						|
            iot_cus_printf("RECV_UART_CMD frame, fn: 0x%02x\n",
 | 
						|
                hdr_645->control.fn);
 | 
						|
            proto_645_sub33_handle(hdr_645->data, hdr_645->len);
 | 
						|
            switch (hdr_645->control.fn) {
 | 
						|
                case IOT_DEV_TEST_FN_SET_BAND:
 | 
						|
                    band_id = hdr_645->data[0];
 | 
						|
                    iot_cus_printf("[dev_test]recved set band cmd, band-id: "
 | 
						|
                        "%lu\n", band_id);
 | 
						|
                    iot_dev_test_set_band(band_id);
 | 
						|
                    break;
 | 
						|
                case IOT_DEV_TEST_FN_QUERRY_VER:
 | 
						|
                    iot_dev_test_querry_ver_handle();
 | 
						|
                    break;
 | 
						|
                case IOT_DEV_TEST_FN_QUERRY_BAND:
 | 
						|
                    iot_dev_test_querry_band_handle();
 | 
						|
                    break;
 | 
						|
                case IOT_DEV_TEST_FN_SET_MAC:
 | 
						|
                    iot_mac_addr_cpy(t_mac, hdr_645->data);
 | 
						|
                    iot_mac_addr_reverse(t_mac);
 | 
						|
                    iot_dev_test_set_mac(t_mac);
 | 
						|
                    break;
 | 
						|
                case IOT_DEV_TEST_FN_QUERRY_MAC:
 | 
						|
                    iot_dev_test_querry_mac_handle();
 | 
						|
                    break;
 | 
						|
                case IOT_DEV_TEST_FN_SET_OP_MODE:
 | 
						|
                    op_mode = hdr_645->data[0];
 | 
						|
                    iot_dev_test_set_op_mode(op_mode);
 | 
						|
                    break;
 | 
						|
                case IOT_DEV_TEST_FN_QUERY_OP_MODE:
 | 
						|
                    iot_dev_test_query_op_mode();
 | 
						|
                    break;
 | 
						|
                case IOT_DEV_TEST_FN_SET_UART_BAUDRATE:
 | 
						|
                    baud_index = hdr_645->data[0];
 | 
						|
                    iot_dev_test_set_baudrate(baud_index);
 | 
						|
                    break;
 | 
						|
                case IOT_DEV_TEST_FN_QUERY_BAUDRATE:
 | 
						|
                    iot_dev_test_query_baudrate();
 | 
						|
                    break;
 | 
						|
                case IOT_DEV_TEST_FN_SET_RF:
 | 
						|
                    rf_option = hdr_645->data[0];
 | 
						|
                    rf_channel = hdr_645->data[1];
 | 
						|
                    iot_dev_test_set_rf(rf_option, rf_channel, 1);
 | 
						|
                    break;
 | 
						|
                case IOT_DEV_TEST_FN_SET_RF_TX_POWER:
 | 
						|
                    rf_tx_power = hdr_645->data[0];
 | 
						|
                    iot_dev_test_set_rf_tx_power(rf_tx_power);
 | 
						|
                    break;
 | 
						|
                case IOT_DEV_TEST_FN_SET_HPLC_TX_POWER:
 | 
						|
                    hplc_tx_power = hdr_645->data[0];
 | 
						|
                    iot_dev_test_set_hplc_tx_power(hplc_tx_power);
 | 
						|
                    break;
 | 
						|
                case IOT_DEV_TEST_FN_SET_TX_LINK_TYPE:
 | 
						|
                    link_type = hdr_645->data[0];
 | 
						|
                    iot_dev_test_set_tx_link_type(link_type, 1);
 | 
						|
                    break;
 | 
						|
                default:
 | 
						|
                    iot_dev_test_form_rsp_cfm_frame(hdr_645->control.fn,
 | 
						|
                        IOT_DEV_TEST_RSP_ERR, IOT_DEV_TEST_REASON_NOT_SUPPORT);
 | 
						|
                    iot_cus_printf("[err]cmd fn: %lu not supported!\n",
 | 
						|
                        hdr_645->control.fn);
 | 
						|
                    break;
 | 
						|
            }
 | 
						|
            proto_645_add33_handle(hdr_645->data, hdr_645->len);
 | 
						|
        } else {
 | 
						|
            proto_645_get_di_by_sub33(hdr_645->data, PROTO_645_2007_DI_LEN,
 | 
						|
                PROTO_645_2007_ID, &di);
 | 
						|
            iot_cus_printf("RECV_UART_645 frame, di 0x%04x, data_len %lu\n",
 | 
						|
                di, hdr_645->len);
 | 
						|
 | 
						|
            if (iot_dev_test_check_addr_set_condition(hdr_645)) {
 | 
						|
                iot_mac_addr_cpy(t_mac, hdr_645->data);
 | 
						|
                proto_645_sub33_handle(t_mac, IOT_MAC_ADDR_LEN);
 | 
						|
                iot_mac_addr_reverse(t_mac);
 | 
						|
                iot_dev_test_set_mac(t_mac);
 | 
						|
 | 
						|
                dev_test_task_data->m2m_ciu_query_addr =
 | 
						|
                    IOT_DEV_TEST_QUERY_CIU_ADDR_SUCC;
 | 
						|
            }
 | 
						|
            if (iot_mac_addr_valid(hdr_645->addr) &&
 | 
						|
                !iot_mac_is_bcast(hdr_645->addr)) {
 | 
						|
                if (iot_mac_addr_cmp(hdr_645->addr, proto_645_any_addr)) {
 | 
						|
                    iot_set_bcast_mac(t_mac);
 | 
						|
                } else {
 | 
						|
                    iot_mac_addr_cpy(t_mac, hdr_645->addr);
 | 
						|
                }
 | 
						|
                iot_mac_addr_reverse(t_mac);
 | 
						|
                /* only if the dev_test support pushed-data handling,
 | 
						|
                 * matching mac can be updated.
 | 
						|
                 */
 | 
						|
                iot_dev_test_update_match_mac(t_mac);
 | 
						|
                iot_dev_test_stop_send_bootup_ind();
 | 
						|
 | 
						|
                iot_dev_test_handle_mr_req(GW_APP_DATA_TYPE_645_2007,
 | 
						|
                    (uint8_t *)hdr_645, pkt_len, t_mac);
 | 
						|
            }
 | 
						|
        }
 | 
						|
        fe_cnt = (uint16_t)((uint8_t*)hdr_645 - data);
 | 
						|
        data = pkt_len + (uint8_t*)hdr_645;
 | 
						|
    } else {
 | 
						|
        hdr_698 = proto_69845_sanity_check(data, len);
 | 
						|
        if (hdr_698) {
 | 
						|
            iot_cus_printf("RECV_UART_69845 frame, fn 0x%04x, data_len %lu\n",
 | 
						|
                hdr_698->len, hdr_698->ctrl.fn);
 | 
						|
 | 
						|
            proto_69845_get_addr_info(hdr_698, &svr_info);
 | 
						|
            iot_mac_addr_cpy(t_mac, svr_info.ser_info.addr);
 | 
						|
            iot_mac_addr_reverse(t_mac);
 | 
						|
            if (iot_dev_test_69845_control_cmd(hdr_698) == ERR_OK) {
 | 
						|
                goto out;
 | 
						|
            }
 | 
						|
            pkt_len = (uint8_t)(hdr_698->len + PROTO_69845_START_END_LEN);
 | 
						|
            iot_dev_test_handle_mr_req(GW_APP_DATA_TYPE_69845,
 | 
						|
                (uint8_t *)hdr_698, hdr_698->len + PROTO_69845_START_END_LEN,
 | 
						|
                t_mac);
 | 
						|
            fe_cnt = (uint16_t)((uint8_t*)hdr_698 - data);
 | 
						|
            data = pkt_len + (uint8_t*)hdr_698;
 | 
						|
        } else {
 | 
						|
            hdr_645 = proto_645_format_check(data, len, PROTO_645_DIR_SLAVE);
 | 
						|
            if (hdr_645) {
 | 
						|
                pkt_len = sizeof(*hdr_645) + hdr_645->len +
 | 
						|
                    sizeof(proto_645_tailer_t);
 | 
						|
                switch (hdr_645->control.fn) {
 | 
						|
                case IOT_DEV_TEST_645_FN_ACK_FROM_CIU:
 | 
						|
                {
 | 
						|
                    iot_dev_test_handle_ack_data_from_host(hdr_645);
 | 
						|
                    break;
 | 
						|
                }
 | 
						|
                case IOT_DEV_TEST_645_FN_RSP_BOOTUP_IND:
 | 
						|
                {
 | 
						|
                    iot_dev_test_stop_send_bootup_ind();
 | 
						|
                    break;
 | 
						|
                }
 | 
						|
                default:
 | 
						|
                    iot_cus_printf("%s FN not supported!\n", __FUNCTION__);
 | 
						|
                    break;
 | 
						|
                }
 | 
						|
                fe_cnt = (uint16_t)((uint8_t*)hdr_645 - data);
 | 
						|
                data = pkt_len + (uint8_t*)hdr_645;
 | 
						|
            } else {
 | 
						|
                hdr_dlms = proto_dlms_hdlc_parse(data, len, &cache_dlms);
 | 
						|
                if (hdr_dlms) {
 | 
						|
                    iot_cus_printf("RECV_UART_DLMS frame, type %lu, "
 | 
						|
                        "data_len %lu\n", hdr_dlms->frame_format.bit.frame_type,
 | 
						|
                        hdr_dlms->frame_format.bit.len);
 | 
						|
                    if (cache_dlms.dest_addr.type !=
 | 
						|
                        PROTO_DLMS_HDLC_ADD_TYPE_4) {
 | 
						|
                        goto out;
 | 
						|
                    }
 | 
						|
                    proto_dlms_hdlc_type_4_addr_to_bcd_addr(dst_mac,
 | 
						|
                        &cache_dlms.dest_addr);
 | 
						|
                    if (!iot_mac_addr_valid(dst_mac)) {
 | 
						|
                        goto out;
 | 
						|
                    }
 | 
						|
                    iot_mac_addr_reverse(dst_mac);
 | 
						|
                    iot_mac_addr_cpy(t_mac, dst_mac);
 | 
						|
                    frame_format.value =
 | 
						|
                        iot_ntohs(hdr_dlms->frame_format.value);
 | 
						|
                    pkt_len = frame_format.bit.len +
 | 
						|
                        PROTO_DLMS_HDLC_START_END_LEN;
 | 
						|
                    iot_dev_test_handle_mr_req(GW_APP_DATA_TYPE_TRANSPARENT,
 | 
						|
                        (uint8_t *)hdr_dlms, pkt_len, t_mac);
 | 
						|
                } else {
 | 
						|
                    iot_cus_printf("%s No more valid frame found!\n",
 | 
						|
                        __FUNCTION__);
 | 
						|
                    goto out;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    len = len - pkt_len - fe_cnt;
 | 
						|
 | 
						|
    if (len) {
 | 
						|
        goto again;
 | 
						|
    }
 | 
						|
out:
 | 
						|
    iot_pkt_free(pkt);
 | 
						|
}
 | 
						|
 | 
						|
static void iot_dev_test_uart_send(iot_pkt_t *pkt)
 | 
						|
{
 | 
						|
    iot_uart_send(dev_test_task_data->host_com, pkt, NULL);
 | 
						|
    return;
 | 
						|
}
 | 
						|
 | 
						|
static iot_uart_h iot_dev_test_open_uart(uint8_t port)
 | 
						|
{
 | 
						|
    iot_uart_h uart = 0;
 | 
						|
 | 
						|
    uart = iot_uart_open(port, iot_dev_test_uart_meter_port_func,
 | 
						|
        IOT_DEV_TEST_UART_RECV_BUF_SIZE, NULL);
 | 
						|
 | 
						|
    return uart;
 | 
						|
}
 | 
						|
 | 
						|
static bool_t iot_dev_test_set_uart_config(iot_uart_h uart)
 | 
						|
{
 | 
						|
    bool_t ret = false;
 | 
						|
    uint8_t parity;
 | 
						|
    uint32_t uart_baud = baud_tbl[dev_test_task_data->flashinfo.baud_index];
 | 
						|
    iot_frame_fmt fmt = { 0 };
 | 
						|
    iot_cus_printf("desire baudrate:[%lu]\n", uart_baud);
 | 
						|
    if (dev_test_task_data->user_type == USER_TYPE_STATE_GRID_OVERSEAS_SX) {
 | 
						|
        parity = IOT_UART_PARITY_NONE;
 | 
						|
    } else {
 | 
						|
        parity = IOT_UART_PARITY_EVEN;
 | 
						|
    }
 | 
						|
    ret = iot_uart_set_config(uart, uart_baud, parity, IOT_UART_DLEN_8_BITS,
 | 
						|
        IOT_UART_STOP_1_BITS);
 | 
						|
    /* config the UART port settings */
 | 
						|
    fmt.preamble_code[0] = PROTO_645_START_CHAR;
 | 
						|
    fmt.preamble_codelen = 1;
 | 
						|
    fmt.datalen_offset   = 8;
 | 
						|
    fmt.datalen_size     = 1;
 | 
						|
    fmt.backcode_offset  = 1;
 | 
						|
    fmt.backcode_len     = 1;
 | 
						|
    fmt.datalen_fix      = 0;
 | 
						|
    fmt.backcode[0]      = PROTO_645_END_CHAR;
 | 
						|
    fmt.frame_timeout    = 30;
 | 
						|
    fmt.timeout_mode     = TIMEOUT_PERDATA;
 | 
						|
    fmt.check_frame_func = proto_645_check_frame_handler;
 | 
						|
    iot_uart_set_frame(uart, &fmt);
 | 
						|
 | 
						|
    /* report the data to app after 3 bytes' interval */
 | 
						|
    iot_uart_set_threshold(uart, UART_THR_RXTIMEOUT, 3);
 | 
						|
    /* report the data to app once received 100 bytes */
 | 
						|
    iot_uart_set_threshold(uart, UART_THR_RXFULL, 100);
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
static void iot_dev_test_close_uart(iot_uart_h uart)
 | 
						|
{
 | 
						|
    iot_uart_close(uart);
 | 
						|
}
 | 
						|
 | 
						|
static void iot_dev_test_query_ciu_addr(void)
 | 
						|
{
 | 
						|
    iot_pkt_t *pkt = NULL;
 | 
						|
    uint32_t length = 0;
 | 
						|
 | 
						|
    if (dev_test_task_data->query_addr_cnt >= IOT_DEV_TEST_QUERY_ADDR_CNT_MAX
 | 
						|
        || dev_test_task_data->m2m_ciu_query_addr ==
 | 
						|
        IOT_DEV_TEST_QUERY_CIU_ADDR_SUCC) {
 | 
						|
        os_stop_timer(dev_test_task_data->query_addr_tm);
 | 
						|
        dev_test_task_data->query_addr_cnt = 0;
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    dev_test_task_data->query_addr_cnt++;
 | 
						|
 | 
						|
    pkt = iot_pkt_alloc(PROTO_645_2007_READ_ADDR_PKT_LEN, IOT_APP_DEV_TEST_MID);
 | 
						|
    if (!pkt) {
 | 
						|
        iot_cus_printf("%s failed to alloc pkt\n", __FUNCTION__);
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    iot_pkt_reserve(pkt, PROTO_645_PREAMBLE_LEN);
 | 
						|
    length = proto_645_fill_frame(iot_pkt_data(pkt), PROTO_645_2007_ID,
 | 
						|
        proto_645_any_addr, PROTO_645_DIR_MASTER, PROTO_645_ACK_NORMAL,
 | 
						|
        PROTO_645_FOLLOW_INVALID, PROTO_645_2007_FN_READ_ADDR,
 | 
						|
        PROTO_645_INVALID_DI, 0, NULL);
 | 
						|
    IOT_ASSERT(length);
 | 
						|
    iot_pkt_put(pkt, length);
 | 
						|
    iot_dev_test_uart_send(pkt);
 | 
						|
 | 
						|
    return;
 | 
						|
}
 | 
						|
 | 
						|
static uint8_t iot_dev_test_handle_msdu_data_recv(iot_pkt_t *pkt)
 | 
						|
{
 | 
						|
    uint8_t consumed = 0;
 | 
						|
    uint8_t *ptr = NULL;
 | 
						|
    iot_plc_msdu_recv_t *msdu = NULL;
 | 
						|
    proto_conn_less_hdr_t *frm_hdr = NULL;
 | 
						|
 | 
						|
    iot_plc_msg_header_t *hdr =
 | 
						|
        (iot_plc_msg_header_t*)iot_pkt_block_ptr(pkt, IOT_PKT_BLOCK_DATA);
 | 
						|
    msdu = (iot_plc_msdu_recv_t*)(hdr + 1);
 | 
						|
 | 
						|
    ptr = msdu->data;
 | 
						|
    frm_hdr = (proto_conn_less_hdr_t *)ptr;
 | 
						|
 | 
						|
    if (CONN_LESS_APP_PORT != frm_hdr->port) {
 | 
						|
        iot_cus_printf("received msdu data: wrong port\n");
 | 
						|
        return consumed;
 | 
						|
    }
 | 
						|
 | 
						|
    switch (frm_hdr->id) {
 | 
						|
    case CONN_LESS_APP_ID_METER_R:
 | 
						|
        consumed = iot_dev_test_handle_normal_data(pkt);
 | 
						|
        break;
 | 
						|
    case CONN_LESS_APP_ID_DATA_PUSH:
 | 
						|
        consumed = iot_dev_test_handle_pushed_data(pkt);
 | 
						|
        break;
 | 
						|
    case CONN_LESS_APP_ID_CONFIG:
 | 
						|
        consumed = iot_dev_test_handle_config_data(pkt);
 | 
						|
        break;
 | 
						|
    default:
 | 
						|
        iot_cus_printf("received msdu data id 0x%04x "
 | 
						|
            "is not supported by app\n", frm_hdr->id);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
 | 
						|
    return consumed;
 | 
						|
}
 | 
						|
 | 
						|
#else /* IOT_STA_CONTROL_MODE == IOT_STA_CONTROL_TYPE_METER */
 | 
						|
 | 
						|
static void iot_dev_test_buf_refresh(void)
 | 
						|
{
 | 
						|
    return;
 | 
						|
}
 | 
						|
 | 
						|
static void iot_dev_test_uart_qsxj_data_handle(iot_pkt_t *pkt)
 | 
						|
{
 | 
						|
    iot_pkt_free(pkt);
 | 
						|
}
 | 
						|
 | 
						|
static void iot_dev_test_uart_data_handle(iot_pkt_t *pkt)
 | 
						|
{
 | 
						|
    iot_pkt_free(pkt);
 | 
						|
}
 | 
						|
 | 
						|
static uint8_t iot_dev_test_handle_msdu_data_recv(iot_pkt_t *pkt)
 | 
						|
{
 | 
						|
    (void)pkt;
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
static void iot_dev_test_close_uart(iot_uart_h uart)
 | 
						|
{
 | 
						|
    (void)uart;
 | 
						|
}
 | 
						|
 | 
						|
static bool_t iot_dev_test_set_uart_config(iot_uart_h uart)
 | 
						|
{
 | 
						|
    (void)uart;
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
static void iot_dev_test_query_ciu_addr(void)
 | 
						|
{
 | 
						|
    return;
 | 
						|
}
 | 
						|
 | 
						|
static void iot_dev_test_send_bootup_indication(void)
 | 
						|
{
 | 
						|
    return;
 | 
						|
}
 | 
						|
 | 
						|
static void iot_dev_test_ppm_detect_init()
 | 
						|
{
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
static int8_t iot_dev_test_get_fix_ppm(void)
 | 
						|
{
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
#endif /* IOT_STA_CONTROL_MODE == IOT_STA_CONTROL_TYPE_METER */
 | 
						|
 | 
						|
/* Load config from PIB. */
 | 
						|
static uint8_t iot_dev_test_flash_load(void)
 | 
						|
{
 | 
						|
    uint8_t *rw = NULL;
 | 
						|
    uint8_t temp_pt = MAX_PIB_TYPE;
 | 
						|
    iot_pib_get_app_section(&rw, &temp_pt, IOT_PIB_APP_GET_WRITE_SECTION);
 | 
						|
    IOT_ASSERT(rw);
 | 
						|
 | 
						|
    IOT_ASSERT(temp_pt == STA_PIB_TYPE);
 | 
						|
 | 
						|
    os_mem_cpy(&dev_test_task_data->flashinfo, rw, sizeof(iot_dev_test_pib_t));
 | 
						|
    dev_test_task_data->section = rw;
 | 
						|
 | 
						|
    iot_dev_test_pib_t *info = &dev_test_task_data->flashinfo;
 | 
						|
    iot_cus_printf("boot cnt: %lu, loaded mac[%02x:%02x:%02x:%02x:%02x:%02x],"
 | 
						|
        "baud index: %lu\n",
 | 
						|
        info->boot_cnt, info->match_mac[0], info->match_mac[1],
 | 
						|
        info->match_mac[2], info->match_mac[3], info->match_mac[4],
 | 
						|
        info->match_mac[5], info->baud_index);
 | 
						|
 | 
						|
    return ERR_OK;
 | 
						|
}
 | 
						|
 | 
						|
/* Check the magic code to tell if the flash infor is damaged. */
 | 
						|
static uint8_t iot_dev_test_flashinfo_check(iot_dev_test_pib_t *p_info)
 | 
						|
{
 | 
						|
    uint32_t magic1, magic2;
 | 
						|
    uint8_t ret = ERR_OK;
 | 
						|
 | 
						|
    magic1 = p_info->magic1;
 | 
						|
 | 
						|
    magic2 = p_info->magic2;
 | 
						|
 | 
						|
    iot_cus_printf("Magic = 0x%08x, 0x%08x!\n", magic1, magic2);
 | 
						|
 | 
						|
    if ((IOT_DEV_TEST_FLASHINFO_MAGIC1 != magic1)
 | 
						|
        ||(IOT_DEV_TEST_FLASHINFO_MAGIC2 != magic2)) {
 | 
						|
        ret = ERR_FAIL;
 | 
						|
    }
 | 
						|
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
/* This will store config into PIB area. */
 | 
						|
static uint8_t iot_dev_test_flash_save(iot_dev_test_pib_t *p_info)
 | 
						|
{
 | 
						|
    uint8_t ref;
 | 
						|
    uint16_t ticket;
 | 
						|
 | 
						|
    iot_pib_acquire_app_commit_ref(&ref);
 | 
						|
    os_mem_cpy(dev_test_task_data->section, p_info, sizeof(*p_info));
 | 
						|
    iot_pib_release_app_commit_ref(&ref);
 | 
						|
    iot_pib_app_commit(&ticket);
 | 
						|
 | 
						|
    return ERR_OK;
 | 
						|
}
 | 
						|
 | 
						|
/* load flash infor and update local infor */
 | 
						|
static void iot_dev_test_flash_info_init(void)
 | 
						|
{
 | 
						|
    iot_dev_test_pib_t *p_info = &dev_test_task_data->flashinfo;
 | 
						|
 | 
						|
    if (ERR_FAIL == iot_dev_test_flash_load() ||
 | 
						|
        ERR_FAIL == iot_dev_test_flashinfo_check(p_info)) {
 | 
						|
        iot_cus_printf("get flash info failed\n!");
 | 
						|
        os_mem_set(p_info, 0x0, sizeof(*p_info));
 | 
						|
        p_info->baud_index = DEFAULT_BAUDRATE_INDEX;
 | 
						|
        p_info->magic1 = IOT_DEV_TEST_FLASHINFO_MAGIC1;
 | 
						|
        p_info->magic2 = IOT_DEV_TEST_FLASHINFO_MAGIC2;
 | 
						|
        iot_dev_test_flash_save(p_info);
 | 
						|
    }
 | 
						|
 | 
						|
    return;
 | 
						|
}
 | 
						|
 | 
						|
/* get start-up app SN from boot cnt and rondom data */
 | 
						|
static uint16_t iot_dev_test_startup_app_sn_create(void) {
 | 
						|
    uint16_t app_sn;
 | 
						|
    uint16_t boot_cnt = dev_test_task_data->flashinfo.boot_cnt;
 | 
						|
 | 
						|
    app_sn = (boot_cnt << 12) + (uint16_t)(os_rand() & 0xFFF);
 | 
						|
    iot_cus_printf("[dev_test]boot_cnt %lu, created SN %lu\n",
 | 
						|
        dev_test_task_data->flashinfo.boot_cnt, app_sn);
 | 
						|
    /* update the boot cnt then store into flash */
 | 
						|
    iot_counter_inc(dev_test_task_data->flashinfo.boot_cnt);
 | 
						|
    iot_dev_test_flash_save(&dev_test_task_data->flashinfo);
 | 
						|
    return app_sn;
 | 
						|
}
 | 
						|
 | 
						|
/* allocte a conn_less_msdu, then fill the msdu pkt with
 | 
						|
 * conn_less mode config data
 | 
						|
 */
 | 
						|
static uint8_t iot_dev_test_send_mode_config(uint8_t *dst_mac)
 | 
						|
{
 | 
						|
    uint16_t buflen = 0;
 | 
						|
    uint8_t *ptr = NULL;
 | 
						|
    iot_pkt_t *msdu_pkt;
 | 
						|
    dev_test_mode_cfg_t  *cfg;
 | 
						|
    uint8_t *msdu_dst_mac = NULL;
 | 
						|
    int8_t fix_ppm;
 | 
						|
 | 
						|
    if (dev_test_task_data->user_type == USER_TYPE_YNS) {
 | 
						|
        return ERR_OK;
 | 
						|
    }
 | 
						|
    if (!iot_mac_addr_valid(dst_mac)) {
 | 
						|
        iot_cus_printf("%s: dst mac is invalid!\n", __FUNCTION__);
 | 
						|
        return ERR_INVAL;
 | 
						|
    }
 | 
						|
 | 
						|
#if (IOT_DEV_TEST_BROADCAST_MODD_CFG == 1)
 | 
						|
    if (!iot_mac_is_bcast(dst_mac)) {
 | 
						|
        return ERR_INVAL;
 | 
						|
    }
 | 
						|
#else
 | 
						|
    if (iot_mac_is_bcast(dst_mac)) {
 | 
						|
        return ERR_INVAL;
 | 
						|
    }
 | 
						|
#endif
 | 
						|
 | 
						|
    fix_ppm = iot_dev_test_get_fix_ppm();
 | 
						|
 | 
						|
    if (IOT_DEV_TEST_SUPPORT_CT_MR_EN && !dev_test_task_data->collector_vaild) {
 | 
						|
        msdu_dst_mac = (uint8_t *)bcast_mac;
 | 
						|
    } else if (dev_test_task_data->collector_vaild) {
 | 
						|
        msdu_dst_mac = dev_test_task_data->collector;
 | 
						|
    } else {
 | 
						|
        msdu_dst_mac = dst_mac;
 | 
						|
    }
 | 
						|
 | 
						|
    buflen = sizeof(dev_test_mode_cfg_t) + sizeof(dev_test_ext_cfg_t);
 | 
						|
 | 
						|
    msdu_pkt = iot_plc_alloc_conn_less_msdu_ext(dev_test_task_data->app_handle,
 | 
						|
        IOT_PLC_MSG_TYPE_CONN_LESS_CMD, dst_mac, dev_test_task_data->mac_addr,
 | 
						|
        dev_test_task_data->link_id, buflen, IOT_PLC_LOCAL_RETRY_CNT,
 | 
						|
        fix_ppm, 0, dev_test_task_data->tx_link_type);
 | 
						|
 | 
						|
    if (msdu_pkt == NULL) {
 | 
						|
        iot_cus_printf("%s:allocate msdu failed!\n", __FUNCTION__);
 | 
						|
        return ERR_NOMEM;
 | 
						|
    }
 | 
						|
 | 
						|
    ptr = iot_pkt_block_ptr(msdu_pkt, IOT_PKT_BLOCK_TAIL);
 | 
						|
    iot_pkt_put(msdu_pkt, buflen);
 | 
						|
    cfg = (dev_test_mode_cfg_t *)ptr;
 | 
						|
    cfg->band_id = dev_test_task_data->band_id;
 | 
						|
    cfg->dur = IOT_DEV_TEST_MODE_CFG_DUR;
 | 
						|
    cfg->ext_cfg_en = dev_test_task_data->ext_cfg_en;
 | 
						|
    os_mem_cpy((uint8_t *)&cfg->ext_cfg,
 | 
						|
        (uint8_t *)&dev_test_task_data->ext_cfg, sizeof(dev_test_ext_cfg_t));
 | 
						|
#if IOT_STA_CONTROL_MODE == IOT_STA_CONTROL_TYPE_METER
 | 
						|
    cfg->target_id_mask = IOT_DEV_TEST_TARGET_ID_MSK_STA;
 | 
						|
#elif IOT_DEV_TEST_CCO_MODE
 | 
						|
    cfg->target_id_mask = IOT_DEV_TEST_TARGET_ID_MSK_CCO;
 | 
						|
#endif
 | 
						|
 | 
						|
    iot_cus_printf("send mode config to [%02x:%02x:%02x:%02x:%02x:%02x]"
 | 
						|
        " band id-%lu, duration-%lu sec, mask-%lu, ext en-%lu, [valid-%lu] "
 | 
						|
        "rf option-%lu rf channel-%lu, [valid-%lu]rf power-(%d)dbm, "
 | 
						|
        "[valid-%lu]hplc power-(%lu)dbuv\n",
 | 
						|
        msdu_dst_mac[0], msdu_dst_mac[1], msdu_dst_mac[2], msdu_dst_mac[3],
 | 
						|
        msdu_dst_mac[4], msdu_dst_mac[5], cfg->band_id, cfg->dur,
 | 
						|
        cfg->target_id_mask, cfg->ext_cfg_en, cfg->ext_cfg[0].rf_valid,
 | 
						|
        cfg->ext_cfg[0].rf_option, cfg->ext_cfg[0].rf_channel,
 | 
						|
        cfg->ext_cfg[0].rf_power_valid, cfg->ext_cfg[0].rf_tx_power,
 | 
						|
        cfg->ext_cfg[0].hplc_power_valid, cfg->ext_cfg[0].hplc_tx_power);
 | 
						|
    iot_plc_send_msdu(dev_test_task_data->app_handle, msdu_pkt);
 | 
						|
 | 
						|
    return ERR_OK;
 | 
						|
}
 | 
						|
 | 
						|
static void iot_dev_test_msdu_recv(void *param, iot_pkt_t *pkt)
 | 
						|
{
 | 
						|
    (void)param;
 | 
						|
    iot_dev_test_post_task_msg(IOT_DEV_TEST_MAC_MSG, 0, pkt);
 | 
						|
    return;
 | 
						|
}
 | 
						|
 | 
						|
static void iot_dev_test_periodic_timer_func(timer_id_t timer_id,
 | 
						|
    void * arg)
 | 
						|
{
 | 
						|
    (void)timer_id;
 | 
						|
    (void)arg;
 | 
						|
 | 
						|
    iot_dev_test_post_task_msg(IOT_DEV_TEST_TIMER_MSG,
 | 
						|
        IOT_DEV_TEST_TIMER_CHECK, NULL);
 | 
						|
}
 | 
						|
 | 
						|
static void iot_dev_test_query_addr_timer_func (timer_id_t timer_id, void * arg)
 | 
						|
{
 | 
						|
    (void)timer_id;
 | 
						|
    (void)arg;
 | 
						|
 | 
						|
    iot_dev_test_post_task_msg(IOT_DEV_TEST_TIMER_MSG,
 | 
						|
        IOT_DEV_TEST_TIMER_QUERY_ADDR, NULL);
 | 
						|
}
 | 
						|
 | 
						|
static void iot_dev_test_handle_timer_msg(
 | 
						|
    iot_dev_test_task_msg_t* task_msg)
 | 
						|
{
 | 
						|
    switch (task_msg->msg.id) {
 | 
						|
    case IOT_DEV_TEST_TIMER_CHECK:
 | 
						|
    {
 | 
						|
        iot_dev_test_config_all_sta_test_mode();
 | 
						|
 | 
						|
        iot_dev_test_buf_refresh();
 | 
						|
 | 
						|
		iot_dev_test_send_bootup_indication();
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case IOT_DEV_TEST_TIMER_QUERY_ADDR:
 | 
						|
    {
 | 
						|
        iot_dev_test_query_ciu_addr();
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    default:
 | 
						|
        break;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void iot_dev_test_set_cfg_after_app_reg(void)
 | 
						|
{
 | 
						|
    iot_plc_cfg_set_req_t cfg = {0};
 | 
						|
    iot_plc_app_h app_hdl = dev_test_task_data->app_handle;
 | 
						|
 | 
						|
    /* enable whitelist */
 | 
						|
    iot_plc_set_whitelist(app_hdl, IOT_PLC_API_REQ_ID_DEFAULT,
 | 
						|
        IOT_PLC_WL_ENABLE, 0, NULL);
 | 
						|
 | 
						|
    /* stop network formation */
 | 
						|
    iot_plc_stop_nw_fmt(app_hdl);
 | 
						|
 | 
						|
    /* set configuration of local device */
 | 
						|
    iot_dev_test_pib_t *p_flash = &dev_test_task_data->flashinfo;
 | 
						|
 | 
						|
#if IOT_DEV_TEST_BUILD_CIU_TESTER && (IOT_DEV_TEST_BROADCAST_MODD_CFG == 0)
 | 
						|
    iot_mac_addr_cpy( p_flash->match_mac, (uint8_t *)ciu_tester_mac);
 | 
						|
#endif
 | 
						|
 | 
						|
    if (!iot_mac_is_bcast(p_flash->match_mac)
 | 
						|
        && iot_mac_addr_valid(p_flash->match_mac)) {
 | 
						|
        iot_mac_addr_cpy(cfg.addr, p_flash->match_mac);
 | 
						|
        cfg.addr_valid = 1;
 | 
						|
        iot_cus_printf("%s: set local mac[%02x:%02x:%02x:%02x:%02x:%02x] "
 | 
						|
            "successfully\n", __FUNCTION__, cfg.addr[0], cfg.addr[1],
 | 
						|
            cfg.addr[2], cfg.addr[3], cfg.addr[4], cfg.addr[5]);
 | 
						|
    }
 | 
						|
    cfg.reset = 1;
 | 
						|
    cfg.dev_type_valid = 1;
 | 
						|
    cfg.dev_type = IOT_PLC_DEV_TYPE_METER_CONTROLLER;
 | 
						|
    iot_plc_set_cfg(app_hdl, IOT_PLC_API_REQ_ID_DEFAULT, &cfg);
 | 
						|
 | 
						|
    /* set default frequnce band */
 | 
						|
#if (IOT_DEV_TEST_SUPPORT_MUTIBAND == 1)
 | 
						|
    iot_plc_set_freq_band(app_hdl, IOT_PLC_API_REQ_ID_DEFAULT,
 | 
						|
        PLC_LIB_FREQ_BAND_MULTI_1_2);
 | 
						|
#else
 | 
						|
    iot_plc_set_freq_band(app_hdl, IOT_PLC_API_REQ_ID_DEFAULT,
 | 
						|
        dev_test_task_data->band_id);
 | 
						|
#endif
 | 
						|
    /* query device infor */
 | 
						|
    iot_plc_query_dev_info(app_hdl, IOT_PLC_API_REQ_ID_DEFAULT);
 | 
						|
 | 
						|
    /* disable watchdog */
 | 
						|
    iot_plc_wdg_set(app_hdl, 0, 0);
 | 
						|
    /* get the app SN and update the boot counter */
 | 
						|
    dev_test_task_data->app_sn = iot_dev_test_startup_app_sn_create();
 | 
						|
 | 
						|
#if IOT_DEV_TEST_CCO_MODE
 | 
						|
    int8_t rf_power = 16;
 | 
						|
    if (dev_test_task_data->user_type == USER_TYPE_STATE_GRID_LIAONING) {
 | 
						|
        dev_test_task_data->ext_cfg.rf_power_valid = 1;
 | 
						|
        dev_test_task_data->ext_cfg.rf_tx_power = 16;
 | 
						|
        iot_plc_set_tx_power_cap(app_hdl, IOT_PLC_API_REQ_ID_DEFAULT,
 | 
						|
            NULL, &rf_power);
 | 
						|
    }
 | 
						|
#endif
 | 
						|
 | 
						|
    /* start reload timer */
 | 
						|
    os_start_timer(dev_test_task_data->periodic_tm,
 | 
						|
        IOT_DEV_TEST_PERIODIC_TIMER_INTERVAL);
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
static void iot_dev_test_handle_mac_msg(iot_pkt_t *pkt)
 | 
						|
{
 | 
						|
    iot_plc_msg_header_t *hdr =
 | 
						|
        (iot_plc_msg_header_t*)iot_pkt_block_ptr(pkt, IOT_PKT_BLOCK_DATA);
 | 
						|
    uint8_t consumed = 0;
 | 
						|
    uint8_t app_id;
 | 
						|
 | 
						|
#if (IOT_STA_CONTROL_MODE == IOT_STA_CONTROL_TYPE_METER)
 | 
						|
    app_id = IOT_PLC_APP_SMART_GRID;
 | 
						|
#elif IOT_DEV_TEST_CCO_MODE
 | 
						|
    app_id = IOT_PLC_APP_DEV_TEST;
 | 
						|
#endif
 | 
						|
 | 
						|
    if (hdr->app_id != IOT_PLC_APP_ID_BCAST &&
 | 
						|
        hdr->app_id != app_id) {
 | 
						|
        iot_pkt_free(pkt);
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    if (dev_test_task_data->app_registered == 0 &&
 | 
						|
        hdr->msg_id != IOT_PLC_MSG_APP_REG_CONF) {
 | 
						|
        // only handle app register confirm message before app registered
 | 
						|
        iot_pkt_free(pkt);
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    switch (hdr->msg_id) {
 | 
						|
    case IOT_PLC_MSG_APP_REG_CONF:
 | 
						|
    {
 | 
						|
        iot_plc_app_reg_conf_t* rpt = (iot_plc_app_reg_conf_t*)(hdr + 1);
 | 
						|
        iot_cus_printf("%s: IOT_PLC_MSG_APP_REG_CONF result:%d\n", __FUNCTION__,
 | 
						|
            rpt->result);
 | 
						|
        if (rpt->result == IOT_PLC_SUCCESS ||
 | 
						|
            rpt->result == IOT_PLC_SUCCESS_MODIFIED) {
 | 
						|
            dev_test_task_data->app_registered = 1;
 | 
						|
            iot_dev_test_set_cfg_after_app_reg();
 | 
						|
        }
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case IOT_PLC_MSG_DEV_STATE_CHANGE_RPT:
 | 
						|
    {
 | 
						|
        iot_plc_dev_state_change_rpt_t* rpt =
 | 
						|
            (iot_plc_dev_state_change_rpt_t*)(hdr + 1);
 | 
						|
        iot_cus_printf("[dev_test]IOT_PLC_MSG_DEV_STATE_CHANGE_RPT: "
 | 
						|
            "local mac[%02X:%02X:%02X:%02X:%02X:%02X], role:%lu, ready:%lu\n",
 | 
						|
            rpt->local_mac[0], rpt->local_mac[1], rpt->local_mac[2],
 | 
						|
            rpt->local_mac[3], rpt->local_mac[4], rpt->local_mac[5],
 | 
						|
            rpt->dev_role, rpt->is_ready);
 | 
						|
        if (iot_mac_addr_valid(rpt->local_mac)) {
 | 
						|
            dev_test_task_data->dev_role = rpt->dev_role;
 | 
						|
            iot_mac_addr_cpy(dev_test_task_data->mac_addr, rpt->local_mac);
 | 
						|
            dev_test_task_data->dev_ready = 1;
 | 
						|
            iot_dev_test_send_bootup_indication();
 | 
						|
        }
 | 
						|
#if IOT_DEV_TEST_CCO_MODE
 | 
						|
        /* dev_test_cco is fixed band, but when SG app configures plc, band
 | 
						|
         * information is lost and needs to be reconfigured.
 | 
						|
         */
 | 
						|
        iot_plc_set_freq_band(dev_test_task_data->app_handle,
 | 
						|
            IOT_PLC_API_REQ_ID_DEFAULT, dev_test_task_data->band_id);
 | 
						|
#endif
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case IOT_PLC_MSG_DEV_INFO_RPT:
 | 
						|
    {
 | 
						|
        iot_plc_dev_info_rpt_t* rpt = (iot_plc_dev_info_rpt_t*)(hdr + 1);
 | 
						|
        iot_cus_printf("%s: infor report--role %lu, dev type %lu, local mac"
 | 
						|
            "[%02x:%02x:%02x:%02x:%02x:%02x]\n", __FUNCTION__,
 | 
						|
            rpt->dev_role, rpt->dev_type, rpt->local_mac[0], rpt->local_mac[1],
 | 
						|
            rpt->local_mac[2], rpt->local_mac[3], rpt->local_mac[4],
 | 
						|
            rpt->local_mac[5]);
 | 
						|
        if (iot_mac_addr_valid(rpt->local_mac)) {
 | 
						|
            dev_test_task_data->dev_role = rpt->dev_role;
 | 
						|
            dev_test_task_data->dev_type = rpt->dev_type;
 | 
						|
            iot_mac_addr_cpy(dev_test_task_data->mac_addr, rpt->local_mac);
 | 
						|
            dev_test_task_data->dev_ready = 1;
 | 
						|
        } else {
 | 
						|
            IOT_ASSERT(0);
 | 
						|
        }
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case IOT_PLC_MSG_CONN_LESS_RECV:
 | 
						|
    {
 | 
						|
        consumed = iot_dev_test_handle_msdu_data_recv(pkt);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    default:
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    if (consumed == 0) {
 | 
						|
        iot_pkt_free(pkt);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void iot_dev_test_task_handle_msg(iot_task_h task_h,
 | 
						|
    iot_task_msg_t *msg)
 | 
						|
{
 | 
						|
    iot_dev_test_task_msg_t *task_msg;
 | 
						|
    IOT_ASSERT(task_h == dev_test_task_data->task_handle);
 | 
						|
    IOT_ASSERT(msg);
 | 
						|
 | 
						|
    task_msg = (iot_dev_test_task_msg_t*)msg;
 | 
						|
    switch (task_msg->msg.type) {
 | 
						|
    case IOT_DEV_TEST_MAC_MSG:
 | 
						|
    {
 | 
						|
        iot_dev_test_handle_mac_msg(task_msg->data);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case IOT_DEV_TEST_TIMER_MSG:
 | 
						|
    {
 | 
						|
        iot_dev_test_handle_timer_msg(task_msg);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case IOT_DEV_TEST_UART_RECV_MSG:
 | 
						|
    {
 | 
						|
        if (dev_test_task_data->user_type ==
 | 
						|
            USER_TYPE_STATE_GRID_OVERSEAS_SX) {
 | 
						|
            iot_dev_test_uart_qsxj_data_handle(task_msg->data);
 | 
						|
        } else {
 | 
						|
            iot_dev_test_uart_data_handle(task_msg->data);
 | 
						|
        }
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    default:
 | 
						|
        IOT_ASSERT(0);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
 | 
						|
    iot_task_free_msg(dev_test_task_data->task_handle, &task_msg->msg);
 | 
						|
}
 | 
						|
 | 
						|
static void iot_dev_test_task_handle_msg_cancel(iot_task_h task_h,
 | 
						|
    iot_task_msg_t *msg)
 | 
						|
{
 | 
						|
    iot_dev_test_task_msg_t *task_msg;
 | 
						|
    IOT_ASSERT(task_h == dev_test_task_data->task_handle);
 | 
						|
    IOT_ASSERT(msg);
 | 
						|
 | 
						|
    task_msg = (iot_dev_test_task_msg_t*)msg;
 | 
						|
    switch (task_msg->msg.type) {
 | 
						|
    case IOT_DEV_TEST_MAC_MSG:
 | 
						|
    case IOT_DEV_TEST_UART_RECV_MSG:
 | 
						|
    {
 | 
						|
        if (task_msg->data) {
 | 
						|
            iot_pkt_free(task_msg->data);
 | 
						|
        }
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    case IOT_DEV_TEST_TIMER_MSG:
 | 
						|
    {
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    default:
 | 
						|
        break;
 | 
						|
    }
 | 
						|
 | 
						|
    iot_task_free_msg(dev_test_task_data->task_handle, &task_msg->msg);
 | 
						|
}
 | 
						|
 | 
						|
static uint32_t iot_dev_test_task_init()
 | 
						|
{
 | 
						|
    uint32_t ret = ERR_OK;
 | 
						|
    iot_plc_app_t dev_test_app = {0};
 | 
						|
    iot_task_config_t task_cfg;
 | 
						|
    iot_uart_h uart_hdl = NULL;
 | 
						|
 | 
						|
#if (IOT_STA_CONTROL_MODE == IOT_STA_CONTROL_TYPE_METER)
 | 
						|
 | 
						|
    /* when IOT_STA_CONTROL_MODE equals 2, if uart port0 could not be opened,
 | 
						|
     * that means sta controller app is running, dev_test app should not run.
 | 
						|
     * when IOT_DEV_TEST_CCO_MODE equals 1, dev_test no longer using uart port,
 | 
						|
     * check uart port is not neccesary.
 | 
						|
     * when IOT_STA_CONTROL_MODE equals 2, the IOT_DEV_TEST_CCO_MODE
 | 
						|
     * must be 0.
 | 
						|
     */
 | 
						|
    uart_hdl = iot_dev_test_open_uart(iot_board_get_uart(UART_METER_PORT));
 | 
						|
    if (uart_hdl == NULL) {
 | 
						|
        iot_cus_printf("open uart meter port failed!\n");
 | 
						|
        goto out;
 | 
						|
    } else {
 | 
						|
        iot_cus_printf("open uart meter port successfully!\n");
 | 
						|
    }
 | 
						|
 | 
						|
#endif /* IOT_STA_CONTROL_MODE == IOT_STA_CONTROL_TYPE_METER */
 | 
						|
 | 
						|
    dev_test_task_data = os_mem_malloc(IOT_APP_DEV_TEST_MID,
 | 
						|
        sizeof(*dev_test_task_data));
 | 
						|
    if (!dev_test_task_data) {
 | 
						|
        ret = ERR_NOMEM;
 | 
						|
        goto error_1;
 | 
						|
    }
 | 
						|
 | 
						|
    os_mem_set(dev_test_task_data, 0, sizeof(iot_dev_test_task_data_t));
 | 
						|
 | 
						|
    dev_test_task_data->host_com = uart_hdl;
 | 
						|
    dev_test_task_data->link_id = IOT_DEV_TEST_TASK_LINK_ID;
 | 
						|
    dev_test_task_data->dev_role = IOT_PLC_DEV_ROLE_INVALID;
 | 
						|
    dev_test_task_data->dev_mode = IOT_DEV_TEST_APP_MODE_M2S;
 | 
						|
    dev_test_task_data->flashinfo.baud_index = DEFAULT_BAUDRATE_INDEX;
 | 
						|
    dev_test_task_data->user_type = iot_oem_get_user_type();
 | 
						|
    if ((dev_test_task_data->user_type == USER_TYPE_STATE_GRID_CQ) ||
 | 
						|
        (dev_test_task_data->user_type == USER_TYPE_STATE_GRID_JIBEI)) {
 | 
						|
        dev_test_task_data->band_id = PLC_LIB_FREQ_BAND_1;
 | 
						|
    } else {
 | 
						|
        dev_test_task_data->band_id = PLC_LIB_FREQ_BAND_2;
 | 
						|
    }
 | 
						|
    dev_test_task_data->ext_cfg_en = 1;
 | 
						|
 | 
						|
#if IOT_DEV_TEST_HANDLE_PUSH_DATA_EN
 | 
						|
    dev_test_task_data->boot_ind_en = 1;
 | 
						|
#else
 | 
						|
    dev_test_task_data->boot_ind_en = 0;
 | 
						|
#endif
 | 
						|
 | 
						|
    iot_dev_test_flash_info_init();
 | 
						|
    iot_dev_test_ppm_detect_init();
 | 
						|
 | 
						|
    /* Default is for China sg market use.
 | 
						|
     * For outsea market, below need to do:
 | 
						|
     *  1. build CIU binary.
 | 
						|
     *  2. set IOT_DEV_TEST_BUILD_CIU_TESTER = 1 and
 | 
						|
     *     set dev_mode = IOT_DEV_TEST_APP_MODE_M2M, build CIU tester binary.
 | 
						|
     */
 | 
						|
#if IOT_DEV_TEST_BUILD_CIU_TESTER
 | 
						|
    dev_test_task_data->m2m_sub_mode = IOT_DEV_TEST_M2M_SUBMODE_CIUTESTER;
 | 
						|
    dev_test_task_data->dev_mode = IOT_DEV_TEST_APP_MODE_M2M;
 | 
						|
#else
 | 
						|
    dev_test_task_data->m2m_sub_mode = IOT_DEV_TEST_M2M_SUBMODE_CIU;
 | 
						|
#endif
 | 
						|
    dev_test_task_data->m2m_check_addr = IOT_DEV_TEST_ADDR_NOT_SET;
 | 
						|
    dev_test_task_data->m2m_ciu_query_addr = IOT_DEV_TEST_QUERY_CIU_ADDR_FAIL;
 | 
						|
    dev_test_task_data->query_addr_cnt = 0;
 | 
						|
    dev_test_task_data->tx_link_type = IOT_PLC_TX_LINK_TYPE_HPLC;
 | 
						|
 | 
						|
    task_cfg.stack_size = 0;
 | 
						|
    task_cfg.task_prio = IOT_DEV_TEST_TASK_PRIO;
 | 
						|
    task_cfg.msg_size = sizeof(iot_dev_test_task_msg_t);
 | 
						|
    task_cfg.msg_cnt = IOT_DEV_TEST_TASK_POOL_SIZE;
 | 
						|
    task_cfg.queue_cnt = IOT_DEV_TEST_TASK_QUEUE_MAX_PRIO;
 | 
						|
    task_cfg.queue_cfg[IOT_DEV_TEST_TASK_QUEUE_HP].quota = 0;
 | 
						|
    task_cfg.msg_exe_func = iot_dev_test_task_handle_msg;
 | 
						|
    task_cfg.msg_cancel_func = iot_dev_test_task_handle_msg_cancel;
 | 
						|
 | 
						|
    dev_test_task_data->task_handle =
 | 
						|
        iot_task_create(IOT_APP_DEV_TEST_MID, &task_cfg);
 | 
						|
 | 
						|
    if (dev_test_task_data->task_handle == NULL) {
 | 
						|
        ret = ERR_FAIL;
 | 
						|
        goto error_2;
 | 
						|
    }
 | 
						|
 | 
						|
    dev_test_task_data->periodic_tm = os_create_timer(
 | 
						|
        IOT_APP_DEV_TEST_MID, true, iot_dev_test_periodic_timer_func,
 | 
						|
        dev_test_task_data);
 | 
						|
    if (dev_test_task_data->periodic_tm == 0) {
 | 
						|
        ret = ERR_FAIL;
 | 
						|
        goto error_3;
 | 
						|
    }
 | 
						|
 | 
						|
    dev_test_task_data->query_addr_tm = os_create_timer(
 | 
						|
        IOT_APP_DEV_TEST_MID, true, iot_dev_test_query_addr_timer_func,
 | 
						|
        dev_test_task_data);
 | 
						|
    if (dev_test_task_data->query_addr_tm == 0) {
 | 
						|
        ret = ERR_FAIL;
 | 
						|
        goto error_4;
 | 
						|
    }
 | 
						|
 | 
						|
    if (dev_test_task_data->host_com) {
 | 
						|
        if (iot_dev_test_set_uart_config(dev_test_task_data->host_com)) {
 | 
						|
            iot_cus_printf("host uart config success\n");
 | 
						|
        } else {
 | 
						|
            iot_cus_printf("host uart config fail\n");
 | 
						|
            goto error_5;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
#if IOT_DEV_TEST_CCO_MODE
 | 
						|
    dev_test_app.app_id = IOT_PLC_APP_DEV_TEST;
 | 
						|
#elif (IOT_STA_CONTROL_MODE == IOT_STA_CONTROL_TYPE_METER)
 | 
						|
    dev_test_app.app_id = IOT_PLC_APP_SMART_GRID;
 | 
						|
#endif
 | 
						|
 | 
						|
    dev_test_app.param = NULL;
 | 
						|
    dev_test_app.prio = 3;
 | 
						|
    dev_test_app.recv = iot_dev_test_msdu_recv;
 | 
						|
 | 
						|
    dev_test_task_data->app_handle = iot_plc_register_app(&dev_test_app);
 | 
						|
    if (dev_test_task_data->app_handle == NULL) {
 | 
						|
        ret = ERR_FAIL;
 | 
						|
        goto error_5;
 | 
						|
    }
 | 
						|
 | 
						|
    dev_test_task_data->info_pool.remain_cnt = IOT_DEV_TEST_POOL_NUM;
 | 
						|
 | 
						|
#if (IOT_DEV_TEST_BUILD_CIU_TESTER && IOT_DEV_TEST_BROADCAST_MODD_CFG)
 | 
						|
    iot_dev_test_set_mac((uint8_t *)ciu_tester_mac);
 | 
						|
#endif
 | 
						|
 | 
						|
    goto out;
 | 
						|
 | 
						|
error_5:
 | 
						|
    os_delete_timer(dev_test_task_data->query_addr_tm);
 | 
						|
    dev_test_task_data->query_addr_tm = 0;
 | 
						|
error_4:
 | 
						|
    os_delete_timer(dev_test_task_data->periodic_tm);
 | 
						|
    dev_test_task_data->periodic_tm = 0;
 | 
						|
error_3:
 | 
						|
    iot_task_delete(dev_test_task_data->task_handle);
 | 
						|
    dev_test_task_data->task_handle = NULL;
 | 
						|
error_2:
 | 
						|
    os_mem_free(dev_test_task_data);
 | 
						|
    dev_test_task_data = NULL;
 | 
						|
error_1:
 | 
						|
    if (uart_hdl) {
 | 
						|
        iot_dev_test_close_uart(uart_hdl);
 | 
						|
        uart_hdl = NULL;
 | 
						|
    }
 | 
						|
out:
 | 
						|
    iot_cus_printf("[dev_test]Initializing task done, ret: %lu\n", ret);
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
uint32_t app_dev_test_entry()
 | 
						|
{
 | 
						|
    uint32_t ret = ERR_NOT_READY;
 | 
						|
    /* if the firmware is release version(0), disabel log printing, if not,
 | 
						|
     * enable the log printing
 | 
						|
     */
 | 
						|
    if (iot_version_type() == 1) {
 | 
						|
        iot_cus_print_config(true);
 | 
						|
    } else {
 | 
						|
        iot_cus_print_config(false);
 | 
						|
    }
 | 
						|
 | 
						|
    if (iot_dev_test_task_init()) {
 | 
						|
        return ERR_OK;
 | 
						|
    }
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
#endif /* (IOT_STA_CONTROL_MODE == 2) || (IOT_DEV_TEST_CCO_MODE) */
 | 
						|
 |