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 13 modbus_read_input_bits.3 \
14 14 modbus_read_input_registers.3 \
15 15 modbus_read_registers.3 \
  16 + modbus_receive_confirmation.3 \
16 17 modbus_send_raw_request.3 \
17 18 modbus_set_debug.3 \
18 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 47 }
48 48  
49 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 52 modbus_close(ctx);
53 53 modbus_free(ctx);
... ... @@ -55,7 +55,7 @@ modbus_free(ctx);
55 55  
56 56 SEE ALSO
57 57 --------
58   -linkmb:modbus_receive[3]
  58 +linkmb:modbus_receive_confirmation[3]
59 59  
60 60  
61 61 AUTHORS
... ...
src/modbus.c
... ... @@ -428,32 +428,34 @@ int modbus_receive(modbus_t *ctx, int sockfd, uint8_t *req)
428 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 447 int rc;
441 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 451 rsp_length_computed = compute_response_length_from_request(ctx, req);
450 452  
451 453 /* Check length */
452   - if (rc == rsp_length_computed ||
  454 + if (rsp_length == rsp_length_computed ||
453 455 rsp_length_computed == MSG_LENGTH_UNDEFINED) {
454 456 int req_nb_value;
455 457 int rsp_nb_value;
456   - int function = rsp[offset];
  458 + const int function = rsp[offset];
457 459  
458 460 /* Check function code */
459 461 if (function != req[offset]) {
... ... @@ -510,7 +512,7 @@ static int receive_msg_req(modbus_t *ctx, uint8_t *req, uint8_t *rsp)
510 512 errno = EMBBADDATA;
511 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 516 req[offset] == (rsp[offset] - 0x80)) {
515 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 528 if (ctx->debug) {
527 529 fprintf(stderr,
528 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 533 errno = EMBBADDATA;
532 534 rc = -1;
... ... @@ -896,7 +898,11 @@ static int read_io_status(modbus_t *ctx, int function,
896 898 int offset;
897 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 906 if (rc == -1)
901 907 return -1;
902 908  
... ... @@ -991,10 +997,13 @@ static int read_registers(modbus_t *ctx, int function, int addr, int nb,
991 997 int offset;
992 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 1006 return -1;
997   - }
998 1007  
999 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 1072 if (rc > 0) {
1064 1073 /* Used by write_bit and write_register */
1065 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 1083 return rc;
... ... @@ -1129,7 +1143,12 @@ int modbus_write_bits(modbus_t *ctx, int addr, int nb, const uint8_t *src)
1129 1143 rc = send_msg(ctx, req, req_length);
1130 1144 if (rc > 0) {
1131 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 1189 rc = send_msg(ctx, req, req_length);
1171 1190 if (rc > 0) {
1172 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 1200 return rc;
... ... @@ -1228,7 +1252,14 @@ int modbus_read_and_write_registers(modbus_t *ctx,
1228 1252 if (rc > 0) {
1229 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 1263 offset = ctx->backend->header_length;
1233 1264  
1234 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 1293 int offset;
1263 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 1301 if (rc == -1)
1269 1302 return -1;
1270 1303  
1271 1304 offset = ctx->backend->header_length + 2;
1272 1305  
  1306 + /* Byte count, slave id, run indicator status,
  1307 + additional data */
1273 1308 for (i=0; i < rc; i++) {
1274 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 176 int modbus_send_raw_request(modbus_t *ctx, uint8_t *raw_req, int raw_req_length);
177 177  
178 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 181 int modbus_reply(modbus_t *ctx, const uint8_t *req,
180 182 int req_length, modbus_mapping_t *mb_mapping);
181 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 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 654 if ((use_backend == RTU && rc == 15) ||
655 655 ((use_backend == TCP || use_backend == TCP_PI) &&
656 656 rc == 19)) {
... ...