739 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			739 lines
		
	
	
		
			23 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"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* iot common header files */
							 | 
						||
| 
								 | 
							
								#include "iot_io_api.h"
							 | 
						||
| 
								 | 
							
								#include "iot_module_api.h"
							 | 
						||
| 
								 | 
							
								#include "iot_errno_api.h"
							 | 
						||
| 
								 | 
							
								#include "iot_task_api.h"
							 | 
						||
| 
								 | 
							
								#include "iot_pkt_api.h"
							 | 
						||
| 
								 | 
							
								#include "iot_ipc_api.h"
							 | 
						||
| 
								 | 
							
								#include "iot_sg_ext_api.h"
							 | 
						||
| 
								 | 
							
								#include "iot_board_api.h"
							 | 
						||
| 
								 | 
							
								#include "iot_oem_api.h"
							 | 
						||
| 
								 | 
							
								#include "iot_plc_api.h"
							 | 
						||
| 
								 | 
							
								#include "iot_mem_pool_api.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "iot_pkt_api.h"
							 | 
						||
| 
								 | 
							
								#include "iot_proto_common.h"
							 | 
						||
| 
								 | 
							
								#include "iot_proto_ge.h"
							 | 
						||
| 
								 | 
							
								#include "iot_modbus_task.h"
							 | 
						||
| 
								 | 
							
								#include "iot_modbus_ext.h"
							 | 
						||
| 
								 | 
							
								#include "iot_gpio_api.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define IOT_MODBUS_EXT_DATA_DUMP      1
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define IOT_MB_EXT_RESP_TIMER_PERIOD       (2000) /* units:ms */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								extern iot_mb_task_t mb_task;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								mb_ext_cmd_current_t current_handle_cmd;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint8_t mb_ext_gpio_config_flag = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void iot_mb_ext_data_dump(uint8_t * buf, uint32_t len, uint32_t line)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								#if IOT_MODBUS_EXT_DATA_DUMP
							 | 
						||
| 
								 | 
							
								    uint32_t i;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    iot_printf("[mb_task]DUMP(%03d)@line:%d", len, line);
							 | 
						||
| 
								 | 
							
								    for (i = 0; i < len; i++) {
							 | 
						||
| 
								 | 
							
								        iot_printf(" %02X", buf[i]);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    iot_printf("\n");
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								mb_extend_fn_hdr_t * iot_mb_ext_get_current_cmd_head()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    return &(current_handle_cmd.hdr);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static uint8_t iot_mb_ext_resp_transmit(uint8_t * data, uint32_t len, mb_transmit_direction_e dir)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    iot_pkt_t *p_pkt = NULL;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    iot_mb_ext_data_dump(data, len, __LINE__);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* response */
							 | 
						||
| 
								 | 
							
								    if (dir == MODBUS_CMD_FROM_UART) {
							 | 
						||
| 
								 | 
							
								        p_pkt = iot_pkt_alloc(len, IOT_MODBUS_MID);
							 | 
						||
| 
								 | 
							
								        if (NULL == p_pkt) {
							 | 
						||
| 
								 | 
							
								            iot_printf("[mb_ext][err]no mem@line %d\n", __LINE__);
							 | 
						||
| 
								 | 
							
								            IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								            return false;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(iot_pkt_put(p_pkt, len), data, len);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        iot_mb_task_msg_post_to_uart(mb_task.uart_h, p_pkt);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    } else if (dir == MODBUS_CMD_FROM_PLC) {
							 | 
						||
| 
								 | 
							
								        p_pkt = iot_modbus_fn160_appdata_pack(data, len, 0, 1);
							 | 
						||
| 
								 | 
							
								        if (NULL == p_pkt) {
							 | 
						||
| 
								 | 
							
								            iot_printf("[mb_ext][err]no mem@line %d\n", __LINE__);
							 | 
						||
| 
								 | 
							
								            IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								            return ERR_FAIL;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /* parser ge command and post to task */
							 | 
						||
| 
								 | 
							
								        iot_proto_data_parse_and_post(iot_pkt_data(p_pkt), iot_pkt_data_len(p_pkt),
							 | 
						||
| 
								 | 
							
								            iot_mb_task_post_uart_cmd, 0);
							 | 
						||
| 
								 | 
							
								        iot_pkt_free(p_pkt);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    os_mem_set(¤t_handle_cmd, 0, sizeof(current_handle_cmd));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (os_is_timer_active(mb_task.mb_ext_resp_timer)) {
							 | 
						||
| 
								 | 
							
								        os_stop_timer(mb_task.mb_ext_resp_timer);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return ERR_OK;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint8_t modbus_ext_set_resp_handler(iot_pkt_t *p_pkt_frame)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint8_t ret = ERR_FAIL;
							 | 
						||
| 
								 | 
							
								    uint16_t crc16 = 0;
							 | 
						||
| 
								 | 
							
								    uint32_t data_len = 0;
							 | 
						||
| 
								 | 
							
								    ge_frame_cmd_cfm_set_subfn20_t *cfm = (ge_frame_cmd_cfm_set_subfn20_t *)
							 | 
						||
| 
								 | 
							
								        iot_pkt_data(p_pkt_frame);
							 | 
						||
| 
								 | 
							
								    mb_ext_frame_set_resp_t *mb_resp_frm = NULL;
							 | 
						||
| 
								 | 
							
								    iot_pkt_t *mb_resp_pkt = NULL;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (mb_ext_gpio_config_flag) {
							 | 
						||
| 
								 | 
							
								        mb_ext_gpio_config_flag = 0;
							 | 
						||
| 
								 | 
							
								        goto out;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    mb_extend_fn_hdr_t * cur_cmd = iot_mb_ext_get_current_cmd_head();
							 | 
						||
| 
								 | 
							
								    if ((cfm->result == ERR_OK) && ((cur_cmd->fn == MODBUS_EXT_SET_SINGLE_REG_FN)
							 | 
						||
| 
								 | 
							
								        || (cur_cmd->fn == MODBUS_EXT_SET_MULTI_REG_FN))) {
							 | 
						||
| 
								 | 
							
								        data_len = sizeof(mb_ext_frame_set_resp_t);
							 | 
						||
| 
								 | 
							
								        mb_resp_pkt = iot_pkt_alloc(data_len, IOT_GREE_APP_MID);
							 | 
						||
| 
								 | 
							
								        IOT_ASSERT(mb_resp_pkt);
							 | 
						||
| 
								 | 
							
								        mb_resp_frm = (mb_ext_frame_set_resp_t*)iot_pkt_put(mb_resp_pkt,
							 | 
						||
| 
								 | 
							
								            sizeof(mb_ext_frame_set_resp_t));
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(&(mb_resp_frm->hdr), &(current_handle_cmd.hdr),
							 | 
						||
| 
								 | 
							
								            sizeof(mb_extend_fn_hdr_t));
							 | 
						||
| 
								 | 
							
								        mb_resp_frm->data = current_handle_cmd.data;
							 | 
						||
| 
								 | 
							
								        crc16 = iot_modbus_rtu_crc16((uint8_t*)mb_resp_frm, data_len - 2);
							 | 
						||
| 
								 | 
							
								        mb_resp_frm->tail.check_sum = crc16;
							 | 
						||
| 
								 | 
							
								        iot_mb_ext_resp_transmit((uint8_t*)mb_resp_frm, data_len,
							 | 
						||
| 
								 | 
							
								            current_handle_cmd.dir);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        iot_pkt_free(mb_resp_pkt);
							 | 
						||
| 
								 | 
							
								        ret = ERR_OK;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return ret;
							 | 
						||
| 
								 | 
							
								out:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return ERR_OK;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint8_t modbus_ext_aid_query_resp_handler(iot_pkt_t *p_pkt_frame)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint8_t ret = ERR_FAIL;
							 | 
						||
| 
								 | 
							
								    uint16_t crc16 = 0;
							 | 
						||
| 
								 | 
							
								    uint32_t data_len = 0;
							 | 
						||
| 
								 | 
							
								    ge_frame_nid_resp_subfn16_t *resp_cmd = (ge_frame_nid_resp_subfn16_t *)
							 | 
						||
| 
								 | 
							
								        iot_pkt_data(p_pkt_frame);
							 | 
						||
| 
								 | 
							
								    iot_pkt_t *mb_resp_pkt = NULL;
							 | 
						||
| 
								 | 
							
								    mb_ext_frame_aid_query_resp_t* mb_resp_frm = NULL;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    mb_extend_fn_hdr_t * cur_cmd = iot_mb_ext_get_current_cmd_head();
							 | 
						||
| 
								 | 
							
								    if ((cur_cmd->fn == MODBUS_EXT_QUERY_FN) &&
							 | 
						||
| 
								 | 
							
								        (big_little_swap16(cur_cmd->reg_addr) == AID_QUERY_RA)) {
							 | 
						||
| 
								 | 
							
								        data_len = sizeof(mb_ext_frame_aid_query_resp_t);
							 | 
						||
| 
								 | 
							
								        mb_resp_pkt = iot_pkt_alloc(data_len, IOT_GREE_APP_MID);
							 | 
						||
| 
								 | 
							
								        IOT_ASSERT(mb_resp_pkt);
							 | 
						||
| 
								 | 
							
								        mb_resp_frm = (mb_ext_frame_aid_query_resp_t*)iot_pkt_put(mb_resp_pkt,
							 | 
						||
| 
								 | 
							
								            sizeof(mb_ext_frame_aid_query_resp_t));
							 | 
						||
| 
								 | 
							
								        mb_resp_frm->adapt_id = big_little_swap16(resp_cmd->nid);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        mb_resp_frm->sa = current_handle_cmd.hdr.sa;
							 | 
						||
| 
								 | 
							
								        mb_resp_frm->fn = current_handle_cmd.hdr.fn;
							 | 
						||
| 
								 | 
							
								        mb_resp_frm->data_len = sizeof(*mb_resp_frm) - 5;
							 | 
						||
| 
								 | 
							
								        crc16 = iot_modbus_rtu_crc16((uint8_t*)mb_resp_frm, data_len - 2);
							 | 
						||
| 
								 | 
							
								        mb_resp_frm->tail.check_sum = crc16;
							 | 
						||
| 
								 | 
							
								        iot_mb_ext_resp_transmit((uint8_t*)mb_resp_frm, data_len,
							 | 
						||
| 
								 | 
							
								            current_handle_cmd.dir);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        iot_pkt_free(mb_resp_pkt);
							 | 
						||
| 
								 | 
							
								        ret = ERR_OK;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return ret;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint8_t modbus_ext_gpio_query_resp_handler(iot_pkt_t *p_pkt_frame)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint8_t ret = ERR_FAIL;
							 | 
						||
| 
								 | 
							
								    uint16_t crc16 = 0;
							 | 
						||
| 
								 | 
							
								    uint32_t data_len = 0;
							 | 
						||
| 
								 | 
							
								    ge_frame_query_gpio_resp_subfn27_t *resp_cmd =
							 | 
						||
| 
								 | 
							
								        (ge_frame_query_gpio_resp_subfn27_t *)iot_pkt_data(p_pkt_frame);
							 | 
						||
| 
								 | 
							
								    mb_ext_frame_gpio_query_resp_t* mb_resp_frm = NULL;
							 | 
						||
| 
								 | 
							
								    data_len = sizeof(mb_ext_frame_gpio_query_resp_t);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    mb_extend_fn_hdr_t * cur_cmd = iot_mb_ext_get_current_cmd_head();
							 | 
						||
| 
								 | 
							
								    if ((cur_cmd->fn == MODBUS_EXT_QUERY_FN) &&
							 | 
						||
| 
								 | 
							
								        (big_little_swap16(cur_cmd->reg_addr) >= GPIO_QUERY_BASE_RA)) {
							 | 
						||
| 
								 | 
							
								        iot_pkt_t *mb_resp_pkt = NULL;
							 | 
						||
| 
								 | 
							
								        mb_resp_pkt = iot_pkt_alloc(data_len, IOT_GREE_APP_MID);
							 | 
						||
| 
								 | 
							
								        IOT_ASSERT(mb_resp_pkt);
							 | 
						||
| 
								 | 
							
								        mb_resp_frm = (mb_ext_frame_gpio_query_resp_t*)iot_pkt_put(mb_resp_pkt,
							 | 
						||
| 
								 | 
							
								            sizeof(mb_ext_frame_gpio_query_resp_t));
							 | 
						||
| 
								 | 
							
								        mb_resp_frm->gpio_value = big_little_swap16(resp_cmd->value);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        mb_resp_frm->sa = current_handle_cmd.hdr.sa;
							 | 
						||
| 
								 | 
							
								        mb_resp_frm->fn = current_handle_cmd.hdr.fn;
							 | 
						||
| 
								 | 
							
								        mb_resp_frm->data_len = sizeof(*mb_resp_frm) - 5;
							 | 
						||
| 
								 | 
							
								        crc16 = iot_modbus_rtu_crc16((uint8_t*)mb_resp_frm, data_len - 2);
							 | 
						||
| 
								 | 
							
								        mb_resp_frm->tail.check_sum = crc16;
							 | 
						||
| 
								 | 
							
								        iot_mb_ext_resp_transmit((uint8_t*)mb_resp_frm, data_len,
							 | 
						||
| 
								 | 
							
								            current_handle_cmd.dir);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        iot_pkt_free(mb_resp_pkt);
							 | 
						||
| 
								 | 
							
								        ret = ERR_OK;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return ret;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint8_t iot_mb_ext_handle_resp_from_ge(iot_pkt_t *p_pkt_frame)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ge_extend_fn_hdr_t *hdr = (ge_extend_fn_hdr_t *)iot_pkt_data(p_pkt_frame);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if ((hdr->hdr.fn == PROTO_GE_PLC_SET_CMD) &&
							 | 
						||
| 
								 | 
							
								        (hdr->subfn == PROTO_CMD_CFM_CMD)) {
							 | 
						||
| 
								 | 
							
								        if (ERR_OK == modbus_ext_set_resp_handler(p_pkt_frame)) {
							 | 
						||
| 
								 | 
							
								            goto out;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    } else if ((hdr->hdr.fn == PROTO_GE_PLC_RESP_CMD) &&
							 | 
						||
| 
								 | 
							
								        (hdr->subfn == PROTO_NID_QUERY_CMD)) {
							 | 
						||
| 
								 | 
							
								        if (ERR_OK == modbus_ext_aid_query_resp_handler(p_pkt_frame)) {
							 | 
						||
| 
								 | 
							
								            goto out;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    } else if ((hdr->hdr.fn == PROTO_GE_PLC_RESP_CMD) &&
							 | 
						||
| 
								 | 
							
								        (hdr->subfn == PROTO_GE_GPIO_QUERY_CMD)) {
							 | 
						||
| 
								 | 
							
								        if (ERR_OK == modbus_ext_gpio_query_resp_handler(p_pkt_frame)) {
							 | 
						||
| 
								 | 
							
								            goto out;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return ERR_FAIL;
							 | 
						||
| 
								 | 
							
								out:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return ERR_OK;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void iot_mb_ext_resp_cmd_timeout_or_failed()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    if (os_is_timer_active(mb_task.mb_ext_resp_timer)) {
							 | 
						||
| 
								 | 
							
								        os_stop_timer(mb_task.mb_ext_resp_timer);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    os_mem_set(¤t_handle_cmd, 0, sizeof(current_handle_cmd));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static uint8_t modbus_ext_gpio_config(uint8_t gpio_num, uint8_t dir_mode,
							 | 
						||
| 
								 | 
							
								    uint8_t pull_mode, uint8_t default_value)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ge_frame_gpio_config_subfn164_t *pack_frm = NULL;
							 | 
						||
| 
								 | 
							
								    uint32_t pack_frm_len = sizeof(ge_frame_gpio_config_subfn164_t);
							 | 
						||
| 
								 | 
							
								    iot_pkt_t *p_pkt = NULL;
							 | 
						||
| 
								 | 
							
								    uint16_t crc16 = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    p_pkt = iot_pkt_alloc(pack_frm_len, IOT_MODBUS_MID);
							 | 
						||
| 
								 | 
							
								    if (NULL == p_pkt) {
							 | 
						||
| 
								 | 
							
								        iot_printf("[mb_ext][err]no mem@line %d\n", __LINE__);
							 | 
						||
| 
								 | 
							
								        IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								        return false;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* pack ge frame. */
							 | 
						||
| 
								 | 
							
								    pack_frm = (ge_frame_gpio_config_subfn164_t *)iot_pkt_put(p_pkt, pack_frm_len);
							 | 
						||
| 
								 | 
							
								    pack_frm->hdr.hdr.preamble = 0xAAAA;
							 | 
						||
| 
								 | 
							
								    pack_frm->hdr.hdr.data_len = 0x11;
							 | 
						||
| 
								 | 
							
								    pack_frm->hdr.hdr.fn = PROTO_GE_PLC_SET_CMD;
							 | 
						||
| 
								 | 
							
								    pack_frm->hdr.subfn = PROTO_GE_GPIO_CONFIG_CMD;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    pack_frm->seq = 0;
							 | 
						||
| 
								 | 
							
								    iot_mac_addr_cpy(pack_frm->dest_mac, mb_task.local_mac);
							 | 
						||
| 
								 | 
							
								    iot_mac_addr_cpy(pack_frm->src_mac, mb_task.local_mac);
							 | 
						||
| 
								 | 
							
								    pack_frm->gpio_num = gpio_num;
							 | 
						||
| 
								 | 
							
								    pack_frm->dir_mode = dir_mode;
							 | 
						||
| 
								 | 
							
								    pack_frm->pull_mode = pull_mode;
							 | 
						||
| 
								 | 
							
								    pack_frm->output_value = default_value;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    crc16 = ge_frm_checksum_calc((uint8_t *)pack_frm, pack_frm_len - 3);
							 | 
						||
| 
								 | 
							
								    pack_frm->tail.check_sum = crc16;
							 | 
						||
| 
								 | 
							
								    pack_frm->tail.tail = GE_FRM_TAIL_CODE;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* post ge command to ge task */
							 | 
						||
| 
								 | 
							
								    iot_proto_data_parse_and_post(iot_pkt_data(p_pkt), iot_pkt_data_len(p_pkt),
							 | 
						||
| 
								 | 
							
								        iot_mb_task_post_uart_cmd, 0);
							 | 
						||
| 
								 | 
							
								    iot_pkt_free(p_pkt);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return ERR_OK;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								bool_t modbus_ext_aid_query_handler(uint8_t *data, uint8_t len,
							 | 
						||
| 
								 | 
							
								    mb_transmit_direction_e dir)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ge_frame_nid_query_subfn16_t *pack_frm = NULL;
							 | 
						||
| 
								 | 
							
								    uint32_t pack_frm_len = sizeof(ge_frame_nid_query_subfn16_t);
							 | 
						||
| 
								 | 
							
								    iot_pkt_t *p_pkt = NULL;
							 | 
						||
| 
								 | 
							
								    mb_ext_frame_aid_query_t *frm = (mb_ext_frame_aid_query_t *)data;
							 | 
						||
| 
								 | 
							
								    uint16_t crc16 = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    p_pkt = iot_pkt_alloc(pack_frm_len, IOT_MODBUS_MID);
							 | 
						||
| 
								 | 
							
								    if (NULL == p_pkt) {
							 | 
						||
| 
								 | 
							
								        iot_printf("[%s][err]no mem@line %d\n", __FUNCTION__, __LINE__);
							 | 
						||
| 
								 | 
							
								        IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								        return false;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    os_mem_cpy(&(current_handle_cmd.hdr), &(frm->hdr), sizeof(mb_extend_fn_hdr_t));
							 | 
						||
| 
								 | 
							
								    current_handle_cmd.data = frm->reg_count;
							 | 
						||
| 
								 | 
							
								    current_handle_cmd.dir = dir;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* pack ge frame. */
							 | 
						||
| 
								 | 
							
								    pack_frm = (ge_frame_nid_query_subfn16_t *)iot_pkt_put(p_pkt, pack_frm_len);
							 | 
						||
| 
								 | 
							
								    pack_frm->hdr.hdr.preamble = 0xAAAA;
							 | 
						||
| 
								 | 
							
								    pack_frm->hdr.hdr.data_len = 0x01;
							 | 
						||
| 
								 | 
							
								    pack_frm->hdr.hdr.fn = PROTO_GE_PLC_QUERY_CMD;
							 | 
						||
| 
								 | 
							
								    pack_frm->hdr.subfn = PROTO_NID_QUERY_CMD;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    pack_frm->seq = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    crc16 = ge_frm_checksum_calc((uint8_t *)pack_frm, pack_frm_len - 3);
							 | 
						||
| 
								 | 
							
								    pack_frm->tail.check_sum = crc16;
							 | 
						||
| 
								 | 
							
								    pack_frm->tail.tail = GE_FRM_TAIL_CODE;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* post ge command to ge task */
							 | 
						||
| 
								 | 
							
								    iot_proto_data_parse_and_post(iot_pkt_data(p_pkt), iot_pkt_data_len(p_pkt),
							 | 
						||
| 
								 | 
							
								        iot_mb_task_post_uart_cmd, 0);
							 | 
						||
| 
								 | 
							
								    iot_pkt_free(p_pkt);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    os_start_timer(mb_task.mb_ext_resp_timer, IOT_MB_EXT_RESP_TIMER_PERIOD);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return true;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static bool_t modbus_ext_sa_query_handler(uint8_t *data, uint8_t len,
							 | 
						||
| 
								 | 
							
								    mb_transmit_direction_e dir)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    iot_pkt_t *p_pkt = NULL;
							 | 
						||
| 
								 | 
							
								    mb_ext_frame_sa_query_resp_t *resp_frm = NULL;
							 | 
						||
| 
								 | 
							
								    uint32_t resp_frm_len = sizeof(mb_ext_frame_sa_query_resp_t);
							 | 
						||
| 
								 | 
							
								    uint16_t crc16 = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    mb_ext_frame_sa_query_t *frm = (mb_ext_frame_sa_query_t *)data;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    p_pkt = iot_pkt_alloc(resp_frm_len, IOT_MODBUS_MID);
							 | 
						||
| 
								 | 
							
								    if (NULL == p_pkt) {
							 | 
						||
| 
								 | 
							
								        iot_printf("[%s][err]no mem@line %d\n", __FUNCTION__, __LINE__);
							 | 
						||
| 
								 | 
							
								        IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								        return false;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    resp_frm = (mb_ext_frame_sa_query_resp_t *)iot_pkt_put(p_pkt, resp_frm_len);
							 | 
						||
| 
								 | 
							
								    resp_frm->sa = frm->hdr.sa;
							 | 
						||
| 
								 | 
							
								    resp_frm->fn = frm->hdr.fn;
							 | 
						||
| 
								 | 
							
								    resp_frm->data_len = 2;
							 | 
						||
| 
								 | 
							
								    resp_frm->slaver_addr = big_little_swap16(mb_task.slave_addr);
							 | 
						||
| 
								 | 
							
								    crc16 = iot_modbus_rtu_crc16((uint8_t*)resp_frm, resp_frm_len - 2);
							 | 
						||
| 
								 | 
							
								    resp_frm->tail.check_sum = crc16;
							 | 
						||
| 
								 | 
							
								    iot_mb_ext_resp_transmit((uint8_t*)resp_frm, resp_frm_len, dir);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    iot_pkt_free(p_pkt);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return true;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								bool_t modbus_ext_wl_item_count_query_handler(uint8_t *data,
							 | 
						||
| 
								 | 
							
								    uint8_t len, mb_transmit_direction_e dir)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    (void)data;
							 | 
						||
| 
								 | 
							
								    (void)len;
							 | 
						||
| 
								 | 
							
								    (void)dir;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return true;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								bool_t modbus_ext_wl_item_query_handler(uint8_t *data, uint8_t len,
							 | 
						||
| 
								 | 
							
								    mb_transmit_direction_e dir)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    (void)data;
							 | 
						||
| 
								 | 
							
								    (void)len;
							 | 
						||
| 
								 | 
							
								    (void)dir;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return true;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static bool_t modbus_ext_gpio_query_handler(uint8_t *data, uint8_t len,
							 | 
						||
| 
								 | 
							
								    mb_transmit_direction_e dir)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ge_frame_gpio_query_subfn27_t *pack_frm = NULL;
							 | 
						||
| 
								 | 
							
								    uint32_t pack_frm_len = sizeof(ge_frame_gpio_query_subfn27_t);
							 | 
						||
| 
								 | 
							
								    iot_pkt_t *p_pkt = NULL;
							 | 
						||
| 
								 | 
							
								    mb_ext_frame_gpio_query_t *frm = (mb_ext_frame_gpio_query_t *)data;
							 | 
						||
| 
								 | 
							
								    uint16_t crc16 = 0, reg_addr = 0;
							 | 
						||
| 
								 | 
							
								    uint8_t gpio_num = 0xff;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    reg_addr = big_little_swap16(frm->hdr.reg_addr);
							 | 
						||
| 
								 | 
							
								    if ((reg_addr - GPIO_QUERY_BASE_RA) % 8 != 0) {
							 | 
						||
| 
								 | 
							
								       goto param_err;
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        gpio_num = (reg_addr - GPIO_QUERY_BASE_RA) / 8;
							 | 
						||
| 
								 | 
							
								        //if (gpio_num >= GPIO_PIN_COUNT) {
							 | 
						||
| 
								 | 
							
								        //    goto param_err;
							 | 
						||
| 
								 | 
							
								        //}
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    p_pkt = iot_pkt_alloc(pack_frm_len, IOT_MODBUS_MID);
							 | 
						||
| 
								 | 
							
								    if (NULL == p_pkt) {
							 | 
						||
| 
								 | 
							
								        iot_printf("[%s][err]no mem@line %d\n", __FUNCTION__, __LINE__);
							 | 
						||
| 
								 | 
							
								        IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								        return false;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    os_mem_cpy(&(current_handle_cmd.hdr), &(frm->hdr), sizeof(mb_extend_fn_hdr_t));
							 | 
						||
| 
								 | 
							
								    current_handle_cmd.data = frm->reg_count;
							 | 
						||
| 
								 | 
							
								    current_handle_cmd.dir = dir;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    mb_ext_gpio_config_flag = 1;
							 | 
						||
| 
								 | 
							
								    modbus_ext_gpio_config(gpio_num, IOT_GE_GPIO_DIR_INPUT, IOT_GE_GPIO_PULL_NONE, 0);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* pack ge frame. */
							 | 
						||
| 
								 | 
							
								    pack_frm = (ge_frame_gpio_query_subfn27_t *)iot_pkt_put(p_pkt, pack_frm_len);
							 | 
						||
| 
								 | 
							
								    pack_frm->hdr.hdr.preamble = 0xAAAA;
							 | 
						||
| 
								 | 
							
								    pack_frm->hdr.hdr.data_len = 0x0E;
							 | 
						||
| 
								 | 
							
								    pack_frm->hdr.hdr.fn = PROTO_GE_PLC_QUERY_CMD;
							 | 
						||
| 
								 | 
							
								    pack_frm->hdr.subfn = PROTO_GE_GPIO_QUERY_CMD;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    pack_frm->seq = 0;
							 | 
						||
| 
								 | 
							
								    iot_mac_addr_cpy(pack_frm->dest_mac, mb_task.local_mac);
							 | 
						||
| 
								 | 
							
								    iot_mac_addr_cpy(pack_frm->src_mac, mb_task.local_mac);
							 | 
						||
| 
								 | 
							
								    pack_frm->gpio_num = gpio_num;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    crc16 = ge_frm_checksum_calc((uint8_t *)pack_frm, pack_frm_len - 3);
							 | 
						||
| 
								 | 
							
								    pack_frm->tail.check_sum = crc16;
							 | 
						||
| 
								 | 
							
								    pack_frm->tail.tail = GE_FRM_TAIL_CODE;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* post ge command to ge task */
							 | 
						||
| 
								 | 
							
								    iot_proto_data_parse_and_post(iot_pkt_data(p_pkt), iot_pkt_data_len(p_pkt),
							 | 
						||
| 
								 | 
							
								        iot_mb_task_post_uart_cmd, 0);
							 | 
						||
| 
								 | 
							
								    iot_pkt_free(p_pkt);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    os_start_timer(mb_task.mb_ext_resp_timer, IOT_MB_EXT_RESP_TIMER_PERIOD);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return true;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								param_err:
							 | 
						||
| 
								 | 
							
								    iot_printf("[%s][err]param err @line %d\n", __FUNCTION__, __LINE__);
							 | 
						||
| 
								 | 
							
								    return false;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static mb_fnhdl_tbl_t modbus_query_ra_tbl[] = {
							 | 
						||
| 
								 | 
							
								#if PLC_SUPPORT_CCO_ROLE
							 | 
						||
| 
								 | 
							
								    {AID_QUERY_RA,   modbus_ext_aid_query_handler, 0},
							 | 
						||
| 
								 | 
							
								    {WL_ITEM_COUNT_QUERY_RA, modbus_ext_wl_item_count_query_handler, 0},
							 | 
						||
| 
								 | 
							
								    {WL_ITEM_QUERY_BASE_RA, modbus_ext_wl_item_query_handler, 0},
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								    {SA_QUERY_RA, modbus_ext_sa_query_handler, 0},
							 | 
						||
| 
								 | 
							
								    {GPIO_QUERY_BASE_RA,   modbus_ext_gpio_query_handler, 0},
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static bool_t iot_mb_ext_cmd_query_fn_handler(uint8_t *data,
							 | 
						||
| 
								 | 
							
								    uint8_t len, mb_transmit_direction_e dir)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint8_t i, ret = ERR_FAIL;
							 | 
						||
| 
								 | 
							
								    uint16_t reg_addr = 0;
							 | 
						||
| 
								 | 
							
								    mb_extend_fn_hdr_t *mb_head = (mb_extend_fn_hdr_t *)data;
							 | 
						||
| 
								 | 
							
								    uint8_t fncode_hdlr_cnt =
							 | 
						||
| 
								 | 
							
								                sizeof(modbus_query_ra_tbl)/sizeof(mb_fnhdl_tbl_t);
							 | 
						||
| 
								 | 
							
								    MODBUS_FN_HANDLE handler = NULL;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    reg_addr = big_little_swap16(mb_head->reg_addr);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    for (i = 0; i < fncode_hdlr_cnt; i++) {
							 | 
						||
| 
								 | 
							
								        if (modbus_query_ra_tbl[i].cmdid == reg_addr) {
							 | 
						||
| 
								 | 
							
								            handler = modbus_query_ra_tbl[i].cmd_handle_fn;
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								     }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if PLC_SUPPORT_CCO_ROLE
							 | 
						||
| 
								 | 
							
								    if (reg_addr > WL_ITEM_QUERY_BASE_RA) {
							 | 
						||
| 
								 | 
							
								        handler = modbus_ext_wl_item_query_handler;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (reg_addr > GPIO_QUERY_BASE_RA) {
							 | 
						||
| 
								 | 
							
								        handler = modbus_ext_gpio_query_handler;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (handler) {
							 | 
						||
| 
								 | 
							
								        ret = handler(data, len, dir);
							 | 
						||
| 
								 | 
							
								        ret = (ret == true)? ERR_OK: ERR_FAIL;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return ret;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								bool_t modbus_ext_aid_set_handler(uint8_t *data, uint8_t len,
							 | 
						||
| 
								 | 
							
								    mb_transmit_direction_e dir)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ge_frame_cco_nid_set_subfn17_t *pack_frm = NULL;
							 | 
						||
| 
								 | 
							
								    uint32_t pack_frm_len = sizeof(ge_frame_cco_nid_set_subfn17_t);
							 | 
						||
| 
								 | 
							
								    iot_pkt_t *p_pkt = NULL;
							 | 
						||
| 
								 | 
							
								    mb_ext_frame_aid_set_t *frm = (mb_ext_frame_aid_set_t *)data;
							 | 
						||
| 
								 | 
							
								    uint16_t crc16 = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    p_pkt = iot_pkt_alloc(pack_frm_len, IOT_MODBUS_MID);
							 | 
						||
| 
								 | 
							
								    if (NULL == p_pkt) {
							 | 
						||
| 
								 | 
							
								        iot_printf("[mb_ext][err]no mem@line %d\n", __LINE__);
							 | 
						||
| 
								 | 
							
								        IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								        return false;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    os_mem_cpy(&(current_handle_cmd.hdr), &(frm->hdr), sizeof(mb_extend_fn_hdr_t));
							 | 
						||
| 
								 | 
							
								    current_handle_cmd.data = frm->adapt_id;
							 | 
						||
| 
								 | 
							
								    current_handle_cmd.dir = dir;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* pack ge frame. */
							 | 
						||
| 
								 | 
							
								    pack_frm = (ge_frame_cco_nid_set_subfn17_t *)iot_pkt_put(p_pkt, pack_frm_len);
							 | 
						||
| 
								 | 
							
								    pack_frm->hdr.hdr.preamble = 0xAAAA;
							 | 
						||
| 
								 | 
							
								    pack_frm->hdr.hdr.data_len = 0X07;
							 | 
						||
| 
								 | 
							
								    pack_frm->hdr.hdr.fn = PROTO_GE_PLC_SET_CMD;
							 | 
						||
| 
								 | 
							
								    pack_frm->hdr.subfn = PROTO_CCO_NID_SET_CMD;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    pack_frm->nid = (frm->adapt_id) >> 8;
							 | 
						||
| 
								 | 
							
								    pack_frm->seq = 0;
							 | 
						||
| 
								 | 
							
								    iot_mac_addr_cpy(pack_frm->mac, mb_task.local_mac);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    crc16 = ge_frm_checksum_calc((uint8_t *)pack_frm, pack_frm_len - 3);
							 | 
						||
| 
								 | 
							
								    pack_frm->tail.check_sum = crc16;
							 | 
						||
| 
								 | 
							
								    pack_frm->tail.tail = GE_FRM_TAIL_CODE;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* post ge command to ge task */
							 | 
						||
| 
								 | 
							
								    iot_proto_data_parse_and_post(iot_pkt_data(p_pkt), iot_pkt_data_len(p_pkt),
							 | 
						||
| 
								 | 
							
								        iot_mb_task_post_uart_cmd, 0);
							 | 
						||
| 
								 | 
							
								    iot_pkt_free(p_pkt);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    os_start_timer(mb_task.mb_ext_resp_timer, IOT_MB_EXT_RESP_TIMER_PERIOD);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return true;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static bool_t modbus_ext_sa_set_handler(uint8_t *data, uint8_t len,
							 | 
						||
| 
								 | 
							
								    mb_transmit_direction_e dir)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    mb_ext_frame_sa_set_t *frm = (mb_ext_frame_sa_set_t *)data;
							 | 
						||
| 
								 | 
							
								    uint8_t new_sa = (frm->slaver_addr) >> 8;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (mb_task.slave_addr != new_sa) {
							 | 
						||
| 
								 | 
							
								        mb_task.slave_addr = new_sa;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    iot_mb_ext_resp_transmit(data, len, dir);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return true;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								bool_t modbus_ext_wl_set_handler(uint8_t *data, uint8_t len,
							 | 
						||
| 
								 | 
							
								    mb_transmit_direction_e dir)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    (void)data;
							 | 
						||
| 
								 | 
							
								    (void)len;
							 | 
						||
| 
								 | 
							
								    (void)dir;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return true;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static bool_t modbus_ext_gpio_set_handler(uint8_t *data, uint8_t len,
							 | 
						||
| 
								 | 
							
								    mb_transmit_direction_e dir)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ge_frame_gpio_set_subfn165_t *pack_frm = NULL;
							 | 
						||
| 
								 | 
							
								    uint32_t pack_frm_len = sizeof(ge_frame_gpio_set_subfn165_t);
							 | 
						||
| 
								 | 
							
								    iot_pkt_t *p_pkt = NULL;
							 | 
						||
| 
								 | 
							
								    mb_ext_frame_gpio_set_t *frm = (mb_ext_frame_gpio_set_t *)data;
							 | 
						||
| 
								 | 
							
								    uint16_t crc16 = 0, reg_addr = 0;
							 | 
						||
| 
								 | 
							
								    uint8_t gpio_num = 0xff;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    reg_addr = big_little_swap16(frm->hdr.reg_addr);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if ((reg_addr - GPIO_SET_BASE_RA) % 8 != 0) {
							 | 
						||
| 
								 | 
							
								       goto param_err;
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        gpio_num = (reg_addr - GPIO_SET_BASE_RA) / 8;
							 | 
						||
| 
								 | 
							
								        //if (gpio_num >= GPIO_PIN_COUNT) {
							 | 
						||
| 
								 | 
							
								        //    goto param_err;
							 | 
						||
| 
								 | 
							
								        //}
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    p_pkt = iot_pkt_alloc(pack_frm_len, IOT_MODBUS_MID);
							 | 
						||
| 
								 | 
							
								    if (NULL == p_pkt) {
							 | 
						||
| 
								 | 
							
								        iot_printf("[%s][err]no mem@line %d\n", __FUNCTION__, __LINE__);
							 | 
						||
| 
								 | 
							
								        IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								        return false;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    os_mem_cpy(&(current_handle_cmd.hdr), &(frm->hdr), sizeof(mb_extend_fn_hdr_t));
							 | 
						||
| 
								 | 
							
								    current_handle_cmd.data = frm->gpio_value;
							 | 
						||
| 
								 | 
							
								    current_handle_cmd.dir = dir;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    mb_ext_gpio_config_flag = 1;
							 | 
						||
| 
								 | 
							
								    modbus_ext_gpio_config(gpio_num, IOT_GE_GPIO_DIR_OUTPUT, IOT_GE_GPIO_PULL_NONE, 0);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* pack ge frame. */
							 | 
						||
| 
								 | 
							
								    pack_frm = (ge_frame_gpio_set_subfn165_t *)iot_pkt_put(p_pkt, pack_frm_len);
							 | 
						||
| 
								 | 
							
								    pack_frm->hdr.hdr.preamble = 0xAAAA;
							 | 
						||
| 
								 | 
							
								    pack_frm->hdr.hdr.data_len = 0x0F;
							 | 
						||
| 
								 | 
							
								    pack_frm->hdr.hdr.fn = PROTO_GE_PLC_SET_CMD;
							 | 
						||
| 
								 | 
							
								    pack_frm->hdr.subfn = PROTO_GE_GPIO_SET_CMD;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    pack_frm->seq = 0;
							 | 
						||
| 
								 | 
							
								    iot_mac_addr_cpy(pack_frm->dest_mac, mb_task.local_mac);
							 | 
						||
| 
								 | 
							
								    iot_mac_addr_cpy(pack_frm->src_mac, mb_task.local_mac);
							 | 
						||
| 
								 | 
							
								    pack_frm->gpio_num = gpio_num;
							 | 
						||
| 
								 | 
							
								    pack_frm->value = (frm->gpio_value) >> 8;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    crc16 = ge_frm_checksum_calc((uint8_t *)pack_frm, pack_frm_len - 3);
							 | 
						||
| 
								 | 
							
								    pack_frm->tail.check_sum = crc16;
							 | 
						||
| 
								 | 
							
								    pack_frm->tail.tail = GE_FRM_TAIL_CODE;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* post ge command to ge task */
							 | 
						||
| 
								 | 
							
								    iot_proto_data_parse_and_post(iot_pkt_data(p_pkt), iot_pkt_data_len(p_pkt),
							 | 
						||
| 
								 | 
							
								        iot_mb_task_post_uart_cmd, 0);
							 | 
						||
| 
								 | 
							
								    iot_pkt_free(p_pkt);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    os_start_timer(mb_task.mb_ext_resp_timer, IOT_MB_EXT_RESP_TIMER_PERIOD);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return true;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								param_err:
							 | 
						||
| 
								 | 
							
								    iot_printf("[%s][err]param err @line %d\n", __FUNCTION__, __LINE__);
							 | 
						||
| 
								 | 
							
								    return false;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								bool_t modbus_ext_wl_add_item_handler(uint8_t *data, uint8_t len,
							 | 
						||
| 
								 | 
							
								    mb_transmit_direction_e dir)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    (void)data;
							 | 
						||
| 
								 | 
							
								    (void)len;
							 | 
						||
| 
								 | 
							
								    (void)dir;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return true;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								bool_t modbus_ext_wl_remove_item_handler(uint8_t *data, uint8_t len,
							 | 
						||
| 
								 | 
							
								    mb_transmit_direction_e dir)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    (void)data;
							 | 
						||
| 
								 | 
							
								    (void)len;
							 | 
						||
| 
								 | 
							
								    (void)dir;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return true;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static mb_fnhdl_tbl_t modbus_set_ra_tbl[] = {
							 | 
						||
| 
								 | 
							
								#if PLC_SUPPORT_CCO_ROLE
							 | 
						||
| 
								 | 
							
								    {AID_SET_RA, modbus_ext_aid_set_handler, 0},
							 | 
						||
| 
								 | 
							
								    {WL_SET_RA, modbus_ext_wl_set_handler,0},
							 | 
						||
| 
								 | 
							
								    {WL_ADD_ITEM_SET_RA,   modbus_ext_wl_add_item_handler, 0},
							 | 
						||
| 
								 | 
							
								    {WL_RM_ITEM_SET_RA, modbus_ext_wl_remove_item_handler, 0},
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								    {SA_SET_RA, modbus_ext_sa_set_handler,0},
							 | 
						||
| 
								 | 
							
								    {GPIO_SET_BASE_RA, modbus_ext_gpio_set_handler, 0},
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static bool_t iot_mb_ext_cmd_set_handler(uint8_t *data,
							 | 
						||
| 
								 | 
							
								    uint8_t len, mb_transmit_direction_e dir)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint8_t i, ret = ERR_FAIL;
							 | 
						||
| 
								 | 
							
								    mb_extend_fn_hdr_t *mb_head = (mb_extend_fn_hdr_t *)data;;
							 | 
						||
| 
								 | 
							
								    uint8_t fncode_hdlr_cnt =
							 | 
						||
| 
								 | 
							
								                sizeof(modbus_set_ra_tbl)/sizeof(mb_fnhdl_tbl_t);
							 | 
						||
| 
								 | 
							
								    MODBUS_FN_HANDLE handler = NULL;
							 | 
						||
| 
								 | 
							
								    uint16_t reg_addr = big_little_swap16(mb_head->reg_addr);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    for (i = 0; i < fncode_hdlr_cnt; i++) {
							 | 
						||
| 
								 | 
							
								        if (modbus_set_ra_tbl[i].cmdid == reg_addr) {
							 | 
						||
| 
								 | 
							
								            handler = modbus_set_ra_tbl[i].cmd_handle_fn;
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (reg_addr > GPIO_SET_BASE_RA) {
							 | 
						||
| 
								 | 
							
								        handler = modbus_ext_gpio_set_handler;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (handler) {
							 | 
						||
| 
								 | 
							
								        ret = handler(data, len, dir);
							 | 
						||
| 
								 | 
							
								        ret = (ret == true)? ERR_OK: ERR_FAIL;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return ret;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* fncode handler table */
							 | 
						||
| 
								 | 
							
								static mb_fnhdl_tbl_t mb_fn_hdl_tbl[] = {
							 | 
						||
| 
								 | 
							
								    {MODBUS_EXT_QUERY_FN,           iot_mb_ext_cmd_query_fn_handler,    0 },
							 | 
						||
| 
								 | 
							
								    {MODBUS_EXT_SET_SINGLE_REG_FN,  iot_mb_ext_cmd_set_handler,         0 },
							 | 
						||
| 
								 | 
							
								    {MODBUS_EXT_SET_MULTI_REG_FN,   iot_mb_ext_cmd_set_handler,         0 },
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint8_t iot_mb_ext_cmd_handler(uint8_t * data, uint16_t len,
							 | 
						||
| 
								 | 
							
								    mb_transmit_direction_e dir)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint8_t i, ret = ERR_FAIL;
							 | 
						||
| 
								 | 
							
								    mb_extend_fn_hdr_t *mb_head = NULL;
							 | 
						||
| 
								 | 
							
								    uint8_t fncode_hdlr_cnt =
							 | 
						||
| 
								 | 
							
								                sizeof(mb_fn_hdl_tbl)/sizeof(mb_fnhdl_tbl_t);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if ((data == NULL) || (len == 0)) {
							 | 
						||
| 
								 | 
							
								        iot_printf("[%s][err] invalid data, data:%p, len:%d\n", __FUNCTION__, data, len);
							 | 
						||
| 
								 | 
							
								        goto out;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    iot_mb_ext_data_dump(data, len, __LINE__);
							 | 
						||
| 
								 | 
							
								    mb_head = (mb_extend_fn_hdr_t *)data;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* look for fncode handler to handle modbus cmd frame */
							 | 
						||
| 
								 | 
							
								    for (i = 0; i < fncode_hdlr_cnt; i++) {
							 | 
						||
| 
								 | 
							
								        if (mb_head->fn == mb_fn_hdl_tbl[i].cmdid) {
							 | 
						||
| 
								 | 
							
								            /* increase each fn counter */
							 | 
						||
| 
								 | 
							
								            mb_fn_hdl_tbl[i].cmd_num++;
							 | 
						||
| 
								 | 
							
								            mb_fn_hdl_tbl[i].cmd_handle_fn(data, len, dir);
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ret = ERR_OK;
							 | 
						||
| 
								 | 
							
								out:
							 | 
						||
| 
								 | 
							
								    return ret;
							 | 
						||
| 
								 | 
							
								}
							 |