Commit 9d5344cf42e425b33028cae11d5b74e4754af9c2
1 parent
a6e63d7d
Move RTU filtering in CRC check to avoid useless call to modbus_reply
Warning, modbus_receive returns 0 when a query is ignored. - function removed from TCP and RTU code and from backend structure - updated documentation - updated examples
Showing
10 changed files
with
38 additions
and
53 deletions
doc/modbus_receive.txt
| ... | ... | @@ -25,8 +25,9 @@ context 'ctx', see the function linkmb:modbus_set_socket[3]. |
| 25 | 25 | RETURN VALUE |
| 26 | 26 | ------------ |
| 27 | 27 | The _modbus_receive()_ function shall store the indication request in 'req' and |
| 28 | -return the request length if sucessful. Otherwise it shall return -1 and set | |
| 29 | -errno. | |
| 28 | +return the request length if sucessful. The returned request length can be zero | |
| 29 | +if the indication request is ignored (eg. a query for another slave in RTU | |
| 30 | +mode). Otherwise it shall return -1 and set errno. | |
| 30 | 31 | |
| 31 | 32 | |
| 32 | 33 | SEE ALSO | ... | ... |
doc/modbus_receive_confirmation.txt
| ... | ... | @@ -23,8 +23,9 @@ function can be used to receive request not handled by the library. |
| 23 | 23 | RETURN VALUE |
| 24 | 24 | ------------ |
| 25 | 25 | The _modbus_receive_confirmation()_ function shall store the confirmation |
| 26 | -request in 'rsp' and return the response length if sucessful. Otherwise it shall | |
| 27 | -return -1 and set errno. | |
| 26 | +request in 'rsp' and return the response length if sucessful. The returned | |
| 27 | +request length can be zero if the indication request is ignored (eg. a query for | |
| 28 | +another slave in RTU mode). Otherwise it shall return -1 and set errno. | |
| 28 | 29 | |
| 29 | 30 | |
| 30 | 31 | SEE ALSO | ... | ... |
src/modbus-private.h
| ... | ... | @@ -97,7 +97,6 @@ typedef struct _modbus_backend { |
| 97 | 97 | void (*close) (modbus_t *ctx); |
| 98 | 98 | int (*flush) (modbus_t *ctx); |
| 99 | 99 | int (*select) (modbus_t *ctx, fd_set *rfds, struct timeval *tv, int msg_length); |
| 100 | - int (*filter_request) (modbus_t *ctx, int slave); | |
| 101 | 100 | } modbus_backend_t; |
| 102 | 101 | |
| 103 | 102 | struct _modbus { | ... | ... |
src/modbus-rtu.c
| ... | ... | @@ -328,7 +328,7 @@ int _modbus_rtu_pre_check_confirmation(modbus_t *ctx, const uint8_t *req, |
| 328 | 328 | if (req[0] != 0 && req[0] != rsp[0]) { |
| 329 | 329 | if (ctx->debug) { |
| 330 | 330 | fprintf(stderr, |
| 331 | - "The responding slave %d it not the requested slave %d", | |
| 331 | + "The responding slave %d isn't the requested slave %d", | |
| 332 | 332 | rsp[0], req[0]); |
| 333 | 333 | } |
| 334 | 334 | errno = EMBBADSLAVE; |
| ... | ... | @@ -338,13 +338,24 @@ int _modbus_rtu_pre_check_confirmation(modbus_t *ctx, const uint8_t *req, |
| 338 | 338 | } |
| 339 | 339 | } |
| 340 | 340 | |
| 341 | -/* The check_crc16 function shall return the message length if the CRC is | |
| 342 | - valid. Otherwise it shall return -1 and set errno to EMBADCRC. */ | |
| 341 | +/* The check_crc16 function shall return 0 is the message is ignored and the | |
| 342 | + message length if the CRC is valid. Otherwise it shall return -1 and set | |
| 343 | + errno to EMBADCRC. */ | |
| 343 | 344 | int _modbus_rtu_check_integrity(modbus_t *ctx, uint8_t *msg, |
| 344 | 345 | const int msg_length) |
| 345 | 346 | { |
| 346 | 347 | uint16_t crc_calculated; |
| 347 | 348 | uint16_t crc_received; |
| 349 | + int slave = msg[0]; | |
| 350 | + | |
| 351 | + /* Filter on the Modbus unit identifier (slave) in RTU mode */ | |
| 352 | + if (slave != ctx->slave && slave != MODBUS_BROADCAST_ADDRESS) { | |
| 353 | + /* Ignores the request (not for me) */ | |
| 354 | + if (ctx->debug) { | |
| 355 | + printf("Request for slave %d ignored (not %d)\n", slave, ctx->slave); | |
| 356 | + } | |
| 357 | + return 0; | |
| 358 | + } | |
| 348 | 359 | |
| 349 | 360 | crc_calculated = crc16(msg, msg_length - 2); |
| 350 | 361 | crc_received = (msg[msg_length - 2] << 8) | msg[msg_length - 1]; |
| ... | ... | @@ -948,21 +959,6 @@ int _modbus_rtu_select(modbus_t *ctx, fd_set *rfds, |
| 948 | 959 | return s_rc; |
| 949 | 960 | } |
| 950 | 961 | |
| 951 | -int _modbus_rtu_filter_request(modbus_t *ctx, int slave) | |
| 952 | -{ | |
| 953 | - /* Filter on the Modbus unit identifier (slave) in RTU mode */ | |
| 954 | - if (slave != ctx->slave && slave != MODBUS_BROADCAST_ADDRESS) { | |
| 955 | - /* Ignores the request (not for me) */ | |
| 956 | - if (ctx->debug) { | |
| 957 | - printf("Request for slave %d ignored (not %d)\n", | |
| 958 | - slave, ctx->slave); | |
| 959 | - } | |
| 960 | - return 1; | |
| 961 | - } else { | |
| 962 | - return 0; | |
| 963 | - } | |
| 964 | -} | |
| 965 | - | |
| 966 | 962 | const modbus_backend_t _modbus_rtu_backend = { |
| 967 | 963 | _MODBUS_BACKEND_TYPE_RTU, |
| 968 | 964 | _MODBUS_RTU_HEADER_LENGTH, |
| ... | ... | @@ -980,8 +976,7 @@ const modbus_backend_t _modbus_rtu_backend = { |
| 980 | 976 | _modbus_rtu_connect, |
| 981 | 977 | _modbus_rtu_close, |
| 982 | 978 | _modbus_rtu_flush, |
| 983 | - _modbus_rtu_select, | |
| 984 | - _modbus_rtu_filter_request | |
| 979 | + _modbus_rtu_select | |
| 985 | 980 | }; |
| 986 | 981 | |
| 987 | 982 | modbus_t* modbus_new_rtu(const char *device, | ... | ... |
src/modbus-tcp.c
| ... | ... | @@ -586,11 +586,6 @@ int _modbus_tcp_select(modbus_t *ctx, fd_set *rfds, struct timeval *tv, int leng |
| 586 | 586 | return s_rc; |
| 587 | 587 | } |
| 588 | 588 | |
| 589 | -int _modbus_tcp_filter_request(modbus_t *ctx, int slave) | |
| 590 | -{ | |
| 591 | - return 0; | |
| 592 | -} | |
| 593 | - | |
| 594 | 589 | const modbus_backend_t _modbus_tcp_backend = { |
| 595 | 590 | _MODBUS_BACKEND_TYPE_TCP, |
| 596 | 591 | _MODBUS_TCP_HEADER_LENGTH, |
| ... | ... | @@ -608,8 +603,7 @@ const modbus_backend_t _modbus_tcp_backend = { |
| 608 | 603 | _modbus_tcp_connect, |
| 609 | 604 | _modbus_tcp_close, |
| 610 | 605 | _modbus_tcp_flush, |
| 611 | - _modbus_tcp_select, | |
| 612 | - _modbus_tcp_filter_request | |
| 606 | + _modbus_tcp_select | |
| 613 | 607 | }; |
| 614 | 608 | |
| 615 | 609 | |
| ... | ... | @@ -630,8 +624,7 @@ const modbus_backend_t _modbus_tcp_pi_backend = { |
| 630 | 624 | _modbus_tcp_pi_connect, |
| 631 | 625 | _modbus_tcp_close, |
| 632 | 626 | _modbus_tcp_flush, |
| 633 | - _modbus_tcp_select, | |
| 634 | - _modbus_tcp_filter_request | |
| 627 | + _modbus_tcp_select | |
| 635 | 628 | }; |
| 636 | 629 | |
| 637 | 630 | modbus_t* modbus_new_tcp(const char *ip, int port) | ... | ... |
src/modbus.c
| ... | ... | @@ -661,11 +661,6 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req, |
| 661 | 661 | int rsp_length = 0; |
| 662 | 662 | sft_t sft; |
| 663 | 663 | |
| 664 | - if (ctx->backend->filter_request(ctx, slave) == 1) { | |
| 665 | - /* Filtered */ | |
| 666 | - return 0; | |
| 667 | - } | |
| 668 | - | |
| 669 | 664 | sft.slave = slave; |
| 670 | 665 | sft.function = function; |
| 671 | 666 | sft.t_id = ctx->backend->prepare_response_tid(req, &req_length); |
| ... | ... | @@ -935,11 +930,6 @@ int modbus_reply_exception(modbus_t *ctx, const uint8_t *req, |
| 935 | 930 | int dummy_length = 99; |
| 936 | 931 | sft_t sft; |
| 937 | 932 | |
| 938 | - if (ctx->backend->filter_request(ctx, slave) == 1) { | |
| 939 | - /* Filtered */ | |
| 940 | - return 0; | |
| 941 | - } | |
| 942 | - | |
| 943 | 933 | sft.slave = slave; |
| 944 | 934 | sft.function = function + 0x80;; |
| 945 | 935 | sft.t_id = ctx->backend->prepare_response_tid(req, &dummy_length); | ... | ... |
tests/bandwidth-server-many-up.c
| ... | ... | @@ -120,10 +120,11 @@ int main(void) |
| 120 | 120 | |
| 121 | 121 | modbus_set_socket(ctx, master_socket); |
| 122 | 122 | rc = modbus_receive(ctx, query); |
| 123 | - if (rc != -1) { | |
| 123 | + if (rc > 0) { | |
| 124 | 124 | modbus_reply(ctx, query, rc, mb_mapping); |
| 125 | - } else { | |
| 126 | - /* Connection closed by the client, end of server */ | |
| 125 | + } else if (rc == -1) { | |
| 126 | + /* This example server in ended on connection closing or | |
| 127 | + * any errors. */ | |
| 127 | 128 | printf("Connection closed on socket %d\n", master_socket); |
| 128 | 129 | close(master_socket); |
| 129 | 130 | ... | ... |
tests/bandwidth-server-one.c
| ... | ... | @@ -75,10 +75,10 @@ int main(int argc, char *argv[]) |
| 75 | 75 | uint8_t query[MODBUS_TCP_MAX_ADU_LENGTH]; |
| 76 | 76 | |
| 77 | 77 | rc = modbus_receive(ctx, query); |
| 78 | - if (rc >= 0) { | |
| 78 | + if (rc > 0) { | |
| 79 | 79 | modbus_reply(ctx, query, rc, mb_mapping); |
| 80 | - } else { | |
| 81 | - /* Connection closed by the client or server */ | |
| 80 | + } else if (rc == -1) { | |
| 81 | + /* Connection closed by the client or error */ | |
| 82 | 82 | break; |
| 83 | 83 | } |
| 84 | 84 | } | ... | ... |
tests/random-test-server.c
| ... | ... | @@ -47,10 +47,10 @@ int main(void) |
| 47 | 47 | int rc; |
| 48 | 48 | |
| 49 | 49 | rc = modbus_receive(ctx, query); |
| 50 | - if (rc != -1) { | |
| 50 | + if (rc > 0) { | |
| 51 | 51 | /* rc is the query size */ |
| 52 | 52 | modbus_reply(ctx, query, rc, mb_mapping); |
| 53 | - } else { | |
| 53 | + } else if (rc == -1) { | |
| 54 | 54 | /* Connection closed by the client or error */ |
| 55 | 55 | break; |
| 56 | 56 | } | ... | ... |
tests/unit-test-server.c
| ... | ... | @@ -114,12 +114,17 @@ int main(int argc, char*argv[]) |
| 114 | 114 | } |
| 115 | 115 | |
| 116 | 116 | for (;;) { |
| 117 | - rc = modbus_receive(ctx, query); | |
| 117 | + do { | |
| 118 | + rc = modbus_receive(ctx, query); | |
| 119 | + /* Filtered queries return 0 */ | |
| 120 | + } while (rc == 0); | |
| 121 | + | |
| 118 | 122 | if (rc == -1) { |
| 119 | 123 | /* Connection closed by the client or error */ |
| 120 | 124 | break; |
| 121 | 125 | } |
| 122 | 126 | |
| 127 | + | |
| 123 | 128 | /* Read holding registers */ |
| 124 | 129 | if (query[header_length] == 0x03) { |
| 125 | 130 | if (MODBUS_GET_INT16_FROM_INT8(query, header_length + 3) | ... | ... |