Link against socket and nsl libs when building on SunOS
[libmodbus.git] / src / modbus.c
blob813224815ee27f39ed95fb0b98049b8378c5e32a
1 /*
2 * Copyright © Stéphane Raimbault <stephane.raimbault@gmail.com>
4 * SPDX-License-Identifier: LGPL-2.1-or-later
6 * This library implements the Modbus protocol.
7 * http://libmodbus.org/
8 */
10 #include <errno.h>
11 #include <limits.h>
12 #include <stdarg.h>
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <time.h>
17 #ifndef _MSC_VER
18 #include <unistd.h>
19 #endif
21 #include <config.h>
23 #include "modbus-private.h"
24 #include "modbus.h"
26 /* Internal use */
27 #define MSG_LENGTH_UNDEFINED -1
29 /* Exported version */
30 const unsigned int libmodbus_version_major = LIBMODBUS_VERSION_MAJOR;
31 const unsigned int libmodbus_version_minor = LIBMODBUS_VERSION_MINOR;
32 const unsigned int libmodbus_version_micro = LIBMODBUS_VERSION_MICRO;
34 /* Max between RTU and TCP max adu length (so TCP) */
35 #define MAX_MESSAGE_LENGTH 260
37 /* 3 steps are used to parse the query */
38 typedef enum {
39 _STEP_FUNCTION,
40 _STEP_META,
41 _STEP_DATA
42 } _step_t;
44 const char *modbus_strerror(int errnum)
46 switch (errnum) {
47 case EMBXILFUN:
48 return "Illegal function";
49 case EMBXILADD:
50 return "Illegal data address";
51 case EMBXILVAL:
52 return "Illegal data value";
53 case EMBXSFAIL:
54 return "Slave device or server failure";
55 case EMBXACK:
56 return "Acknowledge";
57 case EMBXSBUSY:
58 return "Slave device or server is busy";
59 case EMBXNACK:
60 return "Negative acknowledge";
61 case EMBXMEMPAR:
62 return "Memory parity error";
63 case EMBXGPATH:
64 return "Gateway path unavailable";
65 case EMBXGTAR:
66 return "Target device failed to respond";
67 case EMBBADCRC:
68 return "Invalid CRC";
69 case EMBBADDATA:
70 return "Invalid data";
71 case EMBBADEXC:
72 return "Invalid exception code";
73 case EMBMDATA:
74 return "Too many data";
75 case EMBBADSLAVE:
76 return "Response not from requested slave";
77 default:
78 return strerror(errnum);
82 void _error_print(modbus_t *ctx, const char *context)
84 if (ctx->debug) {
85 fprintf(stderr, "ERROR %s", modbus_strerror(errno));
86 if (context != NULL) {
87 fprintf(stderr, ": %s\n", context);
88 } else {
89 fprintf(stderr, "\n");
94 static void _sleep_response_timeout(modbus_t *ctx)
96 /* Response timeout is always positive */
97 #ifdef _WIN32
98 /* usleep doesn't exist on Windows */
99 Sleep((ctx->response_timeout.tv_sec * 1000) + (ctx->response_timeout.tv_usec / 1000));
100 #else
101 /* usleep source code */
102 struct timespec request, remaining;
103 request.tv_sec = ctx->response_timeout.tv_sec;
104 request.tv_nsec = ((long int) ctx->response_timeout.tv_usec) * 1000;
105 while (nanosleep(&request, &remaining) == -1 && errno == EINTR) {
106 request = remaining;
108 #endif
111 int modbus_flush(modbus_t *ctx)
113 int rc;
115 if (ctx == NULL) {
116 errno = EINVAL;
117 return -1;
120 rc = ctx->backend->flush(ctx);
121 if (rc != -1 && ctx->debug) {
122 /* Not all backends are able to return the number of bytes flushed */
123 printf("Bytes flushed (%d)\n", rc);
125 return rc;
128 /* Computes the length of the expected response */
129 static unsigned int compute_response_length_from_request(modbus_t *ctx, uint8_t *req)
131 int length;
132 const int offset = ctx->backend->header_length;
134 switch (req[offset]) {
135 case MODBUS_FC_READ_COILS:
136 case MODBUS_FC_READ_DISCRETE_INPUTS: {
137 /* Header + nb values (code from write_bits) */
138 int nb = (req[offset + 3] << 8) | req[offset + 4];
139 length = 2 + (nb / 8) + ((nb % 8) ? 1 : 0);
140 } break;
141 case MODBUS_FC_WRITE_AND_READ_REGISTERS:
142 case MODBUS_FC_READ_HOLDING_REGISTERS:
143 case MODBUS_FC_READ_INPUT_REGISTERS:
144 /* Header + 2 * nb values */
145 length = 2 + 2 * (req[offset + 3] << 8 | req[offset + 4]);
146 break;
147 case MODBUS_FC_READ_EXCEPTION_STATUS:
148 length = 3;
149 break;
150 case MODBUS_FC_REPORT_SLAVE_ID:
151 /* The response is device specific (the header provides the
152 length) */
153 return MSG_LENGTH_UNDEFINED;
154 case MODBUS_FC_MASK_WRITE_REGISTER:
155 length = 7;
156 break;
157 default:
158 length = 5;
161 return offset + length + ctx->backend->checksum_length;
164 /* Sends a request/response */
165 static int send_msg(modbus_t *ctx, uint8_t *msg, int msg_length)
167 int rc;
168 int i;
170 msg_length = ctx->backend->send_msg_pre(msg, msg_length);
172 if (ctx->debug) {
173 for (i = 0; i < msg_length; i++)
174 printf("[%.2X]", msg[i]);
175 printf("\n");
178 /* In recovery mode, the write command will be issued until to be
179 successful! Disabled by default. */
180 do {
181 rc = ctx->backend->send(ctx, msg, msg_length);
182 if (rc == -1) {
183 _error_print(ctx, NULL);
184 if (ctx->error_recovery & MODBUS_ERROR_RECOVERY_LINK) {
185 #ifdef _WIN32
186 const int wsa_err = WSAGetLastError();
187 if (wsa_err == WSAENETRESET || wsa_err == WSAENOTCONN ||
188 wsa_err == WSAENOTSOCK || wsa_err == WSAESHUTDOWN ||
189 wsa_err == WSAEHOSTUNREACH || wsa_err == WSAECONNABORTED ||
190 wsa_err == WSAECONNRESET || wsa_err == WSAETIMEDOUT) {
191 modbus_close(ctx);
192 _sleep_response_timeout(ctx);
193 modbus_connect(ctx);
194 } else {
195 _sleep_response_timeout(ctx);
196 modbus_flush(ctx);
198 #else
199 int saved_errno = errno;
201 if ((errno == EBADF || errno == ECONNRESET || errno == EPIPE)) {
202 modbus_close(ctx);
203 _sleep_response_timeout(ctx);
204 modbus_connect(ctx);
205 } else {
206 _sleep_response_timeout(ctx);
207 modbus_flush(ctx);
209 errno = saved_errno;
210 #endif
213 } while ((ctx->error_recovery & MODBUS_ERROR_RECOVERY_LINK) && rc == -1);
215 if (rc > 0 && rc != msg_length) {
216 errno = EMBBADDATA;
217 return -1;
220 return rc;
223 int modbus_send_raw_request_tid(modbus_t *ctx, const uint8_t *raw_req, int raw_req_length, int tid)
225 sft_t sft;
226 uint8_t req[MAX_MESSAGE_LENGTH];
227 int req_length;
229 if (ctx == NULL) {
230 errno = EINVAL;
231 return -1;
234 if (raw_req_length < 2 || raw_req_length > (MODBUS_MAX_PDU_LENGTH + 1)) {
235 /* The raw request must contain function and slave at least and
236 must not be longer than the maximum pdu length plus the slave
237 address. */
238 errno = EINVAL;
239 return -1;
242 sft.slave = raw_req[0];
243 sft.function = raw_req[1];
244 /* The t_id is left to zero */
245 sft.t_id = tid;
246 /* This response function only set the header so it's convenient here */
247 req_length = ctx->backend->build_response_basis(&sft, req);
249 if (raw_req_length > 2) {
250 /* Copy data after function code */
251 memcpy(req + req_length, raw_req + 2, raw_req_length - 2);
252 req_length += raw_req_length - 2;
255 return send_msg(ctx, req, req_length);
258 int modbus_send_raw_request(modbus_t *ctx, const uint8_t *raw_req, int raw_req_length)
260 return modbus_send_raw_request_tid(ctx, raw_req, raw_req_length, 0);
264 * ---------- Request Indication ----------
265 * | Client | ---------------------->| Server |
266 * ---------- Confirmation Response ----------
269 /* Computes the length to read after the function received */
270 static uint8_t compute_meta_length_after_function(int function, msg_type_t msg_type)
272 int length;
274 if (msg_type == MSG_INDICATION) {
275 if (function <= MODBUS_FC_WRITE_SINGLE_REGISTER) {
276 length = 4;
277 } else if (function == MODBUS_FC_WRITE_MULTIPLE_COILS ||
278 function == MODBUS_FC_WRITE_MULTIPLE_REGISTERS) {
279 length = 5;
280 } else if (function == MODBUS_FC_MASK_WRITE_REGISTER) {
281 length = 6;
282 } else if (function == MODBUS_FC_WRITE_AND_READ_REGISTERS) {
283 length = 9;
284 } else {
285 /* MODBUS_FC_READ_EXCEPTION_STATUS, MODBUS_FC_REPORT_SLAVE_ID */
286 length = 0;
288 } else {
289 /* MSG_CONFIRMATION */
290 switch (function) {
291 case MODBUS_FC_WRITE_SINGLE_COIL:
292 case MODBUS_FC_WRITE_SINGLE_REGISTER:
293 case MODBUS_FC_WRITE_MULTIPLE_COILS:
294 case MODBUS_FC_WRITE_MULTIPLE_REGISTERS:
295 length = 4;
296 break;
297 case MODBUS_FC_MASK_WRITE_REGISTER:
298 length = 6;
299 break;
300 default:
301 length = 1;
305 return length;
308 /* Computes the length to read after the meta information (address, count, etc) */
309 static int
310 compute_data_length_after_meta(modbus_t *ctx, uint8_t *msg, msg_type_t msg_type)
312 int function = msg[ctx->backend->header_length];
313 int length;
315 if (msg_type == MSG_INDICATION) {
316 switch (function) {
317 case MODBUS_FC_WRITE_MULTIPLE_COILS:
318 case MODBUS_FC_WRITE_MULTIPLE_REGISTERS:
319 length = msg[ctx->backend->header_length + 5];
320 break;
321 case MODBUS_FC_WRITE_AND_READ_REGISTERS:
322 length = msg[ctx->backend->header_length + 9];
323 break;
324 default:
325 length = 0;
327 } else {
328 /* MSG_CONFIRMATION */
329 if (function <= MODBUS_FC_READ_INPUT_REGISTERS ||
330 function == MODBUS_FC_REPORT_SLAVE_ID ||
331 function == MODBUS_FC_WRITE_AND_READ_REGISTERS) {
332 length = msg[ctx->backend->header_length + 1];
333 } else {
334 length = 0;
338 length += ctx->backend->checksum_length;
340 return length;
343 /* Waits a response from a modbus server or a request from a modbus client.
344 This function blocks if there is no replies (3 timeouts).
346 The function shall return the number of received characters and the received
347 message in an array of uint8_t if successful. Otherwise it shall return -1
348 and errno is set to one of the values defined below:
349 - ECONNRESET
350 - EMBBADDATA
351 - ETIMEDOUT
352 - read() or recv() error codes
355 int _modbus_receive_msg(modbus_t *ctx, uint8_t *msg, msg_type_t msg_type)
357 int rc;
358 fd_set rset;
359 struct timeval tv;
360 struct timeval *p_tv;
361 unsigned int length_to_read;
362 int msg_length = 0;
363 _step_t step;
364 #ifdef _WIN32
365 int wsa_err;
366 #endif
368 if (ctx->debug) {
369 if (msg_type == MSG_INDICATION) {
370 printf("Waiting for an indication...\n");
371 } else {
372 printf("Waiting for a confirmation...\n");
376 if (!ctx->backend->is_connected(ctx)) {
377 if (ctx->debug) {
378 fprintf(stderr, "ERROR The connection is not established.\n");
380 return -1;
383 /* Add a file descriptor to the set */
384 FD_ZERO(&rset);
385 FD_SET(ctx->s, &rset);
387 /* We need to analyse the message step by step. At the first step, we want
388 * to reach the function code because all packets contain this
389 * information. */
390 step = _STEP_FUNCTION;
391 length_to_read = ctx->backend->header_length + 1;
393 if (msg_type == MSG_INDICATION) {
394 /* Wait for a message, we don't know when the message will be
395 * received */
396 if (ctx->indication_timeout.tv_sec == 0 && ctx->indication_timeout.tv_usec == 0) {
397 /* By default, the indication timeout isn't set */
398 p_tv = NULL;
399 } else {
400 /* Wait for an indication (name of a received request by a server, see schema)
402 tv.tv_sec = ctx->indication_timeout.tv_sec;
403 tv.tv_usec = ctx->indication_timeout.tv_usec;
404 p_tv = &tv;
406 } else {
407 tv.tv_sec = ctx->response_timeout.tv_sec;
408 tv.tv_usec = ctx->response_timeout.tv_usec;
409 p_tv = &tv;
412 while (length_to_read != 0) {
413 rc = ctx->backend->select(ctx, &rset, p_tv, length_to_read);
414 if (rc == -1) {
415 _error_print(ctx, "select");
416 if (ctx->error_recovery & MODBUS_ERROR_RECOVERY_LINK) {
417 #ifdef _WIN32
418 wsa_err = WSAGetLastError();
420 // no equivalent to ETIMEDOUT when select fails on Windows
421 if (wsa_err == WSAENETDOWN || wsa_err == WSAENOTSOCK) {
422 modbus_close(ctx);
423 modbus_connect(ctx);
425 #else
426 int saved_errno = errno;
428 if (errno == ETIMEDOUT) {
429 _sleep_response_timeout(ctx);
430 modbus_flush(ctx);
431 } else if (errno == EBADF) {
432 modbus_close(ctx);
433 modbus_connect(ctx);
435 errno = saved_errno;
436 #endif
438 return -1;
441 rc = ctx->backend->recv(ctx, msg + msg_length, length_to_read);
442 if (rc == 0) {
443 errno = ECONNRESET;
444 rc = -1;
447 if (rc == -1) {
448 _error_print(ctx, "read");
449 #ifdef _WIN32
450 wsa_err = WSAGetLastError();
451 if ((ctx->error_recovery & MODBUS_ERROR_RECOVERY_LINK) &&
452 (wsa_err == WSAENOTCONN || wsa_err == WSAENETRESET ||
453 wsa_err == WSAENOTSOCK || wsa_err == WSAESHUTDOWN ||
454 wsa_err == WSAECONNABORTED || wsa_err == WSAETIMEDOUT ||
455 wsa_err == WSAECONNRESET)) {
456 modbus_close(ctx);
457 modbus_connect(ctx);
459 #else
460 if ((ctx->error_recovery & MODBUS_ERROR_RECOVERY_LINK) &&
461 (errno == ECONNRESET || errno == ECONNREFUSED || errno == EBADF)) {
462 int saved_errno = errno;
463 modbus_close(ctx);
464 modbus_connect(ctx);
465 /* Could be removed by previous calls */
466 errno = saved_errno;
468 #endif
469 return -1;
472 /* Display the hex code of each character received */
473 if (ctx->debug) {
474 int i;
475 for (i = 0; i < rc; i++)
476 printf("<%.2X>", msg[msg_length + i]);
479 /* Sums bytes received */
480 msg_length += rc;
481 /* Computes remaining bytes */
482 length_to_read -= rc;
484 if (length_to_read == 0) {
485 switch (step) {
486 case _STEP_FUNCTION:
487 /* Function code position */
488 length_to_read = compute_meta_length_after_function(
489 msg[ctx->backend->header_length], msg_type);
490 if (length_to_read != 0) {
491 step = _STEP_META;
492 break;
493 } /* else switches straight to the next step */
494 case _STEP_META:
495 length_to_read = compute_data_length_after_meta(ctx, msg, msg_type);
496 if ((msg_length + length_to_read) > ctx->backend->max_adu_length) {
497 errno = EMBBADDATA;
498 _error_print(ctx, "too many data");
499 return -1;
501 step = _STEP_DATA;
502 break;
503 default:
504 break;
508 if (length_to_read > 0 &&
509 (ctx->byte_timeout.tv_sec > 0 || ctx->byte_timeout.tv_usec > 0)) {
510 /* If there is no character in the buffer, the allowed timeout
511 interval between two consecutive bytes is defined by
512 byte_timeout */
513 tv.tv_sec = ctx->byte_timeout.tv_sec;
514 tv.tv_usec = ctx->byte_timeout.tv_usec;
515 p_tv = &tv;
517 /* else timeout isn't set again, the full response must be read before
518 expiration of response timeout (for CONFIRMATION only) */
521 if (ctx->debug)
522 printf("\n");
524 return ctx->backend->check_integrity(ctx, msg, msg_length);
527 /* Receive the request from a modbus master */
528 int modbus_receive(modbus_t *ctx, uint8_t *req)
530 if (ctx == NULL) {
531 errno = EINVAL;
532 return -1;
535 return ctx->backend->receive(ctx, req);
538 /* Receives the confirmation.
540 The function shall store the read response in rsp and return the number of
541 values (bits or words). Otherwise, its shall return -1 and errno is set.
543 The function doesn't check the confirmation is the expected response to the
544 initial request.
546 int modbus_receive_confirmation(modbus_t *ctx, uint8_t *rsp)
548 if (ctx == NULL) {
549 errno = EINVAL;
550 return -1;
553 return _modbus_receive_msg(ctx, rsp, MSG_CONFIRMATION);
556 static int check_confirmation(modbus_t *ctx, uint8_t *req, uint8_t *rsp, int rsp_length)
558 int rc;
559 int rsp_length_computed;
560 const unsigned int offset = ctx->backend->header_length;
561 const int function = rsp[offset];
563 if (ctx->backend->pre_check_confirmation) {
564 rc = ctx->backend->pre_check_confirmation(ctx, req, rsp, rsp_length);
565 if (rc == -1) {
566 if (ctx->error_recovery & MODBUS_ERROR_RECOVERY_PROTOCOL) {
567 _sleep_response_timeout(ctx);
568 modbus_flush(ctx);
570 return -1;
574 rsp_length_computed = compute_response_length_from_request(ctx, req);
576 /* Exception code */
577 if (function >= 0x80) {
578 if (rsp_length == (int) (offset + 2 + ctx->backend->checksum_length) &&
579 req[offset] == (rsp[offset] - 0x80)) {
580 /* Valid exception code received */
582 int exception_code = rsp[offset + 1];
583 if (exception_code < MODBUS_EXCEPTION_MAX) {
584 errno = MODBUS_ENOBASE + exception_code;
585 } else {
586 errno = EMBBADEXC;
588 _error_print(ctx, NULL);
589 return -1;
590 } else {
591 errno = EMBBADEXC;
592 _error_print(ctx, NULL);
593 return -1;
597 /* Check length */
598 if ((rsp_length == rsp_length_computed ||
599 rsp_length_computed == MSG_LENGTH_UNDEFINED) &&
600 function < 0x80) {
601 int req_nb_value;
602 int rsp_nb_value;
603 int resp_addr_ok = TRUE;
604 int resp_data_ok = TRUE;
606 /* Check function code */
607 if (function != req[offset]) {
608 if (ctx->debug) {
609 fprintf(
610 stderr,
611 "Received function not corresponding to the request (0x%X != 0x%X)\n",
612 function,
613 req[offset]);
615 if (ctx->error_recovery & MODBUS_ERROR_RECOVERY_PROTOCOL) {
616 _sleep_response_timeout(ctx);
617 modbus_flush(ctx);
619 errno = EMBBADDATA;
620 return -1;
623 /* Check the number of values is corresponding to the request */
624 switch (function) {
625 case MODBUS_FC_READ_COILS:
626 case MODBUS_FC_READ_DISCRETE_INPUTS:
627 /* Read functions, 8 values in a byte (nb
628 * of values in the request and byte count in
629 * the response. */
630 req_nb_value = (req[offset + 3] << 8) + req[offset + 4];
631 req_nb_value = (req_nb_value / 8) + ((req_nb_value % 8) ? 1 : 0);
632 rsp_nb_value = rsp[offset + 1];
633 break;
634 case MODBUS_FC_WRITE_AND_READ_REGISTERS:
635 case MODBUS_FC_READ_HOLDING_REGISTERS:
636 case MODBUS_FC_READ_INPUT_REGISTERS:
637 /* Read functions 1 value = 2 bytes */
638 req_nb_value = (req[offset + 3] << 8) + req[offset + 4];
639 rsp_nb_value = (rsp[offset + 1] / 2);
640 break;
641 case MODBUS_FC_WRITE_MULTIPLE_COILS:
642 case MODBUS_FC_WRITE_MULTIPLE_REGISTERS:
643 /* address in request and response must be equal */
644 if ((req[offset + 1] != rsp[offset + 1]) ||
645 (req[offset + 2] != rsp[offset + 2])) {
646 resp_addr_ok = FALSE;
648 /* N Write functions */
649 req_nb_value = (req[offset + 3] << 8) + req[offset + 4];
650 rsp_nb_value = (rsp[offset + 3] << 8) | rsp[offset + 4];
651 break;
652 case MODBUS_FC_REPORT_SLAVE_ID:
653 /* Report slave ID (bytes received) */
654 req_nb_value = rsp_nb_value = rsp[offset + 1];
655 break;
656 case MODBUS_FC_WRITE_SINGLE_COIL:
657 case MODBUS_FC_WRITE_SINGLE_REGISTER:
658 /* address in request and response must be equal */
659 if ((req[offset + 1] != rsp[offset + 1]) ||
660 (req[offset + 2] != rsp[offset + 2])) {
661 resp_addr_ok = FALSE;
663 /* data in request and response must be equal */
664 if ((req[offset + 3] != rsp[offset + 3]) ||
665 (req[offset + 4] != rsp[offset + 4])) {
666 resp_data_ok = FALSE;
668 /* 1 Write functions & others */
669 req_nb_value = rsp_nb_value = 1;
670 break;
671 default:
672 /* 1 Write functions & others */
673 req_nb_value = rsp_nb_value = 1;
674 break;
677 if ((req_nb_value == rsp_nb_value) && (resp_addr_ok == TRUE) &&
678 (resp_data_ok == TRUE)) {
679 rc = rsp_nb_value;
680 } else {
681 if (ctx->debug) {
682 fprintf(stderr,
683 "Received data not corresponding to the request (%d != %d)\n",
684 rsp_nb_value,
685 req_nb_value);
688 if (ctx->error_recovery & MODBUS_ERROR_RECOVERY_PROTOCOL) {
689 _sleep_response_timeout(ctx);
690 modbus_flush(ctx);
693 errno = EMBBADDATA;
694 rc = -1;
696 } else {
697 if (ctx->debug) {
698 fprintf(
699 stderr,
700 "Message length not corresponding to the computed length (%d != %d)\n",
701 rsp_length,
702 rsp_length_computed);
704 if (ctx->error_recovery & MODBUS_ERROR_RECOVERY_PROTOCOL) {
705 _sleep_response_timeout(ctx);
706 modbus_flush(ctx);
708 errno = EMBBADDATA;
709 rc = -1;
712 return rc;
715 static int
716 response_io_status(uint8_t *tab_io_status, int address, int nb, uint8_t *rsp, int offset)
718 int shift = 0;
719 /* Instead of byte (not allowed in Win32) */
720 int one_byte = 0;
721 int i;
723 for (i = address; i < address + nb; i++) {
724 one_byte |= tab_io_status[i] << shift;
725 if (shift == 7) {
726 /* Byte is full */
727 rsp[offset++] = one_byte;
728 one_byte = shift = 0;
729 } else {
730 shift++;
734 if (shift != 0)
735 rsp[offset++] = one_byte;
737 return offset;
740 /* Build the exception response */
741 static int response_exception(modbus_t *ctx,
742 sft_t *sft,
743 int exception_code,
744 uint8_t *rsp,
745 unsigned int to_flush,
746 const char *template,
747 ...)
749 int rsp_length;
751 /* Print debug message */
752 if (ctx->debug) {
753 va_list ap;
755 va_start(ap, template);
756 vfprintf(stderr, template, ap);
757 va_end(ap);
760 /* Flush if required */
761 if (to_flush) {
762 _sleep_response_timeout(ctx);
763 modbus_flush(ctx);
766 /* Build exception response */
767 sft->function = sft->function + 0x80;
768 rsp_length = ctx->backend->build_response_basis(sft, rsp);
769 rsp[rsp_length++] = exception_code;
771 return rsp_length;
774 /* Send a response to the received request.
775 Analyses the request and constructs a response.
777 If an error occurs, this function construct the response
778 accordingly.
780 int modbus_reply(modbus_t *ctx,
781 const uint8_t *req,
782 int req_length,
783 modbus_mapping_t *mb_mapping)
785 unsigned int offset;
786 int slave;
787 int function;
788 uint16_t address;
789 uint8_t rsp[MAX_MESSAGE_LENGTH];
790 int rsp_length = 0;
791 sft_t sft;
793 if (ctx == NULL) {
794 errno = EINVAL;
795 return -1;
798 offset = ctx->backend->header_length;
799 slave = req[offset - 1];
800 function = req[offset];
801 address = (req[offset + 1] << 8) + req[offset + 2];
803 sft.slave = slave;
804 sft.function = function;
805 sft.t_id = ctx->backend->prepare_response_tid(req, &req_length);
807 /* Data are flushed on illegal number of values errors. */
808 switch (function) {
809 case MODBUS_FC_READ_COILS:
810 case MODBUS_FC_READ_DISCRETE_INPUTS: {
811 unsigned int is_input = (function == MODBUS_FC_READ_DISCRETE_INPUTS);
812 int start_bits = is_input ? mb_mapping->start_input_bits : mb_mapping->start_bits;
813 int nb_bits = is_input ? mb_mapping->nb_input_bits : mb_mapping->nb_bits;
814 uint8_t *tab_bits = is_input ? mb_mapping->tab_input_bits : mb_mapping->tab_bits;
815 const char *const name = is_input ? "read_input_bits" : "read_bits";
816 int nb = (req[offset + 3] << 8) + req[offset + 4];
817 /* The mapping can be shifted to reduce memory consumption and it
818 doesn't always start at address zero. */
819 int mapping_address = address - start_bits;
821 if (nb < 1 || MODBUS_MAX_READ_BITS < nb) {
822 rsp_length = response_exception(ctx,
823 &sft,
824 MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE,
825 rsp,
826 TRUE,
827 "Illegal nb of values %d in %s (max %d)\n",
829 name,
830 MODBUS_MAX_READ_BITS);
831 } else if (mapping_address < 0 || (mapping_address + nb) > nb_bits) {
832 rsp_length = response_exception(ctx,
833 &sft,
834 MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS,
835 rsp,
836 FALSE,
837 "Illegal data address 0x%0X in %s\n",
838 mapping_address < 0 ? address : address + nb,
839 name);
840 } else {
841 rsp_length = ctx->backend->build_response_basis(&sft, rsp);
842 rsp[rsp_length++] = (nb / 8) + ((nb % 8) ? 1 : 0);
843 rsp_length =
844 response_io_status(tab_bits, mapping_address, nb, rsp, rsp_length);
846 } break;
847 case MODBUS_FC_READ_HOLDING_REGISTERS:
848 case MODBUS_FC_READ_INPUT_REGISTERS: {
849 unsigned int is_input = (function == MODBUS_FC_READ_INPUT_REGISTERS);
850 int start_registers =
851 is_input ? mb_mapping->start_input_registers : mb_mapping->start_registers;
852 int nb_registers =
853 is_input ? mb_mapping->nb_input_registers : mb_mapping->nb_registers;
854 uint16_t *tab_registers =
855 is_input ? mb_mapping->tab_input_registers : mb_mapping->tab_registers;
856 const char *const name = is_input ? "read_input_registers" : "read_registers";
857 int nb = (req[offset + 3] << 8) + req[offset + 4];
858 /* The mapping can be shifted to reduce memory consumption and it
859 doesn't always start at address zero. */
860 int mapping_address = address - start_registers;
862 if (nb < 1 || MODBUS_MAX_READ_REGISTERS < nb) {
863 rsp_length = response_exception(ctx,
864 &sft,
865 MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE,
866 rsp,
867 TRUE,
868 "Illegal nb of values %d in %s (max %d)\n",
870 name,
871 MODBUS_MAX_READ_REGISTERS);
872 } else if (mapping_address < 0 || (mapping_address + nb) > nb_registers) {
873 rsp_length = response_exception(ctx,
874 &sft,
875 MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS,
876 rsp,
877 FALSE,
878 "Illegal data address 0x%0X in %s\n",
879 mapping_address < 0 ? address : address + nb,
880 name);
881 } else {
882 int i;
884 rsp_length = ctx->backend->build_response_basis(&sft, rsp);
885 rsp[rsp_length++] = nb << 1;
886 for (i = mapping_address; i < mapping_address + nb; i++) {
887 rsp[rsp_length++] = tab_registers[i] >> 8;
888 rsp[rsp_length++] = tab_registers[i] & 0xFF;
891 } break;
892 case MODBUS_FC_WRITE_SINGLE_COIL: {
893 int mapping_address = address - mb_mapping->start_bits;
895 if (mapping_address < 0 || mapping_address >= mb_mapping->nb_bits) {
896 rsp_length = response_exception(ctx,
897 &sft,
898 MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS,
899 rsp,
900 FALSE,
901 "Illegal data address 0x%0X in write_bit\n",
902 address);
903 } else {
904 int data = (req[offset + 3] << 8) + req[offset + 4];
906 if (data == 0xFF00 || data == 0x0) {
907 mb_mapping->tab_bits[mapping_address] = data ? ON : OFF;
908 memcpy(rsp, req, req_length);
909 rsp_length = req_length;
910 } else {
911 rsp_length = response_exception(
912 ctx,
913 &sft,
914 MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE,
915 rsp,
916 FALSE,
917 "Illegal data value 0x%0X in write_bit request at address %0X\n",
918 data,
919 address);
922 } break;
923 case MODBUS_FC_WRITE_SINGLE_REGISTER: {
924 int mapping_address = address - mb_mapping->start_registers;
926 if (mapping_address < 0 || mapping_address >= mb_mapping->nb_registers) {
927 rsp_length =
928 response_exception(ctx,
929 &sft,
930 MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS,
931 rsp,
932 FALSE,
933 "Illegal data address 0x%0X in write_register\n",
934 address);
935 } else {
936 int data = (req[offset + 3] << 8) + req[offset + 4];
938 mb_mapping->tab_registers[mapping_address] = data;
939 memcpy(rsp, req, req_length);
940 rsp_length = req_length;
942 } break;
943 case MODBUS_FC_WRITE_MULTIPLE_COILS: {
944 int nb = (req[offset + 3] << 8) + req[offset + 4];
945 int nb_bits = req[offset + 5];
946 int mapping_address = address - mb_mapping->start_bits;
948 if (nb < 1 || MODBUS_MAX_WRITE_BITS < nb || nb_bits * 8 < nb) {
949 /* May be the indication has been truncated on reading because of
950 * invalid address (eg. nb is 0 but the request contains values to
951 * write) so it's necessary to flush. */
952 rsp_length =
953 response_exception(ctx,
954 &sft,
955 MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE,
956 rsp,
957 TRUE,
958 "Illegal number of values %d in write_bits (max %d)\n",
960 MODBUS_MAX_WRITE_BITS);
961 } else if (mapping_address < 0 || (mapping_address + nb) > mb_mapping->nb_bits) {
962 rsp_length = response_exception(ctx,
963 &sft,
964 MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS,
965 rsp,
966 FALSE,
967 "Illegal data address 0x%0X in write_bits\n",
968 mapping_address < 0 ? address : address + nb);
969 } else {
970 /* 6 = byte count */
971 modbus_set_bits_from_bytes(
972 mb_mapping->tab_bits, mapping_address, nb, &req[offset + 6]);
974 rsp_length = ctx->backend->build_response_basis(&sft, rsp);
975 /* 4 to copy the bit address (2) and the quantity of bits */
976 memcpy(rsp + rsp_length, req + rsp_length, 4);
977 rsp_length += 4;
979 } break;
980 case MODBUS_FC_WRITE_MULTIPLE_REGISTERS: {
981 int nb = (req[offset + 3] << 8) + req[offset + 4];
982 int nb_bytes = req[offset + 5];
983 int mapping_address = address - mb_mapping->start_registers;
985 if (nb < 1 || MODBUS_MAX_WRITE_REGISTERS < nb || nb_bytes != nb * 2) {
986 rsp_length = response_exception(
987 ctx,
988 &sft,
989 MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE,
990 rsp,
991 TRUE,
992 "Illegal number of values %d in write_registers (max %d)\n",
994 MODBUS_MAX_WRITE_REGISTERS);
995 } else if (mapping_address < 0 ||
996 (mapping_address + nb) > mb_mapping->nb_registers) {
997 rsp_length =
998 response_exception(ctx,
999 &sft,
1000 MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS,
1001 rsp,
1002 FALSE,
1003 "Illegal data address 0x%0X in write_registers\n",
1004 mapping_address < 0 ? address : address + nb);
1005 } else {
1006 int i, j;
1007 for (i = mapping_address, j = 6; i < mapping_address + nb; i++, j += 2) {
1008 /* 6 and 7 = first value */
1009 mb_mapping->tab_registers[i] =
1010 (req[offset + j] << 8) + req[offset + j + 1];
1013 rsp_length = ctx->backend->build_response_basis(&sft, rsp);
1014 /* 4 to copy the address (2) and the no. of registers */
1015 memcpy(rsp + rsp_length, req + rsp_length, 4);
1016 rsp_length += 4;
1018 } break;
1019 case MODBUS_FC_REPORT_SLAVE_ID: {
1020 int str_len;
1021 int byte_count_pos;
1023 rsp_length = ctx->backend->build_response_basis(&sft, rsp);
1024 /* Skip byte count for now */
1025 byte_count_pos = rsp_length++;
1026 rsp[rsp_length++] = _REPORT_SLAVE_ID;
1027 /* Run indicator status to ON */
1028 rsp[rsp_length++] = 0xFF;
1029 /* LMB + length of LIBMODBUS_VERSION_STRING */
1030 str_len = 3 + strlen(LIBMODBUS_VERSION_STRING);
1031 memcpy(rsp + rsp_length, "LMB" LIBMODBUS_VERSION_STRING, str_len);
1032 rsp_length += str_len;
1033 rsp[byte_count_pos] = rsp_length - byte_count_pos - 1;
1034 } break;
1035 case MODBUS_FC_READ_EXCEPTION_STATUS:
1036 if (ctx->debug) {
1037 fprintf(stderr, "FIXME Not implemented\n");
1039 errno = ENOPROTOOPT;
1040 return -1;
1041 break;
1042 case MODBUS_FC_MASK_WRITE_REGISTER: {
1043 int mapping_address = address - mb_mapping->start_registers;
1045 if (mapping_address < 0 || mapping_address >= mb_mapping->nb_registers) {
1046 rsp_length =
1047 response_exception(ctx,
1048 &sft,
1049 MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS,
1050 rsp,
1051 FALSE,
1052 "Illegal data address 0x%0X in write_register\n",
1053 address);
1054 } else {
1055 uint16_t data = mb_mapping->tab_registers[mapping_address];
1056 uint16_t and = (req[offset + 3] << 8) + req[offset + 4];
1057 uint16_t or = (req[offset + 5] << 8) + req[offset + 6];
1059 data = (data & and) | (or &(~and) );
1060 mb_mapping->tab_registers[mapping_address] = data;
1061 memcpy(rsp, req, req_length);
1062 rsp_length = req_length;
1064 } break;
1065 case MODBUS_FC_WRITE_AND_READ_REGISTERS: {
1066 int nb = (req[offset + 3] << 8) + req[offset + 4];
1067 uint16_t address_write = (req[offset + 5] << 8) + req[offset + 6];
1068 int nb_write = (req[offset + 7] << 8) + req[offset + 8];
1069 int nb_write_bytes = req[offset + 9];
1070 int mapping_address = address - mb_mapping->start_registers;
1071 int mapping_address_write = address_write - mb_mapping->start_registers;
1073 if (nb_write < 1 || MODBUS_MAX_WR_WRITE_REGISTERS < nb_write || nb < 1 ||
1074 MODBUS_MAX_WR_READ_REGISTERS < nb || nb_write_bytes != nb_write * 2) {
1075 rsp_length = response_exception(
1076 ctx,
1077 &sft,
1078 MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE,
1079 rsp,
1080 TRUE,
1081 "Illegal nb of values (W%d, R%d) in write_and_read_registers (max W%d, "
1082 "R%d)\n",
1083 nb_write,
1085 MODBUS_MAX_WR_WRITE_REGISTERS,
1086 MODBUS_MAX_WR_READ_REGISTERS);
1087 } else if (mapping_address < 0 ||
1088 (mapping_address + nb) > mb_mapping->nb_registers ||
1089 mapping_address_write < 0 ||
1090 (mapping_address_write + nb_write) > mb_mapping->nb_registers) {
1091 rsp_length = response_exception(
1092 ctx,
1093 &sft,
1094 MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS,
1095 rsp,
1096 FALSE,
1097 "Illegal data read address 0x%0X or write address 0x%0X "
1098 "write_and_read_registers\n",
1099 mapping_address < 0 ? address : address + nb,
1100 mapping_address_write < 0 ? address_write : address_write + nb_write);
1101 } else {
1102 int i, j;
1103 rsp_length = ctx->backend->build_response_basis(&sft, rsp);
1104 rsp[rsp_length++] = nb << 1;
1106 /* Write first.
1107 10 and 11 are the offset of the first values to write */
1108 for (i = mapping_address_write, j = 10; i < mapping_address_write + nb_write;
1109 i++, j += 2) {
1110 mb_mapping->tab_registers[i] =
1111 (req[offset + j] << 8) + req[offset + j + 1];
1114 /* and read the data for the response */
1115 for (i = mapping_address; i < mapping_address + nb; i++) {
1116 rsp[rsp_length++] = mb_mapping->tab_registers[i] >> 8;
1117 rsp[rsp_length++] = mb_mapping->tab_registers[i] & 0xFF;
1120 } break;
1122 default:
1123 rsp_length = response_exception(ctx,
1124 &sft,
1125 MODBUS_EXCEPTION_ILLEGAL_FUNCTION,
1126 rsp,
1127 TRUE,
1128 "Unknown Modbus function code: 0x%0X\n",
1129 function);
1130 break;
1133 /* Suppress any responses in RTU when the request was a broadcast, excepted when quirk
1134 * is enabled. */
1135 if (ctx->backend->backend_type == _MODBUS_BACKEND_TYPE_RTU &&
1136 slave == MODBUS_BROADCAST_ADDRESS &&
1137 !(ctx->quirks & MODBUS_QUIRK_REPLY_TO_BROADCAST)) {
1138 return 0;
1140 return send_msg(ctx, rsp, rsp_length);
1143 int modbus_reply_exception(modbus_t *ctx, const uint8_t *req, unsigned int exception_code)
1145 unsigned int offset;
1146 int slave;
1147 int function;
1148 uint8_t rsp[MAX_MESSAGE_LENGTH];
1149 int rsp_length;
1150 int dummy_length = 99;
1151 sft_t sft;
1153 if (ctx == NULL) {
1154 errno = EINVAL;
1155 return -1;
1158 offset = ctx->backend->header_length;
1159 slave = req[offset - 1];
1160 function = req[offset];
1162 sft.slave = slave;
1163 sft.function = function + 0x80;
1164 sft.t_id = ctx->backend->prepare_response_tid(req, &dummy_length);
1165 rsp_length = ctx->backend->build_response_basis(&sft, rsp);
1167 /* Positive exception code */
1168 if (exception_code < MODBUS_EXCEPTION_MAX) {
1169 rsp[rsp_length++] = exception_code;
1170 return send_msg(ctx, rsp, rsp_length);
1171 } else {
1172 errno = EINVAL;
1173 return -1;
1177 /* Reads IO status */
1178 static int read_io_status(modbus_t *ctx, int function, int addr, int nb, uint8_t *dest)
1180 int rc;
1181 int req_length;
1183 uint8_t req[_MIN_REQ_LENGTH];
1184 uint8_t rsp[MAX_MESSAGE_LENGTH];
1186 req_length = ctx->backend->build_request_basis(ctx, function, addr, nb, req);
1188 rc = send_msg(ctx, req, req_length);
1189 if (rc > 0) {
1190 int temp, bit;
1191 int pos = 0;
1192 unsigned int offset;
1193 unsigned int offset_end;
1194 unsigned int i;
1196 rc = _modbus_receive_msg(ctx, rsp, MSG_CONFIRMATION);
1197 if (rc == -1)
1198 return -1;
1200 rc = check_confirmation(ctx, req, rsp, rc);
1201 if (rc == -1)
1202 return -1;
1204 offset = ctx->backend->header_length + 2;
1205 offset_end = offset + rc;
1206 for (i = offset; i < offset_end; i++) {
1207 /* Shift reg hi_byte to temp */
1208 temp = rsp[i];
1210 for (bit = 0x01; (bit & 0xff) && (pos < nb);) {
1211 dest[pos++] = (temp & bit) ? TRUE : FALSE;
1212 bit = bit << 1;
1217 return rc;
1220 /* Reads the boolean status of bits and sets the array elements
1221 in the destination to TRUE or FALSE (single bits). */
1222 int modbus_read_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest)
1224 int rc;
1226 if (ctx == NULL) {
1227 errno = EINVAL;
1228 return -1;
1231 if (nb > MODBUS_MAX_READ_BITS) {
1232 if (ctx->debug) {
1233 fprintf(stderr,
1234 "ERROR Too many bits requested (%d > %d)\n",
1236 MODBUS_MAX_READ_BITS);
1238 errno = EMBMDATA;
1239 return -1;
1242 rc = read_io_status(ctx, MODBUS_FC_READ_COILS, addr, nb, dest);
1244 if (rc == -1)
1245 return -1;
1246 else
1247 return nb;
1250 /* Same as modbus_read_bits but reads the remote device input table */
1251 int modbus_read_input_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest)
1253 int rc;
1255 if (ctx == NULL) {
1256 errno = EINVAL;
1257 return -1;
1260 if (nb > MODBUS_MAX_READ_BITS) {
1261 if (ctx->debug) {
1262 fprintf(stderr,
1263 "ERROR Too many discrete inputs requested (%d > %d)\n",
1265 MODBUS_MAX_READ_BITS);
1267 errno = EMBMDATA;
1268 return -1;
1271 rc = read_io_status(ctx, MODBUS_FC_READ_DISCRETE_INPUTS, addr, nb, dest);
1273 if (rc == -1)
1274 return -1;
1275 else
1276 return nb;
1279 /* Reads the data from a remote device and put that data into an array */
1280 static int read_registers(modbus_t *ctx, int function, int addr, int nb, uint16_t *dest)
1282 int rc;
1283 int req_length;
1284 uint8_t req[_MIN_REQ_LENGTH];
1285 uint8_t rsp[MAX_MESSAGE_LENGTH];
1287 if (nb > MODBUS_MAX_READ_REGISTERS) {
1288 if (ctx->debug) {
1289 fprintf(stderr,
1290 "ERROR Too many registers requested (%d > %d)\n",
1292 MODBUS_MAX_READ_REGISTERS);
1294 errno = EMBMDATA;
1295 return -1;
1298 req_length = ctx->backend->build_request_basis(ctx, function, addr, nb, req);
1300 rc = send_msg(ctx, req, req_length);
1301 if (rc > 0) {
1302 unsigned int offset;
1303 int i;
1305 rc = _modbus_receive_msg(ctx, rsp, MSG_CONFIRMATION);
1306 if (rc == -1)
1307 return -1;
1309 rc = check_confirmation(ctx, req, rsp, rc);
1310 if (rc == -1)
1311 return -1;
1313 offset = ctx->backend->header_length;
1315 for (i = 0; i < rc; i++) {
1316 /* shift reg hi_byte to temp OR with lo_byte */
1317 dest[i] = (rsp[offset + 2 + (i << 1)] << 8) | rsp[offset + 3 + (i << 1)];
1321 return rc;
1324 /* Reads the holding registers of remote device and put the data into an
1325 array */
1326 int modbus_read_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest)
1328 int status;
1330 if (ctx == NULL) {
1331 errno = EINVAL;
1332 return -1;
1335 if (nb > MODBUS_MAX_READ_REGISTERS) {
1336 if (ctx->debug) {
1337 fprintf(stderr,
1338 "ERROR Too many registers requested (%d > %d)\n",
1340 MODBUS_MAX_READ_REGISTERS);
1342 errno = EMBMDATA;
1343 return -1;
1346 status = read_registers(ctx, MODBUS_FC_READ_HOLDING_REGISTERS, addr, nb, dest);
1347 return status;
1350 /* Reads the input registers of remote device and put the data into an array */
1351 int modbus_read_input_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest)
1353 int status;
1355 if (ctx == NULL) {
1356 errno = EINVAL;
1357 return -1;
1360 if (nb > MODBUS_MAX_READ_REGISTERS) {
1361 if (ctx->debug) {
1362 fprintf(stderr,
1363 "ERROR Too many input registers requested (%d > %d)\n",
1365 MODBUS_MAX_READ_REGISTERS);
1367 errno = EMBMDATA;
1368 return -1;
1371 status = read_registers(ctx, MODBUS_FC_READ_INPUT_REGISTERS, addr, nb, dest);
1373 return status;
1376 /* Write a value to the specified register of the remote device.
1377 Used by write_bit and write_register */
1378 static int write_single(modbus_t *ctx, int function, int addr, const uint16_t value)
1380 int rc;
1381 int req_length;
1382 uint8_t req[_MIN_REQ_LENGTH];
1384 if (ctx == NULL) {
1385 errno = EINVAL;
1386 return -1;
1389 req_length = ctx->backend->build_request_basis(ctx, function, addr, (int) value, req);
1391 rc = send_msg(ctx, req, req_length);
1392 if (rc > 0) {
1393 /* Used by write_bit and write_register */
1394 uint8_t rsp[MAX_MESSAGE_LENGTH];
1396 rc = _modbus_receive_msg(ctx, rsp, MSG_CONFIRMATION);
1397 if (rc == -1)
1398 return -1;
1400 rc = check_confirmation(ctx, req, rsp, rc);
1403 return rc;
1406 /* Turns ON or OFF a single bit of the remote device */
1407 int modbus_write_bit(modbus_t *ctx, int addr, int status)
1409 if (ctx == NULL) {
1410 errno = EINVAL;
1411 return -1;
1414 return write_single(ctx, MODBUS_FC_WRITE_SINGLE_COIL, addr, status ? 0xFF00 : 0);
1417 /* Writes a value in one register of the remote device */
1418 int modbus_write_register(modbus_t *ctx, int addr, const uint16_t value)
1420 if (ctx == NULL) {
1421 errno = EINVAL;
1422 return -1;
1425 return write_single(ctx, MODBUS_FC_WRITE_SINGLE_REGISTER, addr, value);
1428 /* Write the bits of the array in the remote device */
1429 int modbus_write_bits(modbus_t *ctx, int addr, int nb, const uint8_t *src)
1431 int rc;
1432 int i;
1433 int byte_count;
1434 int req_length;
1435 int bit_check = 0;
1436 int pos = 0;
1437 uint8_t req[MAX_MESSAGE_LENGTH];
1439 if (ctx == NULL) {
1440 errno = EINVAL;
1441 return -1;
1444 if (nb > MODBUS_MAX_WRITE_BITS) {
1445 if (ctx->debug) {
1446 fprintf(stderr,
1447 "ERROR Writing too many bits (%d > %d)\n",
1449 MODBUS_MAX_WRITE_BITS);
1451 errno = EMBMDATA;
1452 return -1;
1455 req_length = ctx->backend->build_request_basis(
1456 ctx, MODBUS_FC_WRITE_MULTIPLE_COILS, addr, nb, req);
1457 byte_count = (nb / 8) + ((nb % 8) ? 1 : 0);
1458 req[req_length++] = byte_count;
1460 for (i = 0; i < byte_count; i++) {
1461 int bit;
1463 bit = 0x01;
1464 req[req_length] = 0;
1466 while ((bit & 0xFF) && (bit_check++ < nb)) {
1467 if (src[pos++])
1468 req[req_length] |= bit;
1469 else
1470 req[req_length] &= ~bit;
1472 bit = bit << 1;
1474 req_length++;
1477 rc = send_msg(ctx, req, req_length);
1478 if (rc > 0) {
1479 uint8_t rsp[MAX_MESSAGE_LENGTH];
1481 rc = _modbus_receive_msg(ctx, rsp, MSG_CONFIRMATION);
1482 if (rc == -1)
1483 return -1;
1485 rc = check_confirmation(ctx, req, rsp, rc);
1488 return rc;
1491 /* Write the values from the array to the registers of the remote device */
1492 int modbus_write_registers(modbus_t *ctx, int addr, int nb, const uint16_t *src)
1494 int rc;
1495 int i;
1496 int req_length;
1497 int byte_count;
1498 uint8_t req[MAX_MESSAGE_LENGTH];
1500 if (ctx == NULL) {
1501 errno = EINVAL;
1502 return -1;
1505 if (nb > MODBUS_MAX_WRITE_REGISTERS) {
1506 if (ctx->debug) {
1507 fprintf(stderr,
1508 "ERROR Trying to write to too many registers (%d > %d)\n",
1510 MODBUS_MAX_WRITE_REGISTERS);
1512 errno = EMBMDATA;
1513 return -1;
1516 req_length = ctx->backend->build_request_basis(
1517 ctx, MODBUS_FC_WRITE_MULTIPLE_REGISTERS, addr, nb, req);
1518 byte_count = nb * 2;
1519 req[req_length++] = byte_count;
1521 for (i = 0; i < nb; i++) {
1522 req[req_length++] = src[i] >> 8;
1523 req[req_length++] = src[i] & 0x00FF;
1526 rc = send_msg(ctx, req, req_length);
1527 if (rc > 0) {
1528 uint8_t rsp[MAX_MESSAGE_LENGTH];
1530 rc = _modbus_receive_msg(ctx, rsp, MSG_CONFIRMATION);
1531 if (rc == -1)
1532 return -1;
1534 rc = check_confirmation(ctx, req, rsp, rc);
1537 return rc;
1540 int modbus_mask_write_register(modbus_t *ctx,
1541 int addr,
1542 uint16_t and_mask,
1543 uint16_t or_mask)
1545 int rc;
1546 int req_length;
1547 /* The request length can not exceed _MIN_REQ_LENGTH - 2 and 4 bytes to
1548 * store the masks. The ugly substraction is there to remove the 'nb' value
1549 * (2 bytes) which is not used. */
1550 uint8_t req[_MIN_REQ_LENGTH + 2];
1552 req_length = ctx->backend->build_request_basis(
1553 ctx, MODBUS_FC_MASK_WRITE_REGISTER, addr, 0, req);
1555 /* HACKISH, count is not used */
1556 req_length -= 2;
1558 req[req_length++] = and_mask >> 8;
1559 req[req_length++] = and_mask & 0x00ff;
1560 req[req_length++] = or_mask >> 8;
1561 req[req_length++] = or_mask & 0x00ff;
1563 rc = send_msg(ctx, req, req_length);
1564 if (rc > 0) {
1565 /* Used by write_bit and write_register */
1566 uint8_t rsp[MAX_MESSAGE_LENGTH];
1568 rc = _modbus_receive_msg(ctx, rsp, MSG_CONFIRMATION);
1569 if (rc == -1)
1570 return -1;
1572 rc = check_confirmation(ctx, req, rsp, rc);
1575 return rc;
1578 /* Write multiple registers from src array to remote device and read multiple
1579 registers from remote device to dest array. */
1580 int modbus_write_and_read_registers(modbus_t *ctx,
1581 int write_addr,
1582 int write_nb,
1583 const uint16_t *src,
1584 int read_addr,
1585 int read_nb,
1586 uint16_t *dest)
1589 int rc;
1590 int req_length;
1591 int i;
1592 int byte_count;
1593 uint8_t req[MAX_MESSAGE_LENGTH];
1594 uint8_t rsp[MAX_MESSAGE_LENGTH];
1596 if (ctx == NULL) {
1597 errno = EINVAL;
1598 return -1;
1601 if (write_nb > MODBUS_MAX_WR_WRITE_REGISTERS) {
1602 if (ctx->debug) {
1603 fprintf(stderr,
1604 "ERROR Too many registers to write (%d > %d)\n",
1605 write_nb,
1606 MODBUS_MAX_WR_WRITE_REGISTERS);
1608 errno = EMBMDATA;
1609 return -1;
1612 if (read_nb > MODBUS_MAX_WR_READ_REGISTERS) {
1613 if (ctx->debug) {
1614 fprintf(stderr,
1615 "ERROR Too many registers requested (%d > %d)\n",
1616 read_nb,
1617 MODBUS_MAX_WR_READ_REGISTERS);
1619 errno = EMBMDATA;
1620 return -1;
1622 req_length = ctx->backend->build_request_basis(
1623 ctx, MODBUS_FC_WRITE_AND_READ_REGISTERS, read_addr, read_nb, req);
1625 req[req_length++] = write_addr >> 8;
1626 req[req_length++] = write_addr & 0x00ff;
1627 req[req_length++] = write_nb >> 8;
1628 req[req_length++] = write_nb & 0x00ff;
1629 byte_count = write_nb * 2;
1630 req[req_length++] = byte_count;
1632 for (i = 0; i < write_nb; i++) {
1633 req[req_length++] = src[i] >> 8;
1634 req[req_length++] = src[i] & 0x00FF;
1637 rc = send_msg(ctx, req, req_length);
1638 if (rc > 0) {
1639 unsigned int offset;
1641 rc = _modbus_receive_msg(ctx, rsp, MSG_CONFIRMATION);
1642 if (rc == -1)
1643 return -1;
1645 rc = check_confirmation(ctx, req, rsp, rc);
1646 if (rc == -1)
1647 return -1;
1649 offset = ctx->backend->header_length;
1650 for (i = 0; i < rc; i++) {
1651 /* shift reg hi_byte to temp OR with lo_byte */
1652 dest[i] = (rsp[offset + 2 + (i << 1)] << 8) | rsp[offset + 3 + (i << 1)];
1656 return rc;
1659 /* Send a request to get the slave ID of the device (only available in serial
1660 communication). */
1661 int modbus_report_slave_id(modbus_t *ctx, int max_dest, uint8_t *dest)
1663 int rc;
1664 int req_length;
1665 uint8_t req[_MIN_REQ_LENGTH];
1667 if (ctx == NULL || max_dest <= 0) {
1668 errno = EINVAL;
1669 return -1;
1672 req_length =
1673 ctx->backend->build_request_basis(ctx, MODBUS_FC_REPORT_SLAVE_ID, 0, 0, req);
1675 /* HACKISH, addr and count are not used */
1676 req_length -= 4;
1678 rc = send_msg(ctx, req, req_length);
1679 if (rc > 0) {
1680 int i;
1681 unsigned int offset;
1682 uint8_t rsp[MAX_MESSAGE_LENGTH];
1684 rc = _modbus_receive_msg(ctx, rsp, MSG_CONFIRMATION);
1685 if (rc == -1)
1686 return -1;
1688 rc = check_confirmation(ctx, req, rsp, rc);
1689 if (rc == -1)
1690 return -1;
1692 offset = ctx->backend->header_length + 2;
1694 /* Byte count, slave id, run indicator status and
1695 additional data. Truncate copy to max_dest. */
1696 for (i = 0; i < rc && i < max_dest; i++) {
1697 dest[i] = rsp[offset + i];
1701 return rc;
1704 void _modbus_init_common(modbus_t *ctx)
1706 /* Slave and socket are initialized to -1 */
1707 ctx->slave = -1;
1708 ctx->s = -1;
1710 ctx->debug = FALSE;
1711 ctx->error_recovery = MODBUS_ERROR_RECOVERY_NONE;
1712 ctx->quirks = MODBUS_QUIRK_NONE;
1714 ctx->response_timeout.tv_sec = 0;
1715 ctx->response_timeout.tv_usec = _RESPONSE_TIMEOUT;
1717 ctx->byte_timeout.tv_sec = 0;
1718 ctx->byte_timeout.tv_usec = _BYTE_TIMEOUT;
1720 ctx->indication_timeout.tv_sec = 0;
1721 ctx->indication_timeout.tv_usec = 0;
1724 /* Define the slave number */
1725 int modbus_set_slave(modbus_t *ctx, int slave)
1727 if (ctx == NULL) {
1728 errno = EINVAL;
1729 return -1;
1732 return ctx->backend->set_slave(ctx, slave);
1735 int modbus_get_slave(modbus_t *ctx)
1737 if (ctx == NULL) {
1738 errno = EINVAL;
1739 return -1;
1742 return ctx->slave;
1745 int modbus_set_error_recovery(modbus_t *ctx, modbus_error_recovery_mode error_recovery)
1747 if (ctx == NULL) {
1748 errno = EINVAL;
1749 return -1;
1752 /* The type of modbus_error_recovery_mode is unsigned enum */
1753 ctx->error_recovery = (uint8_t) error_recovery;
1754 return 0;
1757 // FIXME Doesn't work under Windows RTU
1758 int modbus_set_socket(modbus_t *ctx, int s)
1760 if (ctx == NULL) {
1761 errno = EINVAL;
1762 return -1;
1765 ctx->s = s;
1766 return 0;
1769 int modbus_get_socket(modbus_t *ctx)
1771 if (ctx == NULL) {
1772 errno = EINVAL;
1773 return -1;
1776 return ctx->s;
1779 /* Get the timeout interval used to wait for a response */
1780 int modbus_get_response_timeout(modbus_t *ctx, uint32_t *to_sec, uint32_t *to_usec)
1782 if (ctx == NULL) {
1783 errno = EINVAL;
1784 return -1;
1787 *to_sec = ctx->response_timeout.tv_sec;
1788 *to_usec = ctx->response_timeout.tv_usec;
1789 return 0;
1792 int modbus_set_response_timeout(modbus_t *ctx, uint32_t to_sec, uint32_t to_usec)
1794 if (ctx == NULL || (to_sec == 0 && to_usec == 0) || to_usec > 999999) {
1795 errno = EINVAL;
1796 return -1;
1799 ctx->response_timeout.tv_sec = to_sec;
1800 ctx->response_timeout.tv_usec = to_usec;
1801 return 0;
1804 /* Get the timeout interval between two consecutive bytes of a message */
1805 int modbus_get_byte_timeout(modbus_t *ctx, uint32_t *to_sec, uint32_t *to_usec)
1807 if (ctx == NULL) {
1808 errno = EINVAL;
1809 return -1;
1812 *to_sec = ctx->byte_timeout.tv_sec;
1813 *to_usec = ctx->byte_timeout.tv_usec;
1814 return 0;
1817 int modbus_set_byte_timeout(modbus_t *ctx, uint32_t to_sec, uint32_t to_usec)
1819 /* Byte timeout can be disabled when both values are zero */
1820 if (ctx == NULL || to_usec > 999999) {
1821 errno = EINVAL;
1822 return -1;
1825 ctx->byte_timeout.tv_sec = to_sec;
1826 ctx->byte_timeout.tv_usec = to_usec;
1827 return 0;
1830 /* Get the timeout interval used by the server to wait for an indication from a client */
1831 int modbus_get_indication_timeout(modbus_t *ctx, uint32_t *to_sec, uint32_t *to_usec)
1833 if (ctx == NULL) {
1834 errno = EINVAL;
1835 return -1;
1838 *to_sec = ctx->indication_timeout.tv_sec;
1839 *to_usec = ctx->indication_timeout.tv_usec;
1840 return 0;
1843 int modbus_set_indication_timeout(modbus_t *ctx, uint32_t to_sec, uint32_t to_usec)
1845 /* Indication timeout can be disabled when both values are zero */
1846 if (ctx == NULL || to_usec > 999999) {
1847 errno = EINVAL;
1848 return -1;
1851 ctx->indication_timeout.tv_sec = to_sec;
1852 ctx->indication_timeout.tv_usec = to_usec;
1853 return 0;
1856 int modbus_get_header_length(modbus_t *ctx)
1858 if (ctx == NULL) {
1859 errno = EINVAL;
1860 return -1;
1863 return ctx->backend->header_length;
1866 int modbus_enable_quirks(modbus_t *ctx, unsigned int quirks_mask)
1868 if (ctx == NULL) {
1869 errno = EINVAL;
1870 return -1;
1873 /* Enable quirks that have a true value at their index in the mask */
1874 ctx->quirks |= quirks_mask;
1875 return 0;
1878 int modbus_disable_quirks(modbus_t *ctx, unsigned int quirks_mask)
1880 if (ctx == NULL) {
1881 errno = EINVAL;
1882 return -1;
1885 /* Disable quirks that have a true value at ther index in the mask */
1886 ctx->quirks &= ~quirks_mask;
1887 return 0;
1890 int modbus_connect(modbus_t *ctx)
1892 if (ctx == NULL) {
1893 errno = EINVAL;
1894 return -1;
1897 return ctx->backend->connect(ctx);
1900 void modbus_close(modbus_t *ctx)
1902 if (ctx == NULL)
1903 return;
1905 ctx->backend->close(ctx);
1908 void modbus_free(modbus_t *ctx)
1910 if (ctx == NULL)
1911 return;
1913 ctx->backend->free(ctx);
1916 int modbus_set_debug(modbus_t *ctx, int flag)
1918 if (ctx == NULL) {
1919 errno = EINVAL;
1920 return -1;
1923 ctx->debug = flag;
1924 return 0;
1927 /* Allocates 4 arrays to store bits, input bits, registers and inputs
1928 registers. The pointers are stored in modbus_mapping structure.
1930 The modbus_mapping_new_start_address() function shall return the new allocated
1931 structure if successful. Otherwise it shall return NULL and set errno to
1932 ENOMEM. */
1933 modbus_mapping_t *modbus_mapping_new_start_address(unsigned int start_bits,
1934 unsigned int nb_bits,
1935 unsigned int start_input_bits,
1936 unsigned int nb_input_bits,
1937 unsigned int start_registers,
1938 unsigned int nb_registers,
1939 unsigned int start_input_registers,
1940 unsigned int nb_input_registers)
1942 modbus_mapping_t *mb_mapping;
1944 mb_mapping = (modbus_mapping_t *) malloc(sizeof(modbus_mapping_t));
1945 if (mb_mapping == NULL) {
1946 return NULL;
1949 /* 0X */
1950 mb_mapping->nb_bits = nb_bits;
1951 mb_mapping->start_bits = start_bits;
1952 if (nb_bits == 0) {
1953 mb_mapping->tab_bits = NULL;
1954 } else {
1955 /* Negative number raises a POSIX error */
1956 mb_mapping->tab_bits = (uint8_t *) malloc(nb_bits * sizeof(uint8_t));
1957 if (mb_mapping->tab_bits == NULL) {
1958 free(mb_mapping);
1959 return NULL;
1961 memset(mb_mapping->tab_bits, 0, nb_bits * sizeof(uint8_t));
1964 /* 1X */
1965 mb_mapping->nb_input_bits = nb_input_bits;
1966 mb_mapping->start_input_bits = start_input_bits;
1967 if (nb_input_bits == 0) {
1968 mb_mapping->tab_input_bits = NULL;
1969 } else {
1970 mb_mapping->tab_input_bits = (uint8_t *) malloc(nb_input_bits * sizeof(uint8_t));
1971 if (mb_mapping->tab_input_bits == NULL) {
1972 free(mb_mapping->tab_bits);
1973 free(mb_mapping);
1974 return NULL;
1976 memset(mb_mapping->tab_input_bits, 0, nb_input_bits * sizeof(uint8_t));
1979 /* 4X */
1980 mb_mapping->nb_registers = nb_registers;
1981 mb_mapping->start_registers = start_registers;
1982 if (nb_registers == 0) {
1983 mb_mapping->tab_registers = NULL;
1984 } else {
1985 mb_mapping->tab_registers = (uint16_t *) malloc(nb_registers * sizeof(uint16_t));
1986 if (mb_mapping->tab_registers == NULL) {
1987 free(mb_mapping->tab_input_bits);
1988 free(mb_mapping->tab_bits);
1989 free(mb_mapping);
1990 return NULL;
1992 memset(mb_mapping->tab_registers, 0, nb_registers * sizeof(uint16_t));
1995 /* 3X */
1996 mb_mapping->nb_input_registers = nb_input_registers;
1997 mb_mapping->start_input_registers = start_input_registers;
1998 if (nb_input_registers == 0) {
1999 mb_mapping->tab_input_registers = NULL;
2000 } else {
2001 mb_mapping->tab_input_registers =
2002 (uint16_t *) malloc(nb_input_registers * sizeof(uint16_t));
2003 if (mb_mapping->tab_input_registers == NULL) {
2004 free(mb_mapping->tab_registers);
2005 free(mb_mapping->tab_input_bits);
2006 free(mb_mapping->tab_bits);
2007 free(mb_mapping);
2008 return NULL;
2010 memset(mb_mapping->tab_input_registers, 0, nb_input_registers * sizeof(uint16_t));
2013 return mb_mapping;
2016 modbus_mapping_t *modbus_mapping_new(int nb_bits,
2017 int nb_input_bits,
2018 int nb_registers,
2019 int nb_input_registers)
2021 return modbus_mapping_new_start_address(
2022 0, nb_bits, 0, nb_input_bits, 0, nb_registers, 0, nb_input_registers);
2025 /* Frees the 4 arrays */
2026 void modbus_mapping_free(modbus_mapping_t *mb_mapping)
2028 if (mb_mapping == NULL) {
2029 return;
2032 free(mb_mapping->tab_input_registers);
2033 free(mb_mapping->tab_registers);
2034 free(mb_mapping->tab_input_bits);
2035 free(mb_mapping->tab_bits);
2036 free(mb_mapping);
2039 #ifndef HAVE_STRLCPY
2041 * Function strlcpy was originally developed by
2042 * Todd C. Miller <Todd.Miller@courtesan.com> to simplify writing secure code.
2043 * See ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/strlcpy.3
2044 * for more information.
2046 * Thank you Ulrich Drepper... not!
2048 * Copy src to string dest of size dest_size. At most dest_size-1 characters
2049 * will be copied. Always NUL terminates (unless dest_size == 0). Returns
2050 * strlen(src); if retval >= dest_size, truncation occurred.
2052 size_t strlcpy(char *dest, const char *src, size_t dest_size)
2054 register char *d = dest;
2055 register const char *s = src;
2056 register size_t n = dest_size;
2058 /* Copy as many bytes as will fit */
2059 if (n != 0 && --n != 0) {
2060 do {
2061 if ((*d++ = *s++) == 0)
2062 break;
2063 } while (--n != 0);
2066 /* Not enough room in dest, add NUL and traverse rest of src */
2067 if (n == 0) {
2068 if (dest_size != 0)
2069 *d = '\0'; /* NUL-terminate dest */
2070 while (*s++)
2074 return (s - src - 1); /* count does not include NUL */
2076 #endif