1726 lines
		
	
	
		
			52 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			1726 lines
		
	
	
		
			52 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_timer_api.h"
							 | 
						|||
| 
								 | 
							
								#include "os_utils_api.h"
							 | 
						|||
| 
								 | 
							
								#include "iot_app_api.h"
							 | 
						|||
| 
								 | 
							
								#include "iot_io_api.h"
							 | 
						|||
| 
								 | 
							
								#include "iot_task_api.h"
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								#include "iot_proto_ge.h"
							 | 
						|||
| 
								 | 
							
								#include "iot_board_api.h"
							 | 
						|||
| 
								 | 
							
								#include "iot_proto_cctt.h"
							 | 
						|||
| 
								 | 
							
								#include "iot_plc_msg_cco_api.h"
							 | 
						|||
| 
								 | 
							
								#include "iot_gpio_api.h"
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								#if PLC_SUPPORT_CCO_ROLE
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								/* iot concentrator module, version 3.0 */
							 | 
						|||
| 
								 | 
							
								#ifndef HW_VERSION_IOT_CCTT_V3_0
							 | 
						|||
| 
								 | 
							
								#define HW_VERSION_IOT_CCTT_V3_0        0x720A0100  //114.10.01.00
							 | 
						|||
| 
								 | 
							
								#endif
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								/* iot concentrator module, version 3.5 */
							 | 
						|||
| 
								 | 
							
								#ifndef HW_VERSION_IOT_CCTT_V3_5
							 | 
						|||
| 
								 | 
							
								#define HW_VERSION_IOT_CCTT_V3_5        0x760A0100  //118.10.01.00
							 | 
						|||
| 
								 | 
							
								#endif
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								#define PLC_NW_OPEN                 (0xAA)
							 | 
						|||
| 
								 | 
							
								#define PLC_NW_CLOSE                (0x55)
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								/* timeout period if rs485 device has no response */
							 | 
						|||
| 
								 | 
							
								#define RS485_DEV_RESP_TO_MS        (2000)
							 | 
						|||
| 
								 | 
							
								/* timeout period to judge rs485 data receive done */
							 | 
						|||
| 
								 | 
							
								#define RS485_DEV_IDLE_TO_MS        (20)
							 | 
						|||
| 
								 | 
							
								/* fn of reporting sta join/leave state */
							 | 
						|||
| 
								 | 
							
								#define RPT_STA_STATE_FN            (0x07)
							 | 
						|||
| 
								 | 
							
								/* event to report sta joined */
							 | 
						|||
| 
								 | 
							
								#define EVENT_RPT_STA_JOINED        (0x01)
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								/* for cco */
							 | 
						|||
| 
								 | 
							
								static cctt_context_t g_cctt_context = {0};
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								/* local rs485 manager object */
							 | 
						|||
| 
								 | 
							
								static cctt_local_rs485_t g_local_rs485 = {0};
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								/**
							 | 
						|||
| 
								 | 
							
								 * @brief cctt_resp_cmd_ack() - dl645 query err、set cmd ack
							 | 
						|||
| 
								 | 
							
								 * @param ctrl:   read or write cmd
							 | 
						|||
| 
								 | 
							
								 * @param err:    error number,see DL645_ERR_XXX
							 | 
						|||
| 
								 | 
							
								 * @return: 0 success, others false
							 | 
						|||
| 
								 | 
							
								 */
							 | 
						|||
| 
								 | 
							
								static uint8_t cctt_resp_cmd_ack(uint8_t ctrl, uint8_t err)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    uint8_t *send_cmd;
							 | 
						|||
| 
								 | 
							
								    uint8_t data_len = DL645_PARSE_FRM_MIN_LEN;
							 | 
						|||
| 
								 | 
							
								    iot_pkt_t *pkt = NULL;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    iot_cus_printf("cctt resp ack:%lu\n", err);
							 | 
						|||
| 
								 | 
							
								    if (err > 0) {
							 | 
						|||
| 
								 | 
							
								        data_len += 1;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    pkt = iot_pkt_alloc(data_len, IOT_GREE_APP_MID);
							 | 
						|||
| 
								 | 
							
								    if (pkt == NULL) {
							 | 
						|||
| 
								 | 
							
								        iot_cus_printf("[err]cctt pkt alloc fail\n");
							 | 
						|||
| 
								 | 
							
								        return 1;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    send_cmd = iot_pkt_put(pkt, data_len);
							 | 
						|||
| 
								 | 
							
								    iot_proto_645_build_resp_msg((proto_645_header_t *)send_cmd, NULL, 0,
							 | 
						|||
| 
								 | 
							
								        err, ctrl);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    iot_proto_send_to_mainboard(pkt);
							 | 
						|||
| 
								 | 
							
								    return 0;
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								/* set whitelist */
							 | 
						|||
| 
								 | 
							
								uint8_t iot_cctt_set_whitelist(uint8_t *data, uint8_t len, uint8_t action)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    uint8_t i;
							 | 
						|||
| 
								 | 
							
								    int32_t mac_in_dev, mac_in_dev_tmp;
							 | 
						|||
| 
								 | 
							
								    proto_dev_t wlist;
							 | 
						|||
| 
								 | 
							
								    cctt_set_whitelist_t *cmd = (cctt_set_whitelist_t*)data;
							 | 
						|||
| 
								 | 
							
								    uint8_t reason = DL645_ERR_OTHER_ERROR;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    if (sizeof(cctt_set_whitelist_t) + cmd->cnt * IOT_MAC_ADDR_LEN != len ||
							 | 
						|||
| 
								 | 
							
								        cmd->cnt == 0) {
							 | 
						|||
| 
								 | 
							
								        /* length or count err */
							 | 
						|||
| 
								 | 
							
								        reason = DL645_ERR_OTHER_ERROR;
							 | 
						|||
| 
								 | 
							
								    } else if ((action == GE_PROTO_ACTION_ADD) ||
							 | 
						|||
| 
								 | 
							
								        (action == GE_PROTO_ACTION_DEL)) {
							 | 
						|||
| 
								 | 
							
								        iot_cus_printf("cctt_set_whitelist act:%d seq:%d cnt:%d\n", action,
							 | 
						|||
| 
								 | 
							
								            cmd->seq, cmd->cnt);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        for (i = 0; i < cmd->cnt; i++) {
							 | 
						|||
| 
								 | 
							
								            iot_mac_addr_reverse(cmd->mac[i]);
							 | 
						|||
| 
								 | 
							
								            mac_in_dev = iot_proto_check_mac_exists(cmd->mac[i],
							 | 
						|||
| 
								 | 
							
								                prototask_contxt.dev_lst.dev,
							 | 
						|||
| 
								 | 
							
								                prototask_contxt.dev_lst.valid_dev_cnt);
							 | 
						|||
| 
								 | 
							
								            mac_in_dev_tmp = iot_proto_check_mac_exists(cmd->mac[i],
							 | 
						|||
| 
								 | 
							
								                prototask_contxt.dev_lst.dev_tmp,
							 | 
						|||
| 
								 | 
							
								                prototask_contxt.dev_lst.valid_dev_tmp_cnt);
							 | 
						|||
| 
								 | 
							
								            if (((action == GE_PROTO_ACTION_ADD) && (mac_in_dev < 0) &&
							 | 
						|||
| 
								 | 
							
								                (mac_in_dev_tmp < 0)) || ((action == GE_PROTO_ACTION_DEL) &&
							 | 
						|||
| 
								 | 
							
								                (mac_in_dev>= 0) && (mac_in_dev_tmp < 0))) {
							 | 
						|||
| 
								 | 
							
								                /* mac is not in dev_tmp and dev,which will be added if need,
							 | 
						|||
| 
								 | 
							
								                or is in dev and not in dev_tmp, which will be deleted if need */
							 | 
						|||
| 
								 | 
							
								                os_mem_set(&wlist, 0x00, sizeof(wlist));
							 | 
						|||
| 
								 | 
							
								                iot_mac_addr_cpy(wlist.mac, cmd->mac[i]);
							 | 
						|||
| 
								 | 
							
								                iot_proto_add_wl_to_tmp(&wlist);
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        if (cmd->seq == 0) {
							 | 
						|||
| 
								 | 
							
								            if (action == GE_PROTO_ACTION_ADD) {
							 | 
						|||
| 
								 | 
							
								                iot_proto_add_wl_tmp2formal();
							 | 
						|||
| 
								 | 
							
								            } else {
							 | 
						|||
| 
								 | 
							
								                iot_proto_del_wl_from_formal();
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								            iot_proto_whitelist_add_remove(action, NULL, false);
							 | 
						|||
| 
								 | 
							
								            iot_proto_wl_save2flash();
							 | 
						|||
| 
								 | 
							
								            iot_proto_whitelist_state_init();
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        reason = DL645_ERR_OK;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    iot_cus_printf("cctt_set_whitelist end\n");
							 | 
						|||
| 
								 | 
							
								    cctt_resp_cmd_ack(PROTO_645_2007_FN_WRITE_DATA, reason);
							 | 
						|||
| 
								 | 
							
								    return (reason != DL645_ERR_OK);
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								/* reboot cco */
							 | 
						|||
| 
								 | 
							
								uint8_t iot_cctt_reboot_cco(uint8_t *data, uint8_t len)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    (void)data;
							 | 
						|||
| 
								 | 
							
								    uint8_t reason = DL645_ERR_OTHER_ERROR;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    if (len != sizeof(cctt_reboot_cco_t)) {
							 | 
						|||
| 
								 | 
							
								        reason = DL645_ERR_PARAMETER_ERROR;
							 | 
						|||
| 
								 | 
							
								    } else {
							 | 
						|||
| 
								 | 
							
								        os_start_timer(prototask_contxt.reboot_tmr,
							 | 
						|||
| 
								 | 
							
								            PROTO_TIMER_REBOOT_DELAY_INTVL);
							 | 
						|||
| 
								 | 
							
								        reason = DL645_ERR_OK;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    iot_cus_printf("cctt reboot cco end\n");
							 | 
						|||
| 
								 | 
							
								    cctt_resp_cmd_ack(PROTO_645_2007_FN_WRITE_DATA, reason);
							 | 
						|||
| 
								 | 
							
								    return (reason != DL645_ERR_OK);
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								static void iot_cctt_build_reboot_sta_frame(uint8_t *ge_data, uint8_t *dst_mac)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    ge_frame_reboot_sta_set_subfn18_t *data_frm;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    data_frm = (ge_frame_reboot_sta_set_subfn18_t *)ge_data;
							 | 
						|||
| 
								 | 
							
								    data_frm->hdr.hdr.preamble = GE_FRM_PREAMBLE_CODE;
							 | 
						|||
| 
								 | 
							
								    data_frm->hdr.hdr.data_len = sizeof(ge_frame_reboot_sta_set_subfn18_t) -
							 | 
						|||
| 
								 | 
							
								        GE_FRM_MIN_LEN;
							 | 
						|||
| 
								 | 
							
								    data_frm->hdr.hdr.fn = PROTO_GE_PLC_SET_CMD;
							 | 
						|||
| 
								 | 
							
								    data_frm->hdr.subfn = PROTO_REBOOT_STA_CMD;
							 | 
						|||
| 
								 | 
							
								    data_frm->nid = prototask_contxt.local_dev.nid;
							 | 
						|||
| 
								 | 
							
								    data_frm->reboot_type = REBOOT_NORMAL;
							 | 
						|||
| 
								 | 
							
								    data_frm->seq = 0;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    iot_mac_addr_cpy(data_frm->src_mac, prototask_contxt.local_dev.mac);
							 | 
						|||
| 
								 | 
							
								    iot_mac_addr_cpy(data_frm->dst_mac, dst_mac);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    data_frm->tail.check_sum =
							 | 
						|||
| 
								 | 
							
								        ge_frm_checksum_calc(ge_data, data_frm->hdr.hdr.data_len +
							 | 
						|||
| 
								 | 
							
								        GE_FRM_CHECK_SUM_FIELD_POS);;
							 | 
						|||
| 
								 | 
							
								    data_frm->tail.tail = GE_FRM_TAIL_CODE;
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								static void iot_reboot_sta(uint8_t *dst_mac)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    iot_pkt_t *pkt;
							 | 
						|||
| 
								 | 
							
								    uint8_t *cmd_data;
							 | 
						|||
| 
								 | 
							
								    protpkt_tx_info_t txinfo = { 0 };
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    iot_cus_printf("reboot sta:%02X%02X%02X%02X%02X%02X\n",
							 | 
						|||
| 
								 | 
							
								        dst_mac[0], dst_mac[1], dst_mac[2],
							 | 
						|||
| 
								 | 
							
								        dst_mac[3], dst_mac[4], dst_mac[5]);
							 | 
						|||
| 
								 | 
							
								    pkt = iot_pkt_alloc(sizeof(ge_frame_reboot_sta_set_subfn18_t),
							 | 
						|||
| 
								 | 
							
								        IOT_GREE_APP_MID);
							 | 
						|||
| 
								 | 
							
								    if (pkt == NULL) {
							 | 
						|||
| 
								 | 
							
								        iot_cus_printf("[err]cctt pkt alloc fail\n");
							 | 
						|||
| 
								 | 
							
								        return;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    cmd_data = iot_pkt_put(pkt, sizeof(ge_frame_reboot_sta_set_subfn18_t));
							 | 
						|||
| 
								 | 
							
								    iot_cctt_build_reboot_sta_frame(cmd_data, dst_mac);
							 | 
						|||
| 
								 | 
							
								    iot_proto_fill_txinfo(&txinfo, false, PLCTXRX_UNICAST,
							 | 
						|||
| 
								 | 
							
								        PROTO_UNICAST_RETRY_DEFAULT_CNT, PROTO_UNICAST_RETRY_DEFAULT_INTVL, 1,
							 | 
						|||
| 
								 | 
							
								        prototask_contxt.local_dev.mac, dst_mac);
							 | 
						|||
| 
								 | 
							
								    iot_proto_remote_cmd_send_to_plctxrx(cmd_data,
							 | 
						|||
| 
								 | 
							
								        sizeof(ge_frame_reboot_sta_set_subfn18_t), &txinfo);
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								/* reboot sta */
							 | 
						|||
| 
								 | 
							
								uint8_t iot_cctt_reboot_sta(uint8_t *cmd, uint8_t len)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    uint8_t reason = DL645_ERR_OTHER_ERROR;
							 | 
						|||
| 
								 | 
							
								    cctt_reboot_sta_t *reboot_cmd;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    if (len != sizeof(cctt_reboot_sta_t)) {
							 | 
						|||
| 
								 | 
							
								        goto out;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    // TODO: check dst mac is in whitelist
							 | 
						|||
| 
								 | 
							
								    reboot_cmd = (cctt_reboot_sta_t*)cmd;
							 | 
						|||
| 
								 | 
							
								    iot_mac_addr_reverse(reboot_cmd->mac);
							 | 
						|||
| 
								 | 
							
								    iot_reboot_sta(reboot_cmd->mac);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    reason = DL645_ERR_OK;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								out:
							 | 
						|||
| 
								 | 
							
								    iot_cus_printf("cctt reboot sta end\n");
							 | 
						|||
| 
								 | 
							
								    cctt_resp_cmd_ack(PROTO_645_2007_FN_WRITE_DATA, reason);
							 | 
						|||
| 
								 | 
							
								    return (reason != DL645_ERR_OK);
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								/* set whitelist state */
							 | 
						|||
| 
								 | 
							
								uint8_t iot_cctt_set_wl_state(uint8_t *data, uint8_t len)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    uint8_t reason = DL645_ERR_PARAMETER_ERROR;
							 | 
						|||
| 
								 | 
							
								    cctt_set_wl_state_t *set_cmd;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    if (len != sizeof(cctt_set_wl_state_t)) {
							 | 
						|||
| 
								 | 
							
								        goto out;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    set_cmd = (cctt_set_wl_state_t*)data;
							 | 
						|||
| 
								 | 
							
								    if (set_cmd->state == 0) {
							 | 
						|||
| 
								 | 
							
								        iot_proto_whitelist_en_disable(GE_PROTO_WL_DISABLE, false);
							 | 
						|||
| 
								 | 
							
								    } else if (set_cmd->state == 1) {
							 | 
						|||
| 
								 | 
							
								        iot_proto_whitelist_en_disable(GE_PROTO_WL_ENABLE, false);
							 | 
						|||
| 
								 | 
							
								    } else {
							 | 
						|||
| 
								 | 
							
								        /* error state */
							 | 
						|||
| 
								 | 
							
								        goto out;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    reason = DL645_ERR_OK;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								out:
							 | 
						|||
| 
								 | 
							
								    iot_cus_printf("cctt set wl state end\n");
							 | 
						|||
| 
								 | 
							
								    cctt_resp_cmd_ack(PROTO_645_2007_FN_WRITE_DATA, reason);
							 | 
						|||
| 
								 | 
							
								    return (reason != DL645_ERR_OK);
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								/* clear whitelist */
							 | 
						|||
| 
								 | 
							
								uint8_t iot_cctt_clear_whitelist(uint8_t *data, uint8_t len)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    (void)data;
							 | 
						|||
| 
								 | 
							
								    uint8_t reason;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    if (sizeof(cctt_clear_whitelist_t) != len) {
							 | 
						|||
| 
								 | 
							
								        /* cmd length error */
							 | 
						|||
| 
								 | 
							
								        reason = DL645_ERR_PARAMETER_ERROR;
							 | 
						|||
| 
								 | 
							
								    } else {
							 | 
						|||
| 
								 | 
							
								        if (prototask_contxt.dev_lst.valid_dev_cnt > 0) {
							 | 
						|||
| 
								 | 
							
								            prototask_contxt.dev_lst.valid_dev_cnt = 0;
							 | 
						|||
| 
								 | 
							
								            os_mem_set(prototask_contxt.dev_lst.dev, 0,
							 | 
						|||
| 
								 | 
							
								                sizeof(proto_dev_t) * STA_DEV_MAX);
							 | 
						|||
| 
								 | 
							
								            iot_proto_wl_save2flash();
							 | 
						|||
| 
								 | 
							
								            iot_proto_whitelist_remove_all(false);
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        reason = DL645_ERR_OK;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    iot_cus_printf("cctt clear whitelist end\n");
							 | 
						|||
| 
								 | 
							
								    cctt_resp_cmd_ack(PROTO_645_2007_FN_WRITE_DATA, reason);
							 | 
						|||
| 
								 | 
							
								    return (reason != DL645_ERR_OK);
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								/* check address in whitelist */
							 | 
						|||
| 
								 | 
							
								uint8_t iot_cctt_check_whitelist_mac(uint8_t *data, uint8_t len)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    uint16_t i;
							 | 
						|||
| 
								 | 
							
								    uint8_t reason = DL645_ERR_NO_REQ_DATA;
							 | 
						|||
| 
								 | 
							
								    cctt_check_whitelist_mac_t *cmd;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    if (sizeof(cctt_check_whitelist_mac_t) != len) {
							 | 
						|||
| 
								 | 
							
								        /* cmd length error */
							 | 
						|||
| 
								 | 
							
								        reason = DL645_ERR_PARAMETER_ERROR;
							 | 
						|||
| 
								 | 
							
								    } else {
							 | 
						|||
| 
								 | 
							
								        cmd = (cctt_check_whitelist_mac_t*)data;
							 | 
						|||
| 
								 | 
							
								        iot_mac_addr_reverse(cmd->mac);
							 | 
						|||
| 
								 | 
							
								        if (prototask_contxt.dev_lst.valid_dev_cnt > 0) {
							 | 
						|||
| 
								 | 
							
								            for (i = 0; i < STA_DEV_MAX; i++) {
							 | 
						|||
| 
								 | 
							
								                if (iot_mac_addr_cmp(cmd->mac,
							 | 
						|||
| 
								 | 
							
								                    prototask_contxt.dev_lst.dev[i].mac)) {
							 | 
						|||
| 
								 | 
							
								                    reason = DL645_ERR_OK;
							 | 
						|||
| 
								 | 
							
								                    break;
							 | 
						|||
| 
								 | 
							
								                }
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    iot_cus_printf("cctt check whitelist mac cco end\n");
							 | 
						|||
| 
								 | 
							
								    cctt_resp_cmd_ack(PROTO_645_2007_FN_WRITE_DATA, reason);
							 | 
						|||
| 
								 | 
							
								    return (reason != DL645_ERR_OK);
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								/* resp whitelist */
							 | 
						|||
| 
								 | 
							
								static void cco_resp_whitelist_to_cctt(uint16_t start, uint8_t resp_cnt)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    uint8_t flow = 0;
							 | 
						|||
| 
								 | 
							
								    uint8_t *send_cmd;
							 | 
						|||
| 
								 | 
							
								    uint16_t out_len;
							 | 
						|||
| 
								 | 
							
								    uint8_t ctrl, i;
							 | 
						|||
| 
								 | 
							
								    uint8_t *tmp_mac;
							 | 
						|||
| 
								 | 
							
								    uint8_t dst_mac[IOT_MAC_ADDR_LEN];
							 | 
						|||
| 
								 | 
							
								    proto_645_header_t *hdr;
							 | 
						|||
| 
								 | 
							
								    iot_pkt_t *pkt;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    out_len = DL645_PARSE_FRM_MIN_LEN + IOT_MAC_ADDR_LEN * resp_cnt;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    if (g_cctt_context.q_wl_seq) {
							 | 
						|||
| 
								 | 
							
								        ctrl = PROTO_645_2007_FN_READ_DATA_C;
							 | 
						|||
| 
								 | 
							
								        out_len += sizeof(cctt_resp_whitelist_withseq_t) + sizeof(uint8_t);
							 | 
						|||
| 
								 | 
							
								    } else {
							 | 
						|||
| 
								 | 
							
								        ctrl = PROTO_645_2007_FN_READ_DATA;
							 | 
						|||
| 
								 | 
							
								        out_len += sizeof(cctt_resp_whitelist_t);
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    if ((g_cctt_context.q_wl_cnt == 0xFFFF &&
							 | 
						|||
| 
								 | 
							
								        (start + resp_cnt < prototask_contxt.dev_lst.valid_dev_cnt)) ||
							 | 
						|||
| 
								 | 
							
								        (g_cctt_context.q_wl_cnt != 0xFFFF &&
							 | 
						|||
| 
								 | 
							
								        (start + resp_cnt < g_cctt_context.q_wl_cnt))) {
							 | 
						|||
| 
								 | 
							
								        g_cctt_context.q_wl_pos += resp_cnt;
							 | 
						|||
| 
								 | 
							
								        flow = 1;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    iot_cus_printf("cco_resp_whitelist_to_cctt start:%d cnt:%d "
							 | 
						|||
| 
								 | 
							
								        "ctrl:0x%02X seq:%d flow:%d out_len:%d\n", start, resp_cnt, ctrl,
							 | 
						|||
| 
								 | 
							
								        g_cctt_context.q_wl_seq, flow, out_len);
							 | 
						|||
| 
								 | 
							
								    pkt = iot_pkt_alloc(out_len, IOT_GREE_APP_MID);
							 | 
						|||
| 
								 | 
							
								    if (pkt == NULL) {
							 | 
						|||
| 
								 | 
							
								        iot_cus_printf("[err]cctt pkt alloc fail\n");
							 | 
						|||
| 
								 | 
							
								        return ;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    send_cmd = iot_pkt_put(pkt, out_len);
							 | 
						|||
| 
								 | 
							
								    hdr = (proto_645_header_t*)send_cmd;
							 | 
						|||
| 
								 | 
							
								    iot_mac_addr_cpy(dst_mac, prototask_contxt.local_dev.mac);
							 | 
						|||
| 
								 | 
							
								    iot_mac_addr_reverse(dst_mac);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    iot_proto_645_header_init(hdr, dst_mac, ctrl, PROTO_645_DIR_SLAVE,
							 | 
						|||
| 
								 | 
							
								        PROTO_645_2007_ERR_OK, flow);
							 | 
						|||
| 
								 | 
							
								    if (g_cctt_context.q_wl_seq == 0) {
							 | 
						|||
| 
								 | 
							
								        hdr->len = sizeof(cctt_resp_whitelist_t);
							 | 
						|||
| 
								 | 
							
								        ((cctt_resp_whitelist_t*)(hdr->data))->total_cnt =
							 | 
						|||
| 
								 | 
							
								            prototask_contxt.dev_lst.valid_dev_cnt;
							 | 
						|||
| 
								 | 
							
								        tmp_mac = hdr->data + sizeof(cctt_resp_whitelist_t);
							 | 
						|||
| 
								 | 
							
								    } else {
							 | 
						|||
| 
								 | 
							
								        hdr->len = sizeof(cctt_resp_whitelist_withseq_t);
							 | 
						|||
| 
								 | 
							
								        tmp_mac = hdr->data + sizeof(cctt_resp_whitelist_withseq_t);
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    proto_645_2007_di_to_byte(DL645_07_DI_QUERY_WHITELIST, hdr->data);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    hdr->len += IOT_MAC_ADDR_LEN * resp_cnt;
							 | 
						|||
| 
								 | 
							
								    for (i = 0; i < resp_cnt; i++) {
							 | 
						|||
| 
								 | 
							
								        iot_mac_addr_cpy(tmp_mac + i * IOT_MAC_ADDR_LEN,
							 | 
						|||
| 
								 | 
							
								            prototask_contxt.dev_lst.dev[start + i - 1].mac);
							 | 
						|||
| 
								 | 
							
								        iot_mac_addr_reverse(tmp_mac + i * IOT_MAC_ADDR_LEN);
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    if (g_cctt_context.q_wl_seq) {
							 | 
						|||
| 
								 | 
							
								        *(hdr->data + hdr->len) = g_cctt_context.q_wl_seq;
							 | 
						|||
| 
								 | 
							
								        hdr->len += 1;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    if (flow == 0) {
							 | 
						|||
| 
								 | 
							
								        os_mem_set(&g_cctt_context, 0, sizeof(cctt_context_t));
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    iot_proto_645_ext_add33_handle(hdr->data, hdr->len);
							 | 
						|||
| 
								 | 
							
								    iot_proto_645_tail_init(hdr);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    iot_proto_send_to_mainboard(pkt);
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								/* read whitelist */
							 | 
						|||
| 
								 | 
							
								uint8_t iot_cctt_read_whitelist(uint8_t *data, uint8_t len)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    uint8_t ctrl;
							 | 
						|||
| 
								 | 
							
								    uint8_t read_cnt;
							 | 
						|||
| 
								 | 
							
								    cctt_query_whitelist_t *read_cmd;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    read_cnt = (DL645_FRM_DATA_MAX_LEN - DL645_PARSE_FRM_MIN_LEN -
							 | 
						|||
| 
								 | 
							
								        sizeof(cctt_resp_whitelist_t)) / IOT_MAC_ADDR_LEN;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    if (len == sizeof(cctt_query_whitelist_t)) {
							 | 
						|||
| 
								 | 
							
								        ctrl = PROTO_645_2007_FN_READ_DATA;
							 | 
						|||
| 
								 | 
							
								        read_cmd = (cctt_query_whitelist_t*)data;
							 | 
						|||
| 
								 | 
							
								        iot_cus_printf("cctt_read_whitelist start:%d cnt:%d q_cnt:%d total:%d\n",
							 | 
						|||
| 
								 | 
							
								            read_cmd->start, read_cnt, read_cmd->cnt,
							 | 
						|||
| 
								 | 
							
								            prototask_contxt.dev_lst.valid_dev_cnt);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        os_mem_set(&g_cctt_context, 0, sizeof(cctt_context_t));
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        g_cctt_context.q_wl_cnt = read_cmd->cnt;
							 | 
						|||
| 
								 | 
							
								        if (read_cmd->start > 0) {
							 | 
						|||
| 
								 | 
							
								            g_cctt_context.q_wl_pos = read_cmd->start;
							 | 
						|||
| 
								 | 
							
								             if (g_cctt_context.q_wl_pos + read_cnt - 1 >
							 | 
						|||
| 
								 | 
							
								                prototask_contxt.dev_lst.valid_dev_cnt) {
							 | 
						|||
| 
								 | 
							
								                read_cnt = prototask_contxt.dev_lst.valid_dev_cnt -
							 | 
						|||
| 
								 | 
							
								                    g_cctt_context.q_wl_pos + 1;
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								        } else {
							 | 
						|||
| 
								 | 
							
								            goto err;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								    } else {
							 | 
						|||
| 
								 | 
							
								        ctrl = PROTO_645_2007_FN_READ_DATA_C;
							 | 
						|||
| 
								 | 
							
								         /* check query topo for next frame */
							 | 
						|||
| 
								 | 
							
								        if (g_cctt_context.q_wl_seq + 1 == data[DL645_DI_LEN] &&
							 | 
						|||
| 
								 | 
							
								            g_cctt_context.q_wl_pos > 0) {
							 | 
						|||
| 
								 | 
							
								            g_cctt_context.q_wl_seq = data[DL645_DI_LEN];
							 | 
						|||
| 
								 | 
							
								            /* q_topo_cnt will be change after topo resp */
							 | 
						|||
| 
								 | 
							
								        } else {
							 | 
						|||
| 
								 | 
							
								            goto err;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        iot_cus_printf("cctt_read_whitelist start:%d seq:%d cnt:%d total:%d\n",
							 | 
						|||
| 
								 | 
							
								            g_cctt_context.q_wl_pos, g_cctt_context.q_wl_seq,
							 | 
						|||
| 
								 | 
							
								            g_cctt_context.q_wl_cnt, prototask_contxt.dev_lst.valid_dev_cnt);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        if (g_cctt_context.q_wl_pos > prototask_contxt.dev_lst.valid_dev_cnt) {
							 | 
						|||
| 
								 | 
							
								            read_cnt = 0;
							 | 
						|||
| 
								 | 
							
								        } else if (g_cctt_context.q_wl_pos + read_cnt - 1 >
							 | 
						|||
| 
								 | 
							
								            prototask_contxt.dev_lst.valid_dev_cnt) {
							 | 
						|||
| 
								 | 
							
								            read_cnt = prototask_contxt.dev_lst.valid_dev_cnt -
							 | 
						|||
| 
								 | 
							
								                g_cctt_context.q_wl_pos + 1;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    if (read_cnt > g_cctt_context.q_wl_cnt) {
							 | 
						|||
| 
								 | 
							
								        read_cnt = g_cctt_context.q_wl_cnt;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    cco_resp_whitelist_to_cctt(g_cctt_context.q_wl_pos, read_cnt);
							 | 
						|||
| 
								 | 
							
								    return 0;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								err:
							 | 
						|||
| 
								 | 
							
								    /* read cmd error */
							 | 
						|||
| 
								 | 
							
								    os_mem_set(&g_cctt_context, 0, sizeof(cctt_context_t));
							 | 
						|||
| 
								 | 
							
								    iot_cus_printf("cctt read whitelist err\n");
							 | 
						|||
| 
								 | 
							
								    cctt_resp_cmd_ack(ctrl, DL645_ERR_PARAMETER_ERROR);
							 | 
						|||
| 
								 | 
							
								    return 1;
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								/**
							 | 
						|||
| 
								 | 
							
								 * @brief: report sta join or leave event
							 | 
						|||
| 
								 | 
							
								 *
							 | 
						|||
| 
								 | 
							
								 * @param p_mac: mac address of sta device
							 | 
						|||
| 
								 | 
							
								 * @param evt  : event of sta device, 1=join, 2=leave
							 | 
						|||
| 
								 | 
							
								 * @return : 0 if success, 1 when failed
							 | 
						|||
| 
								 | 
							
								 */
							 | 
						|||
| 
								 | 
							
								uint8_t iot_cctt_report_sta_event(uint8_t *p_mac, uint8_t evt)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    uint8_t *send_cmd;
							 | 
						|||
| 
								 | 
							
								    uint16_t out_len;
							 | 
						|||
| 
								 | 
							
								    uint8_t dst_mac[IOT_MAC_ADDR_LEN];
							 | 
						|||
| 
								 | 
							
								    iot_pkt_t *pkt;
							 | 
						|||
| 
								 | 
							
								    proto_645_header_t *hdr;
							 | 
						|||
| 
								 | 
							
								    cctt_rpt_sta_evt_t *rpt;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    out_len = DL645_PARSE_FRM_MIN_LEN + sizeof(cctt_rpt_sta_evt_t);
							 | 
						|||
| 
								 | 
							
								    pkt = iot_pkt_alloc(out_len, IOT_GREE_APP_MID);
							 | 
						|||
| 
								 | 
							
								    if (pkt == NULL) {
							 | 
						|||
| 
								 | 
							
								        iot_cus_printf("[err]cctt pkt alloc fail\n");
							 | 
						|||
| 
								 | 
							
								        return 1;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    send_cmd = iot_pkt_put(pkt, out_len);
							 | 
						|||
| 
								 | 
							
								    hdr = (proto_645_header_t*)send_cmd;
							 | 
						|||
| 
								 | 
							
								    iot_mac_addr_cpy(dst_mac, prototask_contxt.local_dev.mac);
							 | 
						|||
| 
								 | 
							
								    iot_mac_addr_reverse(dst_mac);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    iot_proto_645_header_init(hdr, dst_mac, RPT_STA_STATE_FN, 0,
							 | 
						|||
| 
								 | 
							
								        PROTO_645_2007_ERR_OK, 0);
							 | 
						|||
| 
								 | 
							
								    hdr->len = sizeof(cctt_rpt_sta_evt_t);
							 | 
						|||
| 
								 | 
							
								    rpt = (cctt_rpt_sta_evt_t *)hdr->data;
							 | 
						|||
| 
								 | 
							
								    rpt->event = evt;
							 | 
						|||
| 
								 | 
							
								    iot_mac_addr_cpy(rpt->mac, p_mac);
							 | 
						|||
| 
								 | 
							
								    iot_mac_addr_reverse(rpt->mac);
							 | 
						|||
| 
								 | 
							
								    iot_proto_645_tail_init(hdr);
							 | 
						|||
| 
								 | 
							
								    iot_proto_send_to_mainboard(pkt);
							 | 
						|||
| 
								 | 
							
								    return 0;
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								uint8_t iot_cctt_report_sta_online(plctxrx_cmd_topov2_t *resp_node,
							 | 
						|||
| 
								 | 
							
								    uint16_t total_cnt, uint16_t cur_cnt)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    uint8_t i = 0;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    if (iot_mac_addr_cmp(resp_node[0].mac, prototask_contxt.local_dev.mac)){
							 | 
						|||
| 
								 | 
							
								        /* skip cco device report */
							 | 
						|||
| 
								 | 
							
								        i++;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    for (; i < cur_cnt; i++) {
							 | 
						|||
| 
								 | 
							
								        iot_cus_printf("sta %02X:%02X:%02X:%02X:%02X:%02X report online\n",
							 | 
						|||
| 
								 | 
							
								            resp_node[i].mac[0], resp_node[i].mac[1], resp_node[i].mac[2],
							 | 
						|||
| 
								 | 
							
								            resp_node[i].mac[3], resp_node[i].mac[4], resp_node[i].mac[5]);
							 | 
						|||
| 
								 | 
							
								        iot_cctt_report_sta_event(resp_node[i].mac, EVENT_RPT_STA_JOINED);
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    if (total_cnt == cur_cnt) {
							 | 
						|||
| 
								 | 
							
								        iot_cus_printf("topo report online done, total = %u\n", total_cnt);
							 | 
						|||
| 
								 | 
							
								        g_cctt_context.q_topo_rpt_online = 0;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    return 0;
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								/* report topo info as DL645 frame */
							 | 
						|||
| 
								 | 
							
								uint8_t iot_cctt_report_topo(plctxrx_cmd_topov2_t *resp_node,
							 | 
						|||
| 
								 | 
							
								    uint16_t total_cnt, uint16_t cur_cnt, uint8_t flow)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    uint8_t ctrl, i;
							 | 
						|||
| 
								 | 
							
								    uint8_t resp_cnt;
							 | 
						|||
| 
								 | 
							
								    uint8_t *send_cmd;
							 | 
						|||
| 
								 | 
							
								    uint16_t out_len;
							 | 
						|||
| 
								 | 
							
								    uint8_t dst_mac[IOT_MAC_ADDR_LEN];
							 | 
						|||
| 
								 | 
							
								    iot_pkt_t *pkt;
							 | 
						|||
| 
								 | 
							
								    node_t *node;
							 | 
						|||
| 
								 | 
							
								    proto_645_header_t *hdr;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    resp_cnt = cur_cnt;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    out_len = DL645_PARSE_FRM_MIN_LEN  + sizeof(node_t) * resp_cnt;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    if (g_cctt_context.q_topo_seq) {
							 | 
						|||
| 
								 | 
							
								        ctrl = PROTO_645_2007_FN_READ_DATA_C;
							 | 
						|||
| 
								 | 
							
								        out_len += DL645_DI_LEN + 1;
							 | 
						|||
| 
								 | 
							
								    } else {
							 | 
						|||
| 
								 | 
							
								        ctrl = PROTO_645_2007_FN_READ_DATA;
							 | 
						|||
| 
								 | 
							
								        out_len += sizeof(cctt_resp_topo_t) ;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    iot_cus_printf("topo_resp cnt:%d ctrl:0x%02X seq:%d flow:%d out_len:%d\n",
							 | 
						|||
| 
								 | 
							
								        resp_cnt, ctrl, g_cctt_context.q_topo_seq, flow, out_len);
							 | 
						|||
| 
								 | 
							
								    pkt = iot_pkt_alloc(out_len, IOT_GREE_APP_MID);
							 | 
						|||
| 
								 | 
							
								    if (pkt == NULL) {
							 | 
						|||
| 
								 | 
							
								        iot_cus_printf("[err]cctt pkt alloc fail\n");
							 | 
						|||
| 
								 | 
							
								        cctt_resp_cmd_ack(ctrl, DL645_ERR_OTHER_ERROR);
							 | 
						|||
| 
								 | 
							
								        return 1;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    send_cmd = iot_pkt_put(pkt, out_len);
							 | 
						|||
| 
								 | 
							
								    hdr = (proto_645_header_t*)send_cmd;
							 | 
						|||
| 
								 | 
							
								    iot_mac_addr_cpy(dst_mac, prototask_contxt.local_dev.mac);
							 | 
						|||
| 
								 | 
							
								    iot_mac_addr_reverse(dst_mac);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    iot_proto_645_header_init(hdr, dst_mac, ctrl, PROTO_645_DIR_SLAVE,
							 | 
						|||
| 
								 | 
							
								        PROTO_645_2007_ERR_OK, flow);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    proto_645_2007_di_to_byte(DL645_07_DI_QUERY_TOPO, hdr->data);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    if (g_cctt_context.q_topo_seq) {
							 | 
						|||
| 
								 | 
							
								        hdr->len = DL645_DI_LEN;
							 | 
						|||
| 
								 | 
							
								        node = (node_t*)(hdr->data + DL645_DI_LEN);
							 | 
						|||
| 
								 | 
							
								    } else {
							 | 
						|||
| 
								 | 
							
								        hdr->len = sizeof(cctt_resp_topo_t);
							 | 
						|||
| 
								 | 
							
								        ((cctt_resp_topo_t*)(hdr->data))->total_cnt = total_cnt;
							 | 
						|||
| 
								 | 
							
								        ((cctt_resp_topo_t*)(hdr->data))->q_ver = 0;
							 | 
						|||
| 
								 | 
							
								        node = ((cctt_resp_topo_t*)(hdr->data))->node;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    hdr->len += sizeof(node_t) * resp_cnt;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    for (i = 0; i < resp_cnt; i++) {
							 | 
						|||
| 
								 | 
							
								        node->level = resp_node[i].level;
							 | 
						|||
| 
								 | 
							
								        iot_mac_addr_cpy(node->mac, resp_node[i].mac);
							 | 
						|||
| 
								 | 
							
								        iot_mac_addr_reverse(node->mac);
							 | 
						|||
| 
								 | 
							
								        node++;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    if (g_cctt_context.q_topo_seq) {
							 | 
						|||
| 
								 | 
							
								        *(hdr->data + hdr->len) = g_cctt_context.q_topo_seq;
							 | 
						|||
| 
								 | 
							
								        hdr->len += 1;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    /*  check end */
							 | 
						|||
| 
								 | 
							
								    if (flow == 0) {
							 | 
						|||
| 
								 | 
							
								        os_mem_set(&g_cctt_context, 0, sizeof(cctt_context_t));
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    iot_proto_645_ext_add33_handle(hdr->data, hdr->len);
							 | 
						|||
| 
								 | 
							
								    iot_proto_645_tail_init(hdr);
							 | 
						|||
| 
								 | 
							
								    iot_proto_send_to_mainboard(pkt);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    return 0;
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								/* response topo info */
							 | 
						|||
| 
								 | 
							
								uint8_t iot_cco_resp_topo_to_cctt(plctxrx_cmd_topov2_t *resp_node,
							 | 
						|||
| 
								 | 
							
								    uint16_t total_cnt, uint16_t cur_cnt, uint8_t flow)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    if (g_cctt_context.q_topo_rpt_online) {
							 | 
						|||
| 
								 | 
							
								        /* request to report sta online by iot_cctt_req_online_sta_report */
							 | 
						|||
| 
								 | 
							
								        return iot_cctt_report_sta_online(resp_node, total_cnt, cur_cnt);
							 | 
						|||
| 
								 | 
							
								    } else {
							 | 
						|||
| 
								 | 
							
								        return iot_cctt_report_topo(resp_node, total_cnt, cur_cnt, flow);
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								/**
							 | 
						|||
| 
								 | 
							
								 * @brief: send cmd to txrx to request topo info
							 | 
						|||
| 
								 | 
							
								 *
							 | 
						|||
| 
								 | 
							
								 * @param start: start of topo to request
							 | 
						|||
| 
								 | 
							
								 * @param count: number of topo to request
							 | 
						|||
| 
								 | 
							
								 * @param seq  : frame sequence
							 | 
						|||
| 
								 | 
							
								 * @return 0 if success, 1 when failed
							 | 
						|||
| 
								 | 
							
								 */
							 | 
						|||
| 
								 | 
							
								uint8_t iot_cctt_req_txrx_topo(uint16_t start, uint16_t count, uint8_t seq)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    uint8_t txrx_cmd_len;
							 | 
						|||
| 
								 | 
							
								    iot_pkt_t *pkt;
							 | 
						|||
| 
								 | 
							
								    plctxrx_cmd_arg_t *cmd;
							 | 
						|||
| 
								 | 
							
								    plctxrx_cmd_query_topo_t *topo_cmd;
							 | 
						|||
| 
								 | 
							
								    proto_cmd_hdl_state_t *sm = iot_proto_cmd_handle_state_get();
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    iot_cus_printf("cctt_query_topo seq=%d pos:%d cnt:%d\n",
							 | 
						|||
| 
								 | 
							
								        g_cctt_context.q_topo_seq, g_cctt_context.q_topo_pos, count);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    txrx_cmd_len = sizeof(plctxrx_cmd_arg_t) + sizeof(plctxrx_cmd_query_topo_t);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    /* send txrx cmd */
							 | 
						|||
| 
								 | 
							
								    pkt = iot_pkt_alloc(txrx_cmd_len, IOT_GREE_APP_MID);
							 | 
						|||
| 
								 | 
							
								    if (pkt == NULL) {
							 | 
						|||
| 
								 | 
							
								        iot_cus_printf("[err]cctt pkt alloc fail\n");
							 | 
						|||
| 
								 | 
							
								        goto err;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    cmd = (plctxrx_cmd_arg_t*)iot_pkt_put(pkt, txrx_cmd_len);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    cmd->cid.cid = PLCTXRX_CID_TOPO;
							 | 
						|||
| 
								 | 
							
								    cmd->cid.opcode = PLCTXRX_OP_QUERY;
							 | 
						|||
| 
								 | 
							
								    cmd->need_ack = true;
							 | 
						|||
| 
								 | 
							
								    cmd->prio = 0;
							 | 
						|||
| 
								 | 
							
								    cmd->dlen = sizeof(plctxrx_cmd_query_topo_t);
							 | 
						|||
| 
								 | 
							
								    topo_cmd = (plctxrx_cmd_query_topo_t*)cmd->arg;
							 | 
						|||
| 
								 | 
							
								    topo_cmd->ver = IOT_PLC_CCO_TOPO_REQ_DATA_VER_V2;
							 | 
						|||
| 
								 | 
							
								    topo_cmd->start = start;
							 | 
						|||
| 
								 | 
							
								    topo_cmd->cnt = count;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    sm->state = PROTO_CMD_DL645_WAIT_TOPO_INFO_RESP;
							 | 
						|||
| 
								 | 
							
								    sm->dir   = CMD_LOCAL_UP_LINK;
							 | 
						|||
| 
								 | 
							
								    sm->seq   = seq;
							 | 
						|||
| 
								 | 
							
								    iot_proto_cmd_send_to_plctxrx(pkt);
							 | 
						|||
| 
								 | 
							
								    return 0;
							 | 
						|||
| 
								 | 
							
								err:
							 | 
						|||
| 
								 | 
							
								    return 1;
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								/**
							 | 
						|||
| 
								 | 
							
								 * @brief: request online sta device report online to server
							 | 
						|||
| 
								 | 
							
								 *
							 | 
						|||
| 
								 | 
							
								 * @param none
							 | 
						|||
| 
								 | 
							
								 * @return 0 if success, 1 when failed
							 | 
						|||
| 
								 | 
							
								 */
							 | 
						|||
| 
								 | 
							
								uint8_t iot_cctt_req_online_sta_report(void)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    os_mem_set(&g_cctt_context, 0, sizeof(cctt_context_t));
							 | 
						|||
| 
								 | 
							
								    g_cctt_context.q_topo_type = 0;
							 | 
						|||
| 
								 | 
							
								    g_cctt_context.q_topo_pos = 1;
							 | 
						|||
| 
								 | 
							
								    g_cctt_context.q_topo_cnt = 0xFFFF;
							 | 
						|||
| 
								 | 
							
								    g_cctt_context.q_topo_rpt_online = 1;
							 | 
						|||
| 
								 | 
							
								    return iot_cctt_req_txrx_topo(1, 0xFFFF, 0);
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								/* query topo, only send cmd to query topo */
							 | 
						|||
| 
								 | 
							
								uint8_t iot_cctt_query_topo(uint8_t *data, uint8_t len)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    uint8_t ctrl;
							 | 
						|||
| 
								 | 
							
								    uint8_t err_num;
							 | 
						|||
| 
								 | 
							
								    uint8_t query_cnt;
							 | 
						|||
| 
								 | 
							
								    cctt_query_topo_t *query_cmd;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    query_cnt = (DL645_FRM_DATA_MAX_LEN - DL645_PARSE_FRM_MIN_LEN -
							 | 
						|||
| 
								 | 
							
								        sizeof(cctt_resp_topo_t)) / sizeof(node_t);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    if (len == sizeof(cctt_query_topo_t) ) {
							 | 
						|||
| 
								 | 
							
								        ctrl = PROTO_645_2007_FN_READ_DATA;
							 | 
						|||
| 
								 | 
							
								        query_cmd = (cctt_query_topo_t*)data;
							 | 
						|||
| 
								 | 
							
								        os_mem_set(&g_cctt_context, 0, sizeof(cctt_context_t));
							 | 
						|||
| 
								 | 
							
								        if (query_cmd->start > 0) {
							 | 
						|||
| 
								 | 
							
								            g_cctt_context.q_topo_type = query_cmd->q_ver;
							 | 
						|||
| 
								 | 
							
								            g_cctt_context.q_topo_pos = query_cmd->start;
							 | 
						|||
| 
								 | 
							
								            g_cctt_context.q_topo_cnt = query_cmd->cnt;
							 | 
						|||
| 
								 | 
							
								        } else {
							 | 
						|||
| 
								 | 
							
								            err_num = DL645_ERR_PARAMETER_ERROR;
							 | 
						|||
| 
								 | 
							
								            goto err;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								    } else {
							 | 
						|||
| 
								 | 
							
								        ctrl = PROTO_645_2007_FN_READ_DATA_C;
							 | 
						|||
| 
								 | 
							
								        /* check query topo for next frame */
							 | 
						|||
| 
								 | 
							
								        if (g_cctt_context.q_topo_seq + 1 == data[DL645_DI_LEN] &&
							 | 
						|||
| 
								 | 
							
								            g_cctt_context.q_topo_pos > 0) {
							 | 
						|||
| 
								 | 
							
								            g_cctt_context.q_topo_seq = data[DL645_DI_LEN];
							 | 
						|||
| 
								 | 
							
								            /* q_topo_cnt will be change after topo resp */
							 | 
						|||
| 
								 | 
							
								        } else {
							 | 
						|||
| 
								 | 
							
								            err_num = DL645_ERR_PARAMETER_ERROR;
							 | 
						|||
| 
								 | 
							
								            goto err;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    if (query_cnt > g_cctt_context.q_topo_cnt) {
							 | 
						|||
| 
								 | 
							
								        query_cnt = g_cctt_context.q_topo_cnt;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    if (g_cctt_context.q_topo_rpt_online) {
							 | 
						|||
| 
								 | 
							
								        iot_cus_printf("cctt query topo, and reporting online, wait...\n");
							 | 
						|||
| 
								 | 
							
								        err_num = DL645_ERR_OTHER_ERROR;
							 | 
						|||
| 
								 | 
							
								        goto err;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    if (0 != iot_cctt_req_txrx_topo(g_cctt_context.q_topo_pos,
							 | 
						|||
| 
								 | 
							
								        query_cnt, g_cctt_context.q_topo_seq)) {
							 | 
						|||
| 
								 | 
							
								        err_num = DL645_ERR_OTHER_ERROR;
							 | 
						|||
| 
								 | 
							
								        goto err;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    return 0;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								err:
							 | 
						|||
| 
								 | 
							
								    iot_cus_printf("cctt query topo end\n");
							 | 
						|||
| 
								 | 
							
								    cctt_resp_cmd_ack(ctrl, err_num);
							 | 
						|||
| 
								 | 
							
								    return 1;
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								void iot_cctt_set_plc_nw(uint8_t *data, uint8_t len)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    uint8_t reason = DL645_ERR_OK;
							 | 
						|||
| 
								 | 
							
								    cctt_set_plc_net_t *nw_handle = (cctt_set_plc_net_t *)data;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    if (nw_handle->action == 0) {
							 | 
						|||
| 
								 | 
							
								        iot_plc_stop_nw_fmt(greeapp->app_handle);
							 | 
						|||
| 
								 | 
							
								        g_cctt_context.plc_nw_state = PLC_NW_CLOSE;
							 | 
						|||
| 
								 | 
							
								    } else {
							 | 
						|||
| 
								 | 
							
								        iot_plc_start_nw_fmt(greeapp->app_handle, 1);
							 | 
						|||
| 
								 | 
							
								        g_cctt_context.plc_nw_state = PLC_NW_OPEN;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    iot_cus_printf("ccct set nw :%d\n", nw_handle->action);
							 | 
						|||
| 
								 | 
							
								    cctt_resp_cmd_ack(PROTO_645_2007_FN_WRITE_DATA, reason);
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								void iot_cctt_get_plc_nw(void)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    uint8_t *send_cmd;
							 | 
						|||
| 
								 | 
							
								    uint8_t datalen = DL645_DI_LEN + sizeof(uint8_t);
							 | 
						|||
| 
								 | 
							
								    uint8_t out_len = DL645_PARSE_FRM_MIN_LEN + datalen;
							 | 
						|||
| 
								 | 
							
								    uint8_t dst_mac[IOT_MAC_ADDR_LEN];
							 | 
						|||
| 
								 | 
							
								    iot_pkt_t *pkt;
							 | 
						|||
| 
								 | 
							
								    proto_645_header_t *hdr;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    pkt = iot_pkt_alloc(out_len, IOT_GREE_APP_MID);
							 | 
						|||
| 
								 | 
							
								    if (pkt == NULL) {
							 | 
						|||
| 
								 | 
							
								        iot_cus_printf("[err]read plc nw fail\n");
							 | 
						|||
| 
								 | 
							
								        return ;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    send_cmd = iot_pkt_put(pkt, out_len);
							 | 
						|||
| 
								 | 
							
								    hdr = (proto_645_header_t*)send_cmd;
							 | 
						|||
| 
								 | 
							
								    iot_mac_addr_cpy(dst_mac, prototask_contxt.local_dev.mac);
							 | 
						|||
| 
								 | 
							
								    iot_mac_addr_reverse(dst_mac);
							 | 
						|||
| 
								 | 
							
								    hdr->len = datalen;
							 | 
						|||
| 
								 | 
							
								    iot_proto_645_header_init(hdr, dst_mac, PROTO_645_2007_FN_READ_DATA,
							 | 
						|||
| 
								 | 
							
								        PROTO_645_DIR_SLAVE, PROTO_645_2007_ERR_OK, 0);
							 | 
						|||
| 
								 | 
							
								    proto_645_2007_di_to_byte(DL645_07_DI_HANDLE_PLC_NW, hdr->data);
							 | 
						|||
| 
								 | 
							
								    hdr->data[DL645_DI_LEN] = g_cctt_context.plc_nw_state;
							 | 
						|||
| 
								 | 
							
								    iot_cus_printf("ccct read nw :0x%x\n", g_cctt_context.plc_nw_state);
							 | 
						|||
| 
								 | 
							
								    iot_proto_645_ext_add33_handle(hdr->data, datalen);
							 | 
						|||
| 
								 | 
							
								    iot_proto_645_tail_init(hdr);
							 | 
						|||
| 
								 | 
							
								    iot_proto_send_to_mainboard(pkt);
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								static void iot_cctt_add_pco(uint8_t *mac)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    uint8_t i;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    iot_cus_printf("add pco mac:%02X%02X%02X%02X%02X%02X\n",
							 | 
						|||
| 
								 | 
							
								        mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    if (iot_mac_addr_cmp(mac, prototask_contxt.local_dev.mac)) {
							 | 
						|||
| 
								 | 
							
								        /* pco is cco, not add */
							 | 
						|||
| 
								 | 
							
								        return;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    for (i = 0; i < IOT_CCTT_CACHE_PCO_CNT; i++) {
							 | 
						|||
| 
								 | 
							
								        if (!iot_mac_addr_valid(g_cctt_context.pco_list[i])) {
							 | 
						|||
| 
								 | 
							
								            /* store pco in blank */
							 | 
						|||
| 
								 | 
							
								            iot_mac_addr_cpy(g_cctt_context.pco_list[i], mac);
							 | 
						|||
| 
								 | 
							
								            g_cctt_context.pco_cnt++;
							 | 
						|||
| 
								 | 
							
								            break;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        if (iot_mac_addr_cmp(mac, g_cctt_context.pco_list[i])) {
							 | 
						|||
| 
								 | 
							
								            /* check pco have stored */
							 | 
						|||
| 
								 | 
							
								            break;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    return;
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								void iot_cctt_reboot_mac_list_pco(uint8_t *data, uint8_t len)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    uint8_t i;
							 | 
						|||
| 
								 | 
							
								    uint16_t j;
							 | 
						|||
| 
								 | 
							
								    uint8_t reason = DL645_ERR_OK;
							 | 
						|||
| 
								 | 
							
								    cctt_reboot_mac_list_pco_t *cmd = (cctt_reboot_mac_list_pco_t *)data;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    if (sizeof(cctt_reboot_mac_list_pco_t) + cmd->cnt * IOT_MAC_ADDR_LEN != len
							 | 
						|||
| 
								 | 
							
								        || cmd->cnt == 0) {
							 | 
						|||
| 
								 | 
							
								        reason = DL645_ERR_PARAMETER_ERROR;
							 | 
						|||
| 
								 | 
							
								        goto out;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    /* find pco */
							 | 
						|||
| 
								 | 
							
								    for (i = 0; i < cmd->cnt; i++) {
							 | 
						|||
| 
								 | 
							
								        if (!iot_mac_addr_valid(cmd->mac[i])) {
							 | 
						|||
| 
								 | 
							
								            continue;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        iot_mac_addr_reverse(cmd->mac[i]);
							 | 
						|||
| 
								 | 
							
								        for (j = 0; j < STA_DEV_MAX; j++) {
							 | 
						|||
| 
								 | 
							
								            if (!iot_mac_addr_valid(prototask_contxt.dev_lst.dev[j].mac)) {
							 | 
						|||
| 
								 | 
							
								                continue;
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								            if (iot_mac_addr_cmp(cmd->mac[i],
							 | 
						|||
| 
								 | 
							
								                prototask_contxt.dev_lst.dev[j].mac)) {
							 | 
						|||
| 
								 | 
							
								                iot_cus_printf("find mac:%02x%02x%02x%02x%02x%02x role=%d\n",
							 | 
						|||
| 
								 | 
							
								                    cmd->mac[i][0], cmd->mac[i][1], cmd->mac[i][2],
							 | 
						|||
| 
								 | 
							
								                    cmd->mac[i][3], cmd->mac[i][4], cmd->mac[i][5],
							 | 
						|||
| 
								 | 
							
								                    prototask_contxt.dev_lst.dev[j].dev_role);
							 | 
						|||
| 
								 | 
							
								                if (prototask_contxt.dev_lst.dev[j].dev_role ==
							 | 
						|||
| 
								 | 
							
								                    IOT_PLC_DEV_ROLE_STA) {
							 | 
						|||
| 
								 | 
							
								                    /* only add sta's pco, not add pco's pco */
							 | 
						|||
| 
								 | 
							
								                    iot_cctt_add_pco(prototask_contxt.dev_lst.dev_pco[j]);
							 | 
						|||
| 
								 | 
							
								                }
							 | 
						|||
| 
								 | 
							
								                break;
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    iot_cus_printf("[cctt]find pco cnt=%d\n", g_cctt_context.pco_cnt);
							 | 
						|||
| 
								 | 
							
								    /* reboot pco */
							 | 
						|||
| 
								 | 
							
								    if (cmd->seq == 0 && g_cctt_context.pco_cnt > 0) {
							 | 
						|||
| 
								 | 
							
								        for (i = 0; i < g_cctt_context.pco_cnt; i++) {
							 | 
						|||
| 
								 | 
							
								            iot_reboot_sta(g_cctt_context.pco_list[i]);
							 | 
						|||
| 
								 | 
							
								            os_delay(50);
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        /* reset param */
							 | 
						|||
| 
								 | 
							
								        g_cctt_context.pco_cnt = 0;
							 | 
						|||
| 
								 | 
							
								        os_mem_set(g_cctt_context.pco_list, 0,
							 | 
						|||
| 
								 | 
							
								            IOT_CCTT_CACHE_PCO_CNT * IOT_MAC_ADDR_LEN);
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								out:
							 | 
						|||
| 
								 | 
							
								    cctt_resp_cmd_ack(PROTO_645_2007_FN_WRITE_DATA, reason);
							 | 
						|||
| 
								 | 
							
								    return;
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								#if IOT_APP_SELECTION == IOT_APP_DEF_22_GE_MICRO_CCTT
							 | 
						|||
| 
								 | 
							
								void iot_cctt_init_rs485_led_pin(void)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    switch (iot_board_hw_version_hex()) {
							 | 
						|||
| 
								 | 
							
								    case HW_VERSION_IOT_CCTT_V3_0:  /* micro cctt 3.0 hardware */
							 | 
						|||
| 
								 | 
							
								        g_local_rs485.rs485_led_pin = 0xFF;
							 | 
						|||
| 
								 | 
							
								        break;
							 | 
						|||
| 
								 | 
							
								    case HW_VERSION_IOT_CCTT_V3_5:  /* micro cctt 3.5 hardware */
							 | 
						|||
| 
								 | 
							
								    default:
							 | 
						|||
| 
								 | 
							
								        g_local_rs485.rs485_led_pin = 54;
							 | 
						|||
| 
								 | 
							
								        break;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    if (g_local_rs485.rs485_led_pin != 0xFF) {
							 | 
						|||
| 
								 | 
							
								        iot_gpio_open_as_output(g_local_rs485.rs485_led_pin);
							 | 
						|||
| 
								 | 
							
								        iot_gpio_value_set(g_local_rs485.rs485_led_pin, 1);
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    iot_cus_printf("g_local_rs485.rs485_led_pin=%u\n",
							 | 
						|||
| 
								 | 
							
								        g_local_rs485.rs485_led_pin);
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								#else
							 | 
						|||
| 
								 | 
							
								void iot_cctt_init_rs485_led_pin(void)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    g_local_rs485.rs485_led_pin = 0xFF;
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								#endif
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								void iot_cctt_rs485_led_blink(void)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    if (g_local_rs485.rs485_led_pin != 0xFF) {
							 | 
						|||
| 
								 | 
							
								        iot_gpio_value_set(g_local_rs485.rs485_led_pin, 0);
							 | 
						|||
| 
								 | 
							
								        os_delay(1);
							 | 
						|||
| 
								 | 
							
								        iot_gpio_value_set(g_local_rs485.rs485_led_pin, 1);
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								void iot_cctt_delaytime(uint8_t *data, uint8_t len)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    uint8_t err_num = DL645_ERR_OK;
							 | 
						|||
| 
								 | 
							
								    uint16_t pkt_len;
							 | 
						|||
| 
								 | 
							
								    iot_pkt_t *data_pkt;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    proto_645_header_t *header = (proto_645_header_t *)data;
							 | 
						|||
| 
								 | 
							
								    cctt_delaytime_t *data_info = (cctt_delaytime_t *)header->data;
							 | 
						|||
| 
								 | 
							
								    ge_frame_delay_time_subfn166_t *ge_frame = NULL;
							 | 
						|||
| 
								 | 
							
								    uint16_t rsv_data_len = data_info->time_info.datalen;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    pkt_len = sizeof(ge_frame_delay_time_subfn166_t) +
							 | 
						|||
| 
								 | 
							
								        data_info->time_info.datalen + sizeof(ge_frm_tail_t);
							 | 
						|||
| 
								 | 
							
								    if (pkt_len > DL645_FRM_DATA_MAX_LEN) {
							 | 
						|||
| 
								 | 
							
								        err_num = DL645_ERR_PARAMETER_ERROR;
							 | 
						|||
| 
								 | 
							
								        goto err;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    data_pkt = iot_pkt_alloc(pkt_len, IOT_GREE_APP_MID);
							 | 
						|||
| 
								 | 
							
								    if (data_pkt == NULL) {
							 | 
						|||
| 
								 | 
							
								        iot_cus_printf("%s alloc pkt err\n", __FUNCTION__);
							 | 
						|||
| 
								 | 
							
								        err_num = DL645_ERR_OTHER_ERROR;
							 | 
						|||
| 
								 | 
							
								        goto err;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    /* pack a ge delaytime frame */
							 | 
						|||
| 
								 | 
							
								    ge_frame = (ge_frame_delay_time_subfn166_t *)iot_pkt_put(data_pkt, pkt_len);
							 | 
						|||
| 
								 | 
							
								    ge_frm_tail_t *tail_data = (ge_frm_tail_t *)(iot_pkt_data(data_pkt) +
							 | 
						|||
| 
								 | 
							
								        sizeof(ge_frame_delay_time_subfn166_t) + rsv_data_len);
							 | 
						|||
| 
								 | 
							
								    os_mem_set((uint8_t *)ge_frame, 0, pkt_len);
							 | 
						|||
| 
								 | 
							
								    g_cctt_context.q_delaytime_seq++;
							 | 
						|||
| 
								 | 
							
								    ge_frame->seq = g_cctt_context.q_delaytime_seq;
							 | 
						|||
| 
								 | 
							
								    ge_frame->resv = DL645_07_RESV0_RESV;
							 | 
						|||
| 
								 | 
							
								    iot_mac_addr_cpy(ge_frame->dest_mac, header->addr);
							 | 
						|||
| 
								 | 
							
								    iot_mac_addr_reverse(ge_frame->dest_mac);
							 | 
						|||
| 
								 | 
							
								    data_info->time_info.level = iot_plctxrx_get_node_level(ge_frame->dest_mac);
							 | 
						|||
| 
								 | 
							
								    if (data_info->time_info.level == -1) {
							 | 
						|||
| 
								 | 
							
								        iot_cus_printf("%s query level failed\n", __FUNCTION__);
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    os_mem_cpy((uint8_t *)&ge_frame->tm_test,(uint8_t *)&data_info->time_info,
							 | 
						|||
| 
								 | 
							
								        sizeof(ge_delay_tm_test_t));
							 | 
						|||
| 
								 | 
							
								    iot_delay_timer_get(&ge_frame->tm_test.mcu_tx_time, CCO_TX_TIME, 0);
							 | 
						|||
| 
								 | 
							
								    EXT_FN_TWO_PART_FRM_PREPARE(ge_frame, tail_data, rsv_data_len,
							 | 
						|||
| 
								 | 
							
								        PROTO_GE_PLC_SET_CMD, PROTO_GE_DELAY_TM_CMD);
							 | 
						|||
| 
								 | 
							
								    tail_data->check_sum = ge_frm_checksum_calc((uint8_t *)ge_frame,
							 | 
						|||
| 
								 | 
							
								        pkt_len - sizeof(ge_frm_tail_t));
							 | 
						|||
| 
								 | 
							
								    iot_proto_delay_time_send(data_pkt, prototask_contxt.local_dev.mac,
							 | 
						|||
| 
								 | 
							
								        ge_frame->dest_mac);
							 | 
						|||
| 
								 | 
							
								    return;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								err:
							 | 
						|||
| 
								 | 
							
								    cctt_resp_cmd_ack(PROTO_645_2007_FN_READ_DATA, err_num);
							 | 
						|||
| 
								 | 
							
								    return;
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								/**
							 | 
						|||
| 
								 | 
							
								 * @brief: set parameter of rs485 interface
							 | 
						|||
| 
								 | 
							
								 *
							 | 
						|||
| 
								 | 
							
								 * @param baudrate: baudrate of rs485
							 | 
						|||
| 
								 | 
							
								 * @param parity  : parity of rs485
							 | 
						|||
| 
								 | 
							
								 * @param databits: data bit number of rs485
							 | 
						|||
| 
								 | 
							
								 * @param stopbits: stopbits of rs485
							 | 
						|||
| 
								 | 
							
								 * @return ERR_OK if success, ERR_FAIL otherwise
							 | 
						|||
| 
								 | 
							
								 */
							 | 
						|||
| 
								 | 
							
								uint8_t iot_cctt_set_rs485_config_impl(uint32_t baudrate, uint8_t parity,
							 | 
						|||
| 
								 | 
							
								                                       uint8_t databits,  uint8_t stopbits)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    ge_app_pib_info_t *p_flash = &prototask_contxt.flashinfo;
							 | 
						|||
| 
								 | 
							
								    uint32_t baud_val[] = PROTO_GE_UART_BAUD_VALUE;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    if (NULL == g_local_rs485.handler) {
							 | 
						|||
| 
								 | 
							
								        return ERR_FAIL;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    if (!iot_proto_uart_param_check(baudrate, parity, databits, stopbits)) {
							 | 
						|||
| 
								 | 
							
								        iot_cus_printf("%s: invalid rs485 param:%u,%u,%u,%u\n",
							 | 
						|||
| 
								 | 
							
								            __FUNCTION__, baudrate, parity, databits, stopbits);
							 | 
						|||
| 
								 | 
							
								        return ERR_FAIL;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    if ((baud_val[p_flash->public.pub.baudidx] != baudrate) ||
							 | 
						|||
| 
								 | 
							
								        (p_flash->public.pub.parity != parity) ||
							 | 
						|||
| 
								 | 
							
								        (p_flash->public.pub.data != databits) ||
							 | 
						|||
| 
								 | 
							
								        (p_flash->public.pub.stop != stopbits)) {
							 | 
						|||
| 
								 | 
							
								        iot_cus_printf("%s: rs485 param:%u,%u,%u,%u changed, save it\n",
							 | 
						|||
| 
								 | 
							
								            __FUNCTION__, baudrate, parity, databits, stopbits);
							 | 
						|||
| 
								 | 
							
								        p_flash->public.pub.baudidx = uart_baud_find_index(baudrate);
							 | 
						|||
| 
								 | 
							
								        p_flash->public.pub.parity = parity;
							 | 
						|||
| 
								 | 
							
								        p_flash->public.pub.data = databits;
							 | 
						|||
| 
								 | 
							
								        p_flash->public.pub.stop = stopbits;
							 | 
						|||
| 
								 | 
							
								        iot_proto_flashsave(p_flash);
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    iot_uart_set_config(g_local_rs485.handler,
							 | 
						|||
| 
								 | 
							
								        baudrate, parity, databits, stopbits);
							 | 
						|||
| 
								 | 
							
								    iot_cus_printf("%s: success to set rs485 param: %u,%u,%u,%u\n",
							 | 
						|||
| 
								 | 
							
								        __FUNCTION__, baudrate, parity, databits, stopbits);
							 | 
						|||
| 
								 | 
							
								    return ERR_OK;
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								/**
							 | 
						|||
| 
								 | 
							
								 * @brief: callback function to receive rs485 data
							 | 
						|||
| 
								 | 
							
								 *
							 | 
						|||
| 
								 | 
							
								 * @param buffer : pointer buffer of storing rs485 data
							 | 
						|||
| 
								 | 
							
								 * @param len    : received data length
							 | 
						|||
| 
								 | 
							
								 * @param is_full_frame: unused
							 | 
						|||
| 
								 | 
							
								 * @param invalid_data_len: unused
							 | 
						|||
| 
								 | 
							
								 * @return none
							 | 
						|||
| 
								 | 
							
								 */
							 | 
						|||
| 
								 | 
							
								static void iot_cctt_rs485_recv_callback(uint8_t *buffer, uint32_t len,
							 | 
						|||
| 
								 | 
							
								    bool_t is_full_frame, uint32_t invalid_data_len)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    uint8_t *p_dst = g_local_rs485.cache;
							 | 
						|||
| 
								 | 
							
								    uint32_t total_len;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    os_acquire_mutex(g_local_rs485.cache_mutex);
							 | 
						|||
| 
								 | 
							
								    total_len = g_local_rs485.cache_len + len;
							 | 
						|||
| 
								 | 
							
								    if (total_len <= IOT_CCTT_RS485_CACHE_SIZE) {
							 | 
						|||
| 
								 | 
							
								        p_dst += g_local_rs485.cache_len;
							 | 
						|||
| 
								 | 
							
								        os_mem_cpy(p_dst, buffer, len);
							 | 
						|||
| 
								 | 
							
								        g_local_rs485.cache_len += len;
							 | 
						|||
| 
								 | 
							
								        g_local_rs485.recv_ts = os_boot_time64();
							 | 
						|||
| 
								 | 
							
								    } else {
							 | 
						|||
| 
								 | 
							
								        iot_cus_printf("%s: rs485 cache overflow\n", __FUNCTION__);
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    os_release_mutex(g_local_rs485.cache_mutex);
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								/**
							 | 
						|||
| 
								 | 
							
								 * @brief: init rs485 interface
							 | 
						|||
| 
								 | 
							
								 *
							 | 
						|||
| 
								 | 
							
								 * @param none
							 | 
						|||
| 
								 | 
							
								 * @return ERR_OK if success, ERR_FAIL otherwise
							 | 
						|||
| 
								 | 
							
								 */
							 | 
						|||
| 
								 | 
							
								uint8_t iot_cctt_init_rs485_intf(void)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    uint8_t uart_port = iot_board_get_uart(UART_RS485_PORT);
							 | 
						|||
| 
								 | 
							
								    int32_t rs485_txe = iot_board_get_gpio(GPIO_RS485_TXE);
							 | 
						|||
| 
								 | 
							
								    ge_app_pib_info_t *p_flash = &prototask_contxt.flashinfo;
							 | 
						|||
| 
								 | 
							
								    uint32_t baud_val[] = PROTO_GE_UART_BAUD_VALUE;
							 | 
						|||
| 
								 | 
							
								    uint8_t ret = ERR_OK;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    if (true == g_local_rs485.ready) {
							 | 
						|||
| 
								 | 
							
								        goto out;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    iot_cctt_init_rs485_led_pin();
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    /* open rs485 uart interface */
							 | 
						|||
| 
								 | 
							
								    g_local_rs485.handler = iot_uart_open(uart_port,
							 | 
						|||
| 
								 | 
							
								        iot_cctt_rs485_recv_callback, 256, NULL);
							 | 
						|||
| 
								 | 
							
								    if (NULL == g_local_rs485.handler) {
							 | 
						|||
| 
								 | 
							
								        iot_cus_printf("%s: open rs485 uart failed!\n", __FUNCTION__);
							 | 
						|||
| 
								 | 
							
								        ret = ERR_FAIL;
							 | 
						|||
| 
								 | 
							
								        goto out;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    /* set rs485 mode and rs485 txe pin */
							 | 
						|||
| 
								 | 
							
								    iot_cus_printf("rs485_txe pin = %u\n", rs485_txe);
							 | 
						|||
| 
								 | 
							
								    iot_uart_enable_rs485(g_local_rs485.handler, rs485_txe);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    /* create mutex to protect rs485 receive cache */
							 | 
						|||
| 
								 | 
							
								    g_local_rs485.cache_mutex = os_create_mutex(IOT_GREE_APP_MID);
							 | 
						|||
| 
								 | 
							
								    IOT_ASSERT(NULL != g_local_rs485.cache_mutex);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    if (false == iot_proto_uart_param_check(
							 | 
						|||
| 
								 | 
							
								        baud_val[p_flash->public.pub.baudidx], p_flash->public.pub.parity,
							 | 
						|||
| 
								 | 
							
								        p_flash->public.pub.data, p_flash->public.pub.stop)) {
							 | 
						|||
| 
								 | 
							
								        p_flash->public.pub.baudidx = 2; // default baudrate = 2400
							 | 
						|||
| 
								 | 
							
								        p_flash->public.pub.parity = IOT_UART_PARITY_EVEN;
							 | 
						|||
| 
								 | 
							
								        p_flash->public.pub.data = IOT_UART_DLEN_8_BITS;
							 | 
						|||
| 
								 | 
							
								        p_flash->public.pub.stop = IOT_UART_STOP_1_BITS;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    iot_cctt_set_rs485_config_impl(baud_val[p_flash->public.pub.baudidx],
							 | 
						|||
| 
								 | 
							
								        p_flash->public.pub.parity, p_flash->public.pub.data,
							 | 
						|||
| 
								 | 
							
								        p_flash->public.pub.stop);
							 | 
						|||
| 
								 | 
							
								    g_local_rs485.ready = true;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								out:
							 | 
						|||
| 
								 | 
							
								    return ret;
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								/**
							 | 
						|||
| 
								 | 
							
								 * @brief: set configuration of rs485 interface by dl645 protocol
							 | 
						|||
| 
								 | 
							
								 *
							 | 
						|||
| 
								 | 
							
								 * @param data: dl645 request data
							 | 
						|||
| 
								 | 
							
								 * @param len : length of dl645 request data
							 | 
						|||
| 
								 | 
							
								 * @return none
							 | 
						|||
| 
								 | 
							
								 */
							 | 
						|||
| 
								 | 
							
								void iot_cctt_set_rs485_config(uint8_t *data, uint8_t len)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    cctt_set_rs485_cfg_t *rs485_cfg = (cctt_set_rs485_cfg_t*)data;
							 | 
						|||
| 
								 | 
							
								    uint8_t reason = DL645_ERR_PARAMETER_ERROR;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    if ((false == g_local_rs485.ready) &&
							 | 
						|||
| 
								 | 
							
								        (ERR_OK != iot_cctt_init_rs485_intf())) {
							 | 
						|||
| 
								 | 
							
								        iot_cus_printf("can not set rs485 config, rs485 not ready!\n");
							 | 
						|||
| 
								 | 
							
								        cctt_resp_cmd_ack(PROTO_645_2007_FN_READ_DATA, DL645_ERR_OTHER_ERROR);
							 | 
						|||
| 
								 | 
							
								        return;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    /* protocol compatibility conversion */
							 | 
						|||
| 
								 | 
							
								    if (2 == rs485_cfg->stopbits) {
							 | 
						|||
| 
								 | 
							
								        rs485_cfg->stopbits = IOT_UART_STOP_2_BITS;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    if (ERR_OK == iot_cctt_set_rs485_config_impl(rs485_cfg->baudrate,
							 | 
						|||
| 
								 | 
							
								        rs485_cfg->parity, rs485_cfg->databits, rs485_cfg->stopbits)) {
							 | 
						|||
| 
								 | 
							
								        reason = DL645_ERR_OK;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    cctt_resp_cmd_ack(PROTO_645_2007_FN_WRITE_DATA, reason);
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								/**
							 | 
						|||
| 
								 | 
							
								 * @brief: readout configuration of rs485 interface by dl645 protocol
							 | 
						|||
| 
								 | 
							
								 *
							 | 
						|||
| 
								 | 
							
								 * @param data: dl645 request data
							 | 
						|||
| 
								 | 
							
								 * @param len : length of dl645 request data
							 | 
						|||
| 
								 | 
							
								 * @return none
							 | 
						|||
| 
								 | 
							
								 */
							 | 
						|||
| 
								 | 
							
								void iot_cctt_read_rs485_config(uint8_t *data, uint8_t len)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    iot_pkt_t *p_pkt;
							 | 
						|||
| 
								 | 
							
								    proto_645_header_t *p_hdr;
							 | 
						|||
| 
								 | 
							
								    cctt_read_rs485_cfg_t *p_rs485_cfg;
							 | 
						|||
| 
								 | 
							
								    uint8_t dst_mac[IOT_MAC_ADDR_LEN];
							 | 
						|||
| 
								 | 
							
								    uint32_t pkt_len = DL645_PARSE_FRM_MIN_LEN + sizeof(cctt_read_rs485_cfg_t);
							 | 
						|||
| 
								 | 
							
								    uint32_t baud_val[] = PROTO_GE_UART_BAUD_VALUE;
							 | 
						|||
| 
								 | 
							
								    ge_app_pib_info_t *p_flash = &prototask_contxt.flashinfo;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    if ((false == g_local_rs485.ready) &&
							 | 
						|||
| 
								 | 
							
								        (ERR_OK != iot_cctt_init_rs485_intf())) {
							 | 
						|||
| 
								 | 
							
								        iot_cus_printf("can not read rs485 config, rs485 not ready!\n");
							 | 
						|||
| 
								 | 
							
								        cctt_resp_cmd_ack(PROTO_645_2007_FN_READ_DATA, DL645_ERR_OTHER_ERROR);
							 | 
						|||
| 
								 | 
							
								        return;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    p_pkt = iot_pkt_alloc(pkt_len, IOT_GREE_APP_MID);
							 | 
						|||
| 
								 | 
							
								    if (NULL == p_pkt) {
							 | 
						|||
| 
								 | 
							
								        iot_cus_printf("%s: memory runout!\n", __FUNCTION__);
							 | 
						|||
| 
								 | 
							
								        cctt_resp_cmd_ack(PROTO_645_2007_FN_READ_DATA, DL645_ERR_OTHER_ERROR);
							 | 
						|||
| 
								 | 
							
								        return;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    p_hdr = (proto_645_header_t *)iot_pkt_put(p_pkt, pkt_len);
							 | 
						|||
| 
								 | 
							
								    p_rs485_cfg = (cctt_read_rs485_cfg_t *)p_hdr->data;
							 | 
						|||
| 
								 | 
							
								    iot_mac_addr_cpy(dst_mac, prototask_contxt.local_dev.mac);
							 | 
						|||
| 
								 | 
							
								    iot_mac_addr_reverse(dst_mac);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    iot_proto_645_header_init(p_hdr, dst_mac, PROTO_645_2007_FN_READ_DATA,
							 | 
						|||
| 
								 | 
							
								        PROTO_645_DIR_SLAVE, PROTO_645_2007_ERR_OK, 0);
							 | 
						|||
| 
								 | 
							
								    p_hdr->len = sizeof(cctt_read_rs485_cfg_t);
							 | 
						|||
| 
								 | 
							
								    proto_645_2007_di_to_byte(DL645_07_DI_RS485_CONFIG,
							 | 
						|||
| 
								 | 
							
								        (uint8_t*)&p_rs485_cfg->di);
							 | 
						|||
| 
								 | 
							
								    p_rs485_cfg->baudrate = baud_val[p_flash->public.pub.baudidx];
							 | 
						|||
| 
								 | 
							
								    p_rs485_cfg->parity   = p_flash->public.pub.parity;
							 | 
						|||
| 
								 | 
							
								    p_rs485_cfg->databits = p_flash->public.pub.data;
							 | 
						|||
| 
								 | 
							
								    p_rs485_cfg->stopbits = p_flash->public.pub.stop;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    /* protocol compatibility conversion */
							 | 
						|||
| 
								 | 
							
								    if (IOT_UART_STOP_2_BITS == p_rs485_cfg->stopbits) {
							 | 
						|||
| 
								 | 
							
								        p_rs485_cfg->stopbits = 2;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    iot_proto_645_ext_add33_handle(p_hdr->data, p_hdr->len);
							 | 
						|||
| 
								 | 
							
								    iot_proto_645_tail_init(p_hdr);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    iot_proto_send_to_mainboard(p_pkt);
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								/**
							 | 
						|||
| 
								 | 
							
								 * @brief: send data to rs485 interface
							 | 
						|||
| 
								 | 
							
								 *
							 | 
						|||
| 
								 | 
							
								 * @param buff    : data buffer to send
							 | 
						|||
| 
								 | 
							
								 * @param buff_len: length of buff
							 | 
						|||
| 
								 | 
							
								 * @return none
							 | 
						|||
| 
								 | 
							
								 */
							 | 
						|||
| 
								 | 
							
								static void iot_cctt_rs485_send(uint8_t *buff, uint32_t buff_len)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    iot_pkt_t *pkt;
							 | 
						|||
| 
								 | 
							
								    uint8_t *data;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    if (NULL == g_local_rs485.handler) {
							 | 
						|||
| 
								 | 
							
								        iot_cus_printf("%s: rs485 handler null!\n", __FUNCTION__);
							 | 
						|||
| 
								 | 
							
								        return;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    pkt = iot_pkt_alloc(buff_len, IOT_GREE_APP_MID);
							 | 
						|||
| 
								 | 
							
								    if (NULL == pkt) {
							 | 
						|||
| 
								 | 
							
								        iot_cus_printf("%s rs485 send fail, pkt alloc fail!\n", __FUNCTION__);
							 | 
						|||
| 
								 | 
							
								        return;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    data = iot_pkt_put(pkt, buff_len);
							 | 
						|||
| 
								 | 
							
								    os_mem_cpy(data, buff, buff_len);
							 | 
						|||
| 
								 | 
							
								    iot_uart_send(g_local_rs485.handler, pkt, NULL);
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								/**
							 | 
						|||
| 
								 | 
							
								 * @brief: dump bin data to log
							 | 
						|||
| 
								 | 
							
								 *
							 | 
						|||
| 
								 | 
							
								 * @param desc  : description of bin data
							 | 
						|||
| 
								 | 
							
								 * @param p_data: data to dump
							 | 
						|||
| 
								 | 
							
								 * @param len   : length of p_data
							 | 
						|||
| 
								 | 
							
								 * @return none
							 | 
						|||
| 
								 | 
							
								 */
							 | 
						|||
| 
								 | 
							
								static void iot_cctt_bin_dump(char *desc, uint8_t *p_data, uint32_t len)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    iot_cus_printf("%s:", desc);
							 | 
						|||
| 
								 | 
							
								    while (len > 0) {
							 | 
						|||
| 
								 | 
							
								        iot_cus_printf("%02X ", *p_data);
							 | 
						|||
| 
								 | 
							
								        p_data++;
							 | 
						|||
| 
								 | 
							
								        len--;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    iot_cus_printf("\n");
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								/**
							 | 
						|||
| 
								 | 
							
								 * @brief: wait data reply from rs485 interface
							 | 
						|||
| 
								 | 
							
								 *
							 | 
						|||
| 
								 | 
							
								 * @param p_buff : buffer used to store received reply
							 | 
						|||
| 
								 | 
							
								 * @param len    : length of p_buff
							 | 
						|||
| 
								 | 
							
								 * @return length of received data
							 | 
						|||
| 
								 | 
							
								 */
							 | 
						|||
| 
								 | 
							
								static uint32_t iot_cctt_wait_rs485_reply(uint8_t *p_buff, uint32_t len)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    uint64_t time_end = RS485_DEV_RESP_TO_MS + os_boot_time64();
							 | 
						|||
| 
								 | 
							
								    uint64_t time_idle;
							 | 
						|||
| 
								 | 
							
								    uint32_t ret = 0;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    while (os_boot_time64() < time_end) {
							 | 
						|||
| 
								 | 
							
								        os_acquire_mutex(g_local_rs485.cache_mutex);
							 | 
						|||
| 
								 | 
							
								        time_idle = os_boot_time64() - g_local_rs485.recv_ts;
							 | 
						|||
| 
								 | 
							
								        if ((g_local_rs485.cache_len > 0) &&
							 | 
						|||
| 
								 | 
							
								            (time_idle >= RS485_DEV_IDLE_TO_MS)) {
							 | 
						|||
| 
								 | 
							
								            if (g_local_rs485.cache_len < len) {
							 | 
						|||
| 
								 | 
							
								                len = g_local_rs485.cache_len;
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								            os_mem_cpy(p_buff, g_local_rs485.cache, len);
							 | 
						|||
| 
								 | 
							
								            ret = g_local_rs485.cache_len;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        os_release_mutex(g_local_rs485.cache_mutex);
							 | 
						|||
| 
								 | 
							
								        if (ret > 0) {
							 | 
						|||
| 
								 | 
							
								            iot_cus_printf("iot_cctt_wait_rs485_reply ret = %u\n", ret);
							 | 
						|||
| 
								 | 
							
								            break;
							 | 
						|||
| 
								 | 
							
								        } else {
							 | 
						|||
| 
								 | 
							
								            os_delay(10);
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    return ret;
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								/**
							 | 
						|||
| 
								 | 
							
								 * @brief: report specified data with specified di with DL645 protocol
							 | 
						|||
| 
								 | 
							
								 *
							 | 
						|||
| 
								 | 
							
								 * @param di   : di of dl645 protocol
							 | 
						|||
| 
								 | 
							
								 * @param data : data to send
							 | 
						|||
| 
								 | 
							
								 * @param len  : length of data
							 | 
						|||
| 
								 | 
							
								 * @return none
							 | 
						|||
| 
								 | 
							
								 */
							 | 
						|||
| 
								 | 
							
								static void iot_cctt_report_local_data(uint32_t di, uint8_t *data, uint8_t len)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    iot_pkt_t *p_pkt;
							 | 
						|||
| 
								 | 
							
								    uint32_t pkt_len;
							 | 
						|||
| 
								 | 
							
								    proto_645_header_t *p_hdr;
							 | 
						|||
| 
								 | 
							
								    uint8_t dst_mac[IOT_MAC_ADDR_LEN];
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    pkt_len = DL645_PARSE_FRM_MIN_LEN + DL645_DI_LEN + len;
							 | 
						|||
| 
								 | 
							
								    p_pkt = iot_pkt_alloc(pkt_len, IOT_GREE_APP_MID);
							 | 
						|||
| 
								 | 
							
								    if (NULL == p_pkt) {
							 | 
						|||
| 
								 | 
							
								        iot_cus_printf("%s: can not alloc modbus reply frame!\n", __FUNCTION__);
							 | 
						|||
| 
								 | 
							
								        cctt_resp_cmd_ack(PROTO_645_2007_FN_READ_DATA, DL645_ERR_OTHER_ERROR);
							 | 
						|||
| 
								 | 
							
								        return;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    p_hdr = (proto_645_header_t*)iot_pkt_put(p_pkt, pkt_len);
							 | 
						|||
| 
								 | 
							
								    iot_mac_addr_cpy(dst_mac, prototask_contxt.local_dev.mac);
							 | 
						|||
| 
								 | 
							
								    iot_mac_addr_reverse(dst_mac);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    iot_proto_645_header_init(p_hdr, dst_mac, PROTO_645_2007_FN_READ_DATA,
							 | 
						|||
| 
								 | 
							
								        PROTO_645_DIR_SLAVE, PROTO_645_2007_ERR_OK, 0);
							 | 
						|||
| 
								 | 
							
								    p_hdr->len = DL645_DI_LEN + len;
							 | 
						|||
| 
								 | 
							
								    proto_645_2007_di_to_byte(di, p_hdr->data);
							 | 
						|||
| 
								 | 
							
								    os_mem_cpy(p_hdr->data + DL645_DI_LEN, data, len);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    iot_proto_645_ext_add33_handle(p_hdr->data, p_hdr->len);
							 | 
						|||
| 
								 | 
							
								    iot_proto_645_tail_init(p_hdr);
							 | 
						|||
| 
								 | 
							
								    iot_proto_send_to_mainboard(p_pkt);
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								/**
							 | 
						|||
| 
								 | 
							
								 * @brief: check whether the specified data is a complete dl645 frame
							 | 
						|||
| 
								 | 
							
								 *
							 | 
						|||
| 
								 | 
							
								 * @param p_data: data to check
							 | 
						|||
| 
								 | 
							
								 * @param len   : length of data
							 | 
						|||
| 
								 | 
							
								 * @param p_frm_offset: pointer to store 645 frame offset in p_data
							 | 
						|||
| 
								 | 
							
								 * @param p_frm_length: pointer to store 645 frame length in p_data
							 | 
						|||
| 
								 | 
							
								 * @return ERR_OK if check pass, ERR_FAIL otherwise
							 | 
						|||
| 
								 | 
							
								 */
							 | 
						|||
| 
								 | 
							
								uint8_t proto_645_format_check(uint8_t *p_data, uint16_t len,
							 | 
						|||
| 
								 | 
							
								    uint8_t *p_frm_offset, uint8_t *p_frm_lenth)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    proto_645_header_t * hdr_645 = (proto_645_header_t*)p_data;
							 | 
						|||
| 
								 | 
							
								    proto_645_tailer_t * tail_645 = NULL;
							 | 
						|||
| 
								 | 
							
								    uint8_t frm_offset = 0;
							 | 
						|||
| 
								 | 
							
								    uint8_t err_code = 0;
							 | 
						|||
| 
								 | 
							
								    uint8_t ret = ERR_OK;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    if ((NULL == p_data) || (len == 0) ||
							 | 
						|||
| 
								 | 
							
								        (NULL == p_frm_offset) || (NULL == p_frm_lenth)) {
							 | 
						|||
| 
								 | 
							
								        err_code = 9;
							 | 
						|||
| 
								 | 
							
								        goto out;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    /* skip preamble code before dl645 frame */
							 | 
						|||
| 
								 | 
							
								    frm_offset = 0;
							 | 
						|||
| 
								 | 
							
								    while ((frm_offset < len) && (p_data[frm_offset] != PROTO_645_START_CHAR)) {
							 | 
						|||
| 
								 | 
							
								        frm_offset++;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    len -= frm_offset;
							 | 
						|||
| 
								 | 
							
								    p_data += frm_offset;
							 | 
						|||
| 
								 | 
							
								    hdr_645 = (proto_645_header_t*)p_data;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    if ((len == 0) || (p_data[0] != PROTO_645_START_CHAR)) {
							 | 
						|||
| 
								 | 
							
								        err_code = 1;
							 | 
						|||
| 
								 | 
							
								        goto out;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    if (len <= PROTO_645_SECOND_HEAD_POS ||
							 | 
						|||
| 
								 | 
							
								        p_data[PROTO_645_SECOND_HEAD_POS] != PROTO_645_START_CHAR) {
							 | 
						|||
| 
								 | 
							
								        err_code = 2;
							 | 
						|||
| 
								 | 
							
								        goto out;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    if (len < sizeof(proto_645_header_t)) {
							 | 
						|||
| 
								 | 
							
								        err_code = 3;
							 | 
						|||
| 
								 | 
							
								        goto out;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    if (hdr_645->start_char_2 != PROTO_645_START_CHAR) {
							 | 
						|||
| 
								 | 
							
								        err_code = 4;
							 | 
						|||
| 
								 | 
							
								        goto out;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    if (len < hdr_645->len + sizeof(proto_645_header_t) +
							 | 
						|||
| 
								 | 
							
								        sizeof(proto_645_tailer_t)) {
							 | 
						|||
| 
								 | 
							
								        err_code = 5;
							 | 
						|||
| 
								 | 
							
								        goto out;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    tail_645 = (proto_645_tailer_t*)(p_data + sizeof(proto_645_header_t) +
							 | 
						|||
| 
								 | 
							
								        hdr_645->len);
							 | 
						|||
| 
								 | 
							
								    if (tail_645->end_char != PROTO_645_END_CHAR) {
							 | 
						|||
| 
								 | 
							
								        err_code = 6;
							 | 
						|||
| 
								 | 
							
								        goto out;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    if (tail_645->cs != iot_proto_645_calc_cs(hdr_645)) {
							 | 
						|||
| 
								 | 
							
								        err_code = 7;
							 | 
						|||
| 
								 | 
							
								        goto out;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    *p_frm_offset = frm_offset;
							 | 
						|||
| 
								 | 
							
								    *p_frm_lenth = sizeof(proto_645_header_t) + hdr_645->len +
							 | 
						|||
| 
								 | 
							
								        sizeof(proto_645_tailer_t);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								out:
							 | 
						|||
| 
								 | 
							
								    if (err_code > 0) {
							 | 
						|||
| 
								 | 
							
								        ret = ERR_FAIL;
							 | 
						|||
| 
								 | 
							
								       iot_cus_printf("%s: error_code=%d\n", __FUNCTION__, err_code);
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    return ret;
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								/**
							 | 
						|||
| 
								 | 
							
								 * @brief: transparent transmit dl645 frame to rs485, reply dl645 response
							 | 
						|||
| 
								 | 
							
								 *
							 | 
						|||
| 
								 | 
							
								 * @param data : data to transparent transmit to rs485
							 | 
						|||
| 
								 | 
							
								 * @param len  : length of data
							 | 
						|||
| 
								 | 
							
								 * @return none
							 | 
						|||
| 
								 | 
							
								 */
							 | 
						|||
| 
								 | 
							
								void iot_cctt_rs485_trans_dl645(uint8_t *data, uint8_t len)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    static uint8_t recv_buff[256];
							 | 
						|||
| 
								 | 
							
								    uint32_t recv_len;
							 | 
						|||
| 
								 | 
							
								    uint8_t frm_offset = 0, frm_length = 0;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    if ((NULL == data) || (len < DL645_DI_LEN)) {
							 | 
						|||
| 
								 | 
							
								        return;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    if ((false == g_local_rs485.ready) &&
							 | 
						|||
| 
								 | 
							
								        (ERR_OK != iot_cctt_init_rs485_intf())) {
							 | 
						|||
| 
								 | 
							
								        iot_cus_printf("can not trans dl645, rs485 not ready!\n");
							 | 
						|||
| 
								 | 
							
								        cctt_resp_cmd_ack(PROTO_645_2007_FN_READ_DATA, DL645_ERR_OTHER_ERROR);
							 | 
						|||
| 
								 | 
							
								        return;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    data += DL645_DI_LEN;
							 | 
						|||
| 
								 | 
							
								    len  -= DL645_DI_LEN;
							 | 
						|||
| 
								 | 
							
								    os_acquire_mutex(g_local_rs485.cache_mutex);
							 | 
						|||
| 
								 | 
							
								    g_local_rs485.cache_len = 0;
							 | 
						|||
| 
								 | 
							
								    os_release_mutex(g_local_rs485.cache_mutex);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    iot_cctt_rs485_led_blink();
							 | 
						|||
| 
								 | 
							
								    iot_cctt_bin_dump("dl645 to rs485", data, len);
							 | 
						|||
| 
								 | 
							
								    iot_cctt_rs485_send(data, len);
							 | 
						|||
| 
								 | 
							
								    recv_len = iot_cctt_wait_rs485_reply(recv_buff, sizeof(recv_buff));
							 | 
						|||
| 
								 | 
							
								    if (recv_len > 0) {
							 | 
						|||
| 
								 | 
							
								        iot_cctt_bin_dump("rs485 reply", recv_buff, recv_len);
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    if (ERR_OK != proto_645_format_check(
							 | 
						|||
| 
								 | 
							
								        recv_buff, recv_len, &frm_offset, &frm_length)) {
							 | 
						|||
| 
								 | 
							
								        cctt_resp_cmd_ack(PROTO_645_2007_FN_READ_DATA, DL645_ERR_NO_REQ_DATA);
							 | 
						|||
| 
								 | 
							
								        return;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    iot_cctt_rs485_led_blink();
							 | 
						|||
| 
								 | 
							
								    iot_cctt_report_local_data(DL645_07_DI_TRANS_DL645,
							 | 
						|||
| 
								 | 
							
								        recv_buff + frm_offset, frm_length);
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								/**
							 | 
						|||
| 
								 | 
							
								 * @brief check the validity of modbus frame.
							 | 
						|||
| 
								 | 
							
								 * @param data:  point to the data
							 | 
						|||
| 
								 | 
							
								 * @param len:   the number of input data
							 | 
						|||
| 
								 | 
							
								 * @return:  ERR_OK --> success; ERR_FAIL --> failed.
							 | 
						|||
| 
								 | 
							
								 */
							 | 
						|||
| 
								 | 
							
								static uint8_t iot_cctt_modbus_frame_check(uint8_t *data, uint32_t len)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    uint8_t i;
							 | 
						|||
| 
								 | 
							
								    uint32_t pos;
							 | 
						|||
| 
								 | 
							
								    uint16_t crc = 0xFFFF;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    for (pos = 0; pos < len; pos++) {
							 | 
						|||
| 
								 | 
							
								        /* XOR byte into least sig. byte of crc */
							 | 
						|||
| 
								 | 
							
								        crc ^= (uint16_t)data[pos];
							 | 
						|||
| 
								 | 
							
								        /* Loop over each bit */
							 | 
						|||
| 
								 | 
							
								        for (i = 8; i != 0; i--) {
							 | 
						|||
| 
								 | 
							
								            /* If the LSB is set */
							 | 
						|||
| 
								 | 
							
								            if ((crc & 0x0001) != 0) {
							 | 
						|||
| 
								 | 
							
								                /* Shift right and XOR 0xA001 */
							 | 
						|||
| 
								 | 
							
								                crc >>= 1;
							 | 
						|||
| 
								 | 
							
								                /* Else LSB is not set */
							 | 
						|||
| 
								 | 
							
								                crc ^= 0xA001;
							 | 
						|||
| 
								 | 
							
								            } else {
							 | 
						|||
| 
								 | 
							
								                /* Just shift right */
							 | 
						|||
| 
								 | 
							
								                crc >>= 1;
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    /* Note, this number has low and high bytes swapped,
							 | 
						|||
| 
								 | 
							
								    so use it accordingly (or swap bytes) */
							 | 
						|||
| 
								 | 
							
								    return (0x0 == crc) ? ERR_OK : ERR_FAIL;
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								/**
							 | 
						|||
| 
								 | 
							
								 * @brief: transparent transmit modbus frame to rs485, reply modbus response
							 | 
						|||
| 
								 | 
							
								 *
							 | 
						|||
| 
								 | 
							
								 * @param data : data to transparent transmit to rs485
							 | 
						|||
| 
								 | 
							
								 * @param len  : length of data
							 | 
						|||
| 
								 | 
							
								 * @return none
							 | 
						|||
| 
								 | 
							
								 */
							 | 
						|||
| 
								 | 
							
								void iot_cctt_rs485_trans_modbus(uint8_t *data, uint8_t len)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    static uint8_t recv_buff[256];
							 | 
						|||
| 
								 | 
							
								    uint32_t recv_len;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    if ((NULL == data) || (len < DL645_DI_LEN)) {
							 | 
						|||
| 
								 | 
							
								        return;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    if ((false == g_local_rs485.ready) &&
							 | 
						|||
| 
								 | 
							
								        (ERR_OK != iot_cctt_init_rs485_intf())) {
							 | 
						|||
| 
								 | 
							
								        iot_cus_printf("can not trans modbus, rs485 not ready!\n");
							 | 
						|||
| 
								 | 
							
								        cctt_resp_cmd_ack(PROTO_645_2007_FN_READ_DATA, DL645_ERR_OTHER_ERROR);
							 | 
						|||
| 
								 | 
							
								        return;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    data += DL645_DI_LEN;
							 | 
						|||
| 
								 | 
							
								    len  -= DL645_DI_LEN;
							 | 
						|||
| 
								 | 
							
								    os_acquire_mutex(g_local_rs485.cache_mutex);
							 | 
						|||
| 
								 | 
							
								    g_local_rs485.cache_len = 0;
							 | 
						|||
| 
								 | 
							
								    os_release_mutex(g_local_rs485.cache_mutex);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    iot_cctt_rs485_led_blink();
							 | 
						|||
| 
								 | 
							
								    iot_cctt_bin_dump("modbus to rs485", data, len);
							 | 
						|||
| 
								 | 
							
								    iot_cctt_rs485_send(data, len);
							 | 
						|||
| 
								 | 
							
								    recv_len = iot_cctt_wait_rs485_reply(recv_buff, sizeof(recv_buff));
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    if (0 != recv_len) {
							 | 
						|||
| 
								 | 
							
								        iot_cctt_bin_dump("rs485 reply", recv_buff, recv_len);
							 | 
						|||
| 
								 | 
							
								    } else {
							 | 
						|||
| 
								 | 
							
								        iot_cus_printf("%s: rs485 device no reply!\n", __FUNCTION__);
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    if(ERR_OK != iot_cctt_modbus_frame_check(recv_buff, recv_len)) {
							 | 
						|||
| 
								 | 
							
								        cctt_resp_cmd_ack(PROTO_645_2007_FN_READ_DATA, DL645_ERR_NO_REQ_DATA);
							 | 
						|||
| 
								 | 
							
								        return;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    iot_cctt_rs485_led_blink();
							 | 
						|||
| 
								 | 
							
								    iot_cctt_report_local_data(DL645_07_DI_TRANS_MODBUS, recv_buff, recv_len);
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								static void cctt_read_data_cmd_handle(proto_645_header_t *header)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    uint32_t di;
							 | 
						|||
| 
								 | 
							
								    iot_pkt_t *p_pkt;
							 | 
						|||
| 
								 | 
							
								    uint16_t msg_id = 0xff;
							 | 
						|||
| 
								 | 
							
								    uint16_t pkt_len;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    proto_645_2007_byte_to_di(header->data, di);
							 | 
						|||
| 
								 | 
							
								    iot_cus_printf("cctt_read_data_cmd_handle di:%08X\n", di);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    switch (di) {
							 | 
						|||
| 
								 | 
							
								    case DL645_07_DI_QUERY_WHITELIST:
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        msg_id = CCTT_QUERY_WHITELIST;
							 | 
						|||
| 
								 | 
							
								        break;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    case DL645_07_DI_QUERY_TOPO:
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        msg_id = CCTT_QUERY_TOPO;
							 | 
						|||
| 
								 | 
							
								        break;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    case DL645_07_DI_RS485_CONFIG:
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        msg_id = CCTT_READ_RS485_CONFIG;
							 | 
						|||
| 
								 | 
							
								        break;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    case DL645_07_DI_TRANS_DL645:
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        msg_id = CCTT_RS485_TRANS_DL645;
							 | 
						|||
| 
								 | 
							
								        break;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    case DL645_07_DI_TRANS_MODBUS:
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        msg_id = CCTT_RS485_TRANS_MODBUS;
							 | 
						|||
| 
								 | 
							
								        break;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    case DL645_07_DI_HANDLE_PLC_NW:
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        msg_id = CCTT_READ_PLC_NW;
							 | 
						|||
| 
								 | 
							
								        break;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    case DL645_07_DI_DELAYTIME:
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        msg_id = CCTT_DELAYTIME;
							 | 
						|||
| 
								 | 
							
								        break;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    default:
							 | 
						|||
| 
								 | 
							
								        break;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    if (msg_id != 0xFF) {
							 | 
						|||
| 
								 | 
							
								        if (msg_id == CCTT_DELAYTIME) {
							 | 
						|||
| 
								 | 
							
								            /* need post dst_mac */
							 | 
						|||
| 
								 | 
							
								            pkt_len = header->len + sizeof(header);
							 | 
						|||
| 
								 | 
							
								        } else {
							 | 
						|||
| 
								 | 
							
								            pkt_len = header->len;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        p_pkt = iot_pkt_alloc(header->len , IOT_GREE_APP_MID);
							 | 
						|||
| 
								 | 
							
								        if (!p_pkt) {
							 | 
						|||
| 
								 | 
							
								            iot_cus_printf("[dl645][err]No Mem!\n");
							 | 
						|||
| 
								 | 
							
								            return;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        if (msg_id == CCTT_DELAYTIME) {
							 | 
						|||
| 
								 | 
							
								            os_mem_cpy(iot_pkt_put(p_pkt, pkt_len), (uint8_t *)header, pkt_len);
							 | 
						|||
| 
								 | 
							
								        } else {
							 | 
						|||
| 
								 | 
							
								            os_mem_cpy(iot_pkt_put(p_pkt, pkt_len), header->data, pkt_len);
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        iot_proto_task_post_msg(PROTO_CCTT_MSG, msg_id, p_pkt,
							 | 
						|||
| 
								 | 
							
								            0, IOT_PROTO_TASK_QUEUE_LP);
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								static void cctt_write_data_cmd_handle(proto_645_header_t *header)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    uint32_t di;
							 | 
						|||
| 
								 | 
							
								    iot_pkt_t *p_pkt;
							 | 
						|||
| 
								 | 
							
								    uint16_t msg_id = 0xff;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    proto_645_2007_byte_to_di(header->data, di);
							 | 
						|||
| 
								 | 
							
								    iot_cus_printf("cctt_write_data_cmd_handle di:%08X\n", di);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    switch (di) {
							 | 
						|||
| 
								 | 
							
								    case DL645_07_DI_ADD_WHITELISET:
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        msg_id = CCTT_ADD_WHITELIST;
							 | 
						|||
| 
								 | 
							
								        break;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    case DL645_07_DI_DEL_WHITELISET:
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        msg_id = CCTT_DEL_WHITELIST;
							 | 
						|||
| 
								 | 
							
								        break;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    case DL645_07_DI_REBOOT_CCTT:
							 | 
						|||
| 
								 | 
							
								    case DL645_07_DI_REBOOT_CCO:
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        msg_id = CCTT_REBOOT_CCO;
							 | 
						|||
| 
								 | 
							
								        break;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    case DL645_07_DI_REBOOT_STA:
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        msg_id = CCTT_REBOOT_STA;
							 | 
						|||
| 
								 | 
							
								        break;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    case DL645_07_DI_WL_STATE:
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        msg_id = CCTT_SET_WL_STATE;
							 | 
						|||
| 
								 | 
							
								        break;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    case DL645_07_DI_CLEAR_WL:
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        msg_id = CCTT_CLR_WHITELIST;
							 | 
						|||
| 
								 | 
							
								        break;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    case DL645_07_DI_CHECK_WL_ADDR:
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        msg_id = CCTT_CHECK_WL_MAC;
							 | 
						|||
| 
								 | 
							
								        break;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    case DL645_07_DI_HANDLE_PLC_NW:
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        msg_id = CCTT_SET_PLC_NW;
							 | 
						|||
| 
								 | 
							
								        break;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    case DL645_07_DI_REBOOT_MAC_LIST_PCO:
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        msg_id = CCTT_REBOOT_MAC_LIST_PCO;
							 | 
						|||
| 
								 | 
							
								        break;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    case DL645_07_DI_RS485_CONFIG:
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        msg_id = CCTT_SET_RS485_CONFIG;
							 | 
						|||
| 
								 | 
							
								        break;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    default:
							 | 
						|||
| 
								 | 
							
								        break;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    if (msg_id != 0xFF) {
							 | 
						|||
| 
								 | 
							
								        p_pkt = iot_pkt_alloc(header->len, IOT_GREE_APP_MID);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        if (!p_pkt) {
							 | 
						|||
| 
								 | 
							
								            iot_cus_printf("[dl645][err]No Mem!\n");
							 | 
						|||
| 
								 | 
							
								            return;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								        os_mem_cpy(iot_pkt_put(p_pkt, header->len), header->data, header->len);
							 | 
						|||
| 
								 | 
							
								        iot_proto_task_post_msg(PROTO_CCTT_MSG, msg_id, p_pkt,
							 | 
						|||
| 
								 | 
							
								            0, IOT_PROTO_TASK_QUEUE_LP);
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								/**
							 | 
						|||
| 
								 | 
							
								 * @brief iot_cctt_handle_local_dl645_cmd() - handle the local cmd
							 | 
						|||
| 
								 | 
							
								 *                                           data is del 0x33
							 | 
						|||
| 
								 | 
							
								 * @param pkt:   point to the dl645 pkt data
							 | 
						|||
| 
								 | 
							
								 */
							 | 
						|||
| 
								 | 
							
								uint8_t iot_cctt_handle_local_dl645_cmd(iot_pkt_t *pkt)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    proto_645_header_t *header = (proto_645_header_t*)iot_pkt_data(pkt);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    switch (header->control.fn) {
							 | 
						|||
| 
								 | 
							
								    case PROTO_645_2007_FN_READ_DATA:
							 | 
						|||
| 
								 | 
							
								    case PROTO_645_2007_FN_READ_DATA_C:
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        cctt_read_data_cmd_handle(header);
							 | 
						|||
| 
								 | 
							
								        break;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    case PROTO_645_2007_FN_WRITE_DATA:
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        cctt_write_data_cmd_handle(header);
							 | 
						|||
| 
								 | 
							
								        break;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    default:
							 | 
						|||
| 
								 | 
							
								        break;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    return 0;
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								uint8_t iot_cco_resp_topo_set_query_info(uint8_t done, uint16_t resp_cnt)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    if (done) {
							 | 
						|||
| 
								 | 
							
								        os_mem_set(&g_cctt_context, 0, sizeof(cctt_context_t));
							 | 
						|||
| 
								 | 
							
								    } else {
							 | 
						|||
| 
								 | 
							
								        g_cctt_context.q_topo_pos += resp_cnt;
							 | 
						|||
| 
								 | 
							
								        if (g_cctt_context.q_topo_cnt != 0xFFFF) {
							 | 
						|||
| 
								 | 
							
								            g_cctt_context.q_topo_cnt -= resp_cnt;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    return 0;
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								void cctt_init(void)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    g_cctt_context.plc_nw_state = PLC_NW_OPEN;
							 | 
						|||
| 
								 | 
							
								    g_local_rs485.ready = false;
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								#endif /* PLC_SUPPORT_CCO_ROLE */
							 |