rtu.c 2.9 KB
Newer Older
1 2 3 4
/*
 * Copyright (C) 2015-2018 Alibaba Group Holding Limited
 */

J
Jinliang Li 已提交
5
#include <mbmaster.h>
6 7 8 9 10 11 12 13 14 15
#include "rtu.h"
#include "../../pdu/pdu.h"
#include "mbcrc.h"

#if (MBMASTER_CONFIG_RTU_ENABLED > 0)
mb_status_t rtu_assemble(mb_handler_t *handler)
{
    uint16_t    crc_16;
    mb_status_t status = MB_SUCCESS;
    uint8_t    *send_buf;
16 17 18 19
#ifdef DEBUG
    uint8_t     debug_buf[100];
    uint8_t     debug_hex[14];
#endif
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35

    if (handler->slave_addr == SLAVE_ADDR_BROADCAST) {
        handler->respond_timeout = 1000;
    } else {
        handler->respond_timeout = 200;
    }

    send_buf = handler->mb_frame_buff;

    send_buf[ADU_SER_ADDR_OFF] = handler->slave_addr;
    handler->mb_frame_length   = handler->pdu_length + 1;
    crc_16 = mb_crc16((uint8_t *) send_buf, handler->mb_frame_length);

    send_buf[handler->mb_frame_length++] = (uint8_t)(crc_16 & 0xFF);
    send_buf[handler->mb_frame_length++] = (uint8_t)(crc_16 >> 8);

36 37 38 39
#ifdef DEBUG
    uint32_t debug_len = 0;
    LOGD(MODBUS_MOUDLE, "start to send data len=%u", (unsigned int)handler->mb_frame_length);
    memset(debug_buf, 0, sizeof(debug_buf));
40
    for (int i = 0; i < handler->mb_frame_length; i++) {
41
        debug_len += snprintf(debug_hex, sizeof(debug_hex),"0x%02x ", send_buf[i]);
42
        if (debug_len >= (sizeof(debug_buf))) {
43 44 45
            LOGD(MODBUS_MOUDLE, "assemble debug buf is not enough");
            break;
        }
46
        strncat(debug_buf, debug_hex, sizeof(debug_buf) - strlen(debug_buf) -1);
47
    }
48 49
    LOGD(MODBUS_MOUDLE, "%s", debug_buf);
#endif
50 51 52 53 54 55 56 57

    return status;
}

mb_status_t rtu_disassemble(mb_handler_t *handler)
{
    mb_status_t status = MB_SUCCESS;
    uint8_t    *recv_buf;
58 59 60 61
#ifdef DEBUG
    uint8_t     debug_buf[100];
    uint8_t     debug_hex[6];
#endif
62 63 64

    recv_buf = handler->mb_frame_buff;

65 66 67 68
#ifdef DEBUG
    uint32_t debug_len = 0;
    LOGD(MODBUS_MOUDLE, "rev data len =%u ,data is :", (unsigned int)handler->mb_frame_length);
    memset(debug_buf, 0, sizeof(debug_buf));
69
    for (int i = 0; i < handler->mb_frame_length; i++) {
70
        debug_len += snprintf(debug_hex, sizeof(debug_hex),"0x%02x ", recv_buf[i]);
71
        if (debug_len >= (sizeof(debug_buf))) {
72 73 74
            LOGD(MODBUS_MOUDLE, "disassemble debug buf is not enough");
            break;
        }
75
        strncat(debug_buf, debug_hex, sizeof(debug_buf) - strlen(debug_buf) -1);
76
    }
77 78
    LOGD(MODBUS_MOUDLE, "%s", debug_buf);
#endif
79 80 81 82 83 84 85

    if ((handler->mb_frame_length >= ADU_SER_LENGTH_MIN)
        && (mb_crc16(( uint8_t *) recv_buf, handler->mb_frame_length) == 0)) {
        handler->slave_addr = recv_buf[ADU_SER_ADDR_OFF];
        handler->pdu_length = handler->mb_frame_length - ADU_SER_PDU_OFF - ADU_SER_LENGTH_CRC;
        handler->pdu_offset = ADU_SER_PDU_OFF;
    } else {
86
        LOGE(MODBUS_MOUDLE, "frame is too short or CRC error");
87 88 89 90 91
        status = MB_RESPOND_FRAME_ERR;
    }
    return status;
}
#endif /* MBMASTER_CONFIG_RTU_ENABLED */