1 /*
2 * Copyright (C) 2015-2018 Alibaba Group Holding Limited
3 */
4
5 #include <mbmaster.h>
6 #include "rtu.h"
7 #include "../../pdu/pdu.h"
8 #include "mbcrc.h"
9
10 #if (MBMASTER_CONFIG_RTU_ENABLED > 0)
rtu_assemble(mb_handler_t * handler)11 mb_status_t rtu_assemble(mb_handler_t *handler)
12 {
13 uint16_t crc_16;
14 mb_status_t status = MB_SUCCESS;
15 uint8_t *send_buf;
16 #ifdef DEBUG
17 uint8_t debug_buf[256];
18 uint8_t debug_hex[6];
19 #endif
20
21 // // ?? why we need to fix timeout to 1000/200
22 // if (handler->slave_addr == SLAVE_ADDR_BROADCAST) {
23 // handler->respond_timeout = 1000;
24 // } else {
25 // handler->respond_timeout = 200;
26 // }
27
28 send_buf = handler->mb_frame_buff;
29
30 send_buf[ADU_SER_ADDR_OFF] = handler->slave_addr;
31 handler->mb_frame_length = handler->pdu_length + 1;
32 crc_16 = mb_crc16((uint8_t *) send_buf, handler->mb_frame_length);
33
34 send_buf[handler->mb_frame_length++] = (uint8_t)(crc_16 & 0xFF);
35 send_buf[handler->mb_frame_length++] = (uint8_t)(crc_16 >> 8);
36
37 #ifdef DEBUG
38 uint32_t debug_len = 0;
39 LOGD(MODBUS_MOUDLE, "start to send data len=%u, data is: ", (unsigned int)handler->mb_frame_length);
40 memset(debug_buf, 0, sizeof(debug_buf));
41 for (int i = 0; i < handler->mb_frame_length; i++) {
42 debug_len += snprintf(debug_hex, sizeof(debug_hex),"0x%02x ", send_buf[i]);
43 if (debug_len >= (sizeof(debug_buf))) {
44 LOGD(MODBUS_MOUDLE, "assemble debug buf is not enough\n");
45 break;
46 }
47 strncat(debug_buf, debug_hex, sizeof(debug_buf) - strlen(debug_buf) -1);
48 }
49 LOGD(MODBUS_MOUDLE, "%s\n", debug_buf);
50 #endif
51
52 return status;
53 }
54
rtu_disassemble(mb_handler_t * handler)55 mb_status_t rtu_disassemble(mb_handler_t *handler)
56 {
57 mb_status_t status = MB_SUCCESS;
58 uint8_t *recv_buf;
59 #ifdef DEBUG
60 uint8_t debug_buf[256];
61 uint8_t debug_hex[6];
62 #endif
63
64 recv_buf = handler->mb_frame_buff;
65
66 #ifdef DEBUG
67 uint32_t debug_len = 0;
68 LOGD(MODBUS_MOUDLE, "rev data len =%u, data is :", (unsigned int)handler->mb_frame_length);
69 memset(debug_buf, 0, sizeof(debug_buf));
70 for (int i = 0; i < handler->mb_frame_length; i++) {
71 debug_len += snprintf(debug_hex, sizeof(debug_hex),"0x%02x ", recv_buf[i]);
72 if (debug_len >= (sizeof(debug_buf))) {
73 LOGD(MODBUS_MOUDLE, "disassemble debug buf is not enough\n");
74 break;
75 }
76 strncat(debug_buf, debug_hex, sizeof(debug_buf) - strlen(debug_buf) -1);
77 }
78 LOGD(MODBUS_MOUDLE, "%s\n", debug_buf);
79 #endif
80
81 if ((handler->mb_frame_length >= ADU_SER_LENGTH_MIN)
82 && (mb_crc16(( uint8_t *) recv_buf, handler->mb_frame_length) == 0)) {
83 handler->slave_addr = recv_buf[ADU_SER_ADDR_OFF];
84 handler->pdu_length = handler->mb_frame_length - ADU_SER_PDU_OFF - ADU_SER_LENGTH_CRC;
85 handler->pdu_offset = ADU_SER_PDU_OFF;
86 } else {
87 LOGE(MODBUS_MOUDLE, "frame is too short or CRC error\n");
88 status = MB_RESPOND_FRAME_ERR;
89 }
90 return status;
91 }
92 #endif /* MBMASTER_CONFIG_RTU_ENABLED */
93