Commit 9d5344cf42e425b33028cae11d5b74e4754af9c2

Authored by Stéphane Raimbault
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
doc/modbus_receive.txt
@@ -25,8 +25,9 @@ context 'ctx', see the function linkmb:modbus_set_socket[3]. @@ -25,8 +25,9 @@ context 'ctx', see the function linkmb:modbus_set_socket[3].
25 RETURN VALUE 25 RETURN VALUE
26 ------------ 26 ------------
27 The _modbus_receive()_ function shall store the indication request in 'req' and 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 SEE ALSO 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,8 +23,9 @@ function can be used to receive request not handled by the library.
23 RETURN VALUE 23 RETURN VALUE
24 ------------ 24 ------------
25 The _modbus_receive_confirmation()_ function shall store the confirmation 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 SEE ALSO 31 SEE ALSO
src/modbus-private.h
@@ -97,7 +97,6 @@ typedef struct _modbus_backend { @@ -97,7 +97,6 @@ typedef struct _modbus_backend {
97 void (*close) (modbus_t *ctx); 97 void (*close) (modbus_t *ctx);
98 int (*flush) (modbus_t *ctx); 98 int (*flush) (modbus_t *ctx);
99 int (*select) (modbus_t *ctx, fd_set *rfds, struct timeval *tv, int msg_length); 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 } modbus_backend_t; 100 } modbus_backend_t;
102 101
103 struct _modbus { 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,7 +328,7 @@ int _modbus_rtu_pre_check_confirmation(modbus_t *ctx, const uint8_t *req,
328 if (req[0] != 0 && req[0] != rsp[0]) { 328 if (req[0] != 0 && req[0] != rsp[0]) {
329 if (ctx->debug) { 329 if (ctx->debug) {
330 fprintf(stderr, 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 rsp[0], req[0]); 332 rsp[0], req[0]);
333 } 333 }
334 errno = EMBBADSLAVE; 334 errno = EMBBADSLAVE;
@@ -338,13 +338,24 @@ int _modbus_rtu_pre_check_confirmation(modbus_t *ctx, const uint8_t *req, @@ -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 int _modbus_rtu_check_integrity(modbus_t *ctx, uint8_t *msg, 344 int _modbus_rtu_check_integrity(modbus_t *ctx, uint8_t *msg,
344 const int msg_length) 345 const int msg_length)
345 { 346 {
346 uint16_t crc_calculated; 347 uint16_t crc_calculated;
347 uint16_t crc_received; 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 crc_calculated = crc16(msg, msg_length - 2); 360 crc_calculated = crc16(msg, msg_length - 2);
350 crc_received = (msg[msg_length - 2] << 8) | msg[msg_length - 1]; 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,21 +959,6 @@ int _modbus_rtu_select(modbus_t *ctx, fd_set *rfds,
948 return s_rc; 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 const modbus_backend_t _modbus_rtu_backend = { 962 const modbus_backend_t _modbus_rtu_backend = {
967 _MODBUS_BACKEND_TYPE_RTU, 963 _MODBUS_BACKEND_TYPE_RTU,
968 _MODBUS_RTU_HEADER_LENGTH, 964 _MODBUS_RTU_HEADER_LENGTH,
@@ -980,8 +976,7 @@ const modbus_backend_t _modbus_rtu_backend = { @@ -980,8 +976,7 @@ const modbus_backend_t _modbus_rtu_backend = {
980 _modbus_rtu_connect, 976 _modbus_rtu_connect,
981 _modbus_rtu_close, 977 _modbus_rtu_close,
982 _modbus_rtu_flush, 978 _modbus_rtu_flush,
983 - _modbus_rtu_select,  
984 - _modbus_rtu_filter_request 979 + _modbus_rtu_select
985 }; 980 };
986 981
987 modbus_t* modbus_new_rtu(const char *device, 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,11 +586,6 @@ int _modbus_tcp_select(modbus_t *ctx, fd_set *rfds, struct timeval *tv, int leng
586 return s_rc; 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 const modbus_backend_t _modbus_tcp_backend = { 589 const modbus_backend_t _modbus_tcp_backend = {
595 _MODBUS_BACKEND_TYPE_TCP, 590 _MODBUS_BACKEND_TYPE_TCP,
596 _MODBUS_TCP_HEADER_LENGTH, 591 _MODBUS_TCP_HEADER_LENGTH,
@@ -608,8 +603,7 @@ const modbus_backend_t _modbus_tcp_backend = { @@ -608,8 +603,7 @@ const modbus_backend_t _modbus_tcp_backend = {
608 _modbus_tcp_connect, 603 _modbus_tcp_connect,
609 _modbus_tcp_close, 604 _modbus_tcp_close,
610 _modbus_tcp_flush, 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,8 +624,7 @@ const modbus_backend_t _modbus_tcp_pi_backend = {
630 _modbus_tcp_pi_connect, 624 _modbus_tcp_pi_connect,
631 _modbus_tcp_close, 625 _modbus_tcp_close,
632 _modbus_tcp_flush, 626 _modbus_tcp_flush,
633 - _modbus_tcp_select,  
634 - _modbus_tcp_filter_request 627 + _modbus_tcp_select
635 }; 628 };
636 629
637 modbus_t* modbus_new_tcp(const char *ip, int port) 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,11 +661,6 @@ int modbus_reply(modbus_t *ctx, const uint8_t *req,
661 int rsp_length = 0; 661 int rsp_length = 0;
662 sft_t sft; 662 sft_t sft;
663 663
664 - if (ctx->backend->filter_request(ctx, slave) == 1) {  
665 - /* Filtered */  
666 - return 0;  
667 - }  
668 -  
669 sft.slave = slave; 664 sft.slave = slave;
670 sft.function = function; 665 sft.function = function;
671 sft.t_id = ctx->backend->prepare_response_tid(req, &req_length); 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,11 +930,6 @@ int modbus_reply_exception(modbus_t *ctx, const uint8_t *req,
935 int dummy_length = 99; 930 int dummy_length = 99;
936 sft_t sft; 931 sft_t sft;
937 932
938 - if (ctx->backend->filter_request(ctx, slave) == 1) {  
939 - /* Filtered */  
940 - return 0;  
941 - }  
942 -  
943 sft.slave = slave; 933 sft.slave = slave;
944 sft.function = function + 0x80;; 934 sft.function = function + 0x80;;
945 sft.t_id = ctx->backend->prepare_response_tid(req, &dummy_length); 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,10 +120,11 @@ int main(void)
120 120
121 modbus_set_socket(ctx, master_socket); 121 modbus_set_socket(ctx, master_socket);
122 rc = modbus_receive(ctx, query); 122 rc = modbus_receive(ctx, query);
123 - if (rc != -1) { 123 + if (rc > 0) {
124 modbus_reply(ctx, query, rc, mb_mapping); 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 printf("Connection closed on socket %d\n", master_socket); 128 printf("Connection closed on socket %d\n", master_socket);
128 close(master_socket); 129 close(master_socket);
129 130
tests/bandwidth-server-one.c
@@ -75,10 +75,10 @@ int main(int argc, char *argv[]) @@ -75,10 +75,10 @@ int main(int argc, char *argv[])
75 uint8_t query[MODBUS_TCP_MAX_ADU_LENGTH]; 75 uint8_t query[MODBUS_TCP_MAX_ADU_LENGTH];
76 76
77 rc = modbus_receive(ctx, query); 77 rc = modbus_receive(ctx, query);
78 - if (rc >= 0) { 78 + if (rc > 0) {
79 modbus_reply(ctx, query, rc, mb_mapping); 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 break; 82 break;
83 } 83 }
84 } 84 }
tests/random-test-server.c
@@ -47,10 +47,10 @@ int main(void) @@ -47,10 +47,10 @@ int main(void)
47 int rc; 47 int rc;
48 48
49 rc = modbus_receive(ctx, query); 49 rc = modbus_receive(ctx, query);
50 - if (rc != -1) { 50 + if (rc > 0) {
51 /* rc is the query size */ 51 /* rc is the query size */
52 modbus_reply(ctx, query, rc, mb_mapping); 52 modbus_reply(ctx, query, rc, mb_mapping);
53 - } else { 53 + } else if (rc == -1) {
54 /* Connection closed by the client or error */ 54 /* Connection closed by the client or error */
55 break; 55 break;
56 } 56 }
tests/unit-test-server.c
@@ -114,12 +114,17 @@ int main(int argc, char*argv[]) @@ -114,12 +114,17 @@ int main(int argc, char*argv[])
114 } 114 }
115 115
116 for (;;) { 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 if (rc == -1) { 122 if (rc == -1) {
119 /* Connection closed by the client or error */ 123 /* Connection closed by the client or error */
120 break; 124 break;
121 } 125 }
122 126
  127 +
123 /* Read holding registers */ 128 /* Read holding registers */
124 if (query[header_length] == 0x03) { 129 if (query[header_length] == 0x03) {
125 if (MODBUS_GET_INT16_FROM_INT8(query, header_length + 3) 130 if (MODBUS_GET_INT16_FROM_INT8(query, header_length + 3)