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 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)
... ...