413 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			413 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								/****************************************************************************
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
							 | 
						||
| 
								 | 
							
								be copied by any method or incorporated into another program without
							 | 
						||
| 
								 | 
							
								the express written consent of Aerospace C.Power. This Information or any portion
							 | 
						||
| 
								 | 
							
								thereof remains the property of Aerospace C.Power. The Information contained herein
							 | 
						||
| 
								 | 
							
								is believed to be accurate and Aerospace C.Power assumes no responsibility or
							 | 
						||
| 
								 | 
							
								liability for its use in any way and conveys no license or title under
							 | 
						||
| 
								 | 
							
								any patent or copyright and makes no representation or warranty that this
							 | 
						||
| 
								 | 
							
								Information is free from patent or copyright infringement.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								****************************************************************************/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* os_ship header files */
							 | 
						||
| 
								 | 
							
								#include "os_timer_api.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* iot common header files */
							 | 
						||
| 
								 | 
							
								#include "iot_app_api.h"
							 | 
						||
| 
								 | 
							
								#include "iot_io_api.h"
							 | 
						||
| 
								 | 
							
								#include "iot_task_api.h"
							 | 
						||
| 
								 | 
							
								#include "iot_proto_common.h"
							 | 
						||
| 
								 | 
							
								#include "iot_proto_dl645.h"
							 | 
						||
| 
								 | 
							
								#include "iot_proto_modbus.h"
							 | 
						||
| 
								 | 
							
								#include "iot_proto_ge.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if PLC_SUPPORT_STA_ROLE
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								mcu_data_handle_t mcu_data_modbus;
							 | 
						||
| 
								 | 
							
								extern uint8_t ge_buf[];
							 | 
						||
| 
								 | 
							
								extern void iot_common_bin_dump(uint8_t *data, uint32_t dlen);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @brief iot_modbus_cal_crc() - To calculate crc of modbus
							 | 
						||
| 
								 | 
							
								 * @param pbyte:   point to the data
							 | 
						||
| 
								 | 
							
								 * @param nlen:    the number of input data
							 | 
						||
| 
								 | 
							
								 * @retval:        the value of crc
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								uint16_t iot_modbus_cal_crc(uint8_t *pbyte, uint32_t nlen)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint8_t i;
							 | 
						||
| 
								 | 
							
								    uint32_t pos;
							 | 
						||
| 
								 | 
							
								    uint16_t crc = 0xFFFF;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    for (pos = 0; pos < nlen; pos++) {
							 | 
						||
| 
								 | 
							
								        /* XOR byte into least sig. byte of crc */
							 | 
						||
| 
								 | 
							
								        crc ^= (uint16_t)pbyte[pos];
							 | 
						||
| 
								 | 
							
								        /* Loop over each bit */
							 | 
						||
| 
								 | 
							
								        for (i = 8; i != 0; i--) {
							 | 
						||
| 
								 | 
							
								            /* If the LSB is set */
							 | 
						||
| 
								 | 
							
								            if ((crc & 0x0001) != 0) {
							 | 
						||
| 
								 | 
							
								                /* Shift right and XOR 0xA001 */
							 | 
						||
| 
								 | 
							
								                crc >>= 1;
							 | 
						||
| 
								 | 
							
								                /* Else LSB is not set */
							 | 
						||
| 
								 | 
							
								                crc ^= 0xA001;
							 | 
						||
| 
								 | 
							
								            } else {
							 | 
						||
| 
								 | 
							
								                /* Just shift right */
							 | 
						||
| 
								 | 
							
								                crc >>= 1;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    /* Note, this number has low and high bytes swapped,
							 | 
						||
| 
								 | 
							
								    so use it accordingly (or swap bytes) */
							 | 
						||
| 
								 | 
							
								    return crc;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @brief iot_match_modbus_cmd() - To check if modbus cmd or not
							 | 
						||
| 
								 | 
							
								 * @param cmd                  the cmd of mudbus
							 | 
						||
| 
								 | 
							
								 * @param retval:              match or not match
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								static uint8_t iot_match_modbus_cmd(uint8_t cmd)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint8_t ret;
							 | 
						||
| 
								 | 
							
								    if ((cmd == MODBUS_CMD_01_READ_COIL_STATUS) ||
							 | 
						||
| 
								 | 
							
								        (cmd == MODBUS_CMD_02_READ_INPUT_STATUS) ||
							 | 
						||
| 
								 | 
							
								        (cmd == MODBUS_CMD_03_READ_HOLD_REG) ||
							 | 
						||
| 
								 | 
							
								        (cmd == MODBUS_CMD_04_READ_INPUT_REG) ||
							 | 
						||
| 
								 | 
							
								        (cmd == MODBUS_CMD_05_ENFORCE_COIL) ||
							 | 
						||
| 
								 | 
							
								        (cmd == MODBUS_CMD_06_PRESET_REG) ||
							 | 
						||
| 
								 | 
							
								        (cmd == MODBUS_CMD_0F_ENFORCE_MULTIPLE_COIL) ||
							 | 
						||
| 
								 | 
							
								        (cmd == MODBUS_CMD_10_PRESET_MULTIPLE_REG)) {
							 | 
						||
| 
								 | 
							
								        ret = MATCH;
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        ret = NO_MATCH;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return ret;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * @brief iot_modbus_extend_dl645_pack() - To pickup modbus cmd frames and pack
							 | 
						||
| 
								 | 
							
								                                           it in extend dl645 frame
							 | 
						||
| 
								 | 
							
								 * @param input:                  point to the input data
							 | 
						||
| 
								 | 
							
								 * @param p_data:                 point to the modbus data length
							 | 
						||
| 
								 | 
							
								 * @param ge_buf_pos:             the position of ge buf
							 | 
						||
| 
								 | 
							
								 * @param half_sign:              half data figure
							 | 
						||
| 
								 | 
							
								 * @param p_loc:                  the distance loop will jump
							 | 
						||
| 
								 | 
							
								 * @param crc_input:              the crc value whitch in the frame
							 | 
						||
| 
								 | 
							
								 * @param crc_cal:                the crc value whitch is calculated
							 | 
						||
| 
								 | 
							
								 * @param ge_len:                 the length of the frame
							 | 
						||
| 
								 | 
							
								 * @param retval:                 how many frames 1 or 0
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								static uint8_t iot_modbus_extend_dl645_pack(uint8_t *input, uint8_t *p_data,
							 | 
						||
| 
								 | 
							
								    uint16_t ge_buf_pos, uint8_t *half_sign, uint16_t* p_loc, uint16_t crc_input,
							 | 
						||
| 
								 | 
							
								    uint16_t crc_cal, uint16_t ge_len)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint8_t frame_num = 0;
							 | 
						||
| 
								 | 
							
								    if (crc_input == crc_cal) {
							 | 
						||
| 
								 | 
							
								        *p_loc = ge_len;
							 | 
						||
| 
								 | 
							
								        if (iot_ge_buf_overflow_test(ge_buf_pos, ge_len +
							 | 
						||
| 
								 | 
							
								            sizeof(ge_frame_data_send_set_subfn160_t) +
							 | 
						||
| 
								 | 
							
								            sizeof(ge_frm_tail_t) + DL645_PARSE_FRM_MIN_LEN + DL645_DI_LEN)) {
							 | 
						||
| 
								 | 
							
								            iot_sta_pack_extend_dl645_to_ge(input, p_data, &ge_len,
							 | 
						||
| 
								 | 
							
								                MODBUS_TYPE);
							 | 
						||
| 
								 | 
							
								            *half_sign = HALF_NO;
							 | 
						||
| 
								 | 
							
								            frame_num = 1;
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            *half_sign = OVERFLOW;
							 | 
						||
| 
								 | 
							
								            iot_cus_printf("cmd %d make ge_buf overflow\n", input[1]);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return frame_num;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * @brief iot_modbus_cmd_01_to_04_fn() - To pickup 0x01 to 0x04 cmd frames from
							 | 
						||
| 
								 | 
							
								                                         buff
							 | 
						||
| 
								 | 
							
								 * @param input:                  point to the input data
							 | 
						||
| 
								 | 
							
								 * @param p_data:                 point to the modbus data length
							 | 
						||
| 
								 | 
							
								 * @param ge_buf_pos:             the position of ge buf
							 | 
						||
| 
								 | 
							
								 * @param half_sign:              half data figure
							 | 
						||
| 
								 | 
							
								 * @param tt_left:                the length of data in the buffer do not check
							 | 
						||
| 
								 | 
							
								 * @param p_loc:                  the distance loop will jump
							 | 
						||
| 
								 | 
							
								 * @param retval:                 how many frames 1 or 0
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								static uint8_t iot_modbus_cmd_01_to_04_fn(uint8_t *input, uint8_t *p_data,
							 | 
						||
| 
								 | 
							
								    uint16_t ge_buf_pos, uint8_t *half_sign, uint8_t tt_left, uint16_t* p_loc)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint8_t frame_num = 0;
							 | 
						||
| 
								 | 
							
								    /* the ask frame, it is not have the member "data[0]", the length of the
							 | 
						||
| 
								 | 
							
								        frame is constant */
							 | 
						||
| 
								 | 
							
								    uint8_t frame_len_no_data = sizeof(modbus_head_01_to_10);
							 | 
						||
| 
								 | 
							
								    uint16_t crc_cal;
							 | 
						||
| 
								 | 
							
								    uint16_t crc_input;
							 | 
						||
| 
								 | 
							
								    uint16_t ack_data_len;
							 | 
						||
| 
								 | 
							
								    modbus_head_01_to_10 *inbuf;
							 | 
						||
| 
								 | 
							
								    modbus_head_01_04_with_len *inbuf_ack;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (tt_left < frame_len_no_data) {
							 | 
						||
| 
								 | 
							
								        *half_sign = HALF_YES;
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        inbuf = (modbus_head_01_to_10 *)input;
							 | 
						||
| 
								 | 
							
								        crc_input = (inbuf->crc_h * LEFT_8BIT + inbuf->crc_l);
							 | 
						||
| 
								 | 
							
								        crc_cal = iot_modbus_cal_crc(input, MODBUS_CMD_LEN_NO_DATA);
							 | 
						||
| 
								 | 
							
								        frame_num = iot_modbus_extend_dl645_pack(input, p_data, ge_buf_pos,
							 | 
						||
| 
								 | 
							
								            half_sign, p_loc, crc_input, crc_cal, frame_len_no_data);
							 | 
						||
| 
								 | 
							
								        if (frame_num == 1) {
							 | 
						||
| 
								 | 
							
								            goto out;
							 | 
						||
| 
								 | 
							
								        } else if (*half_sign == OVERFLOW) {
							 | 
						||
| 
								 | 
							
								            goto out;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    inbuf_ack = (modbus_head_01_04_with_len *)input;
							 | 
						||
| 
								 | 
							
								    if (tt_left < inbuf_ack->len + MODBUS_CMD_01_04_ACK_LEN) {
							 | 
						||
| 
								 | 
							
								        *half_sign = HALF_YES;
							 | 
						||
| 
								 | 
							
								        goto out;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /*check as ack code*/
							 | 
						||
| 
								 | 
							
								    ack_data_len = inbuf_ack->len;
							 | 
						||
| 
								 | 
							
								    crc_cal = iot_modbus_cal_crc(input, ack_data_len +
							 | 
						||
| 
								 | 
							
								        MODBUS_CMD_01_04_ACK_LEN_NO_CRC);
							 | 
						||
| 
								 | 
							
								    crc_input = inbuf_ack->data[ack_data_len + 1] * LEFT_8BIT +
							 | 
						||
| 
								 | 
							
								        inbuf_ack->data[ack_data_len];
							 | 
						||
| 
								 | 
							
								    ack_data_len += MODBUS_CMD_01_04_ACK_LEN;
							 | 
						||
| 
								 | 
							
								    frame_num = iot_modbus_extend_dl645_pack(input, p_data, ge_buf_pos,
							 | 
						||
| 
								 | 
							
								        half_sign, p_loc, crc_input, crc_cal, ack_data_len);
							 | 
						||
| 
								 | 
							
								out:
							 | 
						||
| 
								 | 
							
								    return frame_num;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * @brief iot_modbus_cmd_05_06_fn() - To pickup 0x05 or 0x06 cmd frames from
							 | 
						||
| 
								 | 
							
								                                      buffer
							 | 
						||
| 
								 | 
							
								 * @param input:                  point to the input data
							 | 
						||
| 
								 | 
							
								 * @param p_data:                 point to the modbus data length
							 | 
						||
| 
								 | 
							
								 * @param ge_buf_pos:             the position of ge buf
							 | 
						||
| 
								 | 
							
								 * @param half_sign:              half data figure
							 | 
						||
| 
								 | 
							
								 * @param tt_left:                the length of data in the buffer do not check
							 | 
						||
| 
								 | 
							
								 * @param p_loc:                  the distance loop will jump
							 | 
						||
| 
								 | 
							
								 * @param retval:                 how many frames 1 or 0
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								static uint8_t iot_modbus_cmd_05_06_fn(uint8_t *input, uint8_t *p_data,
							 | 
						||
| 
								 | 
							
								    uint16_t ge_buf_pos, uint8_t *half_sign, uint8_t tt_left, uint16_t* p_loc)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint8_t frame_num = 0;
							 | 
						||
| 
								 | 
							
								    uint8_t frame_len_no_data = sizeof(modbus_head_01_to_10);
							 | 
						||
| 
								 | 
							
								    uint16_t crc_cal;
							 | 
						||
| 
								 | 
							
								    uint16_t crc_input;
							 | 
						||
| 
								 | 
							
								    modbus_head_01_to_10 *inbuf;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (tt_left < frame_len_no_data) {
							 | 
						||
| 
								 | 
							
								        *half_sign = HALF_YES;
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        inbuf = (modbus_head_01_to_10 *)input;
							 | 
						||
| 
								 | 
							
								        crc_input = (inbuf->crc_h * LEFT_8BIT + inbuf->crc_l);
							 | 
						||
| 
								 | 
							
								        crc_cal = iot_modbus_cal_crc(input, MODBUS_CMD_LEN_NO_DATA);
							 | 
						||
| 
								 | 
							
								        frame_num = iot_modbus_extend_dl645_pack(input, p_data, ge_buf_pos,
							 | 
						||
| 
								 | 
							
								            half_sign, p_loc, crc_input, crc_cal, frame_len_no_data);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return frame_num;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * @brief iot_modbus_cmd_0f_10_fn() - To pickup 0x0f or 0x10 cmd frames from
							 | 
						||
| 
								 | 
							
								                                      buffer
							 | 
						||
| 
								 | 
							
								 * @param input:                  point to the input data
							 | 
						||
| 
								 | 
							
								 * @param p_data:                 point to the modbus data length
							 | 
						||
| 
								 | 
							
								 * @param ge_buf_pos:             the position of ge buf
							 | 
						||
| 
								 | 
							
								 * @param half_sign:              half data figure
							 | 
						||
| 
								 | 
							
								 * @param tt_left:                the length of data in the buffer do not check
							 | 
						||
| 
								 | 
							
								 * @param p_loc:                  the distance loop will jump
							 | 
						||
| 
								 | 
							
								 * @param retval:                 how many frames 1 or 0
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								static uint8_t iot_modbus_cmd_0f_10_fn(uint8_t *input, uint8_t *p_data,
							 | 
						||
| 
								 | 
							
								    uint16_t ge_buf_pos, uint8_t *half_sign, uint8_t tt_left, uint16_t* p_loc)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint8_t frame_num = 0;
							 | 
						||
| 
								 | 
							
								    uint8_t frame_len_no_data = sizeof(modbus_head_01_to_10);
							 | 
						||
| 
								 | 
							
								    uint16_t crc_cal;
							 | 
						||
| 
								 | 
							
								    uint16_t crc_input;
							 | 
						||
| 
								 | 
							
								    uint16_t ack_data_len;
							 | 
						||
| 
								 | 
							
								    modbus_head_01_to_10 *inbuf;
							 | 
						||
| 
								 | 
							
								    modbus_head_0f_10_with_len *inbuf_ack;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (tt_left < frame_len_no_data) {
							 | 
						||
| 
								 | 
							
								        *half_sign = HALF_YES;
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        inbuf = (modbus_head_01_to_10 *)input;
							 | 
						||
| 
								 | 
							
								        crc_input = (inbuf->crc_h * LEFT_8BIT + inbuf->crc_l);
							 | 
						||
| 
								 | 
							
								        crc_cal = iot_modbus_cal_crc(input, MODBUS_CMD_LEN_NO_DATA);
							 | 
						||
| 
								 | 
							
								        frame_num = iot_modbus_extend_dl645_pack(input, p_data, ge_buf_pos,
							 | 
						||
| 
								 | 
							
								            half_sign, p_loc, crc_input, crc_cal, frame_len_no_data);
							 | 
						||
| 
								 | 
							
								        if (frame_num == 1) {
							 | 
						||
| 
								 | 
							
								            goto out;
							 | 
						||
| 
								 | 
							
								        } else if (*half_sign == OVERFLOW) {
							 | 
						||
| 
								 | 
							
								            goto out;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    inbuf_ack = (modbus_head_0f_10_with_len *)input;
							 | 
						||
| 
								 | 
							
								    if (tt_left < inbuf_ack->data_len + MODBUS_CMD_0F_10_ACK_LEN) {
							 | 
						||
| 
								 | 
							
								        *half_sign = HALF_YES;
							 | 
						||
| 
								 | 
							
								        goto out;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /*check as ack code*/
							 | 
						||
| 
								 | 
							
								    ack_data_len = inbuf_ack->data_len;
							 | 
						||
| 
								 | 
							
								    crc_cal = iot_modbus_cal_crc(input, ack_data_len +
							 | 
						||
| 
								 | 
							
								        MODBUS_CMD_0F_10_ACK_LEN_NO_CRC);
							 | 
						||
| 
								 | 
							
								    crc_input = inbuf_ack->data[ack_data_len + 1] * LEFT_8BIT +
							 | 
						||
| 
								 | 
							
								        inbuf_ack->data[ack_data_len];
							 | 
						||
| 
								 | 
							
								    ack_data_len += MODBUS_CMD_0F_10_ACK_LEN;
							 | 
						||
| 
								 | 
							
								    frame_num = iot_modbus_extend_dl645_pack(input, p_data, ge_buf_pos,
							 | 
						||
| 
								 | 
							
								        half_sign, p_loc, crc_input, crc_cal, ack_data_len);
							 | 
						||
| 
								 | 
							
								out:
							 | 
						||
| 
								 | 
							
								    return frame_num;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint8_t iot_proto_modbus_format_check(mcu_data_handle_t *recv_data,
							 | 
						||
| 
								 | 
							
								    uint8_t *pdata, uint16_t *ret_size, uint16_t *ge_len_out)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint8_t half_sign = HALF_NO;
							 | 
						||
| 
								 | 
							
								    uint8_t check_result = GET_NO_FRAME;
							 | 
						||
| 
								 | 
							
								    uint8_t *buf = &recv_data->data[recv_data->data_pos];
							 | 
						||
| 
								 | 
							
								    uint16_t tt_len = recv_data->total_len - recv_data->data_pos;
							 | 
						||
| 
								 | 
							
								    uint16_t input_data_pos = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (buf == NULL) {
							 | 
						||
| 
								 | 
							
								        goto result;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (tt_len == 1) {
							 | 
						||
| 
								 | 
							
								        check_result = GET_HALF_FRAME;
							 | 
						||
| 
								 | 
							
								        goto result;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if ((tt_len < MODBUS_MIN_LEN) && (iot_match_modbus_cmd(buf[1]))) {
							 | 
						||
| 
								 | 
							
								        check_result = GET_HALF_FRAME;
							 | 
						||
| 
								 | 
							
								        goto result;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    switch (buf[1]) {
							 | 
						||
| 
								 | 
							
								        case MODBUS_CMD_01_READ_COIL_STATUS:
							 | 
						||
| 
								 | 
							
								        case MODBUS_CMD_02_READ_INPUT_STATUS:
							 | 
						||
| 
								 | 
							
								        case MODBUS_CMD_03_READ_HOLD_REG:
							 | 
						||
| 
								 | 
							
								        case MODBUS_CMD_04_READ_INPUT_REG:
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            check_result = iot_modbus_cmd_01_to_04_fn(&buf[0], &pdata[*ret_size],
							 | 
						||
| 
								 | 
							
								                *ret_size, &half_sign, tt_len, &input_data_pos);
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        case MODBUS_CMD_05_ENFORCE_COIL:
							 | 
						||
| 
								 | 
							
								        case MODBUS_CMD_06_PRESET_REG:
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            check_result = iot_modbus_cmd_05_06_fn(&buf[0], &pdata[*ret_size],
							 | 
						||
| 
								 | 
							
								                *ret_size, &half_sign, tt_len, &input_data_pos);
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        case MODBUS_CMD_0F_ENFORCE_MULTIPLE_COIL:
							 | 
						||
| 
								 | 
							
								        case MODBUS_CMD_10_PRESET_MULTIPLE_REG:
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            check_result = iot_modbus_cmd_0f_10_fn(&buf[0], &pdata[*ret_size],
							 | 
						||
| 
								 | 
							
								                *ret_size, &half_sign, tt_len, &input_data_pos);
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        default:
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (half_sign == HALF_YES) {
							 | 
						||
| 
								 | 
							
								        check_result = GET_HALF_FRAME;
							 | 
						||
| 
								 | 
							
								    } else if (half_sign == OVERFLOW) {
							 | 
						||
| 
								 | 
							
								        check_result = GET_OVERFLOW;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (check_result == GET_ONE_FRAME) {
							 | 
						||
| 
								 | 
							
								        *ret_size += sizeof(ge_frm_tail_t) + DL645_PARSE_FRM_MIN_LEN +
							 | 
						||
| 
								 | 
							
								            input_data_pos + sizeof(ge_frame_data_send_set_subfn160_t) +
							 | 
						||
| 
								 | 
							
								            DL645_DI_LEN;
							 | 
						||
| 
								 | 
							
								        *ge_len_out += input_data_pos;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								result:
							 | 
						||
| 
								 | 
							
								    return check_result;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								uint8_t iot_proto_modbus_frm_format_check(uint8_t *data, uint16_t len)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint8_t err_code = 0, crc_h, crc_l, min_len;
							 | 
						||
| 
								 | 
							
								    uint16_t crc_cal;
							 | 
						||
| 
								 | 
							
								    uint16_t crc_input;
							 | 
						||
| 
								 | 
							
								    modbus_head_01_to_10 *inbuf;
							 | 
						||
| 
								 | 
							
								    modbus_head_0f_10_with_len *buf;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (len < sizeof(modbus_head_01_to_10)) {
							 | 
						||
| 
								 | 
							
								        err_code = 1;
							 | 
						||
| 
								 | 
							
								        goto out;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    switch (data[1]) {
							 | 
						||
| 
								 | 
							
								        case MODBUS_CMD_01_READ_COIL_STATUS:
							 | 
						||
| 
								 | 
							
								        case MODBUS_CMD_02_READ_INPUT_STATUS:
							 | 
						||
| 
								 | 
							
								        case MODBUS_CMD_03_READ_HOLD_REG:
							 | 
						||
| 
								 | 
							
								        case MODBUS_CMD_04_READ_INPUT_REG:
							 | 
						||
| 
								 | 
							
								        case MODBUS_CMD_05_ENFORCE_COIL:
							 | 
						||
| 
								 | 
							
								        case MODBUS_CMD_06_PRESET_REG:
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            if (len != sizeof(modbus_head_01_to_10)) {
							 | 
						||
| 
								 | 
							
								                err_code = 2;
							 | 
						||
| 
								 | 
							
								                goto out;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            inbuf = (modbus_head_01_to_10 *)data;
							 | 
						||
| 
								 | 
							
								            crc_input = (inbuf->crc_h * LEFT_8BIT + inbuf->crc_l);
							 | 
						||
| 
								 | 
							
								            crc_cal = iot_modbus_cal_crc(data, MODBUS_CMD_LEN_NO_DATA);
							 | 
						||
| 
								 | 
							
								            if (crc_input != crc_cal) {
							 | 
						||
| 
								 | 
							
								                err_code = 3;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        case MODBUS_CMD_0F_ENFORCE_MULTIPLE_COIL:
							 | 
						||
| 
								 | 
							
								        case MODBUS_CMD_10_PRESET_MULTIPLE_REG:
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            buf = (modbus_head_0f_10_with_len *)data;
							 | 
						||
| 
								 | 
							
								            min_len = sizeof(modbus_head_0f_10_with_len);
							 | 
						||
| 
								 | 
							
								            if (len != (min_len + buf->data_len + 2)) {
							 | 
						||
| 
								 | 
							
								                err_code = 4;
							 | 
						||
| 
								 | 
							
								                break;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            crc_l = data[min_len + buf->data_len];
							 | 
						||
| 
								 | 
							
								            crc_h = data[min_len + buf->data_len + 1];
							 | 
						||
| 
								 | 
							
								            crc_input = (crc_h * LEFT_8BIT + crc_l);
							 | 
						||
| 
								 | 
							
								            crc_cal = iot_modbus_cal_crc(data, buf->data_len + min_len);
							 | 
						||
| 
								 | 
							
								            if (crc_input != crc_cal) {
							 | 
						||
| 
								 | 
							
								                err_code = 5;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        default:
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            err_code = 6;
							 | 
						||
| 
								 | 
							
								            break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								out:
							 | 
						||
| 
								 | 
							
								    if (err_code > 0) {
							 | 
						||
| 
								 | 
							
								        iot_cus_printf("modbus_frm_check err_code:%x\n", err_code);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return err_code;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif /* PLC_SUPPORT_STA_ROLE */
							 |