Update docs about memory consumption (closes #715)
[libmodbus.git] / src / modbus.c
blob4d3991c9741080251c568cf3debd40f2063ee977
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 (ctx->backend->backend_type == _MODBUS_BACKEND_TYPE_TCP) &&
453 (wsa_err == WSAENOTCONN || wsa_err == WSAENETRESET ||
454 wsa_err == WSAENOTSOCK || wsa_err == WSAESHUTDOWN ||
455 wsa_err == WSAECONNABORTED || wsa_err == WSAETIMEDOUT ||
456 wsa_err == WSAECONNRESET)) {
457 modbus_close(ctx);
458 modbus_connect(ctx);
460 #else
461 if ((ctx->error_recovery & MODBUS_ERROR_RECOVERY_LINK) &&
462 (ctx->backend->backend_type == _MODBUS_BACKEND_TYPE_TCP) &&
463 (errno == ECONNRESET || errno == ECONNREFUSED || errno == EBADF)) {
464 int saved_errno = errno;
465 modbus_close(ctx);
466 modbus_connect(ctx);
467 /* Could be removed by previous calls */
468 errno = saved_errno;
470 #endif
471 return -1;
474 /* Display the hex code of each character received */
475 if (ctx->debug) {
476 int i;
477 for (i = 0; i < rc; i++)
478 printf("<%.2X>", msg[msg_length + i]);
481 /* Sums bytes received */
482 msg_length += rc;
483 /* Computes remaining bytes */
484 length_to_read -= rc;
486 if (length_to_read == 0) {
487 switch (step) {
488 case _STEP_FUNCTION:
489 /* Function code position */
490 length_to_read = compute_meta_length_after_function(
491 msg[ctx->backend->header_length], msg_type);
492 if (length_to_read != 0) {
493 step = _STEP_META;
494 break;
495 } /* else switches straight to the next step */
496 case _STEP_META:
497 length_to_read = compute_data_length_after_meta(ctx, msg, msg_type);
498 if ((msg_length + length_to_read) > ctx->backend->max_adu_length) {
499 errno = EMBBADDATA;
500 _error_print(ctx, "too many data");
501 return -1;
503 step = _STEP_DATA;
504 break;
505 default:
506 break;
510 if (length_to_read > 0 &&
511 (ctx->byte_timeout.tv_sec > 0 || ctx->byte_timeout.tv_usec > 0)) {
512 /* If there is no character in the buffer, the allowed timeout
513 interval between two consecutive bytes is defined by
514 byte_timeout */
515 tv.tv_sec = ctx->byte_timeout.tv_sec;
516 tv.tv_usec = ctx->byte_timeout.tv_usec;
517 p_tv = &tv;
519 /* else timeout isn't set again, the full response must be read before
520 expiration of response timeout (for CONFIRMATION only) */
523 if (ctx->debug)
524 printf("\n");
526 return ctx->backend->check_integrity(ctx, msg, msg_length);
529 /* Receive the request from a modbus master */
530 int modbus_receive(modbus_t *ctx, uint8_t *req)
532 if (ctx == NULL) {
533 errno = EINVAL;
534 return -1;
537 return ctx->backend->receive(ctx, req);
540 /* Receives the confirmation.
542 The function shall store the read response in rsp and return the number of
543 values (bits or words). Otherwise, its shall return -1 and errno is set.
545 The function doesn't check the confirmation is the expected response to the
546 initial request.
548 int modbus_receive_confirmation(modbus_t *ctx, uint8_t *rsp)
550 if (ctx == NULL) {
551 errno = EINVAL;
552 return -1;
555 return _modbus_receive_msg(ctx, rsp, MSG_CONFIRMATION);
558 static int check_confirmation(modbus_t *ctx, uint8_t *req, uint8_t *rsp, int rsp_length)
560 int rc;
561 int rsp_length_computed;
562 const unsigned int offset = ctx->backend->header_length;
563 const int function = rsp[offset];
565 if (ctx->backend->pre_check_confirmation) {
566 rc = ctx->backend->pre_check_confirmation(ctx, req, rsp, rsp_length);
567 if (rc == -1) {
568 if (ctx->error_recovery & MODBUS_ERROR_RECOVERY_PROTOCOL) {
569 _sleep_response_timeout(ctx);
570 modbus_flush(ctx);
572 return -1;
576 rsp_length_computed = compute_response_length_from_request(ctx, req);
578 /* Exception code */
579 if (function >= 0x80) {
580 if (rsp_length == (int) (offset + 2 + ctx->backend->checksum_length) &&
581 req[offset] == (rsp[offset] - 0x80)) {
582 /* Valid exception code received */
584 int exception_code = rsp[offset + 1];
585 if (exception_code < MODBUS_EXCEPTION_MAX) {
586 errno = MODBUS_ENOBASE + exception_code;
587 } else {
588 errno = EMBBADEXC;
590 _error_print(ctx, NULL);
591 return -1;
592 } else {
593 errno = EMBBADEXC;
594 _error_print(ctx, NULL);
595 return -1;
599 /* Check length */
600 if ((rsp_length == rsp_length_computed ||
601 rsp_length_computed == MSG_LENGTH_UNDEFINED) &&
602 function < 0x80) {
603 int req_nb_value;
604 int rsp_nb_value;
605 int resp_addr_ok = TRUE;
606 int resp_data_ok = TRUE;
608 /* Check function code */
609 if (function != req[offset]) {
610 if (ctx->debug) {
611 fprintf(
612 stderr,
613 "Received function not corresponding to the request (0x%X != 0x%X)\n",
614 function,
615 req[offset]);
617 if (ctx->error_recovery & MODBUS_ERROR_RECOVERY_PROTOCOL) {
618 _sleep_response_timeout(ctx);
619 modbus_flush(ctx);
621 errno = EMBBADDATA;
622 return -1;
625 /* Check the number of values is corresponding to the request */
626 switch (function) {
627 case MODBUS_FC_READ_COILS:
628 case MODBUS_FC_READ_DISCRETE_INPUTS:
629 /* Read functions, 8 values in a byte (nb
630 * of values in the request and byte count in
631 * the response. */
632 req_nb_value = (req[offset + 3] << 8) + req[offset + 4];
633 req_nb_value = (req_nb_value / 8) + ((req_nb_value % 8) ? 1 : 0);
634 rsp_nb_value = rsp[offset + 1];
635 break;
636 case MODBUS_FC_WRITE_AND_READ_REGISTERS:
637 case MODBUS_FC_READ_HOLDING_REGISTERS:
638 case MODBUS_FC_READ_INPUT_REGISTERS:
639 /* Read functions 1 value = 2 bytes */
640 req_nb_value = (req[offset + 3] << 8) + req[offset + 4];
641 rsp_nb_value = (rsp[offset + 1] / 2);
642 break;
643 case MODBUS_FC_WRITE_MULTIPLE_COILS:
644 case MODBUS_FC_WRITE_MULTIPLE_REGISTERS:
645 /* address in request and response must be equal */
646 if ((req[offset + 1] != rsp[offset + 1]) ||
647 (req[offset + 2] != rsp[offset + 2])) {
648 resp_addr_ok = FALSE;
650 /* N Write functions */
651 req_nb_value = (req[offset + 3] << 8) + req[offset + 4];
652 rsp_nb_value = (rsp[offset + 3] << 8) | rsp[offset + 4];
653 break;
654 case MODBUS_FC_REPORT_SLAVE_ID:
655 /* Report slave ID (bytes received) */
656 req_nb_value = rsp_nb_value = rsp[offset + 1];
657 break;
658 case MODBUS_FC_WRITE_SINGLE_COIL:
659 case MODBUS_FC_WRITE_SINGLE_REGISTER:
660 /* address in request and response must be equal */
661 if ((req[offset + 1] != rsp[offset + 1]) ||
662 (req[offset + 2] != rsp[offset + 2])) {
663 resp_addr_ok = FALSE;
665 /* data in request and response must be equal */
666 if ((req[offset + 3] != rsp[offset + 3]) ||
667 (req[offset + 4] != rsp[offset + 4])) {
668 resp_data_ok = FALSE;
670 /* 1 Write functions & others */
671 req_nb_value = rsp_nb_value = 1;
672 break;
673 default:
674 /* 1 Write functions & others */
675 req_nb_value = rsp_nb_value = 1;
676 break;
679 if ((req_nb_value == rsp_nb_value) && (resp_addr_ok == TRUE) &&
680 (resp_data_ok == TRUE)) {
681 rc = rsp_nb_value;
682 } else {
683 if (ctx->debug) {
684 fprintf(stderr,
685 "Received data not corresponding to the request (%d != %d)\n",
686 rsp_nb_value,
687 req_nb_value);
690 if (ctx->error_recovery & MODBUS_ERROR_RECOVERY_PROTOCOL) {
691 _sleep_response_timeout(ctx);
692 modbus_flush(ctx);
695 errno = EMBBADDATA;
696 rc = -1;
698 } else {
699 if (ctx->debug) {
700 fprintf(
701 stderr,
702 "Message length not corresponding to the computed length (%d != %d)\n",
703 rsp_length,
704 rsp_length_computed);
706 if (ctx->error_recovery & MODBUS_ERROR_RECOVERY_PROTOCOL) {
707 _sleep_response_timeout(ctx);
708 modbus_flush(ctx);
710 errno = EMBBADDATA;
711 rc = -1;
714 return rc;
717 static int
718 response_io_status(uint8_t *tab_io_status, int address, int nb, uint8_t *rsp, int offset)
720 int shift = 0;
721 /* Instead of byte (not allowed in Win32) */
722 int one_byte = 0;
723 int i;
725 for (i = address; i < address + nb; i++) {
726 one_byte |= tab_io_status[i] << shift;
727 if (shift == 7) {
728 /* Byte is full */
729 rsp[offset++] = one_byte;
730 one_byte = shift = 0;
731 } else {
732 shift++;
736 if (shift != 0)
737 rsp[offset++] = one_byte;
739 return offset;
742 /* Build the exception response */
743 static int response_exception(modbus_t *ctx,
744 sft_t *sft,
745 int exception_code,
746 uint8_t *rsp,
747 unsigned int to_flush,
748 const char *template,
749 ...)
751 int rsp_length;
753 /* Print debug message */
754 if (ctx->debug) {
755 va_list ap;
757 va_start(ap, template);
758 vfprintf(stderr, template, ap);
759 va_end(ap);
762 /* Flush if required */
763 if (to_flush) {
764 _sleep_response_timeout(ctx);
765 modbus_flush(ctx);
768 /* Build exception response */
769 sft->function = sft->function + 0x80;
770 rsp_length = ctx->backend->build_response_basis(sft, rsp);
771 rsp[rsp_length++] = exception_code;
773 return rsp_length;
776 /* Send a response to the received request.
777 Analyses the request and constructs a response.
779 If an error occurs, this function construct the response
780 accordingly.
782 int modbus_reply(modbus_t *ctx,
783 const uint8_t *req,
784 int req_length,
785 modbus_mapping_t *mb_mapping)
787 unsigned int offset;
788 int slave;
789 int function;
790 uint16_t address;
791 uint8_t rsp[MAX_MESSAGE_LENGTH];
792 int rsp_length = 0;
793 sft_t sft;
795 if (ctx == NULL) {
796 errno = EINVAL;
797 return -1;
800 offset = ctx->backend->header_length;
801 slave = req[offset - 1];
802 function = req[offset];
803 address = (req[offset + 1] << 8) + req[offset + 2];
805 sft.slave = slave;
806 sft.function = function;
807 sft.t_id = ctx->backend->prepare_response_tid(req, &req_length);
809 /* Data are flushed on illegal number of values errors. */
810 switch (function) {
811 case MODBUS_FC_READ_COILS:
812 case MODBUS_FC_READ_DISCRETE_INPUTS: {
813 unsigned int is_input = (function == MODBUS_FC_READ_DISCRETE_INPUTS);
814 int start_bits = is_input ? mb_mapping->start_input_bits : mb_mapping->start_bits;
815 int nb_bits = is_input ? mb_mapping->nb_input_bits : mb_mapping->nb_bits;
816 uint8_t *tab_bits = is_input ? mb_mapping->tab_input_bits : mb_mapping->tab_bits;
817 const char *const name = is_input ? "read_input_bits" : "read_bits";
818 int nb = (req[offset + 3] << 8) + req[offset + 4];
819 /* The mapping can be shifted to reduce memory consumption and it
820 doesn't always start at address zero. */
821 int mapping_address = address - start_bits;
823 if (nb < 1 || MODBUS_MAX_READ_BITS < nb) {
824 rsp_length = response_exception(ctx,
825 &sft,
826 MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE,
827 rsp,
828 TRUE,
829 "Illegal nb of values %d in %s (max %d)\n",
831 name,
832 MODBUS_MAX_READ_BITS);
833 } else if (mapping_address < 0 || (mapping_address + nb) > nb_bits) {
834 rsp_length = response_exception(ctx,
835 &sft,
836 MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS,
837 rsp,
838 FALSE,
839 "Illegal data address 0x%0X in %s\n",
840 mapping_address < 0 ? address : address + nb,
841 name);
842 } else {
843 rsp_length = ctx->backend->build_response_basis(&sft, rsp);
844 rsp[rsp_length++] = (nb / 8) + ((nb % 8) ? 1 : 0);
845 rsp_length =
846 response_io_status(tab_bits, mapping_address, nb, rsp, rsp_length);
848 } break;
849 case MODBUS_FC_READ_HOLDING_REGISTERS:
850 case MODBUS_FC_READ_INPUT_REGISTERS: {
851 unsigned int is_input = (function == MODBUS_FC_READ_INPUT_REGISTERS);
852 int start_registers =
853 is_input ? mb_mapping->start_input_registers : mb_mapping->start_registers;
854 int nb_registers =
855 is_input ? mb_mapping->nb_input_registers : mb_mapping->nb_registers;
856 uint16_t *tab_registers =
857 is_input ? mb_mapping->tab_input_registers : mb_mapping->tab_registers;
858 const char *const name = is_input ? "read_input_registers" : "read_registers";
859 int nb = (req[offset + 3] << 8) + req[offset + 4];
860 /* The mapping can be shifted to reduce memory consumption and it
861 doesn't always start at address zero. */
862 int mapping_address = address - start_registers;
864 if (nb < 1 || MODBUS_MAX_READ_REGISTERS < nb) {
865 rsp_length = response_exception(ctx,
866 &sft,
867 MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE,
868 rsp,
869 TRUE,
870 "Illegal nb of values %d in %s (max %d)\n",
872 name,
873 MODBUS_MAX_READ_REGISTERS);
874 } else if (mapping_address < 0 || (mapping_address + nb) > nb_registers) {
875 rsp_length = response_exception(ctx,
876 &sft,
877 MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS,
878 rsp,
879 FALSE,
880 "Illegal data address 0x%0X in %s\n",
881 mapping_address < 0 ? address : address + nb,
882 name);
883 } else {
884 int i;
886 rsp_length = ctx->backend->build_response_basis(&sft, rsp);
887 rsp[rsp_length++] = nb << 1;
888 for (i = mapping_address; i < mapping_address + nb; i++) {
889 rsp[rsp_length++] = tab_registers[i] >> 8;
890 rsp[rsp_length++] = tab_registers[i] & 0xFF;
893 } break;
894 case MODBUS_FC_WRITE_SINGLE_COIL: {
895 int mapping_address = address - mb_mapping->start_bits;
897 if (mapping_address < 0 || mapping_address >= mb_mapping->nb_bits) {
898 rsp_length = response_exception(ctx,
899 &sft,
900 MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS,
901 rsp,
902 FALSE,
903 "Illegal data address 0x%0X in write_bit\n",
904 address);
905 } else {
906 int data = (req[offset + 3] << 8) + req[offset + 4];
908 if (data == 0xFF00 || data == 0x0) {
909 mb_mapping->tab_bits[mapping_address] = data ? ON : OFF;
910 memcpy(rsp, req, req_length);
911 rsp_length = req_length;
912 } else {
913 rsp_length = response_exception(
914 ctx,
915 &sft,
916 MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE,
917 rsp,
918 FALSE,
919 "Illegal data value 0x%0X in write_bit request at address %0X\n",
920 data,
921 address);
924 } break;
925 case MODBUS_FC_WRITE_SINGLE_REGISTER: {
926 int mapping_address = address - mb_mapping->start_registers;
928 if (mapping_address < 0 || mapping_address >= mb_mapping->nb_registers) {
929 rsp_length =
930 response_exception(ctx,
931 &sft,
932 MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS,
933 rsp,
934 FALSE,
935 "Illegal data address 0x%0X in write_register\n",
936 address);
937 } else {
938 int data = (req[offset + 3] << 8) + req[offset + 4];
940 mb_mapping->tab_registers[mapping_address] = data;
941 memcpy(rsp, req, req_length);
942 rsp_length = req_length;
944 } break;
945 case MODBUS_FC_WRITE_MULTIPLE_COILS: {
946 int nb = (req[offset + 3] << 8) + req[offset + 4];
947 int nb_bits = req[offset + 5];
948 int mapping_address = address - mb_mapping->start_bits;
950 if (nb < 1 || MODBUS_MAX_WRITE_BITS < nb || nb_bits * 8 < nb) {
951 /* May be the indication has been truncated on reading because of
952 * invalid address (eg. nb is 0 but the request contains values to
953 * write) so it's necessary to flush. */
954 rsp_length =
955 response_exception(ctx,
956 &sft,
957 MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE,
958 rsp,
959 TRUE,
960 "Illegal number of values %d in write_bits (max %d)\n",
962 MODBUS_MAX_WRITE_BITS);
963 } else if (mapping_address < 0 || (mapping_address + nb) > mb_mapping->nb_bits) {
964 rsp_length = response_exception(ctx,
965 &sft,
966 MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS,
967 rsp,
968 FALSE,
969 "Illegal data address 0x%0X in write_bits\n",
970 mapping_address < 0 ? address : address + nb);
971 } else {
972 /* 6 = byte count */
973 modbus_set_bits_from_bytes(
974 mb_mapping->tab_bits, mapping_address, nb, &req[offset + 6]);
976 rsp_length = ctx->backend->build_response_basis(&sft, rsp);
977 /* 4 to copy the bit address (2) and the quantity of bits */
978 memcpy(rsp + rsp_length, req + rsp_length, 4);
979 rsp_length += 4;
981 } break;
982 case MODBUS_FC_WRITE_MULTIPLE_REGISTERS: {
983 int nb = (req[offset + 3] << 8) + req[offset + 4];
984 int nb_bytes = req[offset + 5];
985 int mapping_address = address - mb_mapping->start_registers;
987 if (nb < 1 || MODBUS_MAX_WRITE_REGISTERS < nb || nb_bytes != nb * 2) {
988 rsp_length = response_exception(
989 ctx,
990 &sft,
991 MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE,
992 rsp,
993 TRUE,
994 "Illegal number of values %d in write_registers (max %d)\n",
996 MODBUS_MAX_WRITE_REGISTERS);
997 } else if (mapping_address < 0 ||
998 (mapping_address + nb) > mb_mapping->nb_registers) {
999 rsp_length =
1000 response_exception(ctx,
1001 &sft,
1002 MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS,
1003 rsp,
1004 FALSE,
1005 "Illegal data address 0x%0X in write_registers\n",
1006 mapping_address < 0 ? address : address + nb);
1007 } else {
1008 int i, j;
1009 for (i = mapping_address, j = 6; i < mapping_address + nb; i++, j += 2) {
1010 /* 6 and 7 = first value */
1011 mb_mapping->tab_registers[i] =
1012 (req[offset + j] << 8) + req[offset + j + 1];
1015 rsp_length = ctx->backend->build_response_basis(&sft, rsp);
1016 /* 4 to copy the address (2) and the no. of registers */
1017 memcpy(rsp + rsp_length, req + rsp_length, 4);
1018 rsp_length += 4;
1020 } break;
1021 case MODBUS_FC_REPORT_SLAVE_ID: {
1022 int str_len;
1023 int byte_count_pos;
1025 rsp_length = ctx->backend->build_response_basis(&sft, rsp);
1026 /* Skip byte count for now */
1027 byte_count_pos = rsp_length++;
1028 rsp[rsp_length++] = _REPORT_SLAVE_ID;
1029 /* Run indicator status to ON */
1030 rsp[rsp_length++] = 0xFF;
1031 /* LMB + length of LIBMODBUS_VERSION_STRING */
1032 str_len = 3 + strlen(LIBMODBUS_VERSION_STRING);
1033 memcpy(rsp + rsp_length, "LMB" LIBMODBUS_VERSION_STRING, str_len);
1034 rsp_length += str_len;
1035 rsp[byte_count_pos] = rsp_length - byte_count_pos - 1;
1036 } break;
1037 case MODBUS_FC_READ_EXCEPTION_STATUS:
1038 if (ctx->debug) {
1039 fprintf(stderr, "FIXME Not implemented\n");
1041 errno = ENOPROTOOPT;
1042 return -1;
1043 break;
1044 case MODBUS_FC_MASK_WRITE_REGISTER: {
1045 int mapping_address = address - mb_mapping->start_registers;
1047 if (mapping_address < 0 || mapping_address >= mb_mapping->nb_registers) {
1048 rsp_length =
1049 response_exception(ctx,
1050 &sft,
1051 MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS,
1052 rsp,
1053 FALSE,
1054 "Illegal data address 0x%0X in write_register\n",
1055 address);
1056 } else {
1057 uint16_t data = mb_mapping->tab_registers[mapping_address];
1058 uint16_t and = (req[offset + 3] << 8) + req[offset + 4];
1059 uint16_t or = (req[offset + 5] << 8) + req[offset + 6];
1061 data = (data & and) | (or &(~and) );
1062 mb_mapping->tab_registers[mapping_address] = data;
1063 memcpy(rsp, req, req_length);
1064 rsp_length = req_length;
1066 } break;
1067 case MODBUS_FC_WRITE_AND_READ_REGISTERS: {
1068 int nb = (req[offset + 3] << 8) + req[offset + 4];
1069 uint16_t address_write = (req[offset + 5] << 8) + req[offset + 6];
1070 int nb_write = (req[offset + 7] << 8) + req[offset + 8];
1071 int nb_write_bytes = req[offset + 9];
1072 int mapping_address = address - mb_mapping->start_registers;
1073 int mapping_address_write = address_write - mb_mapping->start_registers;
1075 if (nb_write < 1 || MODBUS_MAX_WR_WRITE_REGISTERS < nb_write || nb < 1 ||
1076 MODBUS_MAX_WR_READ_REGISTERS < nb || nb_write_bytes != nb_write * 2) {
1077 rsp_length = response_exception(
1078 ctx,
1079 &sft,
1080 MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE,
1081 rsp,
1082 TRUE,
1083 "Illegal nb of values (W%d, R%d) in write_and_read_registers (max W%d, "
1084 "R%d)\n",
1085 nb_write,
1087 MODBUS_MAX_WR_WRITE_REGISTERS,
1088 MODBUS_MAX_WR_READ_REGISTERS);
1089 } else if (mapping_address < 0 ||
1090 (mapping_address + nb) > mb_mapping->nb_registers ||
1091 mapping_address_write < 0 ||
1092 (mapping_address_write + nb_write) > mb_mapping->nb_registers) {
1093 rsp_length = response_exception(
1094 ctx,
1095 &sft,
1096 MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS,
1097 rsp,
1098 FALSE,
1099 "Illegal data read address 0x%0X or write address 0x%0X "
1100 "write_and_read_registers\n",
1101 mapping_address < 0 ? address : address + nb,
1102 mapping_address_write < 0 ? address_write : address_write + nb_write);
1103 } else {
1104 int i, j;
1105 rsp_length = ctx->backend->build_response_basis(&sft, rsp);
1106 rsp[rsp_length++] = nb << 1;
1108 /* Write first.
1109 10 and 11 are the offset of the first values to write */
1110 for (i = mapping_address_write, j = 10; i < mapping_address_write + nb_write;
1111 i++, j += 2) {
1112 mb_mapping->tab_registers[i] =
1113 (req[offset + j] << 8) + req[offset + j + 1];
1116 /* and read the data for the response */
1117 for (i = mapping_address; i < mapping_address + nb; i++) {
1118 rsp[rsp_length++] = mb_mapping->tab_registers[i] >> 8;
1119 rsp[rsp_length++] = mb_mapping->tab_registers[i] & 0xFF;
1122 } break;
1124 default:
1125 rsp_length = response_exception(ctx,
1126 &sft,
1127 MODBUS_EXCEPTION_ILLEGAL_FUNCTION,
1128 rsp,
1129 TRUE,
1130 "Unknown Modbus function code: 0x%0X\n",
1131 function);
1132 break;
1135 /* Suppress any responses in RTU when the request was a broadcast, excepted when quirk
1136 * is enabled. */
1137 if (ctx->backend->backend_type == _MODBUS_BACKEND_TYPE_RTU &&
1138 slave == MODBUS_BROADCAST_ADDRESS &&
1139 !(ctx->quirks & MODBUS_QUIRK_REPLY_TO_BROADCAST)) {
1140 return 0;
1142 return send_msg(ctx, rsp, rsp_length);
1145 int modbus_reply_exception(modbus_t *ctx, const uint8_t *req, unsigned int exception_code)
1147 unsigned int offset;
1148 int slave;
1149 int function;
1150 uint8_t rsp[MAX_MESSAGE_LENGTH];
1151 int rsp_length;
1152 int dummy_length = 99;
1153 sft_t sft;
1155 if (ctx == NULL) {
1156 errno = EINVAL;
1157 return -1;
1160 offset = ctx->backend->header_length;
1161 slave = req[offset - 1];
1162 function = req[offset];
1164 sft.slave = slave;
1165 sft.function = function + 0x80;
1166 sft.t_id = ctx->backend->prepare_response_tid(req, &dummy_length);
1167 rsp_length = ctx->backend->build_response_basis(&sft, rsp);
1169 /* Positive exception code */
1170 if (exception_code < MODBUS_EXCEPTION_MAX) {
1171 rsp[rsp_length++] = exception_code;
1172 return send_msg(ctx, rsp, rsp_length);
1173 } else {
1174 errno = EINVAL;
1175 return -1;
1179 /* Reads IO status */
1180 static int read_io_status(modbus_t *ctx, int function, int addr, int nb, uint8_t *dest)
1182 int rc;
1183 int req_length;
1185 uint8_t req[_MIN_REQ_LENGTH];
1186 uint8_t rsp[MAX_MESSAGE_LENGTH];
1188 req_length = ctx->backend->build_request_basis(ctx, function, addr, nb, req);
1190 rc = send_msg(ctx, req, req_length);
1191 if (rc > 0) {
1192 int temp, bit;
1193 int pos = 0;
1194 unsigned int offset;
1195 unsigned int offset_end;
1196 unsigned int i;
1198 rc = _modbus_receive_msg(ctx, rsp, MSG_CONFIRMATION);
1199 if (rc == -1)
1200 return -1;
1202 rc = check_confirmation(ctx, req, rsp, rc);
1203 if (rc == -1)
1204 return -1;
1206 offset = ctx->backend->header_length + 2;
1207 offset_end = offset + rc;
1208 for (i = offset; i < offset_end; i++) {
1209 /* Shift reg hi_byte to temp */
1210 temp = rsp[i];
1212 for (bit = 0x01; (bit & 0xff) && (pos < nb);) {
1213 dest[pos++] = (temp & bit) ? TRUE : FALSE;
1214 bit = bit << 1;
1219 return rc;
1222 /* Reads the boolean status of bits and sets the array elements
1223 in the destination to TRUE or FALSE (single bits). */
1224 int modbus_read_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest)
1226 int rc;
1228 if (ctx == NULL) {
1229 errno = EINVAL;
1230 return -1;
1233 if (nb > MODBUS_MAX_READ_BITS) {
1234 if (ctx->debug) {
1235 fprintf(stderr,
1236 "ERROR Too many bits requested (%d > %d)\n",
1238 MODBUS_MAX_READ_BITS);
1240 errno = EMBMDATA;
1241 return -1;
1244 rc = read_io_status(ctx, MODBUS_FC_READ_COILS, addr, nb, dest);
1246 if (rc == -1)
1247 return -1;
1248 else
1249 return nb;
1252 /* Same as modbus_read_bits but reads the remote device input table */
1253 int modbus_read_input_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest)
1255 int rc;
1257 if (ctx == NULL) {
1258 errno = EINVAL;
1259 return -1;
1262 if (nb > MODBUS_MAX_READ_BITS) {
1263 if (ctx->debug) {
1264 fprintf(stderr,
1265 "ERROR Too many discrete inputs requested (%d > %d)\n",
1267 MODBUS_MAX_READ_BITS);
1269 errno = EMBMDATA;
1270 return -1;
1273 rc = read_io_status(ctx, MODBUS_FC_READ_DISCRETE_INPUTS, addr, nb, dest);
1275 if (rc == -1)
1276 return -1;
1277 else
1278 return nb;
1281 /* Reads the data from a remote device and put that data into an array */
1282 static int read_registers(modbus_t *ctx, int function, int addr, int nb, uint16_t *dest)
1284 int rc;
1285 int req_length;
1286 uint8_t req[_MIN_REQ_LENGTH];
1287 uint8_t rsp[MAX_MESSAGE_LENGTH];
1289 if (nb > MODBUS_MAX_READ_REGISTERS) {
1290 if (ctx->debug) {
1291 fprintf(stderr,
1292 "ERROR Too many registers requested (%d > %d)\n",
1294 MODBUS_MAX_READ_REGISTERS);
1296 errno = EMBMDATA;
1297 return -1;
1300 req_length = ctx->backend->build_request_basis(ctx, function, addr, nb, req);
1302 rc = send_msg(ctx, req, req_length);
1303 if (rc > 0) {
1304 unsigned int offset;
1305 int i;
1307 rc = _modbus_receive_msg(ctx, rsp, MSG_CONFIRMATION);
1308 if (rc == -1)
1309 return -1;
1311 rc = check_confirmation(ctx, req, rsp, rc);
1312 if (rc == -1)
1313 return -1;
1315 offset = ctx->backend->header_length;
1317 for (i = 0; i < rc; i++) {
1318 /* shift reg hi_byte to temp OR with lo_byte */
1319 dest[i] = (rsp[offset + 2 + (i << 1)] << 8) | rsp[offset + 3 + (i << 1)];
1323 return rc;
1326 /* Reads the holding registers of remote device and put the data into an
1327 array */
1328 int modbus_read_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest)
1330 int status;
1332 if (ctx == NULL) {
1333 errno = EINVAL;
1334 return -1;
1337 if (nb > MODBUS_MAX_READ_REGISTERS) {
1338 if (ctx->debug) {
1339 fprintf(stderr,
1340 "ERROR Too many registers requested (%d > %d)\n",
1342 MODBUS_MAX_READ_REGISTERS);
1344 errno = EMBMDATA;
1345 return -1;
1348 status = read_registers(ctx, MODBUS_FC_READ_HOLDING_REGISTERS, addr, nb, dest);
1349 return status;
1352 /* Reads the input registers of remote device and put the data into an array */
1353 int modbus_read_input_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest)
1355 int status;
1357 if (ctx == NULL) {
1358 errno = EINVAL;
1359 return -1;
1362 if (nb > MODBUS_MAX_READ_REGISTERS) {
1363 if (ctx->debug) {
1364 fprintf(stderr,
1365 "ERROR Too many input registers requested (%d > %d)\n",
1367 MODBUS_MAX_READ_REGISTERS);
1369 errno = EMBMDATA;
1370 return -1;
1373 status = read_registers(ctx, MODBUS_FC_READ_INPUT_REGISTERS, addr, nb, dest);
1375 return status;
1378 /* Write a value to the specified register of the remote device.
1379 Used by write_bit and write_register */
1380 static int write_single(modbus_t *ctx, int function, int addr, const uint16_t value)
1382 int rc;
1383 int req_length;
1384 uint8_t req[_MIN_REQ_LENGTH];
1386 if (ctx == NULL) {
1387 errno = EINVAL;
1388 return -1;
1391 req_length = ctx->backend->build_request_basis(ctx, function, addr, (int) value, req);
1393 rc = send_msg(ctx, req, req_length);
1394 if (rc > 0) {
1395 /* Used by write_bit and write_register */
1396 uint8_t rsp[MAX_MESSAGE_LENGTH];
1398 rc = _modbus_receive_msg(ctx, rsp, MSG_CONFIRMATION);
1399 if (rc == -1)
1400 return -1;
1402 rc = check_confirmation(ctx, req, rsp, rc);
1405 return rc;
1408 /* Turns ON or OFF a single bit of the remote device */
1409 int modbus_write_bit(modbus_t *ctx, int addr, int status)
1411 if (ctx == NULL) {
1412 errno = EINVAL;
1413 return -1;
1416 return write_single(ctx, MODBUS_FC_WRITE_SINGLE_COIL, addr, status ? 0xFF00 : 0);
1419 /* Writes a value in one register of the remote device */
1420 int modbus_write_register(modbus_t *ctx, int addr, const uint16_t value)
1422 if (ctx == NULL) {
1423 errno = EINVAL;
1424 return -1;
1427 return write_single(ctx, MODBUS_FC_WRITE_SINGLE_REGISTER, addr, value);
1430 /* Write the bits of the array in the remote device */
1431 int modbus_write_bits(modbus_t *ctx, int addr, int nb, const uint8_t *src)
1433 int rc;
1434 int i;
1435 int byte_count;
1436 int req_length;
1437 int bit_check = 0;
1438 int pos = 0;
1439 uint8_t req[MAX_MESSAGE_LENGTH];
1441 if (ctx == NULL) {
1442 errno = EINVAL;
1443 return -1;
1446 if (nb > MODBUS_MAX_WRITE_BITS) {
1447 if (ctx->debug) {
1448 fprintf(stderr,
1449 "ERROR Writing too many bits (%d > %d)\n",
1451 MODBUS_MAX_WRITE_BITS);
1453 errno = EMBMDATA;
1454 return -1;
1457 req_length = ctx->backend->build_request_basis(
1458 ctx, MODBUS_FC_WRITE_MULTIPLE_COILS, addr, nb, req);
1459 byte_count = (nb / 8) + ((nb % 8) ? 1 : 0);
1460 req[req_length++] = byte_count;
1462 for (i = 0; i < byte_count; i++) {
1463 int bit;
1465 bit = 0x01;
1466 req[req_length] = 0;
1468 while ((bit & 0xFF) && (bit_check++ < nb)) {
1469 if (src[pos++])
1470 req[req_length] |= bit;
1471 else
1472 req[req_length] &= ~bit;
1474 bit = bit << 1;
1476 req_length++;
1479 rc = send_msg(ctx, req, req_length);
1480 if (rc > 0) {
1481 uint8_t rsp[MAX_MESSAGE_LENGTH];
1483 rc = _modbus_receive_msg(ctx, rsp, MSG_CONFIRMATION);
1484 if (rc == -1)
1485 return -1;
1487 rc = check_confirmation(ctx, req, rsp, rc);
1490 return rc;
1493 /* Write the values from the array to the registers of the remote device */
1494 int modbus_write_registers(modbus_t *ctx, int addr, int nb, const uint16_t *src)
1496 int rc;
1497 int i;
1498 int req_length;
1499 int byte_count;
1500 uint8_t req[MAX_MESSAGE_LENGTH];
1502 if (ctx == NULL) {
1503 errno = EINVAL;
1504 return -1;
1507 if (nb > MODBUS_MAX_WRITE_REGISTERS) {
1508 if (ctx->debug) {
1509 fprintf(stderr,
1510 "ERROR Trying to write to too many registers (%d > %d)\n",
1512 MODBUS_MAX_WRITE_REGISTERS);
1514 errno = EMBMDATA;
1515 return -1;
1518 req_length = ctx->backend->build_request_basis(
1519 ctx, MODBUS_FC_WRITE_MULTIPLE_REGISTERS, addr, nb, req);
1520 byte_count = nb * 2;
1521 req[req_length++] = byte_count;
1523 for (i = 0; i < nb; i++) {
1524 req[req_length++] = src[i] >> 8;
1525 req[req_length++] = src[i] & 0x00FF;
1528 rc = send_msg(ctx, req, req_length);
1529 if (rc > 0) {
1530 uint8_t rsp[MAX_MESSAGE_LENGTH];
1532 rc = _modbus_receive_msg(ctx, rsp, MSG_CONFIRMATION);
1533 if (rc == -1)
1534 return -1;
1536 rc = check_confirmation(ctx, req, rsp, rc);
1539 return rc;
1542 int modbus_mask_write_register(modbus_t *ctx,
1543 int addr,
1544 uint16_t and_mask,
1545 uint16_t or_mask)
1547 int rc;
1548 int req_length;
1549 /* The request length can not exceed _MIN_REQ_LENGTH - 2 and 4 bytes to
1550 * store the masks. The ugly substraction is there to remove the 'nb' value
1551 * (2 bytes) which is not used. */
1552 uint8_t req[_MIN_REQ_LENGTH + 2];
1554 req_length = ctx->backend->build_request_basis(
1555 ctx, MODBUS_FC_MASK_WRITE_REGISTER, addr, 0, req);
1557 /* HACKISH, count is not used */
1558 req_length -= 2;
1560 req[req_length++] = and_mask >> 8;
1561 req[req_length++] = and_mask & 0x00ff;
1562 req[req_length++] = or_mask >> 8;
1563 req[req_length++] = or_mask & 0x00ff;
1565 rc = send_msg(ctx, req, req_length);
1566 if (rc > 0) {
1567 /* Used by write_bit and write_register */
1568 uint8_t rsp[MAX_MESSAGE_LENGTH];
1570 rc = _modbus_receive_msg(ctx, rsp, MSG_CONFIRMATION);
1571 if (rc == -1)
1572 return -1;
1574 rc = check_confirmation(ctx, req, rsp, rc);
1577 return rc;
1580 /* Write multiple registers from src array to remote device and read multiple
1581 registers from remote device to dest array. */
1582 int modbus_write_and_read_registers(modbus_t *ctx,
1583 int write_addr,
1584 int write_nb,
1585 const uint16_t *src,
1586 int read_addr,
1587 int read_nb,
1588 uint16_t *dest)
1591 int rc;
1592 int req_length;
1593 int i;
1594 int byte_count;
1595 uint8_t req[MAX_MESSAGE_LENGTH];
1596 uint8_t rsp[MAX_MESSAGE_LENGTH];
1598 if (ctx == NULL) {
1599 errno = EINVAL;
1600 return -1;
1603 if (write_nb > MODBUS_MAX_WR_WRITE_REGISTERS) {
1604 if (ctx->debug) {
1605 fprintf(stderr,
1606 "ERROR Too many registers to write (%d > %d)\n",
1607 write_nb,
1608 MODBUS_MAX_WR_WRITE_REGISTERS);
1610 errno = EMBMDATA;
1611 return -1;
1614 if (read_nb > MODBUS_MAX_WR_READ_REGISTERS) {
1615 if (ctx->debug) {
1616 fprintf(stderr,
1617 "ERROR Too many registers requested (%d > %d)\n",
1618 read_nb,
1619 MODBUS_MAX_WR_READ_REGISTERS);
1621 errno = EMBMDATA;
1622 return -1;
1624 req_length = ctx->backend->build_request_basis(
1625 ctx, MODBUS_FC_WRITE_AND_READ_REGISTERS, read_addr, read_nb, req);
1627 req[req_length++] = write_addr >> 8;
1628 req[req_length++] = write_addr & 0x00ff;
1629 req[req_length++] = write_nb >> 8;
1630 req[req_length++] = write_nb & 0x00ff;
1631 byte_count = write_nb * 2;
1632 req[req_length++] = byte_count;
1634 for (i = 0; i < write_nb; i++) {
1635 req[req_length++] = src[i] >> 8;
1636 req[req_length++] = src[i] & 0x00FF;
1639 rc = send_msg(ctx, req, req_length);
1640 if (rc > 0) {
1641 unsigned int offset;
1643 rc = _modbus_receive_msg(ctx, rsp, MSG_CONFIRMATION);
1644 if (rc == -1)
1645 return -1;
1647 rc = check_confirmation(ctx, req, rsp, rc);
1648 if (rc == -1)
1649 return -1;
1651 offset = ctx->backend->header_length;
1652 for (i = 0; i < rc; i++) {
1653 /* shift reg hi_byte to temp OR with lo_byte */
1654 dest[i] = (rsp[offset + 2 + (i << 1)] << 8) | rsp[offset + 3 + (i << 1)];
1658 return rc;
1661 /* Send a request to get the slave ID of the device (only available in serial
1662 communication). */
1663 int modbus_report_slave_id(modbus_t *ctx, int max_dest, uint8_t *dest)
1665 int rc;
1666 int req_length;
1667 uint8_t req[_MIN_REQ_LENGTH];
1669 if (ctx == NULL || max_dest <= 0) {
1670 errno = EINVAL;
1671 return -1;
1674 req_length =
1675 ctx->backend->build_request_basis(ctx, MODBUS_FC_REPORT_SLAVE_ID, 0, 0, req);
1677 /* HACKISH, addr and count are not used */
1678 req_length -= 4;
1680 rc = send_msg(ctx, req, req_length);
1681 if (rc > 0) {
1682 int i;
1683 unsigned int offset;
1684 uint8_t rsp[MAX_MESSAGE_LENGTH];
1686 rc = _modbus_receive_msg(ctx, rsp, MSG_CONFIRMATION);
1687 if (rc == -1)
1688 return -1;
1690 rc = check_confirmation(ctx, req, rsp, rc);
1691 if (rc == -1)
1692 return -1;
1694 offset = ctx->backend->header_length + 2;
1696 /* Byte count, slave id, run indicator status and
1697 additional data. Truncate copy to max_dest. */
1698 for (i = 0; i < rc && i < max_dest; i++) {
1699 dest[i] = rsp[offset + i];
1703 return rc;
1706 void _modbus_init_common(modbus_t *ctx)
1708 /* Slave and socket are initialized to -1 */
1709 ctx->slave = -1;
1710 ctx->s = -1;
1712 ctx->debug = FALSE;
1713 ctx->error_recovery = MODBUS_ERROR_RECOVERY_NONE;
1714 ctx->quirks = MODBUS_QUIRK_NONE;
1716 ctx->response_timeout.tv_sec = 0;
1717 ctx->response_timeout.tv_usec = _RESPONSE_TIMEOUT;
1719 ctx->byte_timeout.tv_sec = 0;
1720 ctx->byte_timeout.tv_usec = _BYTE_TIMEOUT;
1722 ctx->indication_timeout.tv_sec = 0;
1723 ctx->indication_timeout.tv_usec = 0;
1726 /* Define the slave number */
1727 int modbus_set_slave(modbus_t *ctx, int slave)
1729 if (ctx == NULL) {
1730 errno = EINVAL;
1731 return -1;
1734 return ctx->backend->set_slave(ctx, slave);
1737 int modbus_get_slave(modbus_t *ctx)
1739 if (ctx == NULL) {
1740 errno = EINVAL;
1741 return -1;
1744 return ctx->slave;
1747 int modbus_set_error_recovery(modbus_t *ctx, modbus_error_recovery_mode error_recovery)
1749 if (ctx == NULL) {
1750 errno = EINVAL;
1751 return -1;
1754 /* The type of modbus_error_recovery_mode is unsigned enum */
1755 ctx->error_recovery = (uint8_t) error_recovery;
1756 return 0;
1759 // FIXME Doesn't work under Windows RTU
1760 int modbus_set_socket(modbus_t *ctx, int s)
1762 if (ctx == NULL) {
1763 errno = EINVAL;
1764 return -1;
1767 ctx->s = s;
1768 return 0;
1771 int modbus_get_socket(modbus_t *ctx)
1773 if (ctx == NULL) {
1774 errno = EINVAL;
1775 return -1;
1778 return ctx->s;
1781 /* Get the timeout interval used to wait for a response */
1782 int modbus_get_response_timeout(modbus_t *ctx, uint32_t *to_sec, uint32_t *to_usec)
1784 if (ctx == NULL) {
1785 errno = EINVAL;
1786 return -1;
1789 *to_sec = ctx->response_timeout.tv_sec;
1790 *to_usec = ctx->response_timeout.tv_usec;
1791 return 0;
1794 int modbus_set_response_timeout(modbus_t *ctx, uint32_t to_sec, uint32_t to_usec)
1796 if (ctx == NULL || (to_sec == 0 && to_usec == 0) || to_usec > 999999) {
1797 errno = EINVAL;
1798 return -1;
1801 ctx->response_timeout.tv_sec = to_sec;
1802 ctx->response_timeout.tv_usec = to_usec;
1803 return 0;
1806 /* Get the timeout interval between two consecutive bytes of a message */
1807 int modbus_get_byte_timeout(modbus_t *ctx, uint32_t *to_sec, uint32_t *to_usec)
1809 if (ctx == NULL) {
1810 errno = EINVAL;
1811 return -1;
1814 *to_sec = ctx->byte_timeout.tv_sec;
1815 *to_usec = ctx->byte_timeout.tv_usec;
1816 return 0;
1819 int modbus_set_byte_timeout(modbus_t *ctx, uint32_t to_sec, uint32_t to_usec)
1821 /* Byte timeout can be disabled when both values are zero */
1822 if (ctx == NULL || to_usec > 999999) {
1823 errno = EINVAL;
1824 return -1;
1827 ctx->byte_timeout.tv_sec = to_sec;
1828 ctx->byte_timeout.tv_usec = to_usec;
1829 return 0;
1832 /* Get the timeout interval used by the server to wait for an indication from a client */
1833 int modbus_get_indication_timeout(modbus_t *ctx, uint32_t *to_sec, uint32_t *to_usec)
1835 if (ctx == NULL) {
1836 errno = EINVAL;
1837 return -1;
1840 *to_sec = ctx->indication_timeout.tv_sec;
1841 *to_usec = ctx->indication_timeout.tv_usec;
1842 return 0;
1845 int modbus_set_indication_timeout(modbus_t *ctx, uint32_t to_sec, uint32_t to_usec)
1847 /* Indication timeout can be disabled when both values are zero */
1848 if (ctx == NULL || to_usec > 999999) {
1849 errno = EINVAL;
1850 return -1;
1853 ctx->indication_timeout.tv_sec = to_sec;
1854 ctx->indication_timeout.tv_usec = to_usec;
1855 return 0;
1858 int modbus_get_header_length(modbus_t *ctx)
1860 if (ctx == NULL) {
1861 errno = EINVAL;
1862 return -1;
1865 return ctx->backend->header_length;
1868 int modbus_enable_quirks(modbus_t *ctx, unsigned int quirks_mask)
1870 if (ctx == NULL) {
1871 errno = EINVAL;
1872 return -1;
1875 /* Enable quirks that have a true value at their index in the mask */
1876 ctx->quirks |= quirks_mask;
1877 return 0;
1880 int modbus_disable_quirks(modbus_t *ctx, unsigned int quirks_mask)
1882 if (ctx == NULL) {
1883 errno = EINVAL;
1884 return -1;
1887 /* Disable quirks that have a true value at ther index in the mask */
1888 ctx->quirks &= ~quirks_mask;
1889 return 0;
1892 int modbus_connect(modbus_t *ctx)
1894 if (ctx == NULL) {
1895 errno = EINVAL;
1896 return -1;
1899 return ctx->backend->connect(ctx);
1902 void modbus_close(modbus_t *ctx)
1904 if (ctx == NULL)
1905 return;
1907 ctx->backend->close(ctx);
1910 void modbus_free(modbus_t *ctx)
1912 if (ctx == NULL)
1913 return;
1915 ctx->backend->free(ctx);
1918 int modbus_set_debug(modbus_t *ctx, int flag)
1920 if (ctx == NULL) {
1921 errno = EINVAL;
1922 return -1;
1925 ctx->debug = flag;
1926 return 0;
1929 /* Allocates 4 arrays to store bits, input bits, registers and inputs
1930 registers. The pointers are stored in modbus_mapping structure.
1932 The modbus_mapping_new_start_address() function shall return the new allocated
1933 structure if successful. Otherwise it shall return NULL and set errno to
1934 ENOMEM. */
1935 modbus_mapping_t *modbus_mapping_new_start_address(unsigned int start_bits,
1936 unsigned int nb_bits,
1937 unsigned int start_input_bits,
1938 unsigned int nb_input_bits,
1939 unsigned int start_registers,
1940 unsigned int nb_registers,
1941 unsigned int start_input_registers,
1942 unsigned int nb_input_registers)
1944 modbus_mapping_t *mb_mapping;
1946 mb_mapping = (modbus_mapping_t *) malloc(sizeof(modbus_mapping_t));
1947 if (mb_mapping == NULL) {
1948 return NULL;
1951 /* 0X */
1952 mb_mapping->nb_bits = nb_bits;
1953 mb_mapping->start_bits = start_bits;
1954 if (nb_bits == 0) {
1955 mb_mapping->tab_bits = NULL;
1956 } else {
1957 /* Negative number raises a POSIX error */
1958 mb_mapping->tab_bits = (uint8_t *) malloc(nb_bits * sizeof(uint8_t));
1959 if (mb_mapping->tab_bits == NULL) {
1960 free(mb_mapping);
1961 return NULL;
1963 memset(mb_mapping->tab_bits, 0, nb_bits * sizeof(uint8_t));
1966 /* 1X */
1967 mb_mapping->nb_input_bits = nb_input_bits;
1968 mb_mapping->start_input_bits = start_input_bits;
1969 if (nb_input_bits == 0) {
1970 mb_mapping->tab_input_bits = NULL;
1971 } else {
1972 mb_mapping->tab_input_bits = (uint8_t *) malloc(nb_input_bits * sizeof(uint8_t));
1973 if (mb_mapping->tab_input_bits == NULL) {
1974 free(mb_mapping->tab_bits);
1975 free(mb_mapping);
1976 return NULL;
1978 memset(mb_mapping->tab_input_bits, 0, nb_input_bits * sizeof(uint8_t));
1981 /* 4X */
1982 mb_mapping->nb_registers = nb_registers;
1983 mb_mapping->start_registers = start_registers;
1984 if (nb_registers == 0) {
1985 mb_mapping->tab_registers = NULL;
1986 } else {
1987 mb_mapping->tab_registers = (uint16_t *) malloc(nb_registers * sizeof(uint16_t));
1988 if (mb_mapping->tab_registers == NULL) {
1989 free(mb_mapping->tab_input_bits);
1990 free(mb_mapping->tab_bits);
1991 free(mb_mapping);
1992 return NULL;
1994 memset(mb_mapping->tab_registers, 0, nb_registers * sizeof(uint16_t));
1997 /* 3X */
1998 mb_mapping->nb_input_registers = nb_input_registers;
1999 mb_mapping->start_input_registers = start_input_registers;
2000 if (nb_input_registers == 0) {
2001 mb_mapping->tab_input_registers = NULL;
2002 } else {
2003 mb_mapping->tab_input_registers =
2004 (uint16_t *) malloc(nb_input_registers * sizeof(uint16_t));
2005 if (mb_mapping->tab_input_registers == NULL) {
2006 free(mb_mapping->tab_registers);
2007 free(mb_mapping->tab_input_bits);
2008 free(mb_mapping->tab_bits);
2009 free(mb_mapping);
2010 return NULL;
2012 memset(mb_mapping->tab_input_registers, 0, nb_input_registers * sizeof(uint16_t));
2015 return mb_mapping;
2018 modbus_mapping_t *modbus_mapping_new(int nb_bits,
2019 int nb_input_bits,
2020 int nb_registers,
2021 int nb_input_registers)
2023 return modbus_mapping_new_start_address(
2024 0, nb_bits, 0, nb_input_bits, 0, nb_registers, 0, nb_input_registers);
2027 /* Frees the 4 arrays */
2028 void modbus_mapping_free(modbus_mapping_t *mb_mapping)
2030 if (mb_mapping == NULL) {
2031 return;
2034 free(mb_mapping->tab_input_registers);
2035 free(mb_mapping->tab_registers);
2036 free(mb_mapping->tab_input_bits);
2037 free(mb_mapping->tab_bits);
2038 free(mb_mapping);
2041 #ifndef HAVE_STRLCPY
2043 * Function strlcpy was originally developed by
2044 * Todd C. Miller <Todd.Miller@courtesan.com> to simplify writing secure code.
2045 * See ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/strlcpy.3
2046 * for more information.
2048 * Thank you Ulrich Drepper... not!
2050 * Copy src to string dest of size dest_size. At most dest_size-1 characters
2051 * will be copied. Always NUL terminates (unless dest_size == 0). Returns
2052 * strlen(src); if retval >= dest_size, truncation occurred.
2054 size_t strlcpy(char *dest, const char *src, size_t dest_size)
2056 register char *d = dest;
2057 register const char *s = src;
2058 register size_t n = dest_size;
2060 /* Copy as many bytes as will fit */
2061 if (n != 0 && --n != 0) {
2062 do {
2063 if ((*d++ = *s++) == 0)
2064 break;
2065 } while (--n != 0);
2068 /* Not enough room in dest, add NUL and traverse rest of src */
2069 if (n == 0) {
2070 if (dest_size != 0)
2071 *d = '\0'; /* NUL-terminate dest */
2072 while (*s++)
2076 return (s - src - 1); /* count does not include NUL */
2078 #endif