Files
kunlun/app/grapp/iot_dev_test.c
2024-09-28 14:24:04 +08:00

1479 lines
45 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/****************************************************************************
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 lastcopy
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, firstlythe 645 frame
should be packed to a extern 645 frame. thenthe 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