Commit 14f42c1896f6d8fdce152e1f9bea82ae67939594
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
Showing
3 changed files
with
116 additions
and
72 deletions
src/modbus.c
| ... | ... | @@ -151,24 +151,44 @@ static const int TAB_MAX_ADU_LENGTH[2] = { |
| 151 | 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 | 171 | /* Treats errors and flush or close connection if necessary */ |
| 155 | 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 | 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 | 188 | break; |
| 165 | 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 | 414 | ret = send(mb_param->fd, query, query_length, 0); |
| 395 | 415 | |
| 396 | 416 | /* Return the number of bytes written (0 to n) |
| 397 | - or PORT_SOCKET_FAILURE on error */ | |
| 417 | + or SOCKET_FAILURE on error */ | |
| 398 | 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 | 423 | return ret; |
| ... | ... | @@ -455,7 +475,7 @@ static int compute_query_length_data(modbus_param_t *mb_param, uint8_t *msg) |
| 455 | 475 | \ |
| 456 | 476 | if (select_ret == 0) { \ |
| 457 | 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 | 554 | return CONNECTION_CLOSED; |
| 535 | 555 | } else if (read_ret < 0) { |
| 536 | 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 | 562 | /* Sums bytes received */ |
| ... | ... | @@ -568,8 +588,8 @@ static int receive_msg(modbus_param_t *mb_param, |
| 568 | 588 | length_to_read = compute_query_length_data(mb_param, msg); |
| 569 | 589 | msg_length_computed += length_to_read; |
| 570 | 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 | 594 | state = COMPLETE; |
| 575 | 595 | break; |
| ... | ... | @@ -692,13 +712,13 @@ static int modbus_receive(modbus_param_t *mb_param, |
| 692 | 712 | ret = response_nb_value; |
| 693 | 713 | } else { |
| 694 | 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 | 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 | 719 | free(s_error); |
| 700 | 720 | } |
| 701 | - } else if (ret == COMM_TIME_OUT) { | |
| 721 | + } else if (ret == SELECT_TIMEOUT) { | |
| 702 | 722 | |
| 703 | 723 | if (response_length == (offset + 2 + TAB_CHECKSUM_LENGTH[mb_param->type_com])) { |
| 704 | 724 | /* EXCEPTION CODE RECEIVED */ |
| ... | ... | @@ -745,8 +765,7 @@ static int modbus_receive(modbus_param_t *mb_param, |
| 745 | 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 | 769 | return ret; |
| 751 | 770 | } |
| 752 | 771 | |
| ... | ... | @@ -1046,7 +1065,7 @@ int read_coil_status(modbus_param_t *mb_param, int start_addr, |
| 1046 | 1065 | if (nb > MAX_STATUS) { |
| 1047 | 1066 | printf("ERROR Too many coils status requested (%d > %d)\n", |
| 1048 | 1067 | nb, MAX_STATUS); |
| 1049 | - return TOO_MANY_DATA; | |
| 1068 | + return INVALID_DATA; | |
| 1050 | 1069 | } |
| 1051 | 1070 | |
| 1052 | 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 | 1087 | if (nb > MAX_STATUS) { |
| 1069 | 1088 | printf("ERROR Too many input status requested (%d > %d)\n", |
| 1070 | 1089 | nb, MAX_STATUS); |
| 1071 | - return TOO_MANY_DATA; | |
| 1090 | + return INVALID_DATA; | |
| 1072 | 1091 | } |
| 1073 | 1092 | |
| 1074 | 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 | 1111 | if (nb > MAX_REGISTERS) { |
| 1093 | 1112 | printf("EROOR Too many holding registers requested (%d > %d)\n", |
| 1094 | 1113 | nb, MAX_REGISTERS); |
| 1095 | - return TOO_MANY_DATA; | |
| 1114 | + return INVALID_DATA; | |
| 1096 | 1115 | } |
| 1097 | 1116 | |
| 1098 | 1117 | query_length = build_query_basis(mb_param, function, |
| ... | ... | @@ -1128,7 +1147,7 @@ int read_holding_registers(modbus_param_t *mb_param, |
| 1128 | 1147 | if (nb > MAX_REGISTERS) { |
| 1129 | 1148 | printf("ERROR Too many holding registers requested (%d > %d)\n", |
| 1130 | 1149 | nb, MAX_REGISTERS); |
| 1131 | - return TOO_MANY_DATA; | |
| 1150 | + return INVALID_DATA; | |
| 1132 | 1151 | } |
| 1133 | 1152 | |
| 1134 | 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 | 1165 | if (nb > MAX_REGISTERS) { |
| 1147 | 1166 | printf("ERROR Too many input registers requested (%d > %d)\n", |
| 1148 | 1167 | nb, MAX_REGISTERS); |
| 1149 | - return TOO_MANY_DATA; | |
| 1168 | + return INVALID_DATA; | |
| 1150 | 1169 | } |
| 1151 | 1170 | |
| 1152 | 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 | 1238 | if (nb > MAX_STATUS) { |
| 1220 | 1239 | printf("ERROR Writing to too many coils (%d > %d)\n", |
| 1221 | 1240 | nb, MAX_STATUS); |
| 1222 | - return TOO_MANY_DATA; | |
| 1241 | + return INVALID_DATA; | |
| 1223 | 1242 | } |
| 1224 | 1243 | |
| 1225 | 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 | 1287 | if (nb > MAX_REGISTERS) { |
| 1269 | 1288 | printf("ERROR Trying to write to too many registers (%d > %d)\n", |
| 1270 | 1289 | nb, MAX_REGISTERS); |
| 1271 | - return TOO_MANY_DATA; | |
| 1290 | + return INVALID_DATA; | |
| 1272 | 1291 | } |
| 1273 | 1292 | |
| 1274 | 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 | 1363 | mb_param->data_bit = data_bit; |
| 1345 | 1364 | mb_param->stop_bit = stop_bit; |
| 1346 | 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 | 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 | 1382 | strncpy(mb_param->ip, ip, sizeof(char)*16); |
| 1364 | 1383 | mb_param->port = port; |
| 1365 | 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 | 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 | 1395 | With NOP_ON_ERROR, it is expected that the application will |
| 1378 | 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 | 1398 | void modbus_set_error_handling(modbus_param_t *mb_param, |
| 1381 | 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 | 1402 | error_handling == NOP_ON_ERROR) { |
| 1385 | 1403 | mb_param->error_handling = error_handling; |
| 1386 | 1404 | } else { | ... | ... |
src/modbus.h
| ... | ... | @@ -120,19 +120,20 @@ extern "C" { |
| 120 | 120 | #define GATEWAY_PROBLEM_TARGET -0x0B |
| 121 | 121 | |
| 122 | 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 | 132 | /* Internal using */ |
| 132 | 133 | #define MSG_LENGTH_UNDEFINED -1 |
| 133 | 134 | |
| 134 | 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 | 138 | /* This structure is byte-aligned */ |
| 138 | 139 | typedef struct { |
| ... | ... | @@ -250,9 +251,9 @@ void modbus_init_rtu(modbus_param_t *mb_param, const char *device, |
| 250 | 251 | void modbus_init_tcp(modbus_param_t *mb_param, const char *ip_address, int port, |
| 251 | 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 | 257 | reconnection which may hang for several seconds if the network to |
| 257 | 258 | the remote target unit is down. |
| 258 | 259 | |
| ... | ... | @@ -270,6 +271,9 @@ int modbus_connect(modbus_param_t *mb_param); |
| 270 | 271 | /* Closes a modbus connection */ |
| 271 | 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 | 277 | /* Activates the debug messages */ |
| 274 | 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 | 42 | |
| 43 | 43 | /* TCP */ |
| 44 | 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 | 47 | if (modbus_connect(&mb_param) == -1) { |
| 49 | 48 | printf("ERROR Connection failed\n"); |
| ... | ... | @@ -267,8 +266,10 @@ int main(void) |
| 267 | 266 | printf("* read_coil_status: "); |
| 268 | 267 | if (ret == ILLEGAL_DATA_ADDRESS) |
| 269 | 268 | printf("OK\n"); |
| 270 | - else | |
| 269 | + else { | |
| 271 | 270 | printf("FAILED\n"); |
| 271 | + goto close; | |
| 272 | + } | |
| 272 | 273 | |
| 273 | 274 | ret = read_input_status(&mb_param, |
| 274 | 275 | UT_INPUT_STATUS_ADDRESS, |
| ... | ... | @@ -277,8 +278,10 @@ int main(void) |
| 277 | 278 | printf("* read_input_status: "); |
| 278 | 279 | if (ret == ILLEGAL_DATA_ADDRESS) |
| 279 | 280 | printf("OK\n"); |
| 280 | - else | |
| 281 | + else { | |
| 281 | 282 | printf("FAILED\n"); |
| 283 | + goto close; | |
| 284 | + } | |
| 282 | 285 | |
| 283 | 286 | ret = read_holding_registers(&mb_param, |
| 284 | 287 | UT_HOLDING_REGISTERS_ADDRESS, |
| ... | ... | @@ -287,8 +290,10 @@ int main(void) |
| 287 | 290 | printf("* read_holding_registers: "); |
| 288 | 291 | if (ret == ILLEGAL_DATA_ADDRESS) |
| 289 | 292 | printf("OK\n"); |
| 290 | - else | |
| 293 | + else { | |
| 291 | 294 | printf("FAILED\n"); |
| 295 | + goto close; | |
| 296 | + } | |
| 292 | 297 | |
| 293 | 298 | ret = read_input_registers(&mb_param, |
| 294 | 299 | UT_INPUT_REGISTERS_ADDRESS, |
| ... | ... | @@ -297,8 +302,10 @@ int main(void) |
| 297 | 302 | printf("* read_input_registers: "); |
| 298 | 303 | if (ret == ILLEGAL_DATA_ADDRESS) |
| 299 | 304 | printf("OK\n"); |
| 300 | - else | |
| 305 | + else { | |
| 301 | 306 | printf("FAILED\n"); |
| 307 | + goto close; | |
| 308 | + } | |
| 302 | 309 | |
| 303 | 310 | ret = force_single_coil(&mb_param, |
| 304 | 311 | UT_COIL_STATUS_ADDRESS + UT_COIL_STATUS_NB_POINTS, |
| ... | ... | @@ -308,6 +315,7 @@ int main(void) |
| 308 | 315 | printf("OK\n"); |
| 309 | 316 | } else { |
| 310 | 317 | printf("FAILED\n"); |
| 318 | + goto close; | |
| 311 | 319 | } |
| 312 | 320 | |
| 313 | 321 | ret = force_multiple_coils(&mb_param, |
| ... | ... | @@ -319,6 +327,7 @@ int main(void) |
| 319 | 327 | printf("OK\n"); |
| 320 | 328 | } else { |
| 321 | 329 | printf("FAILED\n"); |
| 330 | + goto close; | |
| 322 | 331 | } |
| 323 | 332 | |
| 324 | 333 | ret = preset_multiple_registers(&mb_param, |
| ... | ... | @@ -330,6 +339,7 @@ int main(void) |
| 330 | 339 | printf("OK\n"); |
| 331 | 340 | } else { |
| 332 | 341 | printf("FAILED\n"); |
| 342 | + goto close; | |
| 333 | 343 | } |
| 334 | 344 | |
| 335 | 345 | |
| ... | ... | @@ -341,49 +351,58 @@ int main(void) |
| 341 | 351 | MAX_STATUS + 1, |
| 342 | 352 | tab_rp_status); |
| 343 | 353 | printf("* read_coil_status: "); |
| 344 | - if (ret == TOO_MANY_DATA) | |
| 354 | + if (ret == INVALID_DATA) { | |
| 345 | 355 | printf("OK\n"); |
| 346 | - else | |
| 356 | + } else { | |
| 347 | 357 | printf("FAILED\n"); |
| 358 | + goto close; | |
| 359 | + } | |
| 348 | 360 | |
| 349 | 361 | ret = read_input_status(&mb_param, |
| 350 | 362 | UT_INPUT_STATUS_ADDRESS, |
| 351 | 363 | MAX_STATUS + 1, |
| 352 | 364 | tab_rp_status); |
| 353 | 365 | printf("* read_input_status: "); |
| 354 | - if (ret == TOO_MANY_DATA) | |
| 366 | + if (ret == INVALID_DATA) { | |
| 355 | 367 | printf("OK\n"); |
| 356 | - else | |
| 368 | + } else { | |
| 357 | 369 | printf("FAILED\n"); |
| 370 | + goto close; | |
| 371 | + } | |
| 358 | 372 | |
| 359 | 373 | ret = read_holding_registers(&mb_param, |
| 360 | 374 | UT_HOLDING_REGISTERS_ADDRESS, |
| 361 | 375 | MAX_REGISTERS + 1, |
| 362 | 376 | tab_rp_registers); |
| 363 | 377 | printf("* read_holding_registers: "); |
| 364 | - if (ret == TOO_MANY_DATA) | |
| 378 | + if (ret == INVALID_DATA) { | |
| 365 | 379 | printf("OK\n"); |
| 366 | - else | |
| 380 | + } else { | |
| 367 | 381 | printf("FAILED\n"); |
| 382 | + goto close; | |
| 383 | + } | |
| 368 | 384 | |
| 369 | 385 | ret = read_input_registers(&mb_param, |
| 370 | 386 | UT_INPUT_REGISTERS_ADDRESS, |
| 371 | 387 | MAX_REGISTERS + 1, |
| 372 | 388 | tab_rp_registers); |
| 373 | 389 | printf("* read_input_registers: "); |
| 374 | - if (ret == TOO_MANY_DATA) | |
| 390 | + if (ret == INVALID_DATA) { | |
| 375 | 391 | printf("OK\n"); |
| 376 | - else | |
| 392 | + } else { | |
| 377 | 393 | printf("FAILED\n"); |
| 394 | + goto close; | |
| 395 | + } | |
| 378 | 396 | |
| 379 | 397 | ret = force_multiple_coils(&mb_param, |
| 380 | 398 | UT_COIL_STATUS_ADDRESS, |
| 381 | 399 | MAX_STATUS + 1, |
| 382 | 400 | tab_rp_status); |
| 383 | 401 | printf("* force_multiple_coils: "); |
| 384 | - if (ret == TOO_MANY_DATA) { | |
| 402 | + if (ret == INVALID_DATA) { | |
| 385 | 403 | printf("OK\n"); |
| 386 | 404 | } else { |
| 405 | + goto close; | |
| 387 | 406 | printf("FAILED\n"); |
| 388 | 407 | } |
| 389 | 408 | |
| ... | ... | @@ -392,10 +411,11 @@ int main(void) |
| 392 | 411 | MAX_REGISTERS + 1, |
| 393 | 412 | tab_rp_registers); |
| 394 | 413 | printf("* preset_multiple_registers: "); |
| 395 | - if (ret == TOO_MANY_DATA) { | |
| 414 | + if (ret == INVALID_DATA) { | |
| 396 | 415 | printf("OK\n"); |
| 397 | 416 | } else { |
| 398 | 417 | printf("FAILED\n"); |
| 418 | + goto close; | |
| 399 | 419 | } |
| 400 | 420 | |
| 401 | 421 | /** SLAVE REPLY **/ |
| ... | ... | @@ -407,10 +427,11 @@ int main(void) |
| 407 | 427 | UT_HOLDING_REGISTERS_NB_POINTS, |
| 408 | 428 | tab_rp_registers); |
| 409 | 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 | 431 | printf("OK\n", ret); |
| 412 | 432 | } else { |
| 413 | 433 | printf("FAILED\n"); |
| 434 | + goto close; | |
| 414 | 435 | } |
| 415 | 436 | |
| 416 | 437 | mb_param.slave = MODBUS_BROADCAST_ADDRESS; |
| ... | ... | @@ -422,6 +443,7 @@ int main(void) |
| 422 | 443 | if (ret == UT_HOLDING_REGISTERS_NB_POINTS) { |
| 423 | 444 | printf("OK\n", ret); |
| 424 | 445 | } else { |
| 446 | + goto close; | |
| 425 | 447 | printf("FAILED\n"); |
| 426 | 448 | } |
| 427 | 449 | |
| ... | ... | @@ -436,11 +458,11 @@ int main(void) |
| 436 | 458 | UT_HOLDING_REGISTERS_NB_POINTS_SPECIAL, |
| 437 | 459 | tab_rp_registers_bad); |
| 438 | 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 | 462 | printf("OK\n"); |
| 463 | + } else { | |
| 464 | + printf("FAILED\n"); | |
| 465 | + goto close; | |
| 444 | 466 | } |
| 445 | 467 | free(tab_rp_registers_bad); |
| 446 | 468 | ... | ... |