1195 lines
		
	
	
		
			38 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			1195 lines
		
	
	
		
			38 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								/****************************************************************************
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
							 | 
						||
| 
								 | 
							
								be copied by any method or incorporated into another program without
							 | 
						||
| 
								 | 
							
								the express written consent of Aerospace C.Power. This Information or any portion
							 | 
						||
| 
								 | 
							
								thereof remains the property of Aerospace C.Power. The Information contained herein
							 | 
						||
| 
								 | 
							
								is believed to be accurate and Aerospace C.Power assumes no responsibility or
							 | 
						||
| 
								 | 
							
								liability for its use in any way and conveys no license or title under
							 | 
						||
| 
								 | 
							
								any patent or copyright and makes no representation or warranty that this
							 | 
						||
| 
								 | 
							
								Information is free from patent or copyright infringement.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								****************************************************************************/
							 | 
						||
| 
								 | 
							
								/* os_ship header files */
							 | 
						||
| 
								 | 
							
								#include "os_task_api.h"
							 | 
						||
| 
								 | 
							
								#include "os_event_api.h"
							 | 
						||
| 
								 | 
							
								#include "os_timer_api.h"
							 | 
						||
| 
								 | 
							
								#include "os_utils_api.h"
							 | 
						||
| 
								 | 
							
								#include "os_lock_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_grapp.h"
							 | 
						||
| 
								 | 
							
								#include "iot_proto_common.h"
							 | 
						||
| 
								 | 
							
								#include "iot_proto_ge.h"
							 | 
						||
| 
								 | 
							
								#include "iot_modbus_task.h"
							 | 
						||
| 
								 | 
							
								#include "iot_modbus_ext.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if IOT_GE_MODBUS_TASK_ENABLE
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if (IOT_PSRAM_ENABLE)
							 | 
						||
| 
								 | 
							
								#define IOT_MODBUS_TASK_UART_BUF_SIZE       (2048)
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								#define IOT_MODBUS_TASK_UART_BUF_SIZE       (256 + 64)
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								/* define ge FE A0 cmd max data len */
							 | 
						||
| 
								 | 
							
								#define IOT_GE_FE_A0_DATA_LEN_MAX           (GE_FRM_PLD_MAX_LEN - IOT_MAC_ADDR_LEN)
							 | 
						||
| 
								 | 
							
								/* print data buff in hex formate. */
							 | 
						||
| 
								 | 
							
								#define IOT_MODBUS_TASK_DATA_DUMP           (1)
							 | 
						||
| 
								 | 
							
								/* modbus bradcast addr is 0 */
							 | 
						||
| 
								 | 
							
								#define IOT_MODBUS_BROADCAST_ADDR           (0x0)
							 | 
						||
| 
								 | 
							
								/* modbus default slaver address */
							 | 
						||
| 
								 | 
							
								#define IOT_MODBUS_DEFAULT_SLAVER_ADDR      (0xff)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if PLC_SUPPORT_CCO_ROLE // master REQUEST
							 | 
						||
| 
								 | 
							
								const iot_mb_data_check_t mb_check[] = {
							 | 
						||
| 
								 | 
							
								    {0x02, 1 + 5 + 2, 0, 0xff}, // 1 + 5 + 2
							 | 
						||
| 
								 | 
							
								    {0x01, 1 + 5 + 2, 0, 0xff}, // 1 + 5 + 2
							 | 
						||
| 
								 | 
							
								    {0x05, 1 + 5 + 2, 0, 0xff}, // 1 + 5 + 2
							 | 
						||
| 
								 | 
							
								    {0x0F, 1 + 6 + 2, 1, 0x06}, // 1 + 6 + n + 2
							 | 
						||
| 
								 | 
							
								    {0x04, 1 + 5 + 2, 0, 0xff}, // 1 + 5 + 2
							 | 
						||
| 
								 | 
							
								    {0x03, 1 + 5 + 2, 0, 0xff}, // 1 + 5 + 2
							 | 
						||
| 
								 | 
							
								    {0x06, 1 + 5 + 2, 0, 0xff}, // 1 + 5 + 2
							 | 
						||
| 
								 | 
							
								    {0x10, 1 + 6 + 2, 1, 0x06}, // 1 + 6 + n + 2
							 | 
						||
| 
								 | 
							
								    {0x17, 1 + 10 + 2,1, 0x0A}, // 1 + 10 + n + 2
							 | 
						||
| 
								 | 
							
								    {0x16, 1 + 7 + 2, 0, 0xFF}, // 1 + 7 + 2
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								#else // slave RESPONSE
							 | 
						||
| 
								 | 
							
								const iot_mb_data_check_t mb_check[] = {
							 | 
						||
| 
								 | 
							
								    {0x02, 1 + 2 + 2, 1, 0x02}, // 1 + 2 + n + 2
							 | 
						||
| 
								 | 
							
								    {0x01, 1 + 2 + 2, 1, 0x02}, // 1 + 2 + n + 2
							 | 
						||
| 
								 | 
							
								    {0x05, 1 + 5 + 2, 0, 0xff}, // 1 + 5 + 2
							 | 
						||
| 
								 | 
							
								    {0x0F, 1 + 5 + 2, 0, 0xff}, // 1 + 5 + 2
							 | 
						||
| 
								 | 
							
								    {0x04, 1 + 2 + 2, 1, 0x02}, // 1 + 2 + n + 2
							 | 
						||
| 
								 | 
							
								    {0x03, 1 + 2 + 2, 1, 0x02}, // 1 + 2 + n + 2
							 | 
						||
| 
								 | 
							
								    {0x06, 1 + 5 + 2, 0, 0xff}, // 1 + 5 + 2
							 | 
						||
| 
								 | 
							
								    {0x10, 1 + 5 + 2, 0, 0xff}, // 1 + 5 + 2
							 | 
						||
| 
								 | 
							
								    {0x17, 1 + 2 + 2, 1, 0x02}, // 1 + 2 + n + 2
							 | 
						||
| 
								 | 
							
								    {0x16, 1 + 7 + 2, 0, 0xff}, // 1 + 7 + 2
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								const uint8_t max_func_code_num = sizeof(mb_check) / sizeof(mb_check[0]);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/** modbus_task message */
							 | 
						||
| 
								 | 
							
								typedef struct _iot_mb_task_msg {
							 | 
						||
| 
								 | 
							
								    /* iot task message */
							 | 
						||
| 
								 | 
							
								    iot_task_msg_t  task_msg;
							 | 
						||
| 
								 | 
							
								    /* pointer to message data */
							 | 
						||
| 
								 | 
							
								    void            *data;
							 | 
						||
| 
								 | 
							
								    /* another data field */
							 | 
						||
| 
								 | 
							
								    uint32_t        data2;
							 | 
						||
| 
								 | 
							
								} iot_mb_task_msg_t;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								iot_mb_task_t mb_task;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if IOT_MODBUS_RT_TABLE_SUPPORT
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* route entry max nums */
							 | 
						||
| 
								 | 
							
								#define IOT_MODBUS_MAC_RT_ENTRY_MAX          (32)
							 | 
						||
| 
								 | 
							
								/* route entry timeout, unit is second. */
							 | 
						||
| 
								 | 
							
								#define IOT_MODBUS_MAC_RT_ENTRY_TTL          (60)
							 | 
						||
| 
								 | 
							
								/* route entry update interval, unit is second. */
							 | 
						||
| 
								 | 
							
								#define IOT_MODBUS_MAC_RT_UPDATE_INTERVAL    (20)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/** iot mac address hash table entry */
							 | 
						||
| 
								 | 
							
								typedef struct _iot_modbus_addr_rout_entry {
							 | 
						||
| 
								 | 
							
								    struct _iot_modbus_addr_rout_entry *next;
							 | 
						||
| 
								 | 
							
								    /* modbus device id */
							 | 
						||
| 
								 | 
							
								    uint8_t             slaver_addr;
							 | 
						||
| 
								 | 
							
								    /** mac address of the entry */
							 | 
						||
| 
								 | 
							
								    uint8_t             addr[IOT_MAC_ADDR_LEN];
							 | 
						||
| 
								 | 
							
								    /* ttl of the route item. unit is s */
							 | 
						||
| 
								 | 
							
								    int                 ent_ttl;
							 | 
						||
| 
								 | 
							
								} iot_modbus_addr_rout_entry_t;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* iot mac address hash table */
							 | 
						||
| 
								 | 
							
								typedef struct _iot_modbus_addr_rout_table {
							 | 
						||
| 
								 | 
							
								    /* number of entries supported */
							 | 
						||
| 
								 | 
							
								    uint16_t                entry_cnt;
							 | 
						||
| 
								 | 
							
								    /* size of each entry */
							 | 
						||
| 
								 | 
							
								    uint16_t                entry_size;
							 | 
						||
| 
								 | 
							
								    /* entry point for each entry item */
							 | 
						||
| 
								 | 
							
								    iot_modbus_addr_rout_entry_t   *rout_ent;
							 | 
						||
| 
								 | 
							
								    /* entry pool */
							 | 
						||
| 
								 | 
							
								    iot_mem_pool_t          *entry_p;
							 | 
						||
| 
								 | 
							
								} iot_modbus_addr_rout_table_t;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @brief iot_mb_task_rt_update_timer_exe() - timer timeout callback function.
							 | 
						||
| 
								 | 
							
								 * @timer_id : timer id with that timer who causes this api-call.
							 | 
						||
| 
								 | 
							
								 * @arg : param past to this callback api.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								static void iot_mb_task_rt_update_timer_exe(timer_id_t timer_id, void * arg)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    (void)arg;
							 | 
						||
| 
								 | 
							
								    if (timer_id == mb_task.uart_timer) {
							 | 
						||
| 
								 | 
							
								        iot_mb_task_msg_post(IOT_MODBUS_TASK_MT_TIMER,
							 | 
						||
| 
								 | 
							
								            IOT_MODBUS_TASK_MSG_ID_TMR_RT_UPDATE_TIMEOUT, NULL);
							 | 
						||
| 
								 | 
							
								        os_reset_timer(timer_id);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @brief iot_modbus_addr_rout_alloc_entry() - Alloc a rout entry from the mem pool.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								static iot_modbus_addr_rout_entry_t *iot_modbus_addr_rout_alloc_entry(
							 | 
						||
| 
								 | 
							
								    iot_modbus_addr_rout_table_t *table)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    return iot_mem_pool_alloc(table->entry_p);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @brief iot_modbus_addr_rout_table_free_entry() - Free a rout entry of the mem pool.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								static void iot_modbus_addr_rout_table_free_entry(
							 | 
						||
| 
								 | 
							
								    iot_modbus_addr_rout_table_t *table, iot_modbus_addr_rout_entry_t *entry)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    iot_mem_pool_free(table->entry_p, entry);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @brief iot_modbus_addr_rout_table_create() - Create a rout table.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								static iot_modbus_addr_rout_table_h iot_modbus_addr_rout_table_create(
							 | 
						||
| 
								 | 
							
								    module_id_t module, uint16_t entry_cnt, uint16_t entry_size)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t ret;
							 | 
						||
| 
								 | 
							
								    iot_modbus_addr_rout_table_t *table = NULL;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    table = os_mem_malloc(module, sizeof(*table));
							 | 
						||
| 
								 | 
							
								    if (table == NULL) {
							 | 
						||
| 
								 | 
							
								        goto out;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ret = iot_mem_pool_new(module, entry_cnt,
							 | 
						||
| 
								 | 
							
								        entry_size, &table->entry_p, 1);
							 | 
						||
| 
								 | 
							
								    if (ret)
							 | 
						||
| 
								 | 
							
								        goto err_table;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    table->entry_cnt = entry_cnt;
							 | 
						||
| 
								 | 
							
								    table->entry_size = entry_size;
							 | 
						||
| 
								 | 
							
								    goto out;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								err_table:
							 | 
						||
| 
								 | 
							
								    os_mem_free(table);
							 | 
						||
| 
								 | 
							
								    table = NULL;
							 | 
						||
| 
								 | 
							
								out:
							 | 
						||
| 
								 | 
							
								    return table;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @brief iot_modbus_addr_rout_table_clean() - Clean the modbus rout table.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								void iot_modbus_addr_rout_table_clean(iot_modbus_addr_rout_table_h handle)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    iot_modbus_addr_rout_table_t *table = handle;
							 | 
						||
| 
								 | 
							
								    iot_modbus_addr_rout_entry_t *entry = table->rout_ent;
							 | 
						||
| 
								 | 
							
								    iot_modbus_addr_rout_entry_t *tmp = NULL;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    while (entry) {
							 | 
						||
| 
								 | 
							
								        tmp = entry;
							 | 
						||
| 
								 | 
							
								        iot_mem_pool_free(table->entry_p, tmp);
							 | 
						||
| 
								 | 
							
								        entry = entry->next;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @brief iot_modbus_addr_rout_table_find() - Find the rout entry by device id.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								static iot_modbus_addr_rout_entry_t *iot_modbus_addr_rout_table_find(
							 | 
						||
| 
								 | 
							
								    iot_modbus_addr_rout_table_h handle, uint8_t slave_addr)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    iot_modbus_addr_rout_table_t *table = handle;
							 | 
						||
| 
								 | 
							
								    iot_modbus_addr_rout_entry_t *entry = NULL;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    entry = table->rout_ent;
							 | 
						||
| 
								 | 
							
								    while (entry) {
							 | 
						||
| 
								 | 
							
								        if (entry->slaver_addr == slave_addr) {
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        entry = entry->next;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return entry;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @brief iot_modbus_addr_rout_table_find_replaced() - Find the smallest ttl
							 | 
						||
| 
								 | 
							
								 *                                   entry and return to replace it.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								static iot_modbus_addr_rout_entry_t *iot_modbus_addr_rout_table_find_replaced(
							 | 
						||
| 
								 | 
							
								    iot_modbus_addr_rout_table_h handle)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    iot_modbus_addr_rout_table_t *table = handle;
							 | 
						||
| 
								 | 
							
								    iot_modbus_addr_rout_entry_t *entry , *tmp;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    entry = table->rout_ent;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (entry == NULL) {
							 | 
						||
| 
								 | 
							
								        goto out;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    tmp = entry->next;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    while (tmp) {
							 | 
						||
| 
								 | 
							
								        if (entry->ent_ttl > tmp->ent_ttl) {
							 | 
						||
| 
								 | 
							
								            entry = tmp;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        tmp = tmp->next;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								out:
							 | 
						||
| 
								 | 
							
								    return entry;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @brief iot_modbus_add_addr_rt() - Add the MAC address and the corresponding
							 | 
						||
| 
								 | 
							
								 *                                   device id to the routing table .
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								static uint8_t iot_modbus_add_addr_rt(iot_modbus_addr_rout_table_h rt_table,
							 | 
						||
| 
								 | 
							
								    uint8_t *dst_addr, uint8_t slave_addr)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    iot_modbus_addr_rout_entry_t *entry;
							 | 
						||
| 
								 | 
							
								    iot_modbus_addr_rout_table_t *table = rt_table;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    entry = (iot_modbus_addr_rout_entry_t *)iot_modbus_addr_rout_table_find(
							 | 
						||
| 
								 | 
							
								        rt_table, slave_addr);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (entry) {
							 | 
						||
| 
								 | 
							
								        entry->ent_ttl = IOT_MODBUS_MAC_RT_ENTRY_TTL;
							 | 
						||
| 
								 | 
							
								        if(!iot_mac_addr_cmp(dst_addr, entry->addr)) {
							 | 
						||
| 
								 | 
							
								                iot_mac_addr_cpy(entry->addr, dst_addr);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        goto out;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* entry not exist, try to add it */
							 | 
						||
| 
								 | 
							
								    entry = (iot_modbus_addr_rout_entry_t *)iot_modbus_addr_rout_alloc_entry(
							 | 
						||
| 
								 | 
							
								        rt_table);
							 | 
						||
| 
								 | 
							
								    if (entry == NULL) {
							 | 
						||
| 
								 | 
							
								        /* force get the entry that it's ttl is the smallest */
							 | 
						||
| 
								 | 
							
								        entry = iot_modbus_addr_rout_table_find_replaced(rt_table);
							 | 
						||
| 
								 | 
							
								        if (entry == NULL) {
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            entry->slaver_addr = slave_addr;
							 | 
						||
| 
								 | 
							
								            iot_mac_addr_cpy(entry->addr, dst_addr);
							 | 
						||
| 
								 | 
							
								            entry->ent_ttl = IOT_MODBUS_MAC_RT_ENTRY_TTL;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        goto out;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    entry->slaver_addr = slave_addr;
							 | 
						||
| 
								 | 
							
								    iot_mac_addr_cpy(entry->addr, dst_addr);
							 | 
						||
| 
								 | 
							
								    entry->ent_ttl = IOT_MODBUS_MAC_RT_ENTRY_TTL;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    entry->next = table->rout_ent;
							 | 
						||
| 
								 | 
							
								    table->rout_ent = entry;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    iot_printf("[%s][info] update rt table successfully!\n", __FUNCTION__);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								out:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return ERR_OK;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @brief iot_modbus_update_addr_rt() - Update route table every 20 seconds .
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								static void iot_modbus_update_addr_rt(iot_modbus_addr_rout_table_h rt_table)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    iot_modbus_addr_rout_table_t *table = (iot_modbus_addr_rout_table_t *)rt_table;
							 | 
						||
| 
								 | 
							
								    iot_modbus_addr_rout_entry_t *tmp, *entry = table->rout_ent;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (entry == NULL) {
							 | 
						||
| 
								 | 
							
								        return;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    tmp = entry->next;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    while(tmp) {
							 | 
						||
| 
								 | 
							
								        if (tmp->ent_ttl <= 0) {
							 | 
						||
| 
								 | 
							
								            entry->next = tmp->next;
							 | 
						||
| 
								 | 
							
								            iot_modbus_addr_rout_table_free_entry(table, tmp);
							 | 
						||
| 
								 | 
							
								            tmp = entry->next;
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            tmp->ent_ttl -= IOT_MODBUS_MAC_RT_UPDATE_INTERVAL;
							 | 
						||
| 
								 | 
							
								            entry = entry->next;
							 | 
						||
| 
								 | 
							
								            tmp = entry->next;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    entry = table->rout_ent;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (entry) {
							 | 
						||
| 
								 | 
							
								        if (entry->ent_ttl <= 0) {
							 | 
						||
| 
								 | 
							
								            table->rout_ent = entry->next;
							 | 
						||
| 
								 | 
							
								            iot_modbus_addr_rout_table_free_entry(table, entry);
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            entry->ent_ttl -= IOT_MODBUS_MAC_RT_UPDATE_INTERVAL;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @brief iot_modbus_get_addr_rt() - Get the MAC address by looking up the
							 | 
						||
| 
								 | 
							
								 *                                   routing table with the device id.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								static uint8_t iot_modbus_get_addr_rt(iot_modbus_addr_rout_table_h rt_table,
							 | 
						||
| 
								 | 
							
								    uint8_t slave_addr, uint8_t *dst_addr)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    iot_modbus_addr_rout_entry_t *entry;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (dst_addr == NULL) {
							 | 
						||
| 
								 | 
							
								        return ERR_FAIL;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    entry = (iot_modbus_addr_rout_entry_t *)iot_modbus_addr_rout_table_find(
							 | 
						||
| 
								 | 
							
								        rt_table, slave_addr);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (entry) {
							 | 
						||
| 
								 | 
							
								        iot_mac_addr_cpy(dst_addr, entry->addr);
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        return ERR_FAIL;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    iot_printf("[%s][info] get rt entry successfully!\n", __FUNCTION__);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return ERR_OK;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static uint8_t iot_mb_task_get_slaver_addr(uint8_t *modbus_data)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    return modbus_data[0];
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void iot_mb_task_data_dump(uint8_t * buf, uint32_t len, uint32_t line)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								#if IOT_MODBUS_TASK_DATA_DUMP
							 | 
						||
| 
								 | 
							
								    uint32_t i;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    iot_cus_printf("[mb_task]DUMP(%03d)@line:%d", len, line);
							 | 
						||
| 
								 | 
							
								    for (i = 0; i < len; i++) {
							 | 
						||
| 
								 | 
							
								        iot_cus_printf(" %02X", buf[i]);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    iot_cus_printf("\n");
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @brief iot_mb_task_msg_post_to_uart() - send data to uart port.
							 | 
						||
| 
								 | 
							
								 * @param p_pkt_frame: pointer of pkt frame data buffer.
							 | 
						||
| 
								 | 
							
								 * @return ERR_OK
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								uint32_t iot_mb_task_msg_post_to_uart(iot_uart_h uart_h, iot_pkt_t *p_pkt_frame)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t ret;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ret = iot_uart_send(uart_h, p_pkt_frame, NULL);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return (ERR_OK == ret) ? ERR_OK : ERR_FAIL;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static uint32_t iot_mb_task_msg_msg_from_ge(iot_pkt_t *p_pkt_frame)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ge_frame_data_send_set_subfn160_t *p_subfn160;
							 | 
						||
| 
								 | 
							
								    ge_fn160_appdata_mb_t *p_fn160_appdata; /* modbus proto in ge fn160 */
							 | 
						||
| 
								 | 
							
								    uint32_t fn160_applen;                  /* fn160 append data len */
							 | 
						||
| 
								 | 
							
								    iot_pkt_t *p_mb_pkt;        /* pkt for task message post to uart */
							 | 
						||
| 
								 | 
							
								    uint32_t mb_len;            /* current ge modbus frame length */
							 | 
						||
| 
								 | 
							
								    static uint8_t frame_idx_count; /* check current frame index order */
							 | 
						||
| 
								 | 
							
								    uint8_t slaver_addr = 0;
							 | 
						||
| 
								 | 
							
								    uint8_t src_mac[IOT_MAC_ADDR_LEN] = {0};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (p_pkt_frame == NULL) {
							 | 
						||
| 
								 | 
							
								        goto out;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    iot_cus_printf("[mb_task]frame receive from GE.\n");
							 | 
						||
| 
								 | 
							
								    iot_mb_task_data_dump(iot_pkt_data(p_pkt_frame),
							 | 
						||
| 
								 | 
							
								        iot_pkt_data_len(p_pkt_frame), __LINE__);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    p_subfn160 = (ge_frame_data_send_set_subfn160_t*)iot_pkt_data(p_pkt_frame);
							 | 
						||
| 
								 | 
							
								    if (p_subfn160->hdr.hdr.fn == PROTO_GE_PLC_SET_CMD
							 | 
						||
| 
								 | 
							
								        && p_subfn160->hdr.subfn == PROTO_GE_DATA_CMD) {
							 | 
						||
| 
								 | 
							
								        /* subfn160 appdata */
							 | 
						||
| 
								 | 
							
								        p_fn160_appdata = (ge_fn160_appdata_mb_t *)p_subfn160->data;
							 | 
						||
| 
								 | 
							
								        fn160_applen = p_subfn160->hdr.hdr.data_len - IOT_MAC_ADDR_LEN;
							 | 
						||
| 
								 | 
							
								        if (p_fn160_appdata->type == IOT_FN160_TYPE_MODBUS) {
							 | 
						||
| 
								 | 
							
								            iot_mac_addr_cpy(src_mac, p_fn160_appdata->src_mac);
							 | 
						||
| 
								 | 
							
								#if PLC_SUPPORT_STA_ROLE
							 | 
						||
| 
								 | 
							
								            /* save cco mac addr */
							 | 
						||
| 
								 | 
							
								            iot_mac_addr_cpy(mb_task.dest_cco_mac, p_fn160_appdata->src_mac);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								            /* first frame need reset ge buff len and frame index check count */
							 | 
						||
| 
								 | 
							
								            if (p_fn160_appdata->frame_idx == 0) {
							 | 
						||
| 
								 | 
							
								                mb_task.ge_mb_len = 0;
							 | 
						||
| 
								 | 
							
								                frame_idx_count = 0;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            /* Is the current frame index order correct?  */
							 | 
						||
| 
								 | 
							
								            if  (frame_idx_count != p_fn160_appdata->frame_idx) {
							 | 
						||
| 
								 | 
							
								                iot_cus_printf("[mb_task][err] ge frame index error\n");
							 | 
						||
| 
								 | 
							
								                frame_idx_count = 0;
							 | 
						||
| 
								 | 
							
								                iot_pkt_free(p_pkt_frame);
							 | 
						||
| 
								 | 
							
								                return ERR_FAIL;
							 | 
						||
| 
								 | 
							
								            } else {
							 | 
						||
| 
								 | 
							
								                frame_idx_count++;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            /* remove other append data, get modbus data length */
							 | 
						||
| 
								 | 
							
								            mb_len = fn160_applen - sizeof(ge_fn160_appdata_mb_t);
							 | 
						||
| 
								 | 
							
								            /* remain ge buffer size >= current modbus frame size. */
							 | 
						||
| 
								 | 
							
								            if (mb_len <= sizeof(mb_task.ge_mb_buf) - mb_task.ge_mb_len) {
							 | 
						||
| 
								 | 
							
								                /* copy current modbus data to ge buff offset index */
							 | 
						||
| 
								 | 
							
								                os_mem_cpy(mb_task.ge_mb_buf + mb_task.ge_mb_len ,
							 | 
						||
| 
								 | 
							
								                    p_fn160_appdata->data, mb_len);
							 | 
						||
| 
								 | 
							
								                mb_task.ge_mb_len += mb_len;
							 | 
						||
| 
								 | 
							
								            } else {
							 | 
						||
| 
								 | 
							
								                iot_cus_printf("[mb_task][warning] ge modbus data overflow, dropped!!!\n");
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            iot_pkt_free(p_pkt_frame);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            /* last modbus frame, malloc pkt, then send modbus pkt to uart. */
							 | 
						||
| 
								 | 
							
								            if (p_fn160_appdata->frame_idx == p_fn160_appdata->frame_total - 1) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                if (mb_task.ge_mb_len) {
							 | 
						||
| 
								 | 
							
								                    p_mb_pkt = iot_pkt_alloc(mb_task.ge_mb_len, IOT_MODBUS_TASK_ID);
							 | 
						||
| 
								 | 
							
								                    if (NULL == p_mb_pkt) {
							 | 
						||
| 
								 | 
							
								                        iot_cus_printf("[mb_task][err]no mem@line %d\n", __LINE__);
							 | 
						||
| 
								 | 
							
								                        IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								                        return ERR_FAIL;
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                    os_mem_cpy(iot_pkt_put(p_mb_pkt, mb_task.ge_mb_len),
							 | 
						||
| 
								 | 
							
								                        mb_task.ge_mb_buf, mb_task.ge_mb_len);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                    slaver_addr = iot_mb_task_get_slaver_addr(mb_task.ge_mb_buf);
							 | 
						||
| 
								 | 
							
								#if IOT_MODBUS_RT_TABLE_SUPPORT
							 | 
						||
| 
								 | 
							
								                    if (slaver_addr != IOT_MODBUS_BROADCAST_ADDR) {
							 | 
						||
| 
								 | 
							
								                        /* add rt entry */
							 | 
						||
| 
								 | 
							
								                        iot_modbus_add_addr_rt(mb_task.rt_table, src_mac, slaver_addr);
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                    if ((slaver_addr == mb_task.slave_addr) ||
							 | 
						||
| 
								 | 
							
								                        (IOT_MODBUS_BROADCAST_ADDR == slaver_addr)) {
							 | 
						||
| 
								 | 
							
								                        iot_mb_ext_cmd_handler(mb_task.ge_mb_buf, mb_task.ge_mb_len,
							 | 
						||
| 
								 | 
							
								                            MODBUS_CMD_FROM_PLC);
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                    mb_task.ge_mb_len = 0;
							 | 
						||
| 
								 | 
							
								                    frame_idx_count = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                    if ((slaver_addr != mb_task.slave_addr) ||
							 | 
						||
| 
								 | 
							
								                        (IOT_MODBUS_BROADCAST_ADDR == slaver_addr)) {
							 | 
						||
| 
								 | 
							
								                        iot_mb_task_msg_post_to_uart(mb_task.uart_h, p_mb_pkt);
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            goto out;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        goto ge2uart;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (ERR_OK == iot_mb_ext_handle_resp_from_ge(p_pkt_frame)) {
							 | 
						||
| 
								 | 
							
								        iot_pkt_free(p_pkt_frame);
							 | 
						||
| 
								 | 
							
								        goto out;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								ge2uart:
							 | 
						||
| 
								 | 
							
								    iot_mb_task_msg_post_to_uart(mb_task.uart_h, p_pkt_frame);
							 | 
						||
| 
								 | 
							
								out:
							 | 
						||
| 
								 | 
							
								    return ERR_OK;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @brief iot_mb_task_post_uart_cmd() - recveived command from uart, send to
							 | 
						||
| 
								 | 
							
								 *                                       common proto
							 | 
						||
| 
								 | 
							
								 * @param data: command data.
							 | 
						||
| 
								 | 
							
								 * @param len : command data length.
							 | 
						||
| 
								 | 
							
								 * @return    : ERR_OK   - send successfully.
							 | 
						||
| 
								 | 
							
								 *              ERR_FAIL - send failed.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								uint8_t iot_mb_task_post_uart_cmd(uint8_t * data, uint16_t len, uint32_t param)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    (void)param;
							 | 
						||
| 
								 | 
							
								    iot_pkt_t* send_pkt;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    iot_cus_printf("[%s][info] data:%p, len:%d\n", __FUNCTION__, data, len);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    send_pkt = iot_pkt_alloc(len, IOT_MODBUS_TASK_ID);
							 | 
						||
| 
								 | 
							
								    if (send_pkt) {
							 | 
						||
| 
								 | 
							
								        /* copy data from buf to data packet */
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(iot_pkt_put(send_pkt, len), data, len);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        /* alloc message to insert proto task msg queue */
							 | 
						||
| 
								 | 
							
								        iot_mb_task_msg_post(IOT_MODBUS_TASK_MT_UART,
							 | 
						||
| 
								 | 
							
								              IOT_MODBUS_TASK_MSG_ID_CMD_HANDLE, send_pkt);
							 | 
						||
| 
								 | 
							
								        return ERR_OK;
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        iot_cus_printf("[mb_task][err]no mem@line %d\n", __LINE__);
							 | 
						||
| 
								 | 
							
								        IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								        return ERR_FAIL;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* Compute the MODBUS RTU CRC. */
							 | 
						||
| 
								 | 
							
								uint16_t iot_modbus_rtu_crc16(uint8_t *buf, uint32_t len)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint16_t crc = 0xFFFF;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    for (uint32_t pos = 0; pos < len; pos++) {
							 | 
						||
| 
								 | 
							
								        crc ^= (uint16_t)buf[pos];        /* XOR byte into least sig. byte of crc */
							 | 
						||
| 
								 | 
							
								        for (uint8_t i = 8; i != 0; i--) {/* Loop over each bit */
							 | 
						||
| 
								 | 
							
								            if ((crc & 0x0001) != 0) {    /* If the LSB is set */
							 | 
						||
| 
								 | 
							
								                crc >>= 1;                /* Shift right and XOR 0xA001 */
							 | 
						||
| 
								 | 
							
								                crc ^= 0xA001;
							 | 
						||
| 
								 | 
							
								            } else {                      /* Else LSB is not set */
							 | 
						||
| 
								 | 
							
								                crc >>= 1;                /* Just shift right */
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    /* Note, this number has low and high bytes swapped,
							 | 
						||
| 
								 | 
							
								    so use it accordingly (or swap bytes) */
							 | 
						||
| 
								 | 
							
								    return crc;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								iot_pkt_t *iot_modbus_fn160_appdata_pack(uint8_t *mb_data, uint32_t mb_len,
							 | 
						||
| 
								 | 
							
								    uint32_t curr_idx, uint32_t total_idx)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ge_frame_data_send_set_subfn160_t *p_subfn160;
							 | 
						||
| 
								 | 
							
								    ge_fn160_appdata_mb_t *p_fn160_appdata;
							 | 
						||
| 
								 | 
							
								    uint32_t appdata_len = sizeof(ge_fn160_appdata_mb_t) + mb_len;
							 | 
						||
| 
								 | 
							
								    /* subfn160 header + appdata + crc16(2 bytes) + proto end frame(1 bytes) */
							 | 
						||
| 
								 | 
							
								    uint32_t alloc_len = sizeof(ge_frame_data_send_set_subfn160_t) + appdata_len
							 | 
						||
| 
								 | 
							
								        + 2 + 1;
							 | 
						||
| 
								 | 
							
								    uint16_t crc16;
							 | 
						||
| 
								 | 
							
								    iot_pkt_t* p_ge_pkt;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    p_ge_pkt = iot_pkt_alloc(alloc_len, IOT_MODBUS_TASK_ID);
							 | 
						||
| 
								 | 
							
								    if (NULL == p_ge_pkt) {
							 | 
						||
| 
								 | 
							
								        iot_cus_printf("[mb_task][err]no mem@line %d\n", __LINE__);
							 | 
						||
| 
								 | 
							
								        IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								        return NULL;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    p_subfn160 = (ge_frame_data_send_set_subfn160_t*)iot_pkt_put(p_ge_pkt, alloc_len);
							 | 
						||
| 
								 | 
							
								    /* fix header */
							 | 
						||
| 
								 | 
							
								    p_subfn160->hdr.hdr.preamble = GE_FRM_PREAMBLE_CODE;
							 | 
						||
| 
								 | 
							
								    p_subfn160->hdr.hdr.fn = PROTO_GE_PLC_SET_CMD;
							 | 
						||
| 
								 | 
							
								    p_subfn160->hdr.hdr.data_len = appdata_len + IOT_MAC_ADDR_LEN;
							 | 
						||
| 
								 | 
							
								    p_subfn160->hdr.subfn = PROTO_GE_DATA_CMD;
							 | 
						||
| 
								 | 
							
								    /* resv 2 bytes */
							 | 
						||
| 
								 | 
							
								    p_subfn160->force_tx_connless = 0;
							 | 
						||
| 
								 | 
							
								    p_subfn160->force_noaggr = 1;
							 | 
						||
| 
								 | 
							
								    p_subfn160->recv_connless = 0;
							 | 
						||
| 
								 | 
							
								    p_subfn160->data_type = 0;
							 | 
						||
| 
								 | 
							
								    /* payload */
							 | 
						||
| 
								 | 
							
								#if PLC_SUPPORT_STA_ROLE
							 | 
						||
| 
								 | 
							
								    iot_mac_addr_cpy(p_subfn160->dest_mac, mb_task.dest_cco_mac);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								#if IOT_MODBUS_RT_TABLE_SUPPORT
							 | 
						||
| 
								 | 
							
								    uint8_t dest_mac[IOT_MAC_ADDR_LEN];
							 | 
						||
| 
								 | 
							
								    uint8_t slave_addr = iot_mb_task_get_slaver_addr(mb_data);
							 | 
						||
| 
								 | 
							
								    if (ERR_OK != iot_modbus_get_addr_rt(mb_task.rt_table, slave_addr, dest_mac)) {
							 | 
						||
| 
								 | 
							
								        os_mem_set(p_subfn160->dest_mac, 0xff, IOT_MAC_ADDR_LEN);
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        iot_mac_addr_cpy(p_subfn160->dest_mac, dest_mac);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* subfn160 appdata */
							 | 
						||
| 
								 | 
							
								    p_fn160_appdata = (ge_fn160_appdata_mb_t *)p_subfn160->data;
							 | 
						||
| 
								 | 
							
								    p_fn160_appdata->type = IOT_FN160_TYPE_MODBUS; /* modbus proto */
							 | 
						||
| 
								 | 
							
								    iot_mac_addr_cpy(p_fn160_appdata->src_mac, mb_task.local_mac);
							 | 
						||
| 
								 | 
							
								    p_fn160_appdata->frame_idx = curr_idx;
							 | 
						||
| 
								 | 
							
								    p_fn160_appdata->frame_total = total_idx;
							 | 
						||
| 
								 | 
							
								    /* modbus raw data */
							 | 
						||
| 
								 | 
							
								    os_mem_cpy(p_fn160_appdata->data, mb_data, mb_len);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    crc16 = ge_frm_checksum_calc((uint8_t *)p_subfn160, alloc_len - 3);
							 | 
						||
| 
								 | 
							
								    *((uint8_t*)p_subfn160 + alloc_len - 3) = crc16 & 0xff;
							 | 
						||
| 
								 | 
							
								    *((uint8_t*)p_subfn160 + alloc_len - 2) = (crc16 >> 8) & 0xff;
							 | 
						||
| 
								 | 
							
								    *((uint8_t*)p_subfn160 + alloc_len - 1) = GE_FRM_TAIL_CODE;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return p_ge_pkt;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static uint8_t iot_modbus_data_check(uint8_t *p_buffer, uint32_t buffer_len)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    iot_pkt_t *p_pkt;
							 | 
						||
| 
								 | 
							
								    uint32_t buf_index;
							 | 
						||
| 
								 | 
							
								    uint32_t buf_offset;
							 | 
						||
| 
								 | 
							
								    uint32_t buf_len;
							 | 
						||
| 
								 | 
							
								    uint32_t curr_idx;
							 | 
						||
| 
								 | 
							
								    uint32_t total_idx;
							 | 
						||
| 
								 | 
							
								    uint32_t lookup_fc_idx; //look up func code index
							 | 
						||
| 
								 | 
							
								    uint32_t mb_total_len;
							 | 
						||
| 
								 | 
							
								    uint16_t crc16;
							 | 
						||
| 
								 | 
							
								    uint8_t have_modbus_frame = 0, slaver_addr = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    for (buf_index = 0; (buffer_len >= 5) && (buf_index <= buffer_len - 5); ) {
							 | 
						||
| 
								 | 
							
								        uint8_t *p_buf_index = p_buffer + buf_index;
							 | 
						||
| 
								 | 
							
								        iot_cus_printf("index=%d\r\n", buf_index);
							 | 
						||
| 
								 | 
							
								        /* lookup function code index */
							 | 
						||
| 
								 | 
							
								        for (lookup_fc_idx = 0; lookup_fc_idx < max_func_code_num; lookup_fc_idx++) {
							 | 
						||
| 
								 | 
							
								            if (mb_check[lookup_fc_idx].func_code == p_buf_index[1] ||
							 | 
						||
| 
								 | 
							
								                (mb_check[lookup_fc_idx].func_code | 0x80) == p_buf_index[1]) {
							 | 
						||
| 
								 | 
							
								                iot_cus_printf("func_code=%d\r\n", p_buf_index[1]);
							 | 
						||
| 
								 | 
							
								                break;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        /* can not find valid func code */
							 | 
						||
| 
								 | 
							
								        if (lookup_fc_idx == max_func_code_num) {
							 | 
						||
| 
								 | 
							
								            buf_index++;
							 | 
						||
| 
								 | 
							
								            continue;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        /* from func code get modbus total len, then checkout modbus crc16 */
							 | 
						||
| 
								 | 
							
								        if ((p_buf_index[1] & 0x80) == 0) { /* normal function code */
							 | 
						||
| 
								 | 
							
								            mb_total_len = mb_check[lookup_fc_idx].min_len +
							 | 
						||
| 
								 | 
							
								                (mb_check[lookup_fc_idx].not_fix_len ?
							 | 
						||
| 
								 | 
							
								                    p_buf_index[mb_check[lookup_fc_idx].byte_count_idx] : 0);
							 | 
						||
| 
								 | 
							
								        } else { /* error function code */
							 | 
						||
| 
								 | 
							
								            mb_total_len = 5;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        iot_cus_printf("mb_total_len=%d, buffer_len-index=%d\r\n",
							 | 
						||
| 
								 | 
							
								            mb_total_len,  (buffer_len - buf_index));
							 | 
						||
| 
								 | 
							
								        /* modbus lenth <= remain buffer lenth. */
							 | 
						||
| 
								 | 
							
								        if (mb_total_len > buffer_len - buf_index) {
							 | 
						||
| 
								 | 
							
								            buf_index++;
							 | 
						||
| 
								 | 
							
								            continue;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        /* check modbus crc */
							 | 
						||
| 
								 | 
							
								        crc16 = iot_modbus_rtu_crc16(p_buf_index, mb_total_len - 2);
							 | 
						||
| 
								 | 
							
								        if (crc16 !=
							 | 
						||
| 
								 | 
							
								            (((uint16_t)p_buf_index[mb_total_len-1]<<8) | p_buf_index[mb_total_len-2])) {
							 | 
						||
| 
								 | 
							
								            buf_index++;
							 | 
						||
| 
								 | 
							
								            continue;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        iot_cus_printf("uart----------------------modbus\r\n");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        slaver_addr = iot_mb_task_get_slaver_addr(p_buf_index);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if ((slaver_addr != mb_task.slave_addr) ||
							 | 
						||
| 
								 | 
							
								            (IOT_MODBUS_BROADCAST_ADDR == slaver_addr)) {
							 | 
						||
| 
								 | 
							
								            total_idx = (mb_total_len /
							 | 
						||
| 
								 | 
							
								                (IOT_GE_FE_A0_DATA_LEN_MAX - sizeof(ge_fn160_appdata_mb_t))) + 1;
							 | 
						||
| 
								 | 
							
								            /* front frame */
							 | 
						||
| 
								 | 
							
								            for (curr_idx = 0; curr_idx < total_idx - 1; curr_idx++) {
							 | 
						||
| 
								 | 
							
								                buf_offset = (IOT_GE_FE_A0_DATA_LEN_MAX -
							 | 
						||
| 
								 | 
							
								                    sizeof(ge_fn160_appdata_mb_t)) * curr_idx;
							 | 
						||
| 
								 | 
							
								                buf_len = IOT_GE_FE_A0_DATA_LEN_MAX - sizeof(ge_fn160_appdata_mb_t);
							 | 
						||
| 
								 | 
							
								                p_pkt = iot_modbus_fn160_appdata_pack(p_buf_index + buf_offset,
							 | 
						||
| 
								 | 
							
								                    buf_len, curr_idx, total_idx);
							 | 
						||
| 
								 | 
							
								                if (NULL == p_pkt) {
							 | 
						||
| 
								 | 
							
								                    iot_cus_printf("[mb_task][err]no mem@line %d\n", __LINE__);
							 | 
						||
| 
								 | 
							
								                    IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								                    return -1;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                iot_mb_task_data_dump(iot_pkt_data(p_pkt), iot_pkt_data_len(p_pkt), __LINE__);
							 | 
						||
| 
								 | 
							
								                /* 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);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            /* last frame */
							 | 
						||
| 
								 | 
							
								            buf_offset = (IOT_GE_FE_A0_DATA_LEN_MAX -
							 | 
						||
| 
								 | 
							
								                sizeof(ge_fn160_appdata_mb_t)) * curr_idx;
							 | 
						||
| 
								 | 
							
								            buf_len = mb_total_len % (IOT_GE_FE_A0_DATA_LEN_MAX -
							 | 
						||
| 
								 | 
							
								                sizeof(ge_fn160_appdata_mb_t));
							 | 
						||
| 
								 | 
							
								            p_pkt = iot_modbus_fn160_appdata_pack(p_buf_index + buf_offset, buf_len,
							 | 
						||
| 
								 | 
							
								                curr_idx, total_idx);
							 | 
						||
| 
								 | 
							
								            if (NULL == p_pkt) {
							 | 
						||
| 
								 | 
							
								                iot_cus_printf("[mb_task][err]no mem@line %d\n", __LINE__);
							 | 
						||
| 
								 | 
							
								                IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								                return -1;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            iot_mb_task_data_dump(iot_pkt_data(p_pkt), iot_pkt_data_len(p_pkt), __LINE__);
							 | 
						||
| 
								 | 
							
								            /* 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);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if ((slaver_addr == mb_task.slave_addr) ||
							 | 
						||
| 
								 | 
							
								            (IOT_MODBUS_BROADCAST_ADDR == slaver_addr)) {
							 | 
						||
| 
								 | 
							
								            iot_mb_ext_cmd_handler(p_buf_index, mb_total_len, MODBUS_CMD_FROM_UART);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        buf_index += mb_total_len;
							 | 
						||
| 
								 | 
							
								        have_modbus_frame = 1;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return have_modbus_frame;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @brief iot_mb_task_uart_msg_process() - process the data from uart.
							 | 
						||
| 
								 | 
							
								 * @param p_modbus_msg: message received from uart. msg->data will be
							 | 
						||
| 
								 | 
							
								 *   freed by this handle but msg will not.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								static void iot_mb_task_uart_msg_process(iot_mb_task_msg_t *msg)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    iot_pkt_t * p_pkt = (iot_pkt_t*)msg->data;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    switch (msg->task_msg.id) {
							 | 
						||
| 
								 | 
							
								        case IOT_MODBUS_TASK_MSG_ID_CMD_HANDLE:
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            /* trans to GE command */
							 | 
						||
| 
								 | 
							
								            iot_cus_task_message_to_ge(iot_pkt_data(p_pkt),
							 | 
						||
| 
								 | 
							
								                iot_pkt_data_len(p_pkt));
							 | 
						||
| 
								 | 
							
								            iot_pkt_free(p_pkt);
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        default:
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            iot_cus_printf("[mb_task]unknown uart message id #%d.\n",
							 | 
						||
| 
								 | 
							
								                msg->task_msg.id);
							 | 
						||
| 
								 | 
							
								            IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @brief iot_mb_task_timer_msg_process() - process data from local timer.
							 | 
						||
| 
								 | 
							
								 * @msg : message.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								static void iot_mb_task_timer_msg_process(iot_mb_task_msg_t *msg)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    switch (msg->task_msg.id) {
							 | 
						||
| 
								 | 
							
								        case IOT_MODBUS_TASK_MSG_ID_TMR_GE_START_MONITOR:
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            if (iot_grapp_init_success()) {
							 | 
						||
| 
								 | 
							
								                iot_grapp_reg_fn_receive_from_ge(HOST_PORT_CUSTOM_TASK,
							 | 
						||
| 
								 | 
							
								                    iot_mb_task_msg_msg_from_ge);
							 | 
						||
| 
								 | 
							
								                iot_grapp_set_uart_config(mb_task.uart_h);
							 | 
						||
| 
								 | 
							
								                os_stop_timer(mb_task.ge_start_timer);
							 | 
						||
| 
								 | 
							
								                /* update local mac addr. */
							 | 
						||
| 
								 | 
							
								                iot_mac_addr_cpy(mb_task.local_mac, prototask_contxt.local_dev.mac);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        case IOT_MODBUS_TASK_MSG_ID_TMR_UART_MB_TIMEOUT:
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            if (mb_task.uart_mb_len > 0) {
							 | 
						||
| 
								 | 
							
								                /* if not have modbus frame, then send data use ge proto. */
							 | 
						||
| 
								 | 
							
								                if (iot_modbus_data_check(mb_task.uart_mb_buf,
							 | 
						||
| 
								 | 
							
								                    mb_task.uart_mb_len) == 0) {
							 | 
						||
| 
								 | 
							
								                    iot_cus_printf("uart----------------------ge\r\n");
							 | 
						||
| 
								 | 
							
								                    /* parser ge command and post to task */
							 | 
						||
| 
								 | 
							
								                    iot_proto_data_parse_and_post(mb_task.uart_mb_buf,
							 | 
						||
| 
								 | 
							
								                        mb_task.uart_mb_len, iot_mb_task_post_uart_cmd, 0);
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                mb_task.uart_mb_len = 0;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								#if IOT_MODBUS_RT_TABLE_SUPPORT
							 | 
						||
| 
								 | 
							
								        case IOT_MODBUS_TASK_MSG_ID_TMR_RT_UPDATE_TIMEOUT:
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            iot_modbus_update_addr_rt(mb_task.rt_table);
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								        case IOT_MODBUS_MSG_ID_TMR_MB_EXT_RESP_TIMEOUT:
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            iot_mb_ext_resp_cmd_timeout_or_failed();
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        default:
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            iot_cus_printf("[mb_task]unknown timer message id #%d.\n",
							 | 
						||
| 
								 | 
							
								                msg->task_msg.id);
							 | 
						||
| 
								 | 
							
								            IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @brief iot_mb_task_internal_msg_process() - process the data from modbus-task.
							 | 
						||
| 
								 | 
							
								 * @param msg: message received from modbus-task. msg->data
							 | 
						||
| 
								 | 
							
								 *   will be freed by this handle but msg will not.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								static void iot_mb_task_internal_msg_process(iot_mb_task_msg_t *msg)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    iot_pkt_t * p_pkt = (iot_pkt_t*)msg->data;
							 | 
						||
| 
								 | 
							
								    uint8_t *p_data = NULL;
							 | 
						||
| 
								 | 
							
								    uint32_t data_len = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    switch (msg->task_msg.id) {
							 | 
						||
| 
								 | 
							
								        case IOT_MODBUS_TASK_MSG_ID_CMD_HANDLE:
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            p_data = iot_pkt_data(p_pkt);
							 | 
						||
| 
								 | 
							
								            data_len = iot_pkt_data_len(p_pkt);
							 | 
						||
| 
								 | 
							
								            iot_cus_printf("uart buf index=%d\n", mb_task.uart_mb_len);
							 | 
						||
| 
								 | 
							
								            /* save all uart data to uart recv buff, if timer timeout, task begin to
							 | 
						||
| 
								 | 
							
								            checkout modbus frame. */
							 | 
						||
| 
								 | 
							
								            if (data_len <= sizeof(mb_task.uart_mb_buf) - mb_task.uart_mb_len) {
							 | 
						||
| 
								 | 
							
								                /* copy data to uart recv buffer. */
							 | 
						||
| 
								 | 
							
								                os_mem_cpy(mb_task.uart_mb_buf + mb_task.uart_mb_len, p_data, data_len);
							 | 
						||
| 
								 | 
							
								                mb_task.uart_mb_len += data_len;
							 | 
						||
| 
								 | 
							
								            } else {
							 | 
						||
| 
								 | 
							
								                iot_cus_printf("[mb_task][warning] uart modbus data overflow, dropped!!!\n");
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            iot_pkt_free(p_pkt);
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        default:
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @brief iot_mb_task_msg_exe_func() - messages handle function.
							 | 
						||
| 
								 | 
							
								 * @param task_h: handle of task.
							 | 
						||
| 
								 | 
							
								 * @param p_msg: message that will be processed.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								static void iot_mb_task_msg_exe_func(iot_task_h task_h, iot_task_msg_t *p_msg)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    iot_mb_task_msg_t *p_mb_msg = (iot_mb_task_msg_t *)p_msg;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    switch (p_mb_msg->task_msg.type)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        case IOT_MODBUS_TASK_MT_UART:
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            iot_mb_task_uart_msg_process(p_mb_msg);
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        case IOT_MODBUS_TASK_MT_TIMER:
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            iot_mb_task_timer_msg_process(p_mb_msg);
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        case IOT_MODBUS_TASK_MT_INTERNAL:
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            iot_mb_task_internal_msg_process(p_mb_msg);
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        default:
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            if (NULL != p_mb_msg->data) {
							 | 
						||
| 
								 | 
							
								                iot_pkt_free(p_mb_msg->data);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    iot_task_free_msg(task_h, p_msg);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @brief iot_mb_task_msg_cancel_func() - pull back messages that sent to this
							 | 
						||
| 
								 | 
							
								 *   task.
							 | 
						||
| 
								 | 
							
								 * @param task_h: handle of task.
							 | 
						||
| 
								 | 
							
								 * @param p_msg: message that will be pull back.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								static void iot_mb_task_msg_cancel_func(iot_task_h task_h, iot_task_msg_t *p_msg)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    iot_mb_task_msg_t *p_mb_msg = (iot_mb_task_msg_t *)p_msg;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    switch(p_mb_msg->task_msg.type)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        case IOT_MODBUS_TASK_MT_UART:
							 | 
						||
| 
								 | 
							
								        case IOT_MODBUS_TASK_MT_TIMER:
							 | 
						||
| 
								 | 
							
								        case IOT_MODBUS_TASK_MT_INTERNAL:
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            iot_pkt_free(p_mb_msg->data);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        default:
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    iot_task_free_msg(task_h, p_msg);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @brief iot_mb_task_uart_receive_func() - Uart driver callback function
							 | 
						||
| 
								 | 
							
								 *   when data received.
							 | 
						||
| 
								 | 
							
								 * @param buffer: pointer of data buffer.
							 | 
						||
| 
								 | 
							
								 * @param buffer_len: length of data received.
							 | 
						||
| 
								 | 
							
								 * @param is_full_frame: tell if this is a whole frame in this buffer.
							 | 
						||
| 
								 | 
							
								 * @param invalid_data_len: length of invalid data received. we ignore this.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								static void iot_mb_task_uart_receive_func(uint8_t* p_buffer, uint32_t buffer_len,
							 | 
						||
| 
								 | 
							
								    bool_t is_full_frame, uint32_t invalid_data_len)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    iot_pkt_t *p_pkt;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    iot_cus_printf("[mb_task] uart received, len:%d \n", buffer_len);
							 | 
						||
| 
								 | 
							
								    iot_mb_task_data_dump(p_buffer, buffer_len, __LINE__);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* timer to montor uart recv data timeout. */
							 | 
						||
| 
								 | 
							
								    if (0 == os_is_timer_active(mb_task.uart_timer)) {
							 | 
						||
| 
								 | 
							
								        iot_cus_printf("start timer\n");
							 | 
						||
| 
								 | 
							
								       os_start_timer(mb_task.uart_timer, IOT_MODBUS_TASK_UART_MB_TIMER_PERIOD);
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        iot_cus_printf("reset timer\n");
							 | 
						||
| 
								 | 
							
								        os_reset_timer(mb_task.uart_timer);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    p_pkt = iot_pkt_alloc(buffer_len, IOT_MODBUS_TASK_ID);
							 | 
						||
| 
								 | 
							
								    if (p_pkt) {
							 | 
						||
| 
								 | 
							
								        /* copy data from buf to data packet */
							 | 
						||
| 
								 | 
							
								        os_mem_cpy(iot_pkt_put(p_pkt, buffer_len), p_buffer, buffer_len);
							 | 
						||
| 
								 | 
							
								        /* alloc message to insert proto task msg queue */
							 | 
						||
| 
								 | 
							
								        iot_mb_task_msg_post(IOT_MODBUS_TASK_MT_INTERNAL,
							 | 
						||
| 
								 | 
							
								              IOT_MODBUS_TASK_MSG_ID_CMD_HANDLE, p_pkt);
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        iot_cus_printf("[mb_task][err]no mem@line %d\n", __LINE__);
							 | 
						||
| 
								 | 
							
								        IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void iot_mb_task_msg_post(uint16_t msg_type, uint16_t msg_id, iot_pkt_t *data)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    iot_task_msg_t *msg;
							 | 
						||
| 
								 | 
							
								    iot_mb_task_msg_t *task_msg;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    msg = iot_task_alloc_msg_with_reserved(mb_task.task, 0);
							 | 
						||
| 
								 | 
							
								    if (NULL == msg) {
							 | 
						||
| 
								 | 
							
								        if (NULL != data) {
							 | 
						||
| 
								 | 
							
								            iot_pkt_free(data);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        IOT_ASSERT(0);
							 | 
						||
| 
								 | 
							
								        return;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    task_msg = (iot_mb_task_msg_t*)msg;
							 | 
						||
| 
								 | 
							
								    task_msg->task_msg.type = msg_type;
							 | 
						||
| 
								 | 
							
								    task_msg->task_msg.id = msg_id;
							 | 
						||
| 
								 | 
							
								    task_msg->data = data;
							 | 
						||
| 
								 | 
							
								    task_msg->data2 = 0;
							 | 
						||
| 
								 | 
							
								    iot_task_queue_msg(mb_task.task, &task_msg->task_msg, 0);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @brief iot_mb_task_ge_start_timer_exe() - timer timeout callback function.
							 | 
						||
| 
								 | 
							
								 * @timer_id : timer id with that timer who causes this api-call.
							 | 
						||
| 
								 | 
							
								 * @arg : param past to this callback api.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								static void iot_mb_task_ge_start_timer_exe(timer_id_t timer_id, void * arg)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    (void)arg;
							 | 
						||
| 
								 | 
							
								    if (timer_id == mb_task.ge_start_timer) {
							 | 
						||
| 
								 | 
							
								        iot_mb_task_msg_post(IOT_MODBUS_TASK_MT_TIMER,
							 | 
						||
| 
								 | 
							
								            IOT_MODBUS_TASK_MSG_ID_TMR_GE_START_MONITOR, NULL);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @brief iot_mb_task_uart_mb_timer_exe() - timer timeout callback function.
							 | 
						||
| 
								 | 
							
								 * @timer_id : timer id with that timer who causes this api-call.
							 | 
						||
| 
								 | 
							
								 * @arg : param past to this callback api.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								static void iot_mb_task_uart_mb_timer_exe(timer_id_t timer_id, void * arg)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    (void)arg;
							 | 
						||
| 
								 | 
							
								    if (timer_id == mb_task.uart_timer) {
							 | 
						||
| 
								 | 
							
								        iot_mb_task_msg_post(IOT_MODBUS_TASK_MT_TIMER,
							 | 
						||
| 
								 | 
							
								            IOT_MODBUS_TASK_MSG_ID_TMR_UART_MB_TIMEOUT, NULL);
							 | 
						||
| 
								 | 
							
								        os_stop_timer(timer_id);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @brief iot_mb_ext_resp_timer_exe() - timer timeout callback function.
							 | 
						||
| 
								 | 
							
								 * @timer_id : timer id with that timer who causes this api-call.
							 | 
						||
| 
								 | 
							
								 * @arg : param past to this callback api.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								void iot_mb_ext_resp_timer_exe(timer_id_t timer_id, void * arg)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    (void)arg;
							 | 
						||
| 
								 | 
							
								    if (timer_id == mb_task.mb_ext_resp_timer) {
							 | 
						||
| 
								 | 
							
								        iot_mb_ext_resp_cmd_timeout_or_failed();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @brief iot_mb_task_deinit() - Uninitialize modbus task.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								static void iot_mb_task_deinit(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    iot_cus_printf("[mb_task]mb_task deinit!\n");
							 | 
						||
| 
								 | 
							
								    if (NULL != mb_task.uart_h) {
							 | 
						||
| 
								 | 
							
								        iot_uart_close(mb_task.uart_h);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (NULL != mb_task.task) {
							 | 
						||
| 
								 | 
							
								        iot_task_delete(mb_task.task);
							 | 
						||
| 
								 | 
							
								        mb_task.task = NULL;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (0 != mb_task.ge_start_timer) {
							 | 
						||
| 
								 | 
							
								        os_delete_timer(mb_task.ge_start_timer);
							 | 
						||
| 
								 | 
							
								        mb_task.ge_start_timer = 0;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (0 != mb_task.uart_timer) {
							 | 
						||
| 
								 | 
							
								        os_delete_timer(mb_task.uart_timer);
							 | 
						||
| 
								 | 
							
								        mb_task.uart_timer = 0;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    os_mem_set(&mb_task, 0x0, sizeof(iot_mb_task_t));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @brief iot_mb_task_init() - Initialize modbus task.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								static uint32_t iot_mb_task_init(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t ret = ERR_OK;
							 | 
						||
| 
								 | 
							
								    iot_task_config_t task_cfg;
							 | 
						||
| 
								 | 
							
								    uint8_t uart_port;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    iot_cus_printf("[mb_task]mb_task init!\n");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* task configration. */
							 | 
						||
| 
								 | 
							
								    os_mem_set(&task_cfg, 0x0, sizeof(task_cfg));
							 | 
						||
| 
								 | 
							
								    task_cfg.stack_size = IOT_MODBUS_TASK_TASK_STACK_SIZE;
							 | 
						||
| 
								 | 
							
								    task_cfg.task_prio = IOT_MODBUS_TASK_PROTO_TASK_PRIO;
							 | 
						||
| 
								 | 
							
								    task_cfg.msg_size = sizeof(iot_mb_task_msg_t);
							 | 
						||
| 
								 | 
							
								    task_cfg.msg_cnt = IOT_MODBUS_TASK_TASK_POOL_SIZE;
							 | 
						||
| 
								 | 
							
								    task_cfg.queue_cnt = 1;
							 | 
						||
| 
								 | 
							
								    task_cfg.queue_cfg[0].quota = 0;
							 | 
						||
| 
								 | 
							
								    task_cfg.task_event_func = NULL;
							 | 
						||
| 
								 | 
							
								    task_cfg.msg_exe_func = iot_mb_task_msg_exe_func;
							 | 
						||
| 
								 | 
							
								    task_cfg.msg_cancel_func = iot_mb_task_msg_cancel_func;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    os_mem_set(&mb_task, 0, sizeof(iot_mb_task_t));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* default value of slave address is 0xff. */
							 | 
						||
| 
								 | 
							
								    mb_task.slave_addr = IOT_MODBUS_DEFAULT_SLAVER_ADDR;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* IIC:0x3D0A0108(61.10.1.8) */
							 | 
						||
| 
								 | 
							
								    iot_cus_printf("[mb_task]hardware ver:%08x\n", iot_board_hw_version_hex());
							 | 
						||
| 
								 | 
							
								    uart_port = iot_board_get_uart(UART_RS485_PORT);
							 | 
						||
| 
								 | 
							
								    if (uart_port >= iot_uart_get_max_port_num()) {
							 | 
						||
| 
								 | 
							
								        iot_cus_printf("[mb_task]open 485 port err, try to open meter port\n");
							 | 
						||
| 
								 | 
							
								        uart_port = iot_board_get_uart(UART_METER_PORT);
							 | 
						||
| 
								 | 
							
								        /* if need to set meter port as rs485,
							 | 
						||
| 
								 | 
							
								         * use function iot_uart_enable_rs485 after iot_uart_open success.
							 | 
						||
| 
								 | 
							
								         * iot_uart_enable_rs485(mb_task.uart_h,
							 | 
						||
| 
								 | 
							
								         *     iot_board_get_gpio(GPIO_RS485_TXE))
							 | 
						||
| 
								 | 
							
								         */
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    mb_task.uart_h = iot_uart_open(uart_port,
							 | 
						||
| 
								 | 
							
								        iot_mb_task_uart_receive_func, IOT_MODBUS_TASK_UART_BUF_SIZE, NULL);
							 | 
						||
| 
								 | 
							
								    if (NULL == mb_task.uart_h) {
							 | 
						||
| 
								 | 
							
								        ret = ERR_FAIL;
							 | 
						||
| 
								 | 
							
								        goto init_err_handle;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    mb_task.task = iot_task_create(IOT_MODBUS_TASK_ID, &task_cfg);
							 | 
						||
| 
								 | 
							
								    if (NULL == mb_task.task) {
							 | 
						||
| 
								 | 
							
								        iot_cus_printf("[mb_task]create task failed.\n");
							 | 
						||
| 
								 | 
							
								        ret = ERR_FAIL;
							 | 
						||
| 
								 | 
							
								        goto init_err_handle;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* ge start monitor timer. */
							 | 
						||
| 
								 | 
							
								    mb_task.ge_start_timer = os_create_timer(IOT_MODBUS_TASK_ID, true,
							 | 
						||
| 
								 | 
							
								        iot_mb_task_ge_start_timer_exe, NULL);
							 | 
						||
| 
								 | 
							
								    if (0 == mb_task.ge_start_timer) {
							 | 
						||
| 
								 | 
							
								        iot_cus_printf("[mb_task]create ge start timer failed.\n");
							 | 
						||
| 
								 | 
							
								        ret = ERR_FAIL;
							 | 
						||
| 
								 | 
							
								        goto init_err_handle;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    os_start_timer(mb_task.ge_start_timer, IOT_MODBUS_TASK_GE_START_TIMER_PERIOD);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* uart mmodbus recv monitor timer. */
							 | 
						||
| 
								 | 
							
								    mb_task.uart_timer = os_create_timer(IOT_MODBUS_TASK_ID, true,
							 | 
						||
| 
								 | 
							
								        iot_mb_task_uart_mb_timer_exe, NULL);
							 | 
						||
| 
								 | 
							
								    if (0 == mb_task.uart_timer) {
							 | 
						||
| 
								 | 
							
								        iot_cus_printf("[mb_task]create uart modbus timer failed.\n");
							 | 
						||
| 
								 | 
							
								        ret = ERR_FAIL;
							 | 
						||
| 
								 | 
							
								        goto init_err_handle;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* modbus ext resp timer. */
							 | 
						||
| 
								 | 
							
								    mb_task.mb_ext_resp_timer = os_create_timer(IOT_MODBUS_TASK_ID, true,
							 | 
						||
| 
								 | 
							
								        iot_mb_ext_resp_timer_exe, NULL);
							 | 
						||
| 
								 | 
							
								    if (0 == mb_task.mb_ext_resp_timer) {
							 | 
						||
| 
								 | 
							
								        iot_cus_printf("[mb_task]create mb_ext resp timer failed.\n");
							 | 
						||
| 
								 | 
							
								        ret = ERR_FAIL;
							 | 
						||
| 
								 | 
							
								        goto init_err_handle;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if IOT_MODBUS_RT_TABLE_SUPPORT
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    mb_task.rt_table = iot_modbus_addr_rout_table_create(IOT_MODBUS_TASK_ID,
							 | 
						||
| 
								 | 
							
								            IOT_MODBUS_MAC_RT_ENTRY_MAX, sizeof(iot_modbus_addr_rout_entry_t));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* rout table update timer. */
							 | 
						||
| 
								 | 
							
								    mb_task.rt_update_timer = os_create_timer(IOT_MODBUS_TASK_ID, true,
							 | 
						||
| 
								 | 
							
								        iot_mb_task_rt_update_timer_exe, mb_task.rt_table);
							 | 
						||
| 
								 | 
							
								    if (0 == mb_task.rt_update_timer) {
							 | 
						||
| 
								 | 
							
								        iot_cus_printf("[%s][err]create route talbe update timer failed.\n", __FUNCTION__);
							 | 
						||
| 
								 | 
							
								        ret = ERR_FAIL;
							 | 
						||
| 
								 | 
							
								        goto init_err_handle;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    os_start_timer(mb_task.rt_update_timer, IOT_MODBUS_TASK_RT_TIMER_PERIOD);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    iot_cus_printf("[mb_task]task create successfully.\n");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    goto out;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								init_err_handle:
							 | 
						||
| 
								 | 
							
								    iot_mb_task_deinit();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								out:
							 | 
						||
| 
								 | 
							
								    return ret;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint32_t app_modbus_task_entry(void)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint32_t ret = ERR_PENDING;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (ERR_OK == iot_mb_task_init()) {
							 | 
						||
| 
								 | 
							
								        ret = ERR_OK;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return ret;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif /* IOT_GE_EXT_TASK_ENABLE */
							 |