1 /*
2 * Copyright (C) 2015-2018 Alibaba Group Holding Limited
3 */
4
5 #include <mbmaster.h>
6 #include "../pdu/pdu.h"
7 #include "main_process.h"
8
9 /* process function code 0x01 0x02 0x03 0x04, they have the same request parameters */
mbmaster_main_type1_process(mb_handler_t * req_handler,uint8_t function_code,uint8_t slave_addr,uint16_t start_addr,uint16_t quantity,uint8_t * respond_buf,uint8_t * respond_count,uint32_t timeout)10 mb_status_t mbmaster_main_type1_process(mb_handler_t *req_handler, uint8_t function_code, uint8_t slave_addr,
11 uint16_t start_addr, uint16_t quantity, uint8_t *respond_buf,
12 uint8_t *respond_count, uint32_t timeout)
13 {
14 mb_status_t status = MB_SUCCESS;
15
16 MB_MUTEX_LOCK(&req_handler->mb_mutex);
17
18 req_handler->slave_addr = slave_addr;
19
20 switch (function_code) {
21 case FUNC_CODE_READ_COILS:
22 case FUNC_CODE_READ_DISCRETE_INPUTS:
23 /* The modubs protocol limits the maximum number of reads */
24 if ((quantity < 1) || (quantity > QUANTITY_MAX_FUNC01)) {
25 MB_MUTEX_UNLOCK(&req_handler->mb_mutex);
26 return MB_INVALID_PARAM;
27 }
28 status = pdu_type122_assemble(req_handler, function_code, start_addr, quantity);
29 break;
30 case FUNC_CODE_READ_HOLDING_REGISTERS:
31 case FUNC_CODE_READ_INPUT_REGISTERS:
32 /* The modubs protocol limits the maximum number of reads */
33 if ((quantity < 1) || (quantity > QUANTITY_MAX_FUNC01)) {
34 MB_MUTEX_UNLOCK(&req_handler->mb_mutex);
35 return MB_INVALID_PARAM;
36 }
37 status = pdu_type122_assemble(req_handler, function_code, start_addr, quantity);
38 break;
39 default:
40 status = MB_FUNCTION_CODE_NOT_SUPPORT;
41 LOGE(MODBUS_MOUDLE, "invalid funciton code!\n");
42 break;
43 }
44 if (status != MB_SUCCESS) {
45 MB_MUTEX_UNLOCK(&req_handler->mb_mutex);
46 return status;
47 }
48
49 req_handler->adu_assemble(req_handler);
50
51 status = req_handler->frame_send(req_handler, timeout);
52 if (status != MB_SUCCESS) {
53 MB_MUTEX_UNLOCK(&req_handler->mb_mutex);
54 return status;
55 }
56
57 /* wait slave respond */
58 LOGD(MODBUS_MOUDLE, "waiting for respond\n");
59
60 status = req_handler->frame_recv(req_handler);
61 if (status != MB_SUCCESS) {
62 MB_MUTEX_UNLOCK(&req_handler->mb_mutex);
63 return status;
64 }
65
66 req_handler->adu_disassemble(req_handler);
67
68 switch (function_code) {
69 case FUNC_CODE_READ_COILS:
70 case FUNC_CODE_READ_DISCRETE_INPUTS:
71 case FUNC_CODE_READ_HOLDING_REGISTERS:
72 case FUNC_CODE_READ_INPUT_REGISTERS:
73 status = pdu_type11n_disassemble(req_handler, function_code, respond_buf, respond_count);
74 break;
75 }
76
77 MB_MUTEX_UNLOCK(&req_handler->mb_mutex);
78
79 return status;
80 }
81
82 /* process function code 0x05 0x06, they have the same request parameters */
mbmaster_main_type2_process(mb_handler_t * req_handler,uint8_t function_code,uint8_t slave_addr,uint16_t register_addr,uint16_t register_value,uint16_t * resp_addr,uint16_t * resp_value,uint8_t * exception_code,uint32_t timeout)83 mb_status_t mbmaster_main_type2_process(mb_handler_t *req_handler, uint8_t function_code, uint8_t slave_addr,
84 uint16_t register_addr, uint16_t register_value, uint16_t *resp_addr,
85 uint16_t *resp_value, uint8_t* exception_code, uint32_t timeout)
86 {
87 mb_status_t status = MB_SUCCESS;
88
89 MB_MUTEX_LOCK(&req_handler->mb_mutex);
90
91 req_handler->slave_addr = slave_addr;
92
93 switch (function_code) {
94 case FUNC_CODE_WRITE_SINGLE_COIL:
95 if ((register_value != 0) && (register_value != 0xFF00)) {
96 status = MB_INVALID_PARAM;
97 MB_MUTEX_UNLOCK(&req_handler->mb_mutex);
98 return status;
99 }
100 status = pdu_type122_assemble(req_handler, function_code, register_addr, register_value);
101 break;
102 case FUNC_CODE_WRITE_SINGLE_REGISTERS:
103 status = pdu_type122_assemble(req_handler, function_code, register_addr, register_value);
104 break;
105 default:
106 status = MB_FUNCTION_CODE_NOT_SUPPORT;
107 LOGE(MODBUS_MOUDLE, "invalid funciton code!\n");
108 break;
109 }
110 if (status != MB_SUCCESS) {
111 MB_MUTEX_UNLOCK(&req_handler->mb_mutex);
112 return status;
113 }
114
115 req_handler->adu_assemble(req_handler);
116
117 status = req_handler->frame_send(req_handler, timeout);
118 if (status != MB_SUCCESS) {
119 MB_MUTEX_UNLOCK(&req_handler->mb_mutex);
120 return status;
121 }
122
123 /* wait slave respond */
124 LOGD(MODBUS_MOUDLE, "waiting for respond\n");
125
126 status = req_handler->frame_recv(req_handler);
127 if (status != MB_SUCCESS) {
128 MB_MUTEX_UNLOCK(&req_handler->mb_mutex);
129 return status;
130 }
131
132 req_handler->adu_disassemble(req_handler);
133
134 switch (function_code) {
135 case FUNC_CODE_WRITE_SINGLE_COIL:
136 case FUNC_CODE_WRITE_SINGLE_REGISTERS:
137 status = pdu_type122_disassemble(req_handler, function_code, resp_addr, resp_value, exception_code);
138 break;
139 }
140
141 MB_MUTEX_UNLOCK(&req_handler->mb_mutex);
142
143 return status;
144 }
145
146 /* process function code 0x0F 0x10, they have the same request parameters */
mbmaster_main_type3_process(mb_handler_t * req_handler,uint8_t function_code,uint8_t slave_addr,uint16_t start_addr,uint16_t quantity,uint8_t * outputs_buf,uint16_t * resp_addr,uint16_t * resp_quantity,uint8_t * exception_code,uint32_t timeout)147 mb_status_t mbmaster_main_type3_process(mb_handler_t *req_handler, uint8_t function_code, uint8_t slave_addr,
148 uint16_t start_addr, uint16_t quantity, uint8_t *outputs_buf, uint16_t *resp_addr,
149 uint16_t *resp_quantity, uint8_t *exception_code, uint32_t timeout)
150 {
151 uint8_t byte_count;
152 mb_status_t status = MB_SUCCESS;
153
154 MB_MUTEX_LOCK(&req_handler->mb_mutex);
155
156 req_handler->slave_addr = slave_addr;
157
158 switch (function_code) {
159 case FUNC_CODE_WRITE_MULTIPLE_COILS:
160 byte_count = quantity / 8;
161 byte_count = (quantity % 8)?(byte_count + 1):byte_count;
162 status = pdu_type1221n_assemble(req_handler, function_code, start_addr, quantity, byte_count, outputs_buf);
163 break;
164 case FUNC_CODE_WRITE_MULTIPLE_REGISTERS:
165 byte_count = quantity * 2;
166 status = pdu_type1221n_assemble(req_handler, function_code, start_addr, quantity, byte_count, outputs_buf);
167 break;
168 default:
169 status = MB_FUNCTION_CODE_NOT_SUPPORT;
170 LOGE(MODBUS_MOUDLE, "invalid funciton code!\n");
171 break;
172 }
173 if (status != MB_SUCCESS) {
174 MB_MUTEX_UNLOCK(&req_handler->mb_mutex);
175 return status;
176 }
177
178 req_handler->adu_assemble(req_handler);
179
180 status = req_handler->frame_send(req_handler, timeout);
181 if (status != MB_SUCCESS) {
182 MB_MUTEX_UNLOCK(&req_handler->mb_mutex);
183 return status;
184 }
185
186 /* wait slave respond */
187 LOGD(MODBUS_MOUDLE, "waiting for respond\n");
188
189 status = req_handler->frame_recv(req_handler);
190 if (status != MB_SUCCESS) {
191 MB_MUTEX_UNLOCK(&req_handler->mb_mutex);
192 return status;
193 }
194
195 req_handler->adu_disassemble(req_handler);
196
197 switch (function_code) {
198 case FUNC_CODE_WRITE_MULTIPLE_COILS:
199 case FUNC_CODE_WRITE_MULTIPLE_REGISTERS:
200 status = pdu_type122_disassemble(req_handler, function_code, resp_addr, resp_quantity, exception_code);
201 break;
202 }
203
204 MB_MUTEX_UNLOCK(&req_handler->mb_mutex);
205
206 return status;
207 }
208