Commit 14f42c1896f6d8fdce152e1f9bea82ae67939594

Authored by Stéphane Raimbault
1 parent efbbc3f7

Error handling improvements

- new function modbus_flush
- new names and values for error defines
- finer recovery on error
- merge TOO_MANY_DATA and INVALID_DATA
- stop unit-test-master at the first error
- FLUSH_OR_RECONNECT_ON_ERROR -> FLUSH_OR_CONNECT_ON_ERROR
- more precise tests in unit-test-master
src/modbus.c
@@ -151,24 +151,44 @@ static const int TAB_MAX_ADU_LENGTH[2] = { @@ -151,24 +151,44 @@ static const int TAB_MAX_ADU_LENGTH[2] = {
151 MAX_ADU_LENGTH_TCP, 151 MAX_ADU_LENGTH_TCP,
152 }; 152 };
153 153
  154 +void modbus_flush(modbus_param_t *mb_param)
  155 +{
  156 + if (mb_param->type_com == RTU) {
  157 + tcflush(mb_param->fd, TCIOFLUSH);
  158 + } else {
  159 + int ret;
  160 + do {
  161 + /* Extract the garbage from the socket */
  162 + char devnull[MAX_ADU_LENGTH_TCP];
  163 + ret = recv(mb_param->fd, devnull, MAX_ADU_LENGTH_TCP, MSG_DONTWAIT);
  164 + if (mb_param->debug && ret > 0) {
  165 + printf("%d bytes flushed\n", ret);
  166 + }
  167 + } while (ret > 0);
  168 + }
  169 +}
  170 +
154 /* Treats errors and flush or close connection if necessary */ 171 /* Treats errors and flush or close connection if necessary */
155 static void error_treat(modbus_param_t *mb_param, int code, const char *string) 172 static void error_treat(modbus_param_t *mb_param, int code, const char *string)
156 { 173 {
157 - printf("\nERROR %s (%d)\n", string, code); 174 + printf("\nERROR %s (%0X)\n", string, -code);
158 175
159 - if (mb_param->error_handling == FLUSH_OR_RECONNECT_ON_ERROR) { 176 + if (mb_param->error_handling == FLUSH_OR_CONNECT_ON_ERROR) {
160 switch (code) { 177 switch (code) {
161 - case ILLEGAL_DATA_VALUE:  
162 - case ILLEGAL_DATA_ADDRESS:  
163 - case ILLEGAL_FUNCTION: 178 + case INVALID_DATA:
  179 + case INVALID_CRC:
  180 + case INVALID_EXCEPTION_CODE:
  181 + modbus_flush(mb_param);
  182 + break;
  183 + case SELECT_FAILURE:
  184 + case SOCKET_FAILURE:
  185 + case CONNECTION_CLOSED:
  186 + modbus_close(mb_param);
  187 + modbus_connect(mb_param);
164 break; 188 break;
165 default: 189 default:
166 - if (mb_param->type_com == RTU) {  
167 - tcflush(mb_param->fd, TCIOFLUSH);  
168 - } else {  
169 - modbus_close(mb_param);  
170 - modbus_connect(mb_param);  
171 - } 190 + /* NOP */
  191 + break;
172 } 192 }
173 } 193 }
174 } 194 }
@@ -394,10 +414,10 @@ static int modbus_send(modbus_param_t *mb_param, uint8_t *query, @@ -394,10 +414,10 @@ static int modbus_send(modbus_param_t *mb_param, uint8_t *query,
394 ret = send(mb_param->fd, query, query_length, 0); 414 ret = send(mb_param->fd, query, query_length, 0);
395 415
396 /* Return the number of bytes written (0 to n) 416 /* Return the number of bytes written (0 to n)
397 - or PORT_SOCKET_FAILURE on error */ 417 + or SOCKET_FAILURE on error */
398 if ((ret == -1) || (ret != query_length)) { 418 if ((ret == -1) || (ret != query_length)) {
399 - ret = PORT_SOCKET_FAILURE;  
400 - error_treat(mb_param, ret, "Write port/socket failure"); 419 + ret = SOCKET_FAILURE;
  420 + error_treat(mb_param, ret, "Write socket failure");
401 } 421 }
402 422
403 return ret; 423 return ret;
@@ -455,7 +475,7 @@ static int compute_query_length_data(modbus_param_t *mb_param, uint8_t *msg) @@ -455,7 +475,7 @@ static int compute_query_length_data(modbus_param_t *mb_param, uint8_t *msg)
455 \ 475 \
456 if (select_ret == 0) { \ 476 if (select_ret == 0) { \
457 /* Call to error_treat is done later to manage exceptions */ \ 477 /* Call to error_treat is done later to manage exceptions */ \
458 - return COMM_TIME_OUT; \ 478 + return SELECT_TIMEOUT; \
459 } \ 479 } \
460 } 480 }
461 481
@@ -534,9 +554,9 @@ static int receive_msg(modbus_param_t *mb_param, @@ -534,9 +554,9 @@ static int receive_msg(modbus_param_t *mb_param,
534 return CONNECTION_CLOSED; 554 return CONNECTION_CLOSED;
535 } else if (read_ret < 0) { 555 } else if (read_ret < 0) {
536 /* The only negative possible value is -1 */ 556 /* The only negative possible value is -1 */
537 - error_treat(mb_param, PORT_SOCKET_FAILURE,  
538 - "Read port/socket failure");  
539 - return PORT_SOCKET_FAILURE; 557 + error_treat(mb_param, SOCKET_FAILURE,
  558 + "Read socket failure");
  559 + return SOCKET_FAILURE;
540 } 560 }
541 561
542 /* Sums bytes received */ 562 /* Sums bytes received */
@@ -568,8 +588,8 @@ static int receive_msg(modbus_param_t *mb_param, @@ -568,8 +588,8 @@ static int receive_msg(modbus_param_t *mb_param,
568 length_to_read = compute_query_length_data(mb_param, msg); 588 length_to_read = compute_query_length_data(mb_param, msg);
569 msg_length_computed += length_to_read; 589 msg_length_computed += length_to_read;
570 if (msg_length_computed > TAB_MAX_ADU_LENGTH[mb_param->type_com]) { 590 if (msg_length_computed > TAB_MAX_ADU_LENGTH[mb_param->type_com]) {
571 - error_treat(mb_param, TOO_MANY_DATA, "Too many data");  
572 - return TOO_MANY_DATA; 591 + error_treat(mb_param, INVALID_DATA, "Too many data");
  592 + return INVALID_DATA;
573 } 593 }
574 state = COMPLETE; 594 state = COMPLETE;
575 break; 595 break;
@@ -692,13 +712,13 @@ static int modbus_receive(modbus_param_t *mb_param, @@ -692,13 +712,13 @@ static int modbus_receive(modbus_param_t *mb_param,
692 ret = response_nb_value; 712 ret = response_nb_value;
693 } else { 713 } else {
694 char *s_error = malloc(64 * sizeof(char)); 714 char *s_error = malloc(64 * sizeof(char));
695 - sprintf(s_error, "Quantity (%d) not corresponding to the query (%d)", 715 + sprintf(s_error, "Quantity not corresponding to the query (%d != %d)",
696 response_nb_value, query_nb_value); 716 response_nb_value, query_nb_value);
697 - ret = ILLEGAL_DATA_VALUE;  
698 - error_treat(mb_param, ILLEGAL_DATA_VALUE, s_error); 717 + ret = INVALID_DATA;
  718 + error_treat(mb_param, ret, s_error);
699 free(s_error); 719 free(s_error);
700 } 720 }
701 - } else if (ret == COMM_TIME_OUT) { 721 + } else if (ret == SELECT_TIMEOUT) {
702 722
703 if (response_length == (offset + 2 + TAB_CHECKSUM_LENGTH[mb_param->type_com])) { 723 if (response_length == (offset + 2 + TAB_CHECKSUM_LENGTH[mb_param->type_com])) {
704 /* EXCEPTION CODE RECEIVED */ 724 /* EXCEPTION CODE RECEIVED */
@@ -745,8 +765,7 @@ static int modbus_receive(modbus_param_t *mb_param, @@ -745,8 +765,7 @@ static int modbus_receive(modbus_param_t *mb_param,
745 TIME OUT here */ 765 TIME OUT here */
746 } 766 }
747 767
748 - /* COMMUNICATION TIME OUT */  
749 - error_treat(mb_param, ret, "Communication time out"); 768 + error_treat(mb_param, ret, "Select timeout");
750 return ret; 769 return ret;
751 } 770 }
752 771
@@ -1046,7 +1065,7 @@ int read_coil_status(modbus_param_t *mb_param, int start_addr, @@ -1046,7 +1065,7 @@ int read_coil_status(modbus_param_t *mb_param, int start_addr,
1046 if (nb > MAX_STATUS) { 1065 if (nb > MAX_STATUS) {
1047 printf("ERROR Too many coils status requested (%d > %d)\n", 1066 printf("ERROR Too many coils status requested (%d > %d)\n",
1048 nb, MAX_STATUS); 1067 nb, MAX_STATUS);
1049 - return TOO_MANY_DATA; 1068 + return INVALID_DATA;
1050 } 1069 }
1051 1070
1052 status = read_io_status(mb_param, FC_READ_COIL_STATUS, 1071 status = read_io_status(mb_param, FC_READ_COIL_STATUS,
@@ -1068,7 +1087,7 @@ int read_input_status(modbus_param_t *mb_param, int start_addr, @@ -1068,7 +1087,7 @@ int read_input_status(modbus_param_t *mb_param, int start_addr,
1068 if (nb > MAX_STATUS) { 1087 if (nb > MAX_STATUS) {
1069 printf("ERROR Too many input status requested (%d > %d)\n", 1088 printf("ERROR Too many input status requested (%d > %d)\n",
1070 nb, MAX_STATUS); 1089 nb, MAX_STATUS);
1071 - return TOO_MANY_DATA; 1090 + return INVALID_DATA;
1072 } 1091 }
1073 1092
1074 status = read_io_status(mb_param, FC_READ_INPUT_STATUS, 1093 status = read_io_status(mb_param, FC_READ_INPUT_STATUS,
@@ -1092,7 +1111,7 @@ static int read_registers(modbus_param_t *mb_param, int function, @@ -1092,7 +1111,7 @@ static int read_registers(modbus_param_t *mb_param, int function,
1092 if (nb > MAX_REGISTERS) { 1111 if (nb > MAX_REGISTERS) {
1093 printf("EROOR Too many holding registers requested (%d > %d)\n", 1112 printf("EROOR Too many holding registers requested (%d > %d)\n",
1094 nb, MAX_REGISTERS); 1113 nb, MAX_REGISTERS);
1095 - return TOO_MANY_DATA; 1114 + return INVALID_DATA;
1096 } 1115 }
1097 1116
1098 query_length = build_query_basis(mb_param, function, 1117 query_length = build_query_basis(mb_param, function,
@@ -1128,7 +1147,7 @@ int read_holding_registers(modbus_param_t *mb_param, @@ -1128,7 +1147,7 @@ int read_holding_registers(modbus_param_t *mb_param,
1128 if (nb > MAX_REGISTERS) { 1147 if (nb > MAX_REGISTERS) {
1129 printf("ERROR Too many holding registers requested (%d > %d)\n", 1148 printf("ERROR Too many holding registers requested (%d > %d)\n",
1130 nb, MAX_REGISTERS); 1149 nb, MAX_REGISTERS);
1131 - return TOO_MANY_DATA; 1150 + return INVALID_DATA;
1132 } 1151 }
1133 1152
1134 status = read_registers(mb_param, FC_READ_HOLDING_REGISTERS, 1153 status = read_registers(mb_param, FC_READ_HOLDING_REGISTERS,
@@ -1146,7 +1165,7 @@ int read_input_registers(modbus_param_t *mb_param, int start_addr, int nb, @@ -1146,7 +1165,7 @@ int read_input_registers(modbus_param_t *mb_param, int start_addr, int nb,
1146 if (nb > MAX_REGISTERS) { 1165 if (nb > MAX_REGISTERS) {
1147 printf("ERROR Too many input registers requested (%d > %d)\n", 1166 printf("ERROR Too many input registers requested (%d > %d)\n",
1148 nb, MAX_REGISTERS); 1167 nb, MAX_REGISTERS);
1149 - return TOO_MANY_DATA; 1168 + return INVALID_DATA;
1150 } 1169 }
1151 1170
1152 status = read_registers(mb_param, FC_READ_INPUT_REGISTERS, 1171 status = read_registers(mb_param, FC_READ_INPUT_REGISTERS,
@@ -1219,7 +1238,7 @@ int force_multiple_coils(modbus_param_t *mb_param, int start_addr, int nb, @@ -1219,7 +1238,7 @@ int force_multiple_coils(modbus_param_t *mb_param, int start_addr, int nb,
1219 if (nb > MAX_STATUS) { 1238 if (nb > MAX_STATUS) {
1220 printf("ERROR Writing to too many coils (%d > %d)\n", 1239 printf("ERROR Writing to too many coils (%d > %d)\n",
1221 nb, MAX_STATUS); 1240 nb, MAX_STATUS);
1222 - return TOO_MANY_DATA; 1241 + return INVALID_DATA;
1223 } 1242 }
1224 1243
1225 query_length = build_query_basis(mb_param, FC_FORCE_MULTIPLE_COILS, 1244 query_length = build_query_basis(mb_param, FC_FORCE_MULTIPLE_COILS,
@@ -1268,7 +1287,7 @@ int preset_multiple_registers(modbus_param_t *mb_param, int start_addr, int nb, @@ -1268,7 +1287,7 @@ int preset_multiple_registers(modbus_param_t *mb_param, int start_addr, int nb,
1268 if (nb > MAX_REGISTERS) { 1287 if (nb > MAX_REGISTERS) {
1269 printf("ERROR Trying to write to too many registers (%d > %d)\n", 1288 printf("ERROR Trying to write to too many registers (%d > %d)\n",
1270 nb, MAX_REGISTERS); 1289 nb, MAX_REGISTERS);
1271 - return TOO_MANY_DATA; 1290 + return INVALID_DATA;
1272 } 1291 }
1273 1292
1274 query_length = build_query_basis(mb_param, FC_PRESET_MULTIPLE_REGISTERS, 1293 query_length = build_query_basis(mb_param, FC_PRESET_MULTIPLE_REGISTERS,
@@ -1344,7 +1363,7 @@ void modbus_init_rtu(modbus_param_t *mb_param, const char *device, @@ -1344,7 +1363,7 @@ void modbus_init_rtu(modbus_param_t *mb_param, const char *device,
1344 mb_param->data_bit = data_bit; 1363 mb_param->data_bit = data_bit;
1345 mb_param->stop_bit = stop_bit; 1364 mb_param->stop_bit = stop_bit;
1346 mb_param->type_com = RTU; 1365 mb_param->type_com = RTU;
1347 - mb_param->error_handling = FLUSH_OR_RECONNECT_ON_ERROR; 1366 + mb_param->error_handling = FLUSH_OR_CONNECT_ON_ERROR;
1348 mb_param->slave = slave; 1367 mb_param->slave = slave;
1349 } 1368 }
1350 1369
@@ -1363,16 +1382,15 @@ void modbus_init_tcp(modbus_param_t *mb_param, const char *ip, int port, int sla @@ -1363,16 +1382,15 @@ void modbus_init_tcp(modbus_param_t *mb_param, const char *ip, int port, int sla
1363 strncpy(mb_param->ip, ip, sizeof(char)*16); 1382 strncpy(mb_param->ip, ip, sizeof(char)*16);
1364 mb_param->port = port; 1383 mb_param->port = port;
1365 mb_param->type_com = TCP; 1384 mb_param->type_com = TCP;
1366 - mb_param->error_handling = FLUSH_OR_RECONNECT_ON_ERROR; 1385 + mb_param->error_handling = FLUSH_OR_CONNECT_ON_ERROR;
1367 mb_param->slave = slave; 1386 mb_param->slave = slave;
1368 } 1387 }
1369 1388
1370 -/* By default, the error handling mode used is FLUSH_OR_RECONNECT_ON_ERROR. 1389 +/* By default, the error handling mode used is FLUSH_OR_CONNECT_ON_ERROR.
1371 1390
1372 - With FLUSH_OR_RECONNECT_ON_ERROR, the library will flush to I/O  
1373 - port in RTU mode or attempt an immediate reconnection which may  
1374 - hang for several seconds if the network to the remote target unit  
1375 - is down in TCP mode. 1391 + With FLUSH_OR_CONNECT_ON_ERROR, the library will attempt an immediate
  1392 + reconnection which may hang for several seconds if the network to
  1393 + the remote target unit is down.
1376 1394
1377 With NOP_ON_ERROR, it is expected that the application will 1395 With NOP_ON_ERROR, it is expected that the application will
1378 check for error returns and deal with them as necessary. 1396 check for error returns and deal with them as necessary.
@@ -1380,7 +1398,7 @@ void modbus_init_tcp(modbus_param_t *mb_param, const char *ip, int port, int sla @@ -1380,7 +1398,7 @@ void modbus_init_tcp(modbus_param_t *mb_param, const char *ip, int port, int sla
1380 void modbus_set_error_handling(modbus_param_t *mb_param, 1398 void modbus_set_error_handling(modbus_param_t *mb_param,
1381 error_handling_t error_handling) 1399 error_handling_t error_handling)
1382 { 1400 {
1383 - if (error_handling == FLUSH_OR_RECONNECT_ON_ERROR || 1401 + if (error_handling == FLUSH_OR_CONNECT_ON_ERROR ||
1384 error_handling == NOP_ON_ERROR) { 1402 error_handling == NOP_ON_ERROR) {
1385 mb_param->error_handling = error_handling; 1403 mb_param->error_handling = error_handling;
1386 } else { 1404 } else {
src/modbus.h
@@ -120,19 +120,20 @@ extern &quot;C&quot; { @@ -120,19 +120,20 @@ extern &quot;C&quot; {
120 #define GATEWAY_PROBLEM_TARGET -0x0B 120 #define GATEWAY_PROBLEM_TARGET -0x0B
121 121
122 /* Local */ 122 /* Local */
123 -#define COMM_TIME_OUT -0x0C  
124 -#define PORT_SOCKET_FAILURE -0x0D  
125 -#define SELECT_FAILURE -0x0E  
126 -#define TOO_MANY_DATA -0x0F  
127 -#define INVALID_CRC -0x10  
128 -#define INVALID_EXCEPTION_CODE -0x11  
129 -#define CONNECTION_CLOSED -0x12 123 +#define INVALID_DATA -0x10
  124 +#define INVALID_CRC -0x11
  125 +#define INVALID_EXCEPTION_CODE -0x12
  126 +
  127 +#define SELECT_TIMEOUT -0x13
  128 +#define SELECT_FAILURE -0x14
  129 +#define SOCKET_FAILURE -0x15
  130 +#define CONNECTION_CLOSED -0x16
130 131
131 /* Internal using */ 132 /* Internal using */
132 #define MSG_LENGTH_UNDEFINED -1 133 #define MSG_LENGTH_UNDEFINED -1
133 134
134 typedef enum { RTU=0, TCP } type_com_t; 135 typedef enum { RTU=0, TCP } type_com_t;
135 -typedef enum { FLUSH_OR_RECONNECT_ON_ERROR, NOP_ON_ERROR } error_handling_t; 136 +typedef enum { FLUSH_OR_CONNECT_ON_ERROR, NOP_ON_ERROR } error_handling_t;
136 137
137 /* This structure is byte-aligned */ 138 /* This structure is byte-aligned */
138 typedef struct { 139 typedef struct {
@@ -250,9 +251,9 @@ void modbus_init_rtu(modbus_param_t *mb_param, const char *device, @@ -250,9 +251,9 @@ void modbus_init_rtu(modbus_param_t *mb_param, const char *device,
250 void modbus_init_tcp(modbus_param_t *mb_param, const char *ip_address, int port, 251 void modbus_init_tcp(modbus_param_t *mb_param, const char *ip_address, int port,
251 int slave); 252 int slave);
252 253
253 -/* By default, the error handling mode used is RECONNECT_ON_ERROR. 254 +/* By default, the error handling mode used is CONNECT_ON_ERROR.
254 255
255 - With RECONNECT_ON_ERROR, the library will attempt an immediate 256 + With FLUSH_OR_CONNECT_ON_ERROR, the library will attempt an immediate
256 reconnection which may hang for several seconds if the network to 257 reconnection which may hang for several seconds if the network to
257 the remote target unit is down. 258 the remote target unit is down.
258 259
@@ -270,6 +271,9 @@ int modbus_connect(modbus_param_t *mb_param); @@ -270,6 +271,9 @@ int modbus_connect(modbus_param_t *mb_param);
270 /* Closes a modbus connection */ 271 /* Closes a modbus connection */
271 void modbus_close(modbus_param_t *mb_param); 272 void modbus_close(modbus_param_t *mb_param);
272 273
  274 +/* Flush the pending request */
  275 +void modbus_flush(modbus_param_t *mb_param);
  276 +
273 /* Activates the debug messages */ 277 /* Activates the debug messages */
274 void modbus_set_debug(modbus_param_t *mb_param, int boolean); 278 void modbus_set_debug(modbus_param_t *mb_param, int boolean);
275 279
tests/unit-test-master.c
@@ -42,8 +42,7 @@ int main(void) @@ -42,8 +42,7 @@ int main(void)
42 42
43 /* TCP */ 43 /* TCP */
44 modbus_init_tcp(&mb_param, "127.0.0.1", 1502, SLAVE); 44 modbus_init_tcp(&mb_param, "127.0.0.1", 1502, SLAVE);
45 -/* modbus_set_debug(&mb_param, TRUE);*/  
46 - modbus_set_error_handling(&mb_param, NOP_ON_ERROR); 45 +/* modbus_set_debug(&mb_param, TRUE); */
47 46
48 if (modbus_connect(&mb_param) == -1) { 47 if (modbus_connect(&mb_param) == -1) {
49 printf("ERROR Connection failed\n"); 48 printf("ERROR Connection failed\n");
@@ -267,8 +266,10 @@ int main(void) @@ -267,8 +266,10 @@ int main(void)
267 printf("* read_coil_status: "); 266 printf("* read_coil_status: ");
268 if (ret == ILLEGAL_DATA_ADDRESS) 267 if (ret == ILLEGAL_DATA_ADDRESS)
269 printf("OK\n"); 268 printf("OK\n");
270 - else 269 + else {
271 printf("FAILED\n"); 270 printf("FAILED\n");
  271 + goto close;
  272 + }
272 273
273 ret = read_input_status(&mb_param, 274 ret = read_input_status(&mb_param,
274 UT_INPUT_STATUS_ADDRESS, 275 UT_INPUT_STATUS_ADDRESS,
@@ -277,8 +278,10 @@ int main(void) @@ -277,8 +278,10 @@ int main(void)
277 printf("* read_input_status: "); 278 printf("* read_input_status: ");
278 if (ret == ILLEGAL_DATA_ADDRESS) 279 if (ret == ILLEGAL_DATA_ADDRESS)
279 printf("OK\n"); 280 printf("OK\n");
280 - else 281 + else {
281 printf("FAILED\n"); 282 printf("FAILED\n");
  283 + goto close;
  284 + }
282 285
283 ret = read_holding_registers(&mb_param, 286 ret = read_holding_registers(&mb_param,
284 UT_HOLDING_REGISTERS_ADDRESS, 287 UT_HOLDING_REGISTERS_ADDRESS,
@@ -287,8 +290,10 @@ int main(void) @@ -287,8 +290,10 @@ int main(void)
287 printf("* read_holding_registers: "); 290 printf("* read_holding_registers: ");
288 if (ret == ILLEGAL_DATA_ADDRESS) 291 if (ret == ILLEGAL_DATA_ADDRESS)
289 printf("OK\n"); 292 printf("OK\n");
290 - else 293 + else {
291 printf("FAILED\n"); 294 printf("FAILED\n");
  295 + goto close;
  296 + }
292 297
293 ret = read_input_registers(&mb_param, 298 ret = read_input_registers(&mb_param,
294 UT_INPUT_REGISTERS_ADDRESS, 299 UT_INPUT_REGISTERS_ADDRESS,
@@ -297,8 +302,10 @@ int main(void) @@ -297,8 +302,10 @@ int main(void)
297 printf("* read_input_registers: "); 302 printf("* read_input_registers: ");
298 if (ret == ILLEGAL_DATA_ADDRESS) 303 if (ret == ILLEGAL_DATA_ADDRESS)
299 printf("OK\n"); 304 printf("OK\n");
300 - else 305 + else {
301 printf("FAILED\n"); 306 printf("FAILED\n");
  307 + goto close;
  308 + }
302 309
303 ret = force_single_coil(&mb_param, 310 ret = force_single_coil(&mb_param,
304 UT_COIL_STATUS_ADDRESS + UT_COIL_STATUS_NB_POINTS, 311 UT_COIL_STATUS_ADDRESS + UT_COIL_STATUS_NB_POINTS,
@@ -308,6 +315,7 @@ int main(void) @@ -308,6 +315,7 @@ int main(void)
308 printf("OK\n"); 315 printf("OK\n");
309 } else { 316 } else {
310 printf("FAILED\n"); 317 printf("FAILED\n");
  318 + goto close;
311 } 319 }
312 320
313 ret = force_multiple_coils(&mb_param, 321 ret = force_multiple_coils(&mb_param,
@@ -319,6 +327,7 @@ int main(void) @@ -319,6 +327,7 @@ int main(void)
319 printf("OK\n"); 327 printf("OK\n");
320 } else { 328 } else {
321 printf("FAILED\n"); 329 printf("FAILED\n");
  330 + goto close;
322 } 331 }
323 332
324 ret = preset_multiple_registers(&mb_param, 333 ret = preset_multiple_registers(&mb_param,
@@ -330,6 +339,7 @@ int main(void) @@ -330,6 +339,7 @@ int main(void)
330 printf("OK\n"); 339 printf("OK\n");
331 } else { 340 } else {
332 printf("FAILED\n"); 341 printf("FAILED\n");
  342 + goto close;
333 } 343 }
334 344
335 345
@@ -341,49 +351,58 @@ int main(void) @@ -341,49 +351,58 @@ int main(void)
341 MAX_STATUS + 1, 351 MAX_STATUS + 1,
342 tab_rp_status); 352 tab_rp_status);
343 printf("* read_coil_status: "); 353 printf("* read_coil_status: ");
344 - if (ret == TOO_MANY_DATA) 354 + if (ret == INVALID_DATA) {
345 printf("OK\n"); 355 printf("OK\n");
346 - else 356 + } else {
347 printf("FAILED\n"); 357 printf("FAILED\n");
  358 + goto close;
  359 + }
348 360
349 ret = read_input_status(&mb_param, 361 ret = read_input_status(&mb_param,
350 UT_INPUT_STATUS_ADDRESS, 362 UT_INPUT_STATUS_ADDRESS,
351 MAX_STATUS + 1, 363 MAX_STATUS + 1,
352 tab_rp_status); 364 tab_rp_status);
353 printf("* read_input_status: "); 365 printf("* read_input_status: ");
354 - if (ret == TOO_MANY_DATA) 366 + if (ret == INVALID_DATA) {
355 printf("OK\n"); 367 printf("OK\n");
356 - else 368 + } else {
357 printf("FAILED\n"); 369 printf("FAILED\n");
  370 + goto close;
  371 + }
358 372
359 ret = read_holding_registers(&mb_param, 373 ret = read_holding_registers(&mb_param,
360 UT_HOLDING_REGISTERS_ADDRESS, 374 UT_HOLDING_REGISTERS_ADDRESS,
361 MAX_REGISTERS + 1, 375 MAX_REGISTERS + 1,
362 tab_rp_registers); 376 tab_rp_registers);
363 printf("* read_holding_registers: "); 377 printf("* read_holding_registers: ");
364 - if (ret == TOO_MANY_DATA) 378 + if (ret == INVALID_DATA) {
365 printf("OK\n"); 379 printf("OK\n");
366 - else 380 + } else {
367 printf("FAILED\n"); 381 printf("FAILED\n");
  382 + goto close;
  383 + }
368 384
369 ret = read_input_registers(&mb_param, 385 ret = read_input_registers(&mb_param,
370 UT_INPUT_REGISTERS_ADDRESS, 386 UT_INPUT_REGISTERS_ADDRESS,
371 MAX_REGISTERS + 1, 387 MAX_REGISTERS + 1,
372 tab_rp_registers); 388 tab_rp_registers);
373 printf("* read_input_registers: "); 389 printf("* read_input_registers: ");
374 - if (ret == TOO_MANY_DATA) 390 + if (ret == INVALID_DATA) {
375 printf("OK\n"); 391 printf("OK\n");
376 - else 392 + } else {
377 printf("FAILED\n"); 393 printf("FAILED\n");
  394 + goto close;
  395 + }
378 396
379 ret = force_multiple_coils(&mb_param, 397 ret = force_multiple_coils(&mb_param,
380 UT_COIL_STATUS_ADDRESS, 398 UT_COIL_STATUS_ADDRESS,
381 MAX_STATUS + 1, 399 MAX_STATUS + 1,
382 tab_rp_status); 400 tab_rp_status);
383 printf("* force_multiple_coils: "); 401 printf("* force_multiple_coils: ");
384 - if (ret == TOO_MANY_DATA) { 402 + if (ret == INVALID_DATA) {
385 printf("OK\n"); 403 printf("OK\n");
386 } else { 404 } else {
  405 + goto close;
387 printf("FAILED\n"); 406 printf("FAILED\n");
388 } 407 }
389 408
@@ -392,10 +411,11 @@ int main(void) @@ -392,10 +411,11 @@ int main(void)
392 MAX_REGISTERS + 1, 411 MAX_REGISTERS + 1,
393 tab_rp_registers); 412 tab_rp_registers);
394 printf("* preset_multiple_registers: "); 413 printf("* preset_multiple_registers: ");
395 - if (ret == TOO_MANY_DATA) { 414 + if (ret == INVALID_DATA) {
396 printf("OK\n"); 415 printf("OK\n");
397 } else { 416 } else {
398 printf("FAILED\n"); 417 printf("FAILED\n");
  418 + goto close;
399 } 419 }
400 420
401 /** SLAVE REPLY **/ 421 /** SLAVE REPLY **/
@@ -407,10 +427,11 @@ int main(void) @@ -407,10 +427,11 @@ int main(void)
407 UT_HOLDING_REGISTERS_NB_POINTS, 427 UT_HOLDING_REGISTERS_NB_POINTS,
408 tab_rp_registers); 428 tab_rp_registers);
409 printf("1/2 No reply from slave %d: ", mb_param.slave); 429 printf("1/2 No reply from slave %d: ", mb_param.slave);
410 - if (ret != UT_HOLDING_REGISTERS_NB_POINTS) { 430 + if (ret == SELECT_TIMEOUT) {
411 printf("OK\n", ret); 431 printf("OK\n", ret);
412 } else { 432 } else {
413 printf("FAILED\n"); 433 printf("FAILED\n");
  434 + goto close;
414 } 435 }
415 436
416 mb_param.slave = MODBUS_BROADCAST_ADDRESS; 437 mb_param.slave = MODBUS_BROADCAST_ADDRESS;
@@ -422,6 +443,7 @@ int main(void) @@ -422,6 +443,7 @@ int main(void)
422 if (ret == UT_HOLDING_REGISTERS_NB_POINTS) { 443 if (ret == UT_HOLDING_REGISTERS_NB_POINTS) {
423 printf("OK\n", ret); 444 printf("OK\n", ret);
424 } else { 445 } else {
  446 + goto close;
425 printf("FAILED\n"); 447 printf("FAILED\n");
426 } 448 }
427 449
@@ -436,11 +458,11 @@ int main(void) @@ -436,11 +458,11 @@ int main(void)
436 UT_HOLDING_REGISTERS_NB_POINTS_SPECIAL, 458 UT_HOLDING_REGISTERS_NB_POINTS_SPECIAL,
437 tab_rp_registers_bad); 459 tab_rp_registers_bad);
438 printf("* read_holding_registers: "); 460 printf("* read_holding_registers: ");
439 - if (ret > 0) {  
440 - /* Error not detected */  
441 - printf("FAILED\n");  
442 - } else { 461 + if (ret == INVALID_DATA) {
443 printf("OK\n"); 462 printf("OK\n");
  463 + } else {
  464 + printf("FAILED\n");
  465 + goto close;
444 } 466 }
445 free(tab_rp_registers_bad); 467 free(tab_rp_registers_bad);
446 468