Commit 018cdd6e686830c92976bfaaa89345f3c6bc9f18

Authored by Stéphane Raimbault
1 parent 0e4e82e8

New function modbus_receive_confirmation

The _modbus_receive_confirmation()_ function shall receive a
request via the socket of the context 'ctx'. This function must be
used for debugging purposes because the received response isn't
checked against the initial request. This function can be
convenient to receive request not handled by the library.
doc/Makefile.am
@@ -13,6 +13,7 @@ MAN3 = \ @@ -13,6 +13,7 @@ MAN3 = \
13 modbus_read_input_bits.3 \ 13 modbus_read_input_bits.3 \
14 modbus_read_input_registers.3 \ 14 modbus_read_input_registers.3 \
15 modbus_read_registers.3 \ 15 modbus_read_registers.3 \
  16 + modbus_receive_confirmation.3 \
16 modbus_send_raw_request.3 \ 17 modbus_send_raw_request.3 \
17 modbus_set_debug.3 \ 18 modbus_set_debug.3 \
18 modbus_set_error_recovery.3 \ 19 modbus_set_error_recovery.3 \
doc/modbus_receive_confirmation.txt 0 → 100644
  1 +modbus_receive_confirmation(3)
  2 +==============================
  3 +
  4 +
  5 +NAME
  6 +----
  7 +modbus_receive_confirmation - receive a confirmation request
  8 +
  9 +
  10 +SYNOPSIS
  11 +--------
  12 +*int modbus_receive_confirmation(*modbus_t 'ctx', uint8_t *'rsp');*
  13 +
  14 +
  15 +DESCRIPTION
  16 +-----------
  17 +The _modbus_receive_confirmation()_ function shall receive a request via the
  18 +socket of the context 'ctx'. This function must be used for debugging purposes
  19 +because the received response isn't checked against the initial request. This
  20 +function can be used to receive request not handled by the library.
  21 +
  22 +
  23 +RETURN VALUE
  24 +------------
  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.
  28 +
  29 +
  30 +SEE ALSO
  31 +--------
  32 +linkmb:modbus_send_raw_request[3]
  33 +
  34 +
  35 +AUTHORS
  36 +-------
  37 +The libmodbus documentation was written by Stéphane Raimbault
  38 +<stephane.raimbault@gmail.com>
doc/modbus_send_raw_request.txt
@@ -47,7 +47,7 @@ if (modbus_connect(ctx) == -1) { @@ -47,7 +47,7 @@ if (modbus_connect(ctx) == -1) {
47 } 47 }
48 48
49 req_length = modbus_send_raw_request(ctx, raw_req, 6 * sizeof(uint8_t)); 49 req_length = modbus_send_raw_request(ctx, raw_req, 6 * sizeof(uint8_t));
50 -modbus_receive(ctx, -1, rsp); 50 +modbus_receive_confirmation(ctx, rsp);
51 51
52 modbus_close(ctx); 52 modbus_close(ctx);
53 modbus_free(ctx); 53 modbus_free(ctx);
@@ -55,7 +55,7 @@ modbus_free(ctx); @@ -55,7 +55,7 @@ modbus_free(ctx);
55 55
56 SEE ALSO 56 SEE ALSO
57 -------- 57 --------
58 -linkmb:modbus_receive[3] 58 +linkmb:modbus_receive_confirmation[3]
59 59
60 60
61 AUTHORS 61 AUTHORS
src/modbus.c
@@ -428,32 +428,34 @@ int modbus_receive(modbus_t *ctx, int sockfd, uint8_t *req) @@ -428,32 +428,34 @@ int modbus_receive(modbus_t *ctx, int sockfd, uint8_t *req)
428 return receive_msg(ctx, req, MSG_INDICATION); 428 return receive_msg(ctx, req, MSG_INDICATION);
429 } 429 }
430 430
431 -/* Receives the response and checks values. 431 +/* Receives the confirmation.
432 432
433 - The function shall return the number of values (bits or words) and the  
434 - response if successful. Otherwise, its shall return -1 and errno is set. 433 + The function shall store the read response in rsp and return the number of
  434 + values (bits or words). Otherwise, its shall return -1 and errno is set.
435 435
436 - Note: all functions used to send or receive data with modbus return  
437 - these values. */  
438 -static int receive_msg_req(modbus_t *ctx, uint8_t *req, uint8_t *rsp) 436 + The function doesn't check the confirmation is the expected response to the
  437 + initial request.
  438 +*/
  439 +int modbus_receive_confirmation(modbus_t *ctx, uint8_t *rsp)
  440 +{
  441 + return receive_msg(ctx, rsp, MSG_CONFIRMATION);
  442 +}
  443 +
  444 +static int check_confirmation(modbus_t *ctx, uint8_t *req,
  445 + uint8_t *rsp, uint8_t rsp_length)
439 { 446 {
440 int rc; 447 int rc;
441 int rsp_length_computed; 448 int rsp_length_computed;
442 - int offset = ctx->backend->header_length;  
443 -  
444 - rc = receive_msg(ctx, rsp, MSG_CONFIRMATION);  
445 - if (rc == -1) {  
446 - return -1;  
447 - } 449 + const int offset = ctx->backend->header_length;
448 450
449 rsp_length_computed = compute_response_length_from_request(ctx, req); 451 rsp_length_computed = compute_response_length_from_request(ctx, req);
450 452
451 /* Check length */ 453 /* Check length */
452 - if (rc == rsp_length_computed || 454 + if (rsp_length == rsp_length_computed ||
453 rsp_length_computed == MSG_LENGTH_UNDEFINED) { 455 rsp_length_computed == MSG_LENGTH_UNDEFINED) {
454 int req_nb_value; 456 int req_nb_value;
455 int rsp_nb_value; 457 int rsp_nb_value;
456 - int function = rsp[offset]; 458 + const int function = rsp[offset];
457 459
458 /* Check function code */ 460 /* Check function code */
459 if (function != req[offset]) { 461 if (function != req[offset]) {
@@ -510,7 +512,7 @@ static int receive_msg_req(modbus_t *ctx, uint8_t *req, uint8_t *rsp) @@ -510,7 +512,7 @@ static int receive_msg_req(modbus_t *ctx, uint8_t *req, uint8_t *rsp)
510 errno = EMBBADDATA; 512 errno = EMBBADDATA;
511 rc = -1; 513 rc = -1;
512 } 514 }
513 - } else if (rc == (offset + 2 + ctx->backend->checksum_length) && 515 + } else if (rsp_length == (offset + 2 + ctx->backend->checksum_length) &&
514 req[offset] == (rsp[offset] - 0x80)) { 516 req[offset] == (rsp[offset] - 0x80)) {
515 /* EXCEPTION CODE RECEIVED */ 517 /* EXCEPTION CODE RECEIVED */
516 518
@@ -526,7 +528,7 @@ static int receive_msg_req(modbus_t *ctx, uint8_t *req, uint8_t *rsp) @@ -526,7 +528,7 @@ static int receive_msg_req(modbus_t *ctx, uint8_t *req, uint8_t *rsp)
526 if (ctx->debug) { 528 if (ctx->debug) {
527 fprintf(stderr, 529 fprintf(stderr,
528 "Message length not corresponding to the computed length (%d != %d)\n", 530 "Message length not corresponding to the computed length (%d != %d)\n",
529 - rc, rsp_length_computed); 531 + rsp_length, rsp_length_computed);
530 } 532 }
531 errno = EMBBADDATA; 533 errno = EMBBADDATA;
532 rc = -1; 534 rc = -1;
@@ -896,7 +898,11 @@ static int read_io_status(modbus_t *ctx, int function, @@ -896,7 +898,11 @@ static int read_io_status(modbus_t *ctx, int function,
896 int offset; 898 int offset;
897 int offset_end; 899 int offset_end;
898 900
899 - rc = receive_msg_req(ctx, req, rsp); 901 + rc = receive_msg(ctx, rsp, MSG_CONFIRMATION);
  902 + if (rc == -1)
  903 + return -1;
  904 +
  905 + rc = check_confirmation(ctx, req, rsp, rc);
900 if (rc == -1) 906 if (rc == -1)
901 return -1; 907 return -1;
902 908
@@ -991,10 +997,13 @@ static int read_registers(modbus_t *ctx, int function, int addr, int nb, @@ -991,10 +997,13 @@ static int read_registers(modbus_t *ctx, int function, int addr, int nb,
991 int offset; 997 int offset;
992 int i; 998 int i;
993 999
994 - rc = receive_msg_req(ctx, req, rsp);  
995 - if (rc == -1) { 1000 + rc = receive_msg(ctx, rsp, MSG_CONFIRMATION);
  1001 + if (rc == -1)
  1002 + return -1;
  1003 +
  1004 + rc = check_confirmation(ctx, req, rsp, rc);
  1005 + if (rc == -1)
996 return -1; 1006 return -1;
997 - }  
998 1007
999 offset = ctx->backend->header_length; 1008 offset = ctx->backend->header_length;
1000 1009
@@ -1063,7 +1072,12 @@ static int write_single(modbus_t *ctx, int function, int addr, int value) @@ -1063,7 +1072,12 @@ static int write_single(modbus_t *ctx, int function, int addr, int value)
1063 if (rc > 0) { 1072 if (rc > 0) {
1064 /* Used by write_bit and write_register */ 1073 /* Used by write_bit and write_register */
1065 uint8_t rsp[_MIN_REQ_LENGTH]; 1074 uint8_t rsp[_MIN_REQ_LENGTH];
1066 - rc = receive_msg_req(ctx, req, rsp); 1075 +
  1076 + rc = receive_msg(ctx, rsp, MSG_CONFIRMATION);
  1077 + if (rc == -1)
  1078 + return -1;
  1079 +
  1080 + rc = check_confirmation(ctx, req, rsp, rc);
1067 } 1081 }
1068 1082
1069 return rc; 1083 return rc;
@@ -1129,7 +1143,12 @@ int modbus_write_bits(modbus_t *ctx, int addr, int nb, const uint8_t *src) @@ -1129,7 +1143,12 @@ int modbus_write_bits(modbus_t *ctx, int addr, int nb, const uint8_t *src)
1129 rc = send_msg(ctx, req, req_length); 1143 rc = send_msg(ctx, req, req_length);
1130 if (rc > 0) { 1144 if (rc > 0) {
1131 uint8_t rsp[MAX_MESSAGE_LENGTH]; 1145 uint8_t rsp[MAX_MESSAGE_LENGTH];
1132 - rc = receive_msg_req(ctx, req, rsp); 1146 +
  1147 + rc = receive_msg(ctx, rsp, MSG_CONFIRMATION);
  1148 + if (rc == -1)
  1149 + return -1;
  1150 +
  1151 + rc = check_confirmation(ctx, req, rsp, rc);
1133 } 1152 }
1134 1153
1135 1154
@@ -1170,7 +1189,12 @@ int modbus_write_registers(modbus_t *ctx, int addr, int nb, const uint16_t *src) @@ -1170,7 +1189,12 @@ int modbus_write_registers(modbus_t *ctx, int addr, int nb, const uint16_t *src)
1170 rc = send_msg(ctx, req, req_length); 1189 rc = send_msg(ctx, req, req_length);
1171 if (rc > 0) { 1190 if (rc > 0) {
1172 uint8_t rsp[MAX_MESSAGE_LENGTH]; 1191 uint8_t rsp[MAX_MESSAGE_LENGTH];
1173 - rc = receive_msg_req(ctx, req, rsp); 1192 +
  1193 + rc = receive_msg(ctx, rsp, MSG_CONFIRMATION);
  1194 + if (rc == -1)
  1195 + return -1;
  1196 +
  1197 + rc = check_confirmation(ctx, req, rsp, rc);
1174 } 1198 }
1175 1199
1176 return rc; 1200 return rc;
@@ -1228,7 +1252,14 @@ int modbus_read_and_write_registers(modbus_t *ctx, @@ -1228,7 +1252,14 @@ int modbus_read_and_write_registers(modbus_t *ctx,
1228 if (rc > 0) { 1252 if (rc > 0) {
1229 int offset; 1253 int offset;
1230 1254
1231 - rc = receive_msg_req(ctx, req, rsp); 1255 + rc = receive_msg(ctx, rsp, MSG_CONFIRMATION);
  1256 + if (rc == -1)
  1257 + return -1;
  1258 +
  1259 + rc = check_confirmation(ctx, req, rsp, rc);
  1260 + if (rc == -1)
  1261 + return -1;
  1262 +
1232 offset = ctx->backend->header_length; 1263 offset = ctx->backend->header_length;
1233 1264
1234 /* If rc is negative, the loop is jumped ! */ 1265 /* If rc is negative, the loop is jumped ! */
@@ -1262,14 +1293,18 @@ int modbus_report_slave_id(modbus_t *ctx, uint8_t *dest) @@ -1262,14 +1293,18 @@ int modbus_report_slave_id(modbus_t *ctx, uint8_t *dest)
1262 int offset; 1293 int offset;
1263 uint8_t rsp[MAX_MESSAGE_LENGTH]; 1294 uint8_t rsp[MAX_MESSAGE_LENGTH];
1264 1295
1265 - /* Byte count, slave id, run indicator status,  
1266 - additional data */  
1267 - rc = receive_msg_req(ctx, req, rsp); 1296 + rc = receive_msg(ctx, rsp, MSG_CONFIRMATION);
  1297 + if (rc == -1)
  1298 + return -1;
  1299 +
  1300 + rc = check_confirmation(ctx, req, rsp, rc);
1268 if (rc == -1) 1301 if (rc == -1)
1269 return -1; 1302 return -1;
1270 1303
1271 offset = ctx->backend->header_length + 2; 1304 offset = ctx->backend->header_length + 2;
1272 1305
  1306 + /* Byte count, slave id, run indicator status,
  1307 + additional data */
1273 for (i=0; i < rc; i++) { 1308 for (i=0; i < rc; i++) {
1274 dest[i] = rsp[offset + i]; 1309 dest[i] = rsp[offset + i];
1275 } 1310 }
src/modbus.h
@@ -176,6 +176,8 @@ void modbus_mapping_free(modbus_mapping_t *mb_mapping); @@ -176,6 +176,8 @@ void modbus_mapping_free(modbus_mapping_t *mb_mapping);
176 int modbus_send_raw_request(modbus_t *ctx, uint8_t *raw_req, int raw_req_length); 176 int modbus_send_raw_request(modbus_t *ctx, uint8_t *raw_req, int raw_req_length);
177 177
178 int modbus_receive(modbus_t *ctx, int sockfd, uint8_t *req); 178 int modbus_receive(modbus_t *ctx, int sockfd, uint8_t *req);
  179 +int modbus_receive_confirmation(modbus_t *ctx, uint8_t *rsp);
  180 +
179 int modbus_reply(modbus_t *ctx, const uint8_t *req, 181 int modbus_reply(modbus_t *ctx, const uint8_t *req,
180 int req_length, modbus_mapping_t *mb_mapping); 182 int req_length, modbus_mapping_t *mb_mapping);
181 int modbus_reply_exception(modbus_t *ctx, const uint8_t *req, 183 int modbus_reply_exception(modbus_t *ctx, const uint8_t *req,
tests/unit-test-client.c
@@ -649,8 +649,8 @@ int main(int argc, char *argv[]) @@ -649,8 +649,8 @@ int main(int argc, char *argv[])
649 goto close; 649 goto close;
650 } 650 }
651 651
652 - printf("* modbus_receive: ");  
653 - rc = modbus_receive(ctx, -1, rsp); 652 + printf("* modbus_receive_confirmation: ");
  653 + rc = modbus_receive_confirmation(ctx, rsp);
654 if ((use_backend == RTU && rc == 15) || 654 if ((use_backend == RTU && rc == 15) ||
655 ((use_backend == TCP || use_backend == TCP_PI) && 655 ((use_backend == TCP || use_backend == TCP_PI) &&
656 rc == 19)) { 656 rc == 19)) {