1479 lines
		
	
	
		
			45 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1479 lines
		
	
	
		
			45 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /****************************************************************************
 | ||
| 
 | ||
| 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_module_api.h"
 | ||
| #include "iot_queue_api.h"
 | ||
| #include "iot_mem_pool_api.h"
 | ||
| #include "iot_config_api.h"
 | ||
| #include "iot_app_api.h"
 | ||
| #include "iot_io_api.h"
 | ||
| #include "iot_uart_api.h"
 | ||
| #include "iot_task_api.h"
 | ||
| #include "iot_flash_api.h"
 | ||
| #include "iot_system_api.h"
 | ||
| #include "iot_version_api.h"
 | ||
| #include "iot_oem_api.h"
 | ||
| #include "iot_board_api.h"
 | ||
| 
 | ||
| #include "iot_dev_test.h"
 | ||
| #include "iot_grapp.h"
 | ||
| #include "iot_plctxrx.h"
 | ||
| #include "iot_proto_dl645.h"
 | ||
| #include "iot_proto_common.h"
 | ||
| #include "iot_proto_ge.h"
 | ||
| #include "iot_app_cus_flash.h"
 | ||
| 
 | ||
| #if IOT_GE_CKQ_MODE_ENABLE
 | ||
| 
 | ||
| devtest_645_cmd_cache_t g_dev_test_buf;
 | ||
| /* The dev test context. */
 | ||
| static dev_test_context_t *dev_test_context = NULL;
 | ||
| extern mcu_data_handle_t mcu_data;
 | ||
| extern uint8_t ge_buf[];
 | ||
| char dev_test_log_buf[IOT_DEV_TEST_LOG_BUF_LEN];
 | ||
| 
 | ||
| #define dev_test_is_firedup()         (DEV_TEST_MODULE_MAGIC_KEY == \
 | ||
|                                         dev_test_context->mkey)
 | ||
| #define dev_test_fire_now()           (dev_test_context->mkey = \
 | ||
|                                         DEV_TEST_MODULE_MAGIC_KEY)
 | ||
| 
 | ||
| static void iot_dev_test_bin_dump(uint8_t *data, uint32_t dlen)
 | ||
| {
 | ||
|     uint32_t i = 0;
 | ||
|     uint32_t offset = 0;
 | ||
| 
 | ||
|     offset = iot_sprintf(dev_test_log_buf, "dump pkt[len:%d]",dlen);
 | ||
|     for (i = 0; i < dlen; ++i) {
 | ||
|         offset += iot_sprintf(dev_test_log_buf + offset, "%02X ", data[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);
 | ||
|     return;
 | ||
| }
 | ||
| 
 | ||
| /* This will store config onto customer flash area. */
 | ||
| static uint32_t iot_dev_test_flashsave(custom_flash_info_t *p_info)
 | ||
| {
 | ||
|     if (NULL == p_info) {
 | ||
|         DERROR("Invalid argument!\n");
 | ||
|         return ERR_FAIL;
 | ||
|     }
 | ||
| 
 | ||
|     return cus_app_flash_write(IOT_DEV_TEST_FLASH_START_OFFSET, (uint8_t *)p_info,
 | ||
|         sizeof(*p_info));
 | ||
| }
 | ||
| 
 | ||
| /* Load config from customer flash. */
 | ||
| static uint32_t iot_dev_test_flashload(custom_flash_info_t *p_info)
 | ||
| {
 | ||
|     if (NULL == p_info) {
 | ||
|         iot_cus_printf("Invalid argument!\n");
 | ||
|         return ERR_FAIL;
 | ||
|     }
 | ||
| 
 | ||
|     return cus_app_flash_read(IOT_DEV_TEST_FLASH_START_OFFSET, (uint8_t *)p_info,
 | ||
|         sizeof(*p_info));
 | ||
| }
 | ||
| 
 | ||
| /* Repair this config when it is damaged. */
 | ||
| static void iot_dev_test_flashinfo_repair(custom_flash_info_t *p_info)
 | ||
| {
 | ||
|     if (NULL == p_info) {
 | ||
|         iot_cus_printf("Invalid argument!\n");
 | ||
|         return;
 | ||
|     }
 | ||
| 
 | ||
|     p_info->magic1[0] = (IOT_PROTO_CUST_FLASHINFO_MAGIC1 >> 24) & 0xFF;
 | ||
|     p_info->magic1[1] = (IOT_PROTO_CUST_FLASHINFO_MAGIC1 >> 16) & 0xFF;
 | ||
|     p_info->magic1[2] = (IOT_PROTO_CUST_FLASHINFO_MAGIC1 >> 8) & 0xFF;
 | ||
|     p_info->magic1[3] = (IOT_PROTO_CUST_FLASHINFO_MAGIC1) & 0xFF;
 | ||
| 
 | ||
|     p_info->magic2[0] = (IOT_PROTO_CUST_FLASHINFO_MAGIC2 >> 24) & 0xFF;
 | ||
|     p_info->magic2[1] = (IOT_PROTO_CUST_FLASHINFO_MAGIC2 >> 16) & 0xFF;
 | ||
|     p_info->magic2[2] = (IOT_PROTO_CUST_FLASHINFO_MAGIC2 >> 8) & 0xFF;
 | ||
|     p_info->magic2[3] = (IOT_PROTO_CUST_FLASHINFO_MAGIC2) & 0xFF;
 | ||
| 
 | ||
|     /* Write flash. */
 | ||
|     if (ERR_OK == iot_dev_test_flashsave(p_info)) {
 | ||
|         iot_cus_printf("Repair flash successfully!\n");
 | ||
|     } else {
 | ||
|         iot_cus_printf("Repair flash failed!\n");
 | ||
|     }
 | ||
| 
 | ||
|     return;
 | ||
| }
 | ||
| 
 | ||
| /* To dump our config info on flash. */
 | ||
| static void  iot_dev_test_dump_flash(custom_flash_info_t* p_info)
 | ||
| {
 | ||
|     iot_cus_printf("\nMagic1 : 0x%02x%02x%02x%02x.",
 | ||
|         p_info->magic1[0], p_info->magic1[1],
 | ||
|         p_info->magic1[2], p_info->magic1[3]);
 | ||
| 
 | ||
|     iot_cus_printf("\nLocal_dev:%d  Mac: %02x-%02x-%02x-%02x-%02x-%02x.",
 | ||
|         p_info->local_type, p_info->local_mac[0],
 | ||
|         p_info->local_mac[1], p_info->local_mac[2],
 | ||
|         p_info->local_mac[3], p_info->local_mac[4],
 | ||
|         p_info->local_mac[5]);
 | ||
| 
 | ||
|     iot_cus_printf("\nbaudidx=%d-wl_state=%d.",p_info->baudidx,
 | ||
|         p_info->wl_state);
 | ||
| 
 | ||
|     iot_cus_printf("\nMagic2 : 0x%02x%02x%02x%02x.",
 | ||
|         p_info->magic2[0], p_info->magic2[1],
 | ||
|         p_info->magic2[2], p_info->magic2[3]);
 | ||
| 
 | ||
|     return;
 | ||
| }
 | ||
| 
 | ||
| /* Check the magic code to tell if our config damaged. */
 | ||
| static uint32_t iot_dev_test_flashinfo_check(custom_flash_info_t *p_info)
 | ||
| {
 | ||
|     int32_t magic1, magic2;
 | ||
| 
 | ||
|     if (NULL == p_info) {
 | ||
|         iot_cus_printf("Invalid argument!\n");
 | ||
|         return ERR_FAIL;
 | ||
|     }
 | ||
| 
 | ||
|     magic1 = (p_info->magic1[0] << 24) | (p_info->magic1[1] << 16)
 | ||
|             | (p_info->magic1[2] << 8) | p_info->magic1[3];
 | ||
| 
 | ||
|     magic2 = (p_info->magic2[0] << 24) | (p_info->magic2[1] << 16)
 | ||
|             | (p_info->magic2[2] << 8) | p_info->magic2[3];
 | ||
| 
 | ||
|     iot_cus_printf("Magic = 0x%08x, 0x%08x!\n", magic1, magic2);
 | ||
| 
 | ||
|     if ((IOT_PROTO_CUST_FLASHINFO_MAGIC1 != magic1)
 | ||
|         ||(IOT_PROTO_CUST_FLASHINFO_MAGIC2 != magic2)) {
 | ||
|         iot_cus_printf("Magic dismatch!\n");
 | ||
|         return ERR_FAIL;
 | ||
|     }
 | ||
| 
 | ||
|     return ERR_OK;
 | ||
| }
 | ||
| 
 | ||
| static void iot_dev_test_flashinfo_init(void)
 | ||
| {
 | ||
|     custom_flash_info_t *p_flash = &(dev_test_context->flashinfo);
 | ||
| 
 | ||
|     iot_cus_printf("sizeof(custom_flash_info_t) = %d\n",
 | ||
|         sizeof(custom_flash_info_t));
 | ||
| 
 | ||
|     /* Load and check flash info. */
 | ||
|     if ((ERR_FAIL == iot_dev_test_flashload(p_flash)) ||
 | ||
|         (ERR_FAIL == iot_dev_test_flashinfo_check(p_flash))) {
 | ||
|         iot_cus_printf("Cannot get custom flash info!\n");
 | ||
|         os_mem_set(p_flash, 0x0, sizeof(*p_flash));
 | ||
| #if HW_PLATFORM == HW_PLATFORM_SIMU
 | ||
|         iot_mac_addr_cpy(p_flash->local_mac, g_ucMACAddress);
 | ||
| #endif
 | ||
|         p_flash->wl_state = 1;
 | ||
|         p_flash->baudidx = IOT_DEV_TEST_UART_BAUD_IDX_9600;
 | ||
|         iot_dev_test_flashinfo_repair(p_flash);
 | ||
|     }
 | ||
|     /* config uart param */
 | ||
|     iot_grapp_modify_uart_param(p_flash->baudidx, IOT_UART_PARITY_NONE,
 | ||
|         IOT_UART_DLEN_8_BITS, IOT_UART_STOP_1_BITS);
 | ||
|     /* dump flash info */
 | ||
|     iot_dev_test_dump_flash(p_flash);
 | ||
| 
 | ||
|     return;
 | ||
| }
 | ||
| 
 | ||
| /* cut preamble, checksum and tail of a intact frame, send data to plctxrx */
 | ||
| static void iot_dev_test_data_send_to_plctxrx(uint8_t *data, uint8_t len,
 | ||
|                               protpkt_tx_info_t *txinfo)
 | ||
| {
 | ||
|     iot_pkt_t *send_pkt;
 | ||
|     uint8_t *ptr;
 | ||
|     uint8_t org_frm_len;
 | ||
|     uint8_t cur_frm_len;
 | ||
|     uint16_t i;
 | ||
| 
 | ||
|     uint16_t total_frm_len = 0;
 | ||
| 
 | ||
|     /* send connless packet, ckq always send connless pkt, no aggr */
 | ||
|     txinfo->force_tx_connless = 1;
 | ||
|     txinfo->force_noaggr = 1;
 | ||
|     txinfo->need_ack = false;
 | ||
| 
 | ||
|     send_pkt = iot_pkt_alloc(len, IOT_GREE_APP_MID);
 | ||
| 
 | ||
|     if (!send_pkt) {
 | ||
|         IOT_ASSERT(send_pkt);
 | ||
|         return;
 | ||
|     }
 | ||
| 
 | ||
|     ptr = data;
 | ||
|     /** del peamble code,checksum code and tail
 | ||
|      * code of each gree frame
 | ||
|      */
 | ||
|     for (i = 0; i < len;) {
 | ||
|         org_frm_len =
 | ||
|             ACQUIRE_DATA_LEN(ptr[GE_FRM_DATA_LEN_POS]) + GE_FRM_MIN_LEN;
 | ||
|         IOT_ASSERT(org_frm_len >= GE_FRM_MIN_LEN &&
 | ||
|             org_frm_len <= GE_FRM_MAX_LEN);
 | ||
|         cur_frm_len = org_frm_len - GE_FRM_PREAMBLE_FIELD_LEN
 | ||
|                           - GE_FRM_CHECKSUM_FIELD_LEN
 | ||
|                           - GE_FRM_TAIL_FILED_LEN;
 | ||
| 
 | ||
|         os_mem_cpy(iot_pkt_data(send_pkt) + total_frm_len,
 | ||
|             ptr + GE_FRM_PREAMBLE_FIELD_LEN, cur_frm_len);
 | ||
|         total_frm_len += cur_frm_len;
 | ||
|         iot_pkt_put(send_pkt, cur_frm_len);
 | ||
|         /* +1 means move one byte forward */
 | ||
|         i += org_frm_len + 1;
 | ||
|         ptr += org_frm_len;
 | ||
|     }
 | ||
| 
 | ||
|     if (dev_test_context->fn_callback.data_send_cb) {
 | ||
|         /* here send data to remote peer */
 | ||
|         (dev_test_context->fn_callback.data_send_cb)(iot_pkt_data(send_pkt),
 | ||
|             (uint8_t)iot_pkt_data_len(send_pkt), txinfo);
 | ||
|     }
 | ||
| 
 | ||
|     iot_pkt_free(send_pkt);
 | ||
| }
 | ||
| 
 | ||
| static void iot_dev_test_remote_data_send_to_plctxrx(uint8_t *data, uint8_t len,
 | ||
|     protpkt_tx_info_t *txinfo)
 | ||
| {
 | ||
|     iot_cus_printf("[ckq]data_send_to_plctxrx:\n");
 | ||
| 
 | ||
|     iot_dev_test_bin_dump(data, len);
 | ||
| 
 | ||
|     iot_dev_test_data_send_to_plctxrx(data, len, txinfo);
 | ||
| }
 | ||
| 
 | ||
| /* This will send a iot_pkt_t of data to UART connected to mainboard. */
 | ||
| static void iot_dev_test_send_to_mainboard(iot_pkt_t *p_pkt)
 | ||
| {
 | ||
|     iot_cus_printf("[ckq]iot_dev_test_send_to_mainboard:\n");
 | ||
| 
 | ||
|     iot_dev_test_bin_dump(iot_pkt_data(p_pkt), iot_pkt_data_len(p_pkt));
 | ||
| 
 | ||
|     if (dev_test_context->fn_callback.up_send_cb) {
 | ||
|         (dev_test_context->fn_callback.up_send_cb)(p_pkt);
 | ||
|     } else {
 | ||
|         iot_pkt_free(p_pkt);
 | ||
|     }
 | ||
| 
 | ||
|     return;
 | ||
| }
 | ||
| 
 | ||
| static void iot_dev_test_cmd_send_to_plc(iot_pkt_t *p_pkt)
 | ||
| {
 | ||
|     if (!dev_test_is_firedup()) {
 | ||
|         iot_cus_printf("dev test module not ready.\n");
 | ||
|         return;
 | ||
|     }
 | ||
| 
 | ||
|     (dev_test_context->fn_callback.cmd_send_cb)(p_pkt);
 | ||
| 
 | ||
|     return;
 | ||
| }
 | ||
| 
 | ||
| static void iot_dev_test_task_post_msg(uint16_t m_type, uint16_t m_id, iot_pkt_t *data)
 | ||
| {
 | ||
|     dev_test_msg_t *task_msg;
 | ||
| 
 | ||
|     task_msg = (dev_test_msg_t*)iot_task_alloc_msg_with_reserved
 | ||
|         (dev_test_context->task_handle, 0);
 | ||
| 
 | ||
|     if (NULL == task_msg) {
 | ||
|         if (NULL != data) {
 | ||
|             iot_pkt_free(data);
 | ||
|         }
 | ||
|         iot_cus_printf("%s Alloc message failed !!\n", __FUNCTION__);
 | ||
|         return;
 | ||
|     }
 | ||
| 
 | ||
|     task_msg->msg.type = m_type;
 | ||
|     task_msg->msg.id = m_id;
 | ||
|     task_msg->data = data;
 | ||
| 
 | ||
|     iot_task_queue_msg(dev_test_context->task_handle, &task_msg->msg, 0);
 | ||
| 
 | ||
|     return;
 | ||
| }
 | ||
| 
 | ||
| uint8_t iot_dev_test_fn_register_send_to_uart(fn_send_to_ext_mcu_t fn)
 | ||
| {
 | ||
|     IOT_ASSERT(fn);
 | ||
| 
 | ||
|     dev_test_context->fn_callback.up_send_cb = fn;
 | ||
| 
 | ||
|     return ERR_OK;
 | ||
| }
 | ||
| 
 | ||
| static void iot_dev_test_stop_nw_fmt(bool_t need_ack_cfm)
 | ||
| {
 | ||
|     iot_pkt_t *p_pkt;
 | ||
|     plctxrx_cmd_arg_t *p_arg;
 | ||
| 
 | ||
|     p_pkt = iot_pkt_alloc(sizeof(*p_arg), IOT_GREE_APP_MID);
 | ||
|     IOT_ASSERT(p_pkt);
 | ||
|     iot_pkt_put(p_pkt, sizeof(*p_arg));
 | ||
| 
 | ||
|     p_arg = (plctxrx_cmd_arg_t *)iot_pkt_data(p_pkt);
 | ||
|     p_arg->cid.cid = PLCTXRX_CID_END_GROUP_NET;
 | ||
|     p_arg->cid.opcode = PLCTXRX_OP_CONFIG;
 | ||
|     p_arg->prio = 0;
 | ||
|     p_arg->need_ack = need_ack_cfm;
 | ||
|     p_arg->dlen = 0;
 | ||
| 
 | ||
|     iot_dev_test_cmd_send_to_plc(p_pkt);
 | ||
| }
 | ||
| 
 | ||
| static void iot_dev_test_set_band(uint8_t band, bool_t need_ack_cfm)
 | ||
| {
 | ||
|     iot_pkt_t *p_pkt;
 | ||
|     plctxrx_cmd_band_info_t *p_band;
 | ||
|     plctxrx_cmd_arg_t *p_arg;
 | ||
| 
 | ||
|     p_pkt = iot_pkt_alloc(sizeof(*p_band) + sizeof(*p_arg), IOT_GREE_APP_MID);
 | ||
|     IOT_ASSERT(p_pkt);
 | ||
|     iot_pkt_put(p_pkt, sizeof(*p_band) + sizeof(*p_arg));
 | ||
| 
 | ||
|     p_arg = (plctxrx_cmd_arg_t *)iot_pkt_data(p_pkt);
 | ||
|     p_arg->cid.cid = PLCTXRX_CID_BAND_ID;
 | ||
|     p_arg->cid.opcode = PLCTXRX_OP_CONFIG;
 | ||
|     p_arg->prio = 0;
 | ||
|     p_arg->need_ack = need_ack_cfm;
 | ||
|     p_arg->dlen = sizeof(*p_band);
 | ||
| 
 | ||
|     p_band = (plctxrx_cmd_band_info_t *)p_arg->arg;
 | ||
|     p_band->band_id = band;
 | ||
| 
 | ||
|     iot_dev_test_cmd_send_to_plc(p_pkt);
 | ||
| }
 | ||
| 
 | ||
| static void iot_dev_test_set_wdg(uint8_t action, uint16_t interval,
 | ||
|     bool_t need_ack_cfm)
 | ||
| {
 | ||
|     iot_pkt_t *p_pkt;
 | ||
|     plctxrx_cmd_wdg_t *p_wdg;
 | ||
|     plctxrx_cmd_arg_t *p_arg;
 | ||
| 
 | ||
|     p_pkt = iot_pkt_alloc(sizeof(*p_wdg) + sizeof(*p_arg), IOT_GREE_APP_MID);
 | ||
|     IOT_ASSERT(p_pkt);
 | ||
|     iot_pkt_put(p_pkt, sizeof(*p_wdg) + sizeof(*p_arg));
 | ||
| 
 | ||
|     p_arg = (plctxrx_cmd_arg_t *)iot_pkt_data(p_pkt);
 | ||
|     p_arg->cid.cid = PLCTXRX_CID_WDG;
 | ||
|     p_arg->cid.opcode = PLCTXRX_OP_CONFIG;
 | ||
|     p_arg->prio = 0;
 | ||
|     p_arg->need_ack = need_ack_cfm;
 | ||
|     p_arg->dlen = sizeof(*p_wdg);
 | ||
| 
 | ||
|     p_wdg = (plctxrx_cmd_wdg_t *)p_arg->arg;
 | ||
|     p_wdg->action = action;
 | ||
|     p_wdg->interval = interval;
 | ||
| 
 | ||
|     iot_dev_test_cmd_send_to_plc(p_pkt);
 | ||
| }
 | ||
| 
 | ||
| static void iot_dev_test_set_cfg_after_app_reg(void)
 | ||
| {
 | ||
|     /* stop network formation */
 | ||
|     iot_dev_test_stop_nw_fmt(true);
 | ||
| 
 | ||
|     /* close watchdog */
 | ||
|     iot_dev_test_set_wdg(0, 0, true);
 | ||
| 
 | ||
|     /* set band */
 | ||
|     iot_dev_test_set_band(DEV_TEST_DEFAULT_FRQ_BAND, true);
 | ||
| 
 | ||
|     /* start reload timer */
 | ||
|     os_start_timer(dev_test_context->mod_cfg_tmr, DEV_TEST_TMR_MODE_CFG_INTVL);
 | ||
| }
 | ||
| 
 | ||
| static uint8_t iot_dev_test_check_local_dl645_cmd(proto_645_header_t *hdr)
 | ||
| {
 | ||
|     uint8_t ret = false;
 | ||
|     uint32_t di = 0;
 | ||
| 
 | ||
|     proto_645_header_t *hdr_645 = hdr;
 | ||
|     iot_cus_printf("[ckq]local hdr_645->control.fn = %x\n", hdr_645->control.fn);
 | ||
|     iot_proto_645_get_di_by_sub33(hdr_645->data, hdr_645->len, &di);
 | ||
|     iot_cus_printf("[ckq]local check di = %x\n", di);
 | ||
| 
 | ||
|     switch (hdr_645->control.fn) {
 | ||
|     case PROTO_645_2007_FN_READ_DATA:
 | ||
|     {
 | ||
|         if (iot_sta_check_local_645_di(di)) {
 | ||
|             ret = true;
 | ||
|         }
 | ||
|         break;
 | ||
|     }
 | ||
|     case PROTO_645_2007_FN_READ_ADDR:
 | ||
|     {
 | ||
|         //TO DO
 | ||
|         break;
 | ||
|     }
 | ||
|     case PROTO_645_2007_FN_WRITE_DATA:
 | ||
|     {
 | ||
|         if (iot_sta_check_local_645_di(di)) {
 | ||
|             ret = true;
 | ||
|         }
 | ||
|         break;
 | ||
|     }
 | ||
|     default:
 | ||
|         /* TO DO */
 | ||
|         break;
 | ||
|     }
 | ||
| 
 | ||
|     return ret;
 | ||
| }
 | ||
| 
 | ||
| /**
 | ||
|  * @brief iot_dev_test_645_format_check_handle() - get a dl645 frame, firstly,
 | ||
|                                     the 645 frame should be packed to a extern
 | ||
|                                     645 frame. then, the extern 645 frame should
 | ||
|                                     be packed to a FE A0 ge frame. at last,copy
 | ||
|                                     to the ge_buf closely in the function.
 | ||
|  * @param recv_data:   point to the data frame to be checked
 | ||
|  * @param pdata:       point to the output ge data buffer
 | ||
|  * @param ret_size:    point to the length of output ge frame, it should be added
 | ||
|  *                     if a ge frame is built
 | ||
|  * @param checked_len: point to the length of input data checked over, it should
 | ||
|                        be added in order to check the next positon
 | ||
|  */
 | ||
| static uint8_t iot_dev_test_645_format_check_handle(mcu_data_handle_t *recv_data,
 | ||
|     uint8_t *pdata, uint16_t *ret_size, uint16_t *checked_len)
 | ||
| {
 | ||
|     uint8_t check_ret;
 | ||
|     uint16_t intact_dl645_len = 0;
 | ||
|     uint16_t dl645_len = 0;
 | ||
|     uint16_t ge_len = 0;
 | ||
|     proto_645_header_t *intact_hdr_645 = NULL;
 | ||
|     proto_645_header_t *hdr_645 = NULL;
 | ||
|     uint16_t len = recv_data->total_len - recv_data->data_pos;
 | ||
|     uint8_t *data = &recv_data->data[recv_data->data_pos];
 | ||
|     uint8_t revert_local_mac[IOT_MAC_ADDR_LEN];
 | ||
|     uint8_t dst_mac[IOT_MAC_ADDR_LEN];
 | ||
|     uint8_t *ext_645_buf = NULL;
 | ||
|     uint16_t ext_645_len = 0;
 | ||
|     uint32_t di = 0;
 | ||
|     iot_pkt_t *pkt = NULL;
 | ||
| 
 | ||
|     iot_proto_645_frm_format_check(data, len, &check_ret);
 | ||
| 
 | ||
|     if (check_ret != GET_ONE_FRAME) {
 | ||
|         return check_ret;
 | ||
|     }
 | ||
| 
 | ||
|     iot_cus_printf("%s GET_ONE_FRAME!\n", __FUNCTION__);
 | ||
|     intact_hdr_645 = (proto_645_header_t *)data;
 | ||
|     intact_dl645_len = intact_hdr_645->len + DL645_PARSE_FRM_MIN_LEN;
 | ||
|     iot_proto_645_get_di_by_sub33(intact_hdr_645->data, intact_hdr_645->len, &di);
 | ||
| 
 | ||
|     iot_mac_addr_cpy(g_dev_test_buf.dst_mac, intact_hdr_645->addr);
 | ||
|     iot_mac_addr_cpy(dst_mac, intact_hdr_645->addr);
 | ||
| 
 | ||
|     if (DL645_07_DI_DL645_TYPE == di) {
 | ||
|         iot_proto_645_ext_sub33_handle(intact_hdr_645->data, intact_hdr_645->len);
 | ||
|         hdr_645 = (proto_645_header_t *)(intact_hdr_645->data + DL645_DI_LEN);
 | ||
|     } else {
 | ||
|         hdr_645 = intact_hdr_645;
 | ||
|     }
 | ||
| 
 | ||
|     dl645_len = hdr_645->len + DL645_PARSE_FRM_MIN_LEN;
 | ||
|     iot_mac_addr_reverse(dst_mac);
 | ||
| 
 | ||
|     if (iot_ge_buf_overflow_test(*ret_size, dl645_len +
 | ||
|         sizeof(ge_frame_data_send_set_subfn160_t) + sizeof(ge_frm_tail_t))) {
 | ||
|         if (g_dev_test_buf.cmd_valid) {
 | ||
|             iot_cus_printf("%s ckq is already running a cmd\n", __FUNCTION__);
 | ||
|             goto out;
 | ||
|         }
 | ||
| 
 | ||
|         os_mem_cpy(g_dev_test_buf.cmd_buf, hdr_645, dl645_len);
 | ||
|         g_dev_test_buf.cmd_valid = 1;
 | ||
| 
 | ||
|         if (true == iot_dev_test_check_local_dl645_cmd(hdr_645)) {
 | ||
|             /* the dl645 data is local cmd, we skip sending the first cmd to
 | ||
|               enable ckq mode of sta, start the timer directly for sending the
 | ||
|               second cmd
 | ||
|             */
 | ||
|             if (!os_is_timer_active(dev_test_context->ckq_cmd_intvl_tmr)) {
 | ||
|                 os_start_timer(dev_test_context->ckq_cmd_intvl_tmr, 0);
 | ||
|             }
 | ||
|         } else {
 | ||
|             /* send the first cmd to enable ckq mode of sta */
 | ||
|             iot_mac_addr_cpy(revert_local_mac, dev_test_context->mac);
 | ||
|             iot_mac_addr_reverse(revert_local_mac);
 | ||
|             pkt = iot_pkt_alloc(DL645_PARSE_FRM_MAX_LEN, IOT_GREE_APP_MID);
 | ||
| 
 | ||
|             if (pkt == NULL) {
 | ||
|                 iot_cus_printf("%s pkt alloc err!\n", __FUNCTION__);
 | ||
|                 goto out;
 | ||
|             }
 | ||
| 
 | ||
|             ext_645_buf = iot_pkt_data(pkt);
 | ||
|             ext_645_len = dl645_len;
 | ||
|             iot_proto_pack_data_to_dl645((uint8_t *)hdr_645, ext_645_buf,
 | ||
|                 &ext_645_len, DL645_07_DI_CKQ_READ_MODE_EN, revert_local_mac,
 | ||
|                 PROTO_645_2007_FN_READ_DATA, PROTO_645_DIR_MASTER);
 | ||
|             ge_len = ext_645_len;
 | ||
|             iot_cus_printf("[ckq]ext_645_buf:");
 | ||
|             iot_dev_test_bin_dump(ext_645_buf, ext_645_len);
 | ||
|             iot_pack_dl645_to_ge(ext_645_buf, &pdata[*ret_size], &ge_len,
 | ||
|                 dst_mac, true);
 | ||
|             iot_pkt_free(pkt);
 | ||
|             if (!os_is_timer_active(dev_test_context->ckq_cmd_intvl_tmr)) {
 | ||
|                 os_start_timer(dev_test_context->ckq_cmd_intvl_tmr,
 | ||
|                     DEV_TEST_TMR_CKQ_CMD_INTVL);
 | ||
|             }
 | ||
|         }
 | ||
|     } else {
 | ||
|         check_ret = GET_OVERFLOW;
 | ||
|         iot_cus_printf("%s ge_buf overflow!\n", __FUNCTION__);
 | ||
|     }
 | ||
| out:
 | ||
|     *ret_size += ge_len;
 | ||
|     *checked_len = intact_dl645_len;
 | ||
|     return check_ret;
 | ||
| }
 | ||
| 
 | ||
| /* post uart received command to task */
 | ||
| static uint8_t iot_dev_test_task_post_uart_cmd(uint8_t * data, uint16_t len)
 | ||
| {
 | ||
|     iot_pkt_t* send_pkt = NULL;
 | ||
| 
 | ||
|     if (NULL == data || 0 == len) {
 | ||
|         iot_cus_printf("%s data err!\n", __FUNCTION__);
 | ||
|         return ERR_FAIL;
 | ||
|     }
 | ||
| 
 | ||
|     send_pkt = iot_pkt_alloc(len, IOT_GREE_APP_MID);
 | ||
| 
 | ||
|     if (send_pkt) {
 | ||
|         /* copy data from buf to data packet */
 | ||
|         os_mem_cpy(iot_pkt_put(send_pkt, len), data, len);
 | ||
| 
 | ||
|         /* alloc message to insert proto task msg queue */
 | ||
|         iot_dev_test_task_post_msg(DEV_TEST_MCU_RX_MSG, 0, send_pkt);
 | ||
|         return ERR_OK;
 | ||
|     } else {
 | ||
|         iot_cus_printf("%s no mem, frame len:%d\n", __FUNCTION__, len);
 | ||
|         return ERR_FAIL;
 | ||
|     }
 | ||
| }
 | ||
| 
 | ||
| uint8_t iot_dev_test_uart_meter_port_func(uint8_t *buf, uint16_t len)
 | ||
| {
 | ||
|     uint8_t*             pdata;
 | ||
|     uint8_t*             pbuf;
 | ||
|     uint8_t              check_result = GET_NO_FRAME;
 | ||
|     uint16_t             total;
 | ||
|     uint16_t             ge_buflen;
 | ||
|     mcu_data_handle_t*   p_mcudata;
 | ||
|     uint16_t             check_over_len;
 | ||
| 
 | ||
|     if (NULL == buf || len == 0) {
 | ||
|         return ERR_FAIL;
 | ||
|     }
 | ||
| 
 | ||
|     total = len;
 | ||
|     pbuf = buf;
 | ||
|     p_mcudata = &mcu_data;
 | ||
| 
 | ||
|     /* uart drv may report len > UART_RECV_SIZE_MAX, so we handle it in times */
 | ||
|     do {
 | ||
|         /* data_pos indicate possible gree frame start from. if it is larger
 | ||
|            than max gree size, means pmcudata[0] ~ p_mcudata[GE_FRM_MAX_LEN] not
 | ||
|            valide gree frame. however, it should not happen. paser function
 | ||
|            should alreay remove garbage bytes.*/
 | ||
|         if (p_mcudata->data_pos >= GE_FRM_MAX_LEN) {
 | ||
|             iot_cus_printf("[ckq][err] data_pos:%d total:%d\n",
 | ||
|                 p_mcudata->data_pos, total);
 | ||
|             goto error;
 | ||
|         }
 | ||
| 
 | ||
|         pdata = &p_mcudata->data[p_mcudata->data_pos];
 | ||
|         iot_cus_printf("[ckq]break frame pos= %d new_len=%d\n",
 | ||
|             p_mcudata->data_pos, len);
 | ||
| 
 | ||
|         if (total > UART_RECV_SIZE_MAX) {
 | ||
|             os_mem_cpy(pdata, pbuf, UART_RECV_SIZE_MAX);
 | ||
|             pbuf += UART_RECV_SIZE_MAX;
 | ||
|             total -= UART_RECV_SIZE_MAX;
 | ||
|             p_mcudata->total_len = UART_RECV_SIZE_MAX + p_mcudata->data_pos;
 | ||
|         } else {
 | ||
|             os_mem_cpy(pdata, pbuf, total);
 | ||
|             pbuf += total;
 | ||
|             p_mcudata->total_len = total + p_mcudata->data_pos;
 | ||
|             total = 0;
 | ||
|         }
 | ||
|         /* now position should be 0, one new paser cycle starts */
 | ||
|         p_mcudata->data_pos = 0;
 | ||
|         /* clean ge_buf */
 | ||
|         ge_buflen = 0;
 | ||
|         os_mem_set(ge_buf, 0, MCU_DATA_RECV_MAX);
 | ||
|         check_result = GET_NO_FRAME;
 | ||
| 
 | ||
|         /*
 | ||
|           do frame check from mcudata offset 0, and the function will return
 | ||
|           full gree frame buffer, ge_buf, and ge_buflen. Also, wrong packet
 | ||
|           in middle removed. remain half packet moved to head of p_mucdata.
 | ||
|         */
 | ||
|         while (p_mcudata->data_pos < p_mcudata->total_len) {
 | ||
|             check_over_len = 0;
 | ||
|             /*
 | ||
|               check and get the dl645 cmd from uart, firstly,the 645 frame
 | ||
|               should be packed to a extern 645 frame. then,the extern 645 frame
 | ||
|               should be packed to a FE A0 ge frame.
 | ||
|             */
 | ||
|             check_result = iot_dev_test_645_format_check_handle(p_mcudata,
 | ||
|                 ge_buf, &ge_buflen, &check_over_len);
 | ||
|             if (check_result == GET_ONE_FRAME) {
 | ||
|                 p_mcudata->data_pos += check_over_len;
 | ||
|                 continue;
 | ||
|             } else {
 | ||
|                 break;
 | ||
|             }
 | ||
|             p_mcudata->data_pos++;
 | ||
|         }
 | ||
| 
 | ||
|         if ((check_result == GET_HALF_FRAME) ||
 | ||
|             (check_result == GET_OVERFLOW)) {
 | ||
|             /* if half frame or overflow exist, save the rest of data */
 | ||
|             os_mem_cpy(p_mcudata->data, &p_mcudata->data[p_mcudata->data_pos],
 | ||
|                 p_mcudata->total_len - p_mcudata->data_pos);
 | ||
|             p_mcudata->data_pos = p_mcudata->total_len - p_mcudata->data_pos;
 | ||
|         } else {
 | ||
|             p_mcudata->total_len = 0;
 | ||
|             p_mcudata->data_pos = 0;
 | ||
|         }
 | ||
| 
 | ||
|         /* put filtered packeted in message queue */
 | ||
|         if (ge_buflen > 0) {
 | ||
|             iot_cus_printf("[ckq]ge_buflen:%d\n ", ge_buflen);
 | ||
|             iot_dev_test_bin_dump(ge_buf, ge_buflen);
 | ||
|             if (iot_dev_test_task_post_uart_cmd(ge_buf, ge_buflen)) {
 | ||
|                 goto error;
 | ||
|             }
 | ||
|         }
 | ||
|     } while ((total > 0) || (check_result == GET_OVERFLOW));
 | ||
| 
 | ||
|     return ERR_OK;
 | ||
| 
 | ||
| error:
 | ||
|     p_mcudata->data_pos = 0;
 | ||
| 
 | ||
|     return ERR_FAIL;
 | ||
| }
 | ||
| 
 | ||
| uint8_t iot_dev_test_plc_data_recv_func(protpkt_list_t *report_framelist,
 | ||
|                                         plctxrx_rx_data_info_t *rxinfo)
 | ||
| {
 | ||
|     IOT_ASSERT(report_framelist && rxinfo
 | ||
|                 && (report_framelist->frame_cnt > 0)
 | ||
|                 && (report_framelist->total_len > 0));
 | ||
|     uint8_t *buf, *tmp;
 | ||
|     list_node_t* node = report_framelist->list_head;
 | ||
|     /* alloc pkt */
 | ||
|     iot_pkt_t *pkt = iot_pkt_alloc(report_framelist->total_len + sizeof(*rxinfo),
 | ||
|         IOT_GREE_APP_MID);
 | ||
|     IOT_ASSERT(pkt);
 | ||
|     buf = iot_pkt_data(pkt);
 | ||
|     os_mem_cpy(buf, rxinfo, sizeof(*rxinfo));
 | ||
|     iot_pkt_put(pkt, sizeof(*rxinfo));
 | ||
|     /* copy data from each node */
 | ||
|     tmp = iot_pkt_block_ptr(pkt, IOT_PKT_BLOCK_TAIL);
 | ||
|     while (report_framelist->frame_cnt--) {
 | ||
|         IOT_ASSERT(node);
 | ||
|         os_mem_cpy(tmp, node->data, node->len);
 | ||
|         iot_pkt_put(pkt, node->len);
 | ||
|         tmp += node->len;
 | ||
|         node = node->next;
 | ||
|     }
 | ||
| 
 | ||
|     IOT_ASSERT(!node &&
 | ||
|         (buf + report_framelist->total_len + sizeof(*rxinfo) == tmp));
 | ||
| 
 | ||
|     iot_dev_test_task_post_msg(DEV_TEST_PLC_RX_MSG, 0, pkt);
 | ||
| 
 | ||
|     return ERR_OK;
 | ||
| }
 | ||
| 
 | ||
| /* local txrx cmd response  */
 | ||
| uint8_t iot_dev_test_plctxrx_cmd_resp_func(iot_pkt_t *data)
 | ||
| {
 | ||
|     IOT_ASSERT(data);
 | ||
| 
 | ||
|     iot_dev_test_task_post_msg(PROTO_PLC_RX_MSG, PROTO_PLCTXRX_RX_CMD_MSG, data);
 | ||
| 
 | ||
|     return ERR_OK;
 | ||
| }
 | ||
| 
 | ||
| uint8_t iot_dev_test_fn_register_send_to_plc(fn_cmd_send_to_plc_t cmd_cb,
 | ||
|     fn_data_send_to_plc_t data_cb)
 | ||
| {
 | ||
|     IOT_ASSERT(cmd_cb && data_cb);
 | ||
| 
 | ||
|     dev_test_context->fn_callback.data_send_cb = data_cb;
 | ||
|     dev_test_context->fn_callback.cmd_send_cb = cmd_cb;
 | ||
| 
 | ||
|     iot_dev_test_flashinfo_init();
 | ||
| 
 | ||
|     return ERR_OK;
 | ||
| }
 | ||
| 
 | ||
| /* to check the response of dl645 cmd */
 | ||
| static void iot_dev_test_645_cmd_resp_check(proto_645_header_t *hdr)
 | ||
| {
 | ||
|     proto_645_header_t *cmd_645 = NULL;
 | ||
| 
 | ||
|     if (0 == g_dev_test_buf.cmd_valid) {
 | ||
|         iot_cus_printf("dev test cmd buf not valid\n");
 | ||
|         return;
 | ||
|     }
 | ||
| 
 | ||
|     cmd_645 = (proto_645_header_t *)g_dev_test_buf.cmd_buf;
 | ||
|     /* if the mac of recieved dl645 frame same as the mac of cmd or the dst mac,
 | ||
|       means we get the right response, not wait for timeout.
 | ||
|     */
 | ||
|     if (iot_mac_addr_cmp(cmd_645->addr, hdr->addr) ||
 | ||
|         iot_mac_addr_cmp(g_dev_test_buf.dst_mac, hdr->addr)) {
 | ||
|         if (os_is_timer_active(dev_test_context->ckq_timeout_tmr)) {
 | ||
|             os_stop_timer(dev_test_context->ckq_timeout_tmr);
 | ||
|             iot_task_clean_msg(dev_test_context->task_handle,
 | ||
|                 DEV_TEST_TIMER_MSG, DEV_TEST_TIMER_CKQ_TIMEOUT);
 | ||
|             iot_cus_printf("ckq_timeout_tmr cleared\n");
 | ||
|         }
 | ||
|         g_dev_test_buf.cmd_valid = 0;
 | ||
|     }
 | ||
| }
 | ||
| 
 | ||
| static uint8_t iot_dev_test_plc_data_group_frame(uint8_t *dst, uint8_t *src)
 | ||
| {
 | ||
|     /**
 | ||
|      * payload of gree frame
 | ||
|      * field:| data cnt | id |    data      |
 | ||
|      * oct  :|   1 B    | 4B |   data cnt B |
 | ||
|      */
 | ||
|     uint8_t src_frm_len;
 | ||
|     IOT_ASSERT(src && dst);
 | ||
|     uint8_t *tmp_buf = dst;
 | ||
|     uint16_t check_sum = 0;
 | ||
| 
 | ||
|     /* add preamble */
 | ||
|     *((uint16_t *)tmp_buf) = GE_FRM_PREAMBLE_CODE;
 | ||
|     tmp_buf += GE_FRM_PREAMBLE_FIELD_LEN;
 | ||
| 
 | ||
|     /* get net payload len */
 | ||
|     src_frm_len = ACQUIRE_DATA_LEN(src[0]) + GE_FRM_DATA_CNT_FIELD_LEN +
 | ||
|         GE_FRM_ID_FIELD_LEN;
 | ||
| 
 | ||
|     IOT_ASSERT(src[0] <= GE_FRM_PLD_MAX_LEN &&
 | ||
|         src[0] >= GE_FRM_PLD_MIN_LEN);
 | ||
| 
 | ||
|     /* add payload */
 | ||
|     os_mem_cpy(tmp_buf, src, src_frm_len);
 | ||
| 
 | ||
|     tmp_buf += src_frm_len;
 | ||
|     /* add check sum */
 | ||
|     check_sum =
 | ||
|         ge_frm_checksum_calc(dst, src_frm_len + GE_FRM_PREAMBLE_FIELD_LEN);
 | ||
|     *tmp_buf = (uint8_t)(check_sum & 0xFF);
 | ||
| 
 | ||
|     *(tmp_buf + 1) = (uint8_t)(check_sum >> 8);
 | ||
| 
 | ||
|     tmp_buf += GE_FRM_CHECKSUM_FIELD_LEN;
 | ||
| 
 | ||
|     /* add tail */
 | ||
|     *tmp_buf = 0xFF;
 | ||
| 
 | ||
|     return src_frm_len;
 | ||
| }
 | ||
| 
 | ||
| static bool_t iot_dev_test_data_handler(uint8_t *data, uint8_t len,
 | ||
|     transmit_direction_e_t dir)
 | ||
| {
 | ||
|     bool_t rpt2mcu = false;
 | ||
|     protpkt_tx_info_t txinfo = { 0 };
 | ||
|     ge_frame_data_send_set_subfn160_t *hdr =
 | ||
|         (ge_frame_data_send_set_subfn160_t *)data;
 | ||
|     uint8_t dest_mac[IOT_MAC_ADDR_LEN];
 | ||
|     uint8_t retry_cnt;
 | ||
|     transmit_direction_e_t tmp_dir;
 | ||
| 
 | ||
|     if (CMD_LOCAL_DOWN_LINK == dir) {
 | ||
|         if (iot_mac_addr_cmp(hdr->dest_mac, dev_test_context->mac)) {
 | ||
|             return rpt2mcu;
 | ||
|         }
 | ||
|         iot_mac_addr_cpy(dest_mac, hdr->dest_mac);
 | ||
|         tmp_dir = DATA_DOWN_LINK;
 | ||
|     } else {
 | ||
|         tmp_dir = DATA_UP_LINK;
 | ||
|     }
 | ||
|     switch (tmp_dir) {
 | ||
|     case DATA_DOWN_LINK:
 | ||
|     {
 | ||
|         if(hdr->retr_cnt == 0) {
 | ||
|             retry_cnt = DEV_TEST_UNICAST_RETRY_DEFAULT_CNT;
 | ||
|         } else {
 | ||
|             retry_cnt = hdr->retr_cnt;
 | ||
|         }
 | ||
|         if (mac_addr_is_bcast_addr(hdr->dest_mac)) {
 | ||
|             iot_proto_fill_txinfo(&txinfo, false,
 | ||
|                 PLCTXRX_BORADCAST, PROTO_BROADCAST_RETRY_DEFAULT_CNT,
 | ||
|                 PROTO_BROADCAST_RETRY_DEFAULT_INTVL, 0,
 | ||
|                 dev_test_context->mac, NULL);
 | ||
|         } else {
 | ||
|             iot_proto_fill_txinfo(&txinfo, true,
 | ||
|                 PLCTXRX_UNICAST, retry_cnt,
 | ||
|                 PROTO_UNICAST_RETRY_DEFAULT_INTVL, 1,
 | ||
|                 dev_test_context->mac, dest_mac);
 | ||
|         }
 | ||
|         iot_dev_test_remote_data_send_to_plctxrx(data, len, &txinfo);
 | ||
|         break;
 | ||
|     }
 | ||
|     case DATA_UP_LINK:
 | ||
|     {
 | ||
|         rpt2mcu = true;
 | ||
|         break;
 | ||
|     }
 | ||
|     default:
 | ||
|         IOT_ASSERT(0);
 | ||
|         break;
 | ||
|     }
 | ||
|     return rpt2mcu;
 | ||
| }
 | ||
| 
 | ||
| static void iot_dev_test_handle_ge_from_plc(uint8_t *data, uint8_t *len,
 | ||
|     transmit_direction_e_t dir, uint8_t *rpt2mcu)
 | ||
| {
 | ||
|     /* the index of the input data */
 | ||
|     uint16_t index = 0;
 | ||
|     /* the data length of the input pkt */
 | ||
|     uint16_t input_data_len;
 | ||
|     /* the data length of the frame unpacked from ge frame */
 | ||
|     uint16_t data_len_after_handle = 0;
 | ||
|     /* the data length of each data frame */
 | ||
|     uint16_t frame_data_len;
 | ||
|     uint8_t* buf;
 | ||
|     ge_frame_data_send_set_subfn160_t *p_buf;
 | ||
|     ge_extend_fn_hdr_t *p_buf_hdr;
 | ||
|     proto_645_header_t *hdr_645 = NULL;
 | ||
| 
 | ||
|     buf = data;
 | ||
|     input_data_len = *len;
 | ||
| 
 | ||
|     if (CMD_REMOTE_UP_LINK != dir) {
 | ||
|         iot_cus_printf("transmit direction mismatch!\n");
 | ||
|         return;
 | ||
|     }
 | ||
| 
 | ||
|     while (index < input_data_len) {
 | ||
|         p_buf = (ge_frame_data_send_set_subfn160_t *)&buf[index];
 | ||
|         if (p_buf->resv == DL645_07_RESV0_RESV) {
 | ||
|             frame_data_len = p_buf->hdr.hdr.data_len;
 | ||
|             os_mem_cpy(&buf[data_len_after_handle],
 | ||
|                 &buf[index + GE_FEA0_HEAD_LEN],
 | ||
|                 frame_data_len - IOT_MAC_ADDR_LEN);
 | ||
|             hdr_645 = (proto_645_header_t *)(&buf[data_len_after_handle]);
 | ||
|             iot_dev_test_645_cmd_resp_check(hdr_645);
 | ||
|             data_len_after_handle += frame_data_len - IOT_MAC_ADDR_LEN;
 | ||
|             index += frame_data_len +
 | ||
|                 sizeof(ge_frame_data_send_set_subfn160_t) +
 | ||
|                 sizeof(ge_frm_tail_t) - IOT_MAC_ADDR_LEN;
 | ||
|         /* other FEA0 frames */
 | ||
|         } else {
 | ||
|             p_buf_hdr = (ge_extend_fn_hdr_t *)&buf[index];
 | ||
|             frame_data_len = p_buf_hdr->hdr.data_len;
 | ||
|             os_mem_cpy(&buf[data_len_after_handle], &buf[index],
 | ||
|                 GE_FRM_MIN_LEN + frame_data_len);
 | ||
|             index += GE_FRM_MIN_LEN + frame_data_len;
 | ||
|             data_len_after_handle += GE_FRM_MIN_LEN + frame_data_len;
 | ||
|             rpt2mcu = false;
 | ||
|         }
 | ||
|     }
 | ||
|     *len = data_len_after_handle;
 | ||
| }
 | ||
| 
 | ||
| static void iot_dev_test_mode_config_timer(timer_id_t timer_id, void * arg)
 | ||
| {
 | ||
|     (void)arg;
 | ||
|     (void)timer_id;
 | ||
| 
 | ||
|     iot_dev_test_task_post_msg(DEV_TEST_TIMER_MSG,
 | ||
|         DEV_TEST_TIMER_MODE_CONFIG_INTVL, NULL);
 | ||
| }
 | ||
| 
 | ||
| static void iot_dev_test_ckq_cmd_interval_timer(timer_id_t timer_id,
 | ||
|     void * arg)
 | ||
| {
 | ||
|     (void)arg;
 | ||
|     (void)timer_id;
 | ||
| 
 | ||
|     iot_dev_test_task_post_msg(DEV_TEST_TIMER_MSG,
 | ||
|         DEV_TEST_TIMER_CKQ_CMD_INTVL, NULL);
 | ||
| }
 | ||
| 
 | ||
| static void iot_dev_test_ckq_timeout_timer(timer_id_t timer_id,
 | ||
|     void * arg)
 | ||
| {
 | ||
|     (void)arg;
 | ||
|     (void)timer_id;
 | ||
| 
 | ||
|     iot_dev_test_task_post_msg(DEV_TEST_TIMER_MSG,
 | ||
|         DEV_TEST_TIMER_CKQ_TIMEOUT, NULL);
 | ||
| }
 | ||
| 
 | ||
| static void iot_dev_test_plc_data_handle(iot_pkt_t *data)
 | ||
| {
 | ||
|     uint16_t pos = 0;
 | ||
|     uint16_t buf_len = (uint16_t)iot_pkt_data_len(data);
 | ||
|     uint8_t *buf = iot_pkt_data(data);
 | ||
|     bool_t need_report = false;
 | ||
|     transmit_direction_e_t tmp_dir;
 | ||
|     iot_pkt_t *tmp_pkt = NULL;
 | ||
|     uint8_t *tmp_buf;
 | ||
|     ge_frm_hdr_t *ge_hdr = NULL;
 | ||
|     ge_extend_fn_hdr_t *ge_ext_hdr = NULL;
 | ||
|     uint8_t fn = 0, subfn = 0;
 | ||
| 
 | ||
|     tmp_pkt = iot_pkt_alloc(GE_FRM_MAX_LEN, IOT_GREE_APP_MID);
 | ||
|     IOT_ASSERT(tmp_pkt);
 | ||
|     iot_pkt_put(tmp_pkt, GE_FRM_MAX_LEN);
 | ||
| 
 | ||
|     tmp_buf = iot_pkt_data(tmp_pkt);
 | ||
|     os_mem_set(tmp_buf, 0, GE_FRM_MAX_LEN);
 | ||
| 
 | ||
|     /* get rxinfo */
 | ||
|     plctxrx_rx_data_info_t *rxinfo = (plctxrx_rx_data_info_t *)buf;
 | ||
| 
 | ||
|     /* point to data & get data len */
 | ||
|     buf = (uint8_t *)(rxinfo + 1);
 | ||
|     buf_len -= sizeof(*rxinfo);
 | ||
| 
 | ||
|     /* maybe a big buffer,need to extract each intact gree frame */
 | ||
|     while (pos < buf_len) {
 | ||
|         uint8_t src_frame_len;
 | ||
|         /* TODO once gree enlarge pkt size, the local vair is not suitable */
 | ||
|         uint8_t tmp_buf_len = GE_FRM_PREAMBLE_FIELD_LEN +
 | ||
|                                 GE_FRM_CHECKSUM_FIELD_LEN +
 | ||
|                                 GE_FRM_TAIL_FILED_LEN;
 | ||
|         /* pure payload len */
 | ||
|         src_frame_len = iot_dev_test_plc_data_group_frame(tmp_buf, &buf[pos]);
 | ||
|         /* full pkt len */
 | ||
|         tmp_buf_len += src_frame_len;
 | ||
|         /* move analysis mark ahead */
 | ||
|         pos += src_frame_len;
 | ||
|         /* get fn & subfn */
 | ||
|         ge_hdr = (ge_frm_hdr_t *)tmp_buf;
 | ||
|         fn = ge_hdr->fn;
 | ||
|         /*
 | ||
|          * if fn is extended fn,then direction must be
 | ||
|          * CMD_REMOTE_UP_LINK. since this is plc data receive path.
 | ||
|         */
 | ||
|         if (PROTO_GE_PLC_SET_CMD == fn) {
 | ||
|             tmp_dir = CMD_REMOTE_UP_LINK;
 | ||
|             iot_dev_test_bin_dump(tmp_buf, tmp_buf_len);
 | ||
|             ge_ext_hdr = (ge_extend_fn_hdr_t *)tmp_buf;
 | ||
|             subfn = ge_ext_hdr->subfn;
 | ||
|             if (PROTO_GE_DATA_CMD == subfn) {
 | ||
|                 /* handle the FE A0 ge frame */
 | ||
|                 need_report = iot_dev_test_data_handler(tmp_buf, tmp_buf_len,
 | ||
|                     tmp_dir);
 | ||
|                 /* if a dl645 frame is packed in FE A0 frame, we will unpack it,
 | ||
|                   only reserve the dl645 frame.
 | ||
|                 */
 | ||
|                 iot_dev_test_handle_ge_from_plc(tmp_buf, &tmp_buf_len, tmp_dir,
 | ||
|                     &need_report);
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         if (!need_report)
 | ||
|             continue;
 | ||
| 
 | ||
|         /* report to MCU */
 | ||
|         iot_pkt_t *pkt_data = iot_pkt_alloc(tmp_buf_len, IOT_GREE_APP_MID);
 | ||
|         IOT_ASSERT(pkt_data);
 | ||
|         /* make tail pointer of packet ponit to data tail */
 | ||
|         iot_pkt_put(pkt_data, tmp_buf_len);
 | ||
|         /* copy data to packet data field */
 | ||
|         os_mem_cpy(iot_pkt_data(pkt_data), tmp_buf, tmp_buf_len);
 | ||
|         /* report frame to MCU */
 | ||
|         iot_dev_test_send_to_mainboard(pkt_data);
 | ||
|         os_mem_set(tmp_buf, 0, tmp_buf_len);
 | ||
|     }
 | ||
| 
 | ||
|     if (tmp_pkt) {
 | ||
|         iot_pkt_free(tmp_pkt);
 | ||
|     }
 | ||
| 
 | ||
|     iot_pkt_free(data);
 | ||
|     return;
 | ||
| }
 | ||
| 
 | ||
| static void iot_dev_test_plctxrx_response_mac(iot_pkt_t *data)
 | ||
| {
 | ||
|     plctxrx_cmd_resp_t *p_resp;
 | ||
|     custom_flash_info_t *p_flash = &(dev_test_context->flashinfo);
 | ||
|     iot_oem_base_cfg_t *oem_base_cfg;
 | ||
|     plctxrx_cmd_arg_t *p_arg;
 | ||
|     plctxrx_handle_mac_t *p_mac_hd;
 | ||
|     iot_pkt_t *p_pkt;
 | ||
|     uint32_t pkt_len;
 | ||
| 
 | ||
|     if(NULL == data)
 | ||
|     {
 | ||
|         iot_cus_printf("Invalid argument!\n");
 | ||
|         return;
 | ||
|     }
 | ||
| 
 | ||
|     p_resp = (plctxrx_cmd_resp_t *)iot_pkt_data(data);
 | ||
|     if (PLCTXRX_OP_CFM == p_resp->cid.opcode) {
 | ||
|         /* Update MAC address saved in flash. */
 | ||
|         iot_mac_addr_cpy(p_flash->local_mac, dev_test_context->mac);
 | ||
|         if(ERR_OK != iot_dev_test_flashsave(p_flash))
 | ||
|         {
 | ||
|             iot_cus_printf("Local MAC address save to flash failed!\n");
 | ||
|             return;
 | ||
|         }
 | ||
|     } else if (PLCTXRX_OP_INDICATION == p_resp->cid.opcode) {
 | ||
|         /* Get MAC address from flash firstly, need check the MAC address validity. */
 | ||
|         if (mac_addr_in_flash_is_valid_addr(p_flash->local_mac)) {
 | ||
|             iot_cus_printf("Flash's MAC address valid!\n");
 | ||
|             /* Update the dev test layer local MAC address. */
 | ||
|             iot_mac_addr_cpy(dev_test_context->mac, p_flash->local_mac);
 | ||
|         } else {
 | ||
|             /* If flash's MAC address invalid, get MAC address from OEM secondly. */
 | ||
|             (void)iot_oem_get_base_cfg(&oem_base_cfg);
 | ||
| 
 | ||
|             /* Check the MAC address validity. */
 | ||
|             if (!mac_addr_in_flash_is_valid_addr(oem_base_cfg->module_mac))
 | ||
|             {
 | ||
|                 iot_cus_printf("OEM's MAC address invalid!\n");
 | ||
|                 return;
 | ||
|             }
 | ||
| 
 | ||
|             iot_cus_printf("[ckq]we will use oem's mac address as local mac!\n");
 | ||
|             /* Update the dev test layer local MAC address. */
 | ||
|             iot_mac_addr_cpy(dev_test_context->mac, oem_base_cfg->module_mac);
 | ||
|         }
 | ||
| 
 | ||
|         pkt_len = sizeof(*p_arg) + sizeof(*p_mac_hd);
 | ||
|         if (NULL == (p_pkt = iot_pkt_alloc(pkt_len, IOT_GREE_APP_MID)))
 | ||
|         {
 | ||
|             iot_cus_printf("%s No memory!\n", __FUNCTION__);
 | ||
|             return;
 | ||
|         }
 | ||
| 
 | ||
|         p_arg = (plctxrx_cmd_arg_t *)iot_pkt_put(p_pkt, pkt_len);
 | ||
|         p_arg->cid.cid = PLCTXRX_CID_MAC;
 | ||
|         p_arg->cid.opcode = PLCTXRX_OP_CONFIG;
 | ||
|         p_arg->prio = 0;
 | ||
|         p_arg->dlen = sizeof(*p_mac_hd);
 | ||
|         p_arg->need_ack = true;
 | ||
| 
 | ||
|         p_mac_hd = (plctxrx_handle_mac_t *)p_arg->arg;
 | ||
|         iot_mac_addr_cpy(p_mac_hd->mac, dev_test_context->mac);
 | ||
|         p_mac_hd->dev_type = IOT_PLC_DEV_TYPE_METER_CONTROLLER;
 | ||
| 
 | ||
|         iot_dev_test_cmd_send_to_plc(p_pkt);
 | ||
| 
 | ||
|         iot_dev_test_set_cfg_after_app_reg();
 | ||
|     }
 | ||
|     iot_pkt_free(data);
 | ||
| }
 | ||
| 
 | ||
| static void iot_dev_test_plctxrx_cmd_handle(iot_pkt_t *data)
 | ||
| {
 | ||
|     plctxrx_cmd_resp_t *resp = (plctxrx_cmd_resp_t *)iot_pkt_data(data);
 | ||
|     switch(resp->cid.cid)
 | ||
|     {
 | ||
|         case PLCTXRX_CID_GRAPP_REG_CONF:
 | ||
|         case PLCTXRX_CID_MAC:
 | ||
|             iot_dev_test_plctxrx_response_mac(data);
 | ||
|             break;
 | ||
|         default:
 | ||
|             break;
 | ||
|     }
 | ||
| }
 | ||
| 
 | ||
| static void iot_dev_test_mcu_msg_handle(iot_pkt_t *data)
 | ||
| {
 | ||
|     uint8_t fn = 0, subfn = 0;
 | ||
|     uint16_t cur_pos = 0;
 | ||
|     uint16_t total_len = (uint16_t)iot_pkt_data_len(data);
 | ||
|     uint8_t *data_buf = iot_pkt_data(data);
 | ||
|     uint8_t *tmp_buf;
 | ||
|     /* data cnt in each gree frame */
 | ||
|     uint16_t  data_len;
 | ||
|     uint8_t ret = 0;
 | ||
|     transmit_direction_e_t tmp_dir;
 | ||
|     ge_frm_hdr_t *ge_hdr = NULL;
 | ||
|     ge_extend_fn_hdr_t *ge_ext_hdr = NULL;
 | ||
| 
 | ||
|     /* handle each intact frame extracted from uart data buffer */
 | ||
|     do {
 | ||
|         data_len = 0;
 | ||
|         tmp_buf = data_buf + cur_pos;
 | ||
|         if (cur_pos >= (total_len - 1)) {
 | ||
|             iot_cus_printf("[ckq][err] pos=%d >= %d - 1\n", cur_pos, total_len);
 | ||
|             break;
 | ||
|         }
 | ||
| 
 | ||
|         ret = ge_frame_data_len(tmp_buf, total_len - cur_pos, &data_len);
 | ||
|         if (ret != ERR_OK) {
 | ||
|             /* not get a complete frame */
 | ||
|             iot_cus_printf("[ckq][err] incomplete frame\n");
 | ||
|             break;
 | ||
|         }
 | ||
| 
 | ||
|         /* increase current pos to reach next intact frame */
 | ||
|         cur_pos += data_len + GE_FRM_MIN_LEN;
 | ||
| 
 | ||
|         /* get fncode & subfncode from gree frame */
 | ||
|         ge_hdr = (ge_frm_hdr_t *)tmp_buf;
 | ||
|         fn = ge_hdr->fn;
 | ||
| 
 | ||
|         if ( PROTO_GE_PLC_SET_CMD == fn ) {
 | ||
|             ge_ext_hdr = (ge_extend_fn_hdr_t *)tmp_buf;
 | ||
|             subfn = ge_ext_hdr->subfn;
 | ||
|             if (PROTO_GE_DATA_CMD == subfn) {
 | ||
|                 tmp_dir = CMD_LOCAL_DOWN_LINK;
 | ||
|                 iot_dev_test_data_handler(tmp_buf, (uint8_t)(data_len) +
 | ||
|                     GE_FRM_MIN_LEN, tmp_dir);
 | ||
|             }
 | ||
|         }
 | ||
|     } while (cur_pos < total_len);
 | ||
| 
 | ||
|     iot_pkt_free(data);
 | ||
| }
 | ||
| 
 | ||
| static void iot_dev_test_plc_msg_handle(iot_task_msg_t *msg)
 | ||
| {
 | ||
|     dev_test_msg_t *task_msg;
 | ||
|     IOT_ASSERT(msg);
 | ||
| 
 | ||
|     task_msg = (dev_test_msg_t*)msg;
 | ||
| 
 | ||
|     switch (task_msg->msg.id)
 | ||
|     {
 | ||
|         case PROTO_PLC_RX_DATA_MSG:
 | ||
|         {
 | ||
|             iot_dev_test_plc_data_handle(task_msg->data);
 | ||
|             break;
 | ||
|         }
 | ||
|         case PROTO_PLCTXRX_RX_CMD_MSG:
 | ||
|         {
 | ||
|             iot_dev_test_plctxrx_cmd_handle(task_msg->data);
 | ||
|             break;
 | ||
|         }
 | ||
|         default:
 | ||
|         {
 | ||
|             if (task_msg->data)
 | ||
|                 iot_pkt_free(task_msg->data);
 | ||
|             break;
 | ||
|         }
 | ||
|     }
 | ||
| }
 | ||
| 
 | ||
| static void iot_dev_test_mode_config_handler(void)
 | ||
| {
 | ||
|     iot_pkt_t *p_pkt;
 | ||
|     dev_test_mode_cfg_t *p_cfg;
 | ||
|     plctxrx_cmd_arg_t *p_arg;
 | ||
| 
 | ||
|     p_pkt = iot_pkt_alloc(sizeof(*p_cfg) + sizeof(*p_arg),
 | ||
|         IOT_GREE_APP_MID);
 | ||
|     IOT_ASSERT(p_pkt);
 | ||
|     iot_pkt_put(p_pkt, sizeof(*p_cfg) + sizeof(*p_arg));
 | ||
| 
 | ||
|     p_arg = (plctxrx_cmd_arg_t *)iot_pkt_data(p_pkt);
 | ||
|     p_arg->cid.cid = PLCTXRX_CID_MODE_CONF;
 | ||
|     p_arg->cid.opcode = PLCTXRX_OP_CONFIG;
 | ||
|     p_arg->prio = 0;
 | ||
|     p_arg->need_ack = false;
 | ||
|     p_arg->dlen = sizeof(*p_cfg);
 | ||
| 
 | ||
|     p_cfg = (dev_test_mode_cfg_t *)p_arg->arg;
 | ||
|     p_cfg->band_id = DEV_TEST_DEFAULT_FRQ_BAND;
 | ||
|     p_cfg->dur = DEV_TEST_DEFAULT_MODE_CFG_DUR;
 | ||
|     p_cfg->target_id_mask = DEV_TEST_TARGET_ID_MSK_STA;
 | ||
| 
 | ||
|     iot_dev_test_cmd_send_to_plc(p_pkt);
 | ||
| }
 | ||
| 
 | ||
| static void iot_dev_test_ckq_cmd_interval_handler(void)
 | ||
| {
 | ||
|     proto_645_header_t *dl645_hdr = NULL;
 | ||
|     uint16_t dl645_len = 0;
 | ||
|     uint8_t dst_mac[IOT_MAC_ADDR_LEN];
 | ||
|     uint8_t src_mac[IOT_MAC_ADDR_LEN];
 | ||
|     uint8_t *ext_645_buf = NULL;
 | ||
|     uint8_t *ge_buf = NULL;
 | ||
|     uint16_t ge_len = 0;
 | ||
|     iot_pkt_t *pkt = NULL;
 | ||
|     uint16_t pkt_len = 0;
 | ||
|     protpkt_tx_info_t txinfo = { 0 };
 | ||
| 
 | ||
|     if (!g_dev_test_buf.cmd_valid) {
 | ||
|         iot_cus_printf("%s dl645 cmd is invalid!\n", __FUNCTION__);
 | ||
|         goto out;
 | ||
|     }
 | ||
|     /* send the second cmd to read meter data from sta */
 | ||
|     /* ext_645_buf and ge_buf share a big pkt */
 | ||
|     pkt_len = DL645_PARSE_FRM_MAX_LEN + GE_FRM_MAX_LEN;
 | ||
|     pkt = iot_pkt_alloc(pkt_len, IOT_GREE_APP_MID);
 | ||
| 
 | ||
|     if (pkt == NULL) {
 | ||
|         iot_cus_printf("%s pkt alloc err!\n", __FUNCTION__);
 | ||
|         return;
 | ||
|     }
 | ||
| 
 | ||
|     ext_645_buf = iot_pkt_data(pkt);
 | ||
|     ge_buf = ext_645_buf + DL645_PARSE_FRM_MAX_LEN;
 | ||
| 
 | ||
|     dl645_hdr = (proto_645_header_t*)g_dev_test_buf.cmd_buf;
 | ||
|     dl645_len = dl645_hdr->len + DL645_PARSE_FRM_MIN_LEN;
 | ||
| 
 | ||
|     iot_mac_addr_cpy(dst_mac, g_dev_test_buf.dst_mac);
 | ||
|     iot_mac_addr_reverse(dst_mac);
 | ||
|     iot_mac_addr_cpy(src_mac, dev_test_context->mac);
 | ||
|     iot_mac_addr_reverse(src_mac);
 | ||
|     iot_proto_pack_data_to_dl645((uint8_t *)dl645_hdr, ext_645_buf,
 | ||
|         &dl645_len, DL645_07_DI_CKQ_MODE_READ, src_mac,
 | ||
|         PROTO_645_2007_FN_READ_DATA, PROTO_645_DIR_MASTER);
 | ||
| 
 | ||
|     if (dl645_len + GE_FRM_MIN_LEN > GE_FRM_MAX_LEN) {
 | ||
|         iot_cus_printf("%s out of max length!\n", __FUNCTION__);
 | ||
|         return;
 | ||
|     }
 | ||
| 
 | ||
|     ge_len = dl645_len;
 | ||
|     iot_pack_dl645_to_ge(ext_645_buf, ge_buf, &ge_len, dst_mac, true);
 | ||
|     iot_proto_fill_txinfo(&txinfo, true, PLCTXRX_UNICAST,
 | ||
|         PROTO_UNICAST_RETRY_DEFAULT_CNT, PROTO_UNICAST_RETRY_DEFAULT_INTVL,
 | ||
|         1, dev_test_context->mac, dst_mac);
 | ||
|     iot_dev_test_remote_data_send_to_plctxrx(ge_buf, ge_len, &txinfo);
 | ||
|     iot_pkt_free(pkt);
 | ||
| out:
 | ||
|     os_start_timer(dev_test_context->ckq_timeout_tmr,
 | ||
|         DEV_TEST_TMR_CKQ_TIMEOUT_INTVL);
 | ||
| }
 | ||
| 
 | ||
| static void iot_dev_test_ckq_timeout_handler(void)
 | ||
| {
 | ||
|     if (g_dev_test_buf.cmd_valid) {
 | ||
|         g_dev_test_buf.cmd_valid = 0;
 | ||
|         iot_cus_printf("%s timeout\n", __FUNCTION__);
 | ||
|     }
 | ||
| }
 | ||
| 
 | ||
| static void iot_dev_test_handle_timer_msg(dev_test_msg_t* task_msg)
 | ||
| {
 | ||
|     switch (task_msg->msg.id) {
 | ||
|     case DEV_TEST_TIMER_MODE_CONFIG_INTVL:
 | ||
|     {
 | ||
|         iot_dev_test_mode_config_handler();
 | ||
|         break;
 | ||
|     }
 | ||
|     case DEV_TEST_TIMER_CKQ_CMD_INTVL:
 | ||
|     {
 | ||
|         iot_dev_test_ckq_cmd_interval_handler();
 | ||
|         break;
 | ||
|     }
 | ||
|     case DEV_TEST_TIMER_CKQ_TIMEOUT:
 | ||
|     {
 | ||
|         iot_dev_test_ckq_timeout_handler();
 | ||
|         break;
 | ||
|     }
 | ||
|     default:
 | ||
|         break;
 | ||
|     }
 | ||
| }
 | ||
| 
 | ||
| static void iot_dev_test_task_msg_handle(iot_task_h task_h, iot_task_msg_t *msg)
 | ||
| {
 | ||
|     dev_test_msg_t *task_msg = (dev_test_msg_t *)msg;
 | ||
| 
 | ||
|     IOT_ASSERT(task_h == dev_test_context->task_handle);
 | ||
|     IOT_ASSERT(msg);
 | ||
| 
 | ||
|     switch (task_msg->msg.type) {
 | ||
|     /* handle msg from uart  */
 | ||
|     case DEV_TEST_MCU_RX_MSG:
 | ||
|     {
 | ||
|         iot_dev_test_mcu_msg_handle(task_msg->data);
 | ||
|         break;
 | ||
|     }
 | ||
|     /* handle msg from plctxrx layer */
 | ||
|     case DEV_TEST_PLC_RX_MSG:
 | ||
|     {
 | ||
|         iot_dev_test_plc_msg_handle(&task_msg->msg);
 | ||
|         break;
 | ||
|     }
 | ||
|     /* handle msg from timer */
 | ||
|     case DEV_TEST_TIMER_MSG:
 | ||
|     {
 | ||
|         iot_dev_test_handle_timer_msg(task_msg);
 | ||
|         break;
 | ||
|     }
 | ||
|     default:
 | ||
|         break;
 | ||
|     }
 | ||
| 
 | ||
|     iot_task_free_msg(dev_test_context->task_handle, msg);
 | ||
| 
 | ||
|     return;
 | ||
| }
 | ||
| 
 | ||
| static void iot_dev_test_task_msg_cancel(iot_task_h task_h, iot_task_msg_t *msg)
 | ||
| {
 | ||
|     dev_test_msg_t *task_msg;
 | ||
|     IOT_ASSERT(task_h == dev_test_context->task_handle);
 | ||
|     IOT_ASSERT(msg);
 | ||
| 
 | ||
|     task_msg = (dev_test_msg_t *)msg;
 | ||
| 
 | ||
|     switch (task_msg->msg.type) {
 | ||
|     case DEV_TEST_MCU_RX_MSG:
 | ||
|     {
 | ||
|         break;
 | ||
|     }
 | ||
|     case DEV_TEST_PLC_RX_MSG:
 | ||
|     {
 | ||
|         break;
 | ||
|     }
 | ||
|     case DEV_TEST_TIMER_MSG:
 | ||
|     {
 | ||
|         break;
 | ||
|     }
 | ||
|     default:
 | ||
|         IOT_ASSERT(0);
 | ||
|         break;
 | ||
|     }
 | ||
| 
 | ||
|     if (task_msg->data) {
 | ||
|         iot_pkt_free(task_msg->data);
 | ||
|     }
 | ||
| 
 | ||
|     iot_task_free_msg(dev_test_context->task_handle, &task_msg->msg);
 | ||
| }
 | ||
| 
 | ||
| dev_test_context_t *iot_dev_test_context_get(void)
 | ||
| {
 | ||
|     if (!dev_test_is_firedup()) {
 | ||
|         iot_cus_printf("dev test module not ready.\n");
 | ||
|         return NULL;
 | ||
|     }
 | ||
| 
 | ||
|     return dev_test_context;
 | ||
| }
 | ||
| 
 | ||
| void iot_dev_test_task_deinit(void)
 | ||
| {
 | ||
|     if (NULL != dev_test_context->task_handle) {
 | ||
|         iot_task_delete(dev_test_context->task_handle);
 | ||
|         dev_test_context->task_handle = NULL;
 | ||
|     }
 | ||
| 
 | ||
|     if (0 != dev_test_context->mod_cfg_tmr) {
 | ||
|         os_delete_timer(dev_test_context->mod_cfg_tmr);
 | ||
|         dev_test_context->mod_cfg_tmr = 0;
 | ||
|     }
 | ||
| 
 | ||
|     if (0 != dev_test_context->ckq_cmd_intvl_tmr) {
 | ||
|         os_delete_timer(dev_test_context->ckq_cmd_intvl_tmr);
 | ||
|         dev_test_context->ckq_cmd_intvl_tmr = 0;
 | ||
|     }
 | ||
| 
 | ||
|     if (0 != dev_test_context->ckq_timeout_tmr) {
 | ||
|         os_delete_timer(dev_test_context->ckq_timeout_tmr);
 | ||
|         dev_test_context->ckq_timeout_tmr = 0;
 | ||
|     }
 | ||
| 
 | ||
|     os_mem_free(dev_test_context);
 | ||
| 
 | ||
|     return;
 | ||
| }
 | ||
| 
 | ||
| iot_task_h iot_dev_test_task_init(void)
 | ||
| {
 | ||
|     /* alloc memory first. */
 | ||
|     dev_test_context = os_mem_malloc(IOT_GREE_APP_MID, sizeof(*dev_test_context));
 | ||
| 
 | ||
|     if (!dev_test_context) {
 | ||
|         iot_cus_printf("%s mem malloc failed!\n", __FUNCTION__);
 | ||
|         goto error_handle;
 | ||
|     }
 | ||
|     os_mem_set(dev_test_context, 0, sizeof(dev_test_context_t));
 | ||
| 
 | ||
|     dev_test_context->task_cfg.stack_size = 0;
 | ||
|     dev_test_context->task_cfg.task_prio = IOT_DEV_TEST_PRIO;
 | ||
|     dev_test_context->task_cfg.msg_size = sizeof(dev_test_msg_t);
 | ||
|     dev_test_context->task_cfg.msg_cnt = IOT_DEV_TEST_TASK_POOL_SIZE;
 | ||
|     dev_test_context->task_cfg.queue_cnt = IOT_DEV_TEST_TASK_QUEUE_MAX_PRIO;
 | ||
|     dev_test_context->task_cfg.queue_cfg[IOT_DEV_TEST_TASK_QUEUE_LP].quota = 0;
 | ||
|     dev_test_context->task_cfg.msg_exe_func = iot_dev_test_task_msg_handle;
 | ||
|     dev_test_context->task_cfg.msg_cancel_func = iot_dev_test_task_msg_cancel;
 | ||
|     /* create task */
 | ||
|     dev_test_context->task_handle =
 | ||
|         iot_task_create(IOT_GREE_APP_MID, &(dev_test_context->task_cfg));
 | ||
| 
 | ||
|     if (dev_test_context->task_handle == NULL) {
 | ||
|         goto error_handle;
 | ||
|     }
 | ||
| 
 | ||
|     dev_test_context->mod_cfg_tmr =
 | ||
|                 os_create_timer(IOT_GREE_APP_MID, true,
 | ||
|                 iot_dev_test_mode_config_timer, NULL);
 | ||
|     if (dev_test_context->mod_cfg_tmr == 0) {
 | ||
|         goto error_handle;
 | ||
|     }
 | ||
| 
 | ||
|     dev_test_context->ckq_cmd_intvl_tmr =
 | ||
|                 os_create_timer(IOT_GREE_APP_MID, false,
 | ||
|                 iot_dev_test_ckq_cmd_interval_timer, NULL);
 | ||
|     if (dev_test_context->ckq_cmd_intvl_tmr == 0) {
 | ||
|         goto error_handle;
 | ||
|     }
 | ||
| 
 | ||
|     dev_test_context->ckq_timeout_tmr =
 | ||
|                 os_create_timer(IOT_GREE_APP_MID, false,
 | ||
|                 iot_dev_test_ckq_timeout_timer, NULL);
 | ||
|     if (dev_test_context->ckq_timeout_tmr == 0) {
 | ||
|         goto error_handle;
 | ||
|     }
 | ||
| 
 | ||
|     dev_test_fire_now();
 | ||
|     iot_cus_printf("dev test module initailized seccussfully\n");
 | ||
|     return dev_test_context->task_handle;
 | ||
| 
 | ||
| error_handle:
 | ||
|     iot_dev_test_task_deinit();
 | ||
|     iot_cus_printf("dev test module initailized failed\n");
 | ||
|     return NULL;
 | ||
| }
 | ||
| 
 | ||
| #endif
 |