Prepare NEWS file for next release
[libmodbus.git] / src / modbus.c
blobe3737bb2fda84a239cf3c7931247a8dfb3640132
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 including checksum */
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,
224 const uint8_t *raw_req,
225 int raw_req_length,
226 int tid)
228 sft_t sft;
229 uint8_t req[MAX_MESSAGE_LENGTH];
230 int req_length;
232 if (ctx == NULL) {
233 errno = EINVAL;
234 return -1;
237 if (raw_req_length < 2 || raw_req_length > (MODBUS_MAX_PDU_LENGTH + 1)) {
238 /* The raw request must contain function and slave at least and
239 must not be longer than the maximum pdu length plus the slave
240 address. */
241 errno = EINVAL;
242 return -1;
245 sft.slave = raw_req[0];
246 sft.function = raw_req[1];
247 /* The t_id is left to zero */
248 sft.t_id = tid;
249 /* This response function only set the header so it's convenient here */
250 req_length = ctx->backend->build_response_basis(&sft, req);
252 if (raw_req_length > 2) {
253 /* Copy data after function code */
254 memcpy(req + req_length, raw_req + 2, raw_req_length - 2);
255 req_length += raw_req_length - 2;
258 return send_msg(ctx, req, req_length);
261 int modbus_send_raw_request(modbus_t *ctx, const uint8_t *raw_req, int raw_req_length)
263 return modbus_send_raw_request_tid(ctx, raw_req, raw_req_length, 0);
267 * ---------- Request Indication ----------
268 * | Client | ---------------------->| Server |
269 * ---------- Confirmation Response ----------
272 /* Computes the length to read after the function received */
273 static uint8_t compute_meta_length_after_function(int function, msg_type_t msg_type)
275 int length;
277 if (msg_type == MSG_INDICATION) {
278 if (function <= MODBUS_FC_WRITE_SINGLE_REGISTER) {
279 length = 4;
280 } else if (function == MODBUS_FC_WRITE_MULTIPLE_COILS ||
281 function == MODBUS_FC_WRITE_MULTIPLE_REGISTERS) {
282 length = 5;
283 } else if (function == MODBUS_FC_MASK_WRITE_REGISTER) {
284 length = 6;
285 } else if (function == MODBUS_FC_WRITE_AND_READ_REGISTERS) {
286 length = 9;
287 } else {
288 /* MODBUS_FC_READ_EXCEPTION_STATUS, MODBUS_FC_REPORT_SLAVE_ID */
289 length = 0;
291 } else {
292 /* MSG_CONFIRMATION */
293 switch (function) {
294 case MODBUS_FC_WRITE_SINGLE_COIL:
295 case MODBUS_FC_WRITE_SINGLE_REGISTER:
296 case MODBUS_FC_WRITE_MULTIPLE_COILS:
297 case MODBUS_FC_WRITE_MULTIPLE_REGISTERS:
298 length = 4;
299 break;
300 case MODBUS_FC_MASK_WRITE_REGISTER:
301 length = 6;
302 break;
303 default:
304 length = 1;
308 return length;
311 /* Computes the length to read after the meta information (address, count, etc) */
312 static int
313 compute_data_length_after_meta(modbus_t *ctx, uint8_t *msg, msg_type_t msg_type)
315 int function = msg[ctx->backend->header_length];
316 int length;
318 if (msg_type == MSG_INDICATION) {
319 switch (function) {
320 case MODBUS_FC_WRITE_MULTIPLE_COILS:
321 case MODBUS_FC_WRITE_MULTIPLE_REGISTERS:
322 length = msg[ctx->backend->header_length + 5];
323 break;
324 case MODBUS_FC_WRITE_AND_READ_REGISTERS:
325 length = msg[ctx->backend->header_length + 9];
326 break;
327 default:
328 length = 0;
330 } else {
331 /* MSG_CONFIRMATION */
332 if (function <= MODBUS_FC_READ_INPUT_REGISTERS ||
333 function == MODBUS_FC_REPORT_SLAVE_ID ||
334 function == MODBUS_FC_WRITE_AND_READ_REGISTERS) {
335 length = msg[ctx->backend->header_length + 1];
336 } else {
337 length = 0;
341 length += ctx->backend->checksum_length;
343 return length;
346 /* Waits a response from a modbus server or a request from a modbus client.
347 This function blocks if there is no replies (3 timeouts).
349 The function shall return the number of received characters and the received
350 message in an array of uint8_t if successful. Otherwise it shall return -1
351 and errno is set to one of the values defined below:
352 - ECONNRESET
353 - EMBBADDATA
354 - ETIMEDOUT
355 - read() or recv() error codes
358 int _modbus_receive_msg(modbus_t *ctx, uint8_t *msg, msg_type_t msg_type)
360 int rc;
361 fd_set rset;
362 struct timeval tv;
363 struct timeval *p_tv;
364 unsigned int length_to_read;
365 int msg_length = 0;
366 _step_t step;
367 #ifdef _WIN32
368 int wsa_err;
369 #endif
371 if (ctx->debug) {
372 if (msg_type == MSG_INDICATION) {
373 printf("Waiting for an indication...\n");
374 } else {
375 printf("Waiting for a confirmation...\n");
379 if (!ctx->backend->is_connected(ctx)) {
380 if (ctx->debug) {
381 fprintf(stderr, "ERROR The connection is not established.\n");
383 return -1;
386 /* Add a file descriptor to the set */
387 FD_ZERO(&rset);
388 FD_SET(ctx->s, &rset);
390 /* We need to analyse the message step by step. At the first step, we want
391 * to reach the function code because all packets contain this
392 * information. */
393 step = _STEP_FUNCTION;
394 length_to_read = ctx->backend->header_length + 1;
396 if (msg_type == MSG_INDICATION) {
397 /* Wait for a message, we don't know when the message will be received */
398 if (ctx->indication_timeout.tv_sec == 0 && ctx->indication_timeout.tv_usec == 0) {
399 /* By default, the indication timeout isn't set */
400 p_tv = NULL;
401 } else {
402 /* Wait for an indication (name of a received request by a server, see schema)
404 tv.tv_sec = ctx->indication_timeout.tv_sec;
405 tv.tv_usec = ctx->indication_timeout.tv_usec;
406 p_tv = &tv;
408 } else {
409 tv.tv_sec = ctx->response_timeout.tv_sec;
410 tv.tv_usec = ctx->response_timeout.tv_usec;
411 p_tv = &tv;
414 while (length_to_read != 0) {
415 rc = ctx->backend->select(ctx, &rset, p_tv, length_to_read);
416 if (rc == -1) {
417 _error_print(ctx, "select");
418 if (ctx->error_recovery & MODBUS_ERROR_RECOVERY_LINK) {
419 #ifdef _WIN32
420 wsa_err = WSAGetLastError();
422 // no equivalent to ETIMEDOUT when select fails on Windows
423 if (wsa_err == WSAENETDOWN || wsa_err == WSAENOTSOCK) {
424 modbus_close(ctx);
425 modbus_connect(ctx);
427 #else
428 int saved_errno = errno;
430 if (errno == ETIMEDOUT) {
431 _sleep_response_timeout(ctx);
432 modbus_flush(ctx);
433 } else if (errno == EBADF) {
434 modbus_close(ctx);
435 modbus_connect(ctx);
437 errno = saved_errno;
438 #endif
440 return -1;
443 rc = ctx->backend->recv(ctx, msg + msg_length, length_to_read);
444 if (rc == 0) {
445 errno = ECONNRESET;
446 rc = -1;
449 if (rc == -1) {
450 _error_print(ctx, "read");
451 #ifdef _WIN32
452 wsa_err = WSAGetLastError();
453 if ((ctx->error_recovery & MODBUS_ERROR_RECOVERY_LINK) &&
454 (wsa_err == WSAENOTCONN || wsa_err == WSAENETRESET ||
455 wsa_err == WSAENOTSOCK || wsa_err == WSAESHUTDOWN ||
456 wsa_err == WSAECONNABORTED || wsa_err == WSAETIMEDOUT ||
457 wsa_err == WSAECONNRESET)) {
458 modbus_close(ctx);
459 modbus_connect(ctx);
461 #else
462 if ((ctx->error_recovery & MODBUS_ERROR_RECOVERY_LINK) &&
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->get_response_tid(req);
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 break;
908 /* This check is only done here to ensure using memcpy is safe. */
909 rsp_length = compute_response_length_from_request(ctx, (uint8_t *) req);
910 if (rsp_length != req_length) {
911 /* Bad use of modbus_reply */
912 rsp_length = response_exception(
913 ctx,
914 &sft,
915 MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE,
916 rsp,
917 FALSE,
918 "Invalid request length in modbus_reply to write bit (%d)\n",
919 req_length);
920 break;
923 /* Don't copy the CRC, if any, it will be computed later (even if identical to the
924 * request) */
925 rsp_length -= ctx->backend->checksum_length;
927 int data = (req[offset + 3] << 8) + req[offset + 4];
928 if (data == 0xFF00 || data == 0x0) {
929 /* Apply the change to mapping */
930 mb_mapping->tab_bits[mapping_address] = data ? ON : OFF;
931 /* Prepare response */
932 memcpy(rsp, req, rsp_length);
933 } else {
934 rsp_length = response_exception(
935 ctx,
936 &sft,
937 MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE,
938 rsp,
939 FALSE,
940 "Illegal data value 0x%0X in write_bit request at address %0X\n",
941 data,
942 address);
944 } break;
945 case MODBUS_FC_WRITE_SINGLE_REGISTER: {
946 int mapping_address = address - mb_mapping->start_registers;
948 if (mapping_address < 0 || mapping_address >= mb_mapping->nb_registers) {
949 rsp_length =
950 response_exception(ctx,
951 &sft,
952 MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS,
953 rsp,
954 FALSE,
955 "Illegal data address 0x%0X in write_register\n",
956 address);
957 break;
960 rsp_length = compute_response_length_from_request(ctx, (uint8_t *) req);
961 if (rsp_length != req_length) {
962 /* Bad use of modbus_reply */
963 rsp_length = response_exception(
964 ctx,
965 &sft,
966 MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE,
967 rsp,
968 FALSE,
969 "Invalid request length in modbus_reply to write register (%d)\n",
970 req_length);
971 break;
973 int data = (req[offset + 3] << 8) + req[offset + 4];
975 mb_mapping->tab_registers[mapping_address] = data;
977 rsp_length -= ctx->backend->checksum_length;
978 memcpy(rsp, req, rsp_length);
979 } break;
980 case MODBUS_FC_WRITE_MULTIPLE_COILS: {
981 int nb = (req[offset + 3] << 8) + req[offset + 4];
982 int nb_bits = req[offset + 5];
983 int mapping_address = address - mb_mapping->start_bits;
985 if (nb < 1 || MODBUS_MAX_WRITE_BITS < nb || nb_bits * 8 < nb) {
986 /* May be the indication has been truncated on reading because of
987 * invalid address (eg. nb is 0 but the request contains values to
988 * write) so it's necessary to flush. */
989 rsp_length =
990 response_exception(ctx,
991 &sft,
992 MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE,
993 rsp,
994 TRUE,
995 "Illegal number of values %d in write_bits (max %d)\n",
997 MODBUS_MAX_WRITE_BITS);
998 } else if (mapping_address < 0 || (mapping_address + nb) > mb_mapping->nb_bits) {
999 rsp_length = response_exception(ctx,
1000 &sft,
1001 MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS,
1002 rsp,
1003 FALSE,
1004 "Illegal data address 0x%0X in write_bits\n",
1005 mapping_address < 0 ? address : address + nb);
1006 } else {
1007 /* 6 = byte count */
1008 modbus_set_bits_from_bytes(
1009 mb_mapping->tab_bits, mapping_address, nb, &req[offset + 6]);
1011 rsp_length = ctx->backend->build_response_basis(&sft, rsp);
1012 /* 4 to copy the bit address (2) and the quantity of bits */
1013 memcpy(rsp + rsp_length, req + rsp_length, 4);
1014 rsp_length += 4;
1016 } break;
1017 case MODBUS_FC_WRITE_MULTIPLE_REGISTERS: {
1018 int nb = (req[offset + 3] << 8) + req[offset + 4];
1019 int nb_bytes = req[offset + 5];
1020 int mapping_address = address - mb_mapping->start_registers;
1022 if (nb < 1 || MODBUS_MAX_WRITE_REGISTERS < nb || nb_bytes != nb * 2) {
1023 rsp_length = response_exception(
1024 ctx,
1025 &sft,
1026 MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE,
1027 rsp,
1028 TRUE,
1029 "Illegal number of values %d in write_registers (max %d)\n",
1031 MODBUS_MAX_WRITE_REGISTERS);
1032 } else if (mapping_address < 0 ||
1033 (mapping_address + nb) > mb_mapping->nb_registers) {
1034 rsp_length =
1035 response_exception(ctx,
1036 &sft,
1037 MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS,
1038 rsp,
1039 FALSE,
1040 "Illegal data address 0x%0X in write_registers\n",
1041 mapping_address < 0 ? address : address + nb);
1042 } else {
1043 int i, j;
1044 for (i = mapping_address, j = 6; i < mapping_address + nb; i++, j += 2) {
1045 /* 6 and 7 = first value */
1046 mb_mapping->tab_registers[i] =
1047 (req[offset + j] << 8) + req[offset + j + 1];
1050 rsp_length = ctx->backend->build_response_basis(&sft, rsp);
1051 /* 4 to copy the address (2) and the no. of registers */
1052 memcpy(rsp + rsp_length, req + rsp_length, 4);
1053 rsp_length += 4;
1055 } break;
1056 case MODBUS_FC_REPORT_SLAVE_ID: {
1057 int str_len;
1058 int byte_count_pos;
1060 rsp_length = ctx->backend->build_response_basis(&sft, rsp);
1061 /* Skip byte count for now */
1062 byte_count_pos = rsp_length++;
1063 rsp[rsp_length++] = _REPORT_SLAVE_ID;
1064 /* Run indicator status to ON */
1065 rsp[rsp_length++] = 0xFF;
1066 /* LMB + length of LIBMODBUS_VERSION_STRING */
1067 str_len = 3 + strlen(LIBMODBUS_VERSION_STRING);
1068 memcpy(rsp + rsp_length, "LMB" LIBMODBUS_VERSION_STRING, str_len);
1069 rsp_length += str_len;
1070 rsp[byte_count_pos] = rsp_length - byte_count_pos - 1;
1071 } break;
1072 case MODBUS_FC_READ_EXCEPTION_STATUS:
1073 if (ctx->debug) {
1074 fprintf(stderr, "FIXME Not implemented\n");
1076 errno = ENOPROTOOPT;
1077 return -1;
1078 break;
1079 case MODBUS_FC_MASK_WRITE_REGISTER: {
1080 int mapping_address = address - mb_mapping->start_registers;
1082 if (mapping_address < 0 || mapping_address >= mb_mapping->nb_registers) {
1083 rsp_length =
1084 response_exception(ctx,
1085 &sft,
1086 MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS,
1087 rsp,
1088 FALSE,
1089 "Illegal data address 0x%0X in write_register\n",
1090 address);
1091 } else {
1092 uint16_t data = mb_mapping->tab_registers[mapping_address];
1093 uint16_t and = (req[offset + 3] << 8) + req[offset + 4];
1094 uint16_t or = (req[offset + 5] << 8) + req[offset + 6];
1096 data = (data & and) | (or &(~and) );
1097 mb_mapping->tab_registers[mapping_address] = data;
1099 rsp_length = compute_response_length_from_request(ctx, (uint8_t *) req);
1100 if (rsp_length != req_length) {
1101 /* Bad use of modbus_reply */
1102 rsp_length = response_exception(ctx,
1103 &sft,
1104 MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE,
1105 rsp,
1106 FALSE,
1107 "Invalid request length in modbus_reply "
1108 "to mask write register (%d)\n",
1109 req_length);
1110 break;
1113 rsp_length -= ctx->backend->checksum_length;
1114 memcpy(rsp, req, rsp_length);
1116 } break;
1117 case MODBUS_FC_WRITE_AND_READ_REGISTERS: {
1118 int nb = (req[offset + 3] << 8) + req[offset + 4];
1119 uint16_t address_write = (req[offset + 5] << 8) + req[offset + 6];
1120 int nb_write = (req[offset + 7] << 8) + req[offset + 8];
1121 int nb_write_bytes = req[offset + 9];
1122 int mapping_address = address - mb_mapping->start_registers;
1123 int mapping_address_write = address_write - mb_mapping->start_registers;
1125 if (nb_write < 1 || MODBUS_MAX_WR_WRITE_REGISTERS < nb_write || nb < 1 ||
1126 MODBUS_MAX_WR_READ_REGISTERS < nb || nb_write_bytes != nb_write * 2) {
1127 rsp_length = response_exception(
1128 ctx,
1129 &sft,
1130 MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE,
1131 rsp,
1132 TRUE,
1133 "Illegal nb of values (W%d, R%d) in write_and_read_registers (max W%d, "
1134 "R%d)\n",
1135 nb_write,
1137 MODBUS_MAX_WR_WRITE_REGISTERS,
1138 MODBUS_MAX_WR_READ_REGISTERS);
1139 } else if (mapping_address < 0 ||
1140 (mapping_address + nb) > mb_mapping->nb_registers ||
1141 mapping_address_write < 0 ||
1142 (mapping_address_write + nb_write) > mb_mapping->nb_registers) {
1143 rsp_length = response_exception(
1144 ctx,
1145 &sft,
1146 MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS,
1147 rsp,
1148 FALSE,
1149 "Illegal data read address 0x%0X or write address 0x%0X "
1150 "write_and_read_registers\n",
1151 mapping_address < 0 ? address : address + nb,
1152 mapping_address_write < 0 ? address_write : address_write + nb_write);
1153 } else {
1154 int i, j;
1155 rsp_length = ctx->backend->build_response_basis(&sft, rsp);
1156 rsp[rsp_length++] = nb << 1;
1158 /* Write first.
1159 10 and 11 are the offset of the first values to write */
1160 for (i = mapping_address_write, j = 10; i < mapping_address_write + nb_write;
1161 i++, j += 2) {
1162 mb_mapping->tab_registers[i] =
1163 (req[offset + j] << 8) + req[offset + j + 1];
1166 /* and read the data for the response */
1167 for (i = mapping_address; i < mapping_address + nb; i++) {
1168 rsp[rsp_length++] = mb_mapping->tab_registers[i] >> 8;
1169 rsp[rsp_length++] = mb_mapping->tab_registers[i] & 0xFF;
1172 } break;
1174 default:
1175 rsp_length = response_exception(ctx,
1176 &sft,
1177 MODBUS_EXCEPTION_ILLEGAL_FUNCTION,
1178 rsp,
1179 TRUE,
1180 "Unknown Modbus function code: 0x%0X\n",
1181 function);
1182 break;
1185 /* Suppress any responses in RTU when the request was a broadcast, excepted when
1186 * quirk is enabled. */
1187 if (ctx->backend->backend_type == _MODBUS_BACKEND_TYPE_RTU &&
1188 slave == MODBUS_BROADCAST_ADDRESS &&
1189 !(ctx->quirks & MODBUS_QUIRK_REPLY_TO_BROADCAST)) {
1190 return 0;
1192 return send_msg(ctx, rsp, rsp_length);
1195 int modbus_reply_exception(modbus_t *ctx, const uint8_t *req, unsigned int exception_code)
1197 unsigned int offset;
1198 int slave;
1199 int function;
1200 uint8_t rsp[MAX_MESSAGE_LENGTH];
1201 int rsp_length;
1202 sft_t sft;
1204 if (ctx == NULL) {
1205 errno = EINVAL;
1206 return -1;
1209 offset = ctx->backend->header_length;
1210 slave = req[offset - 1];
1211 function = req[offset];
1213 sft.slave = slave;
1214 sft.function = function + 0x80;
1215 sft.t_id = ctx->backend->get_response_tid(req);
1216 rsp_length = ctx->backend->build_response_basis(&sft, rsp);
1218 /* Positive exception code */
1219 if (exception_code < MODBUS_EXCEPTION_MAX) {
1220 rsp[rsp_length++] = exception_code;
1221 return send_msg(ctx, rsp, rsp_length);
1222 } else {
1223 errno = EINVAL;
1224 return -1;
1228 /* Reads IO status */
1229 static int read_io_status(modbus_t *ctx, int function, int addr, int nb, uint8_t *dest)
1231 int rc;
1232 int req_length;
1234 uint8_t req[_MIN_REQ_LENGTH];
1235 uint8_t rsp[MAX_MESSAGE_LENGTH];
1237 req_length = ctx->backend->build_request_basis(ctx, function, addr, nb, req);
1239 rc = send_msg(ctx, req, req_length);
1240 if (rc > 0) {
1241 int temp, bit;
1242 int pos = 0;
1243 unsigned int offset;
1244 unsigned int offset_end;
1245 unsigned int i;
1247 rc = _modbus_receive_msg(ctx, rsp, MSG_CONFIRMATION);
1248 if (rc == -1)
1249 return -1;
1251 rc = check_confirmation(ctx, req, rsp, rc);
1252 if (rc == -1)
1253 return -1;
1255 offset = ctx->backend->header_length + 2;
1256 offset_end = offset + rc;
1257 for (i = offset; i < offset_end; i++) {
1258 /* Shift reg hi_byte to temp */
1259 temp = rsp[i];
1261 for (bit = 0x01; (bit & 0xff) && (pos < nb);) {
1262 dest[pos++] = (temp & bit) ? TRUE : FALSE;
1263 bit = bit << 1;
1268 return rc;
1271 /* Reads the boolean status of bits and sets the array elements
1272 in the destination to TRUE or FALSE (single bits). */
1273 int modbus_read_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest)
1275 int rc;
1277 if (ctx == NULL) {
1278 errno = EINVAL;
1279 return -1;
1282 if (nb > MODBUS_MAX_READ_BITS) {
1283 if (ctx->debug) {
1284 fprintf(stderr,
1285 "ERROR Too many bits requested (%d > %d)\n",
1287 MODBUS_MAX_READ_BITS);
1289 errno = EMBMDATA;
1290 return -1;
1293 rc = read_io_status(ctx, MODBUS_FC_READ_COILS, addr, nb, dest);
1295 if (rc == -1)
1296 return -1;
1297 else
1298 return nb;
1301 /* Same as modbus_read_bits but reads the remote device input table */
1302 int modbus_read_input_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest)
1304 int rc;
1306 if (ctx == NULL) {
1307 errno = EINVAL;
1308 return -1;
1311 if (nb > MODBUS_MAX_READ_BITS) {
1312 if (ctx->debug) {
1313 fprintf(stderr,
1314 "ERROR Too many discrete inputs requested (%d > %d)\n",
1316 MODBUS_MAX_READ_BITS);
1318 errno = EMBMDATA;
1319 return -1;
1322 rc = read_io_status(ctx, MODBUS_FC_READ_DISCRETE_INPUTS, addr, nb, dest);
1324 if (rc == -1)
1325 return -1;
1326 else
1327 return nb;
1330 /* Reads the data from a remote device and put that data into an array */
1331 static int read_registers(modbus_t *ctx, int function, int addr, int nb, uint16_t *dest)
1333 int rc;
1334 int req_length;
1335 uint8_t req[_MIN_REQ_LENGTH];
1336 uint8_t rsp[MAX_MESSAGE_LENGTH];
1338 if (nb > MODBUS_MAX_READ_REGISTERS) {
1339 if (ctx->debug) {
1340 fprintf(stderr,
1341 "ERROR Too many registers requested (%d > %d)\n",
1343 MODBUS_MAX_READ_REGISTERS);
1345 errno = EMBMDATA;
1346 return -1;
1349 req_length = ctx->backend->build_request_basis(ctx, function, addr, nb, req);
1351 rc = send_msg(ctx, req, req_length);
1352 if (rc > 0) {
1353 unsigned int offset;
1354 int i;
1356 rc = _modbus_receive_msg(ctx, rsp, MSG_CONFIRMATION);
1357 if (rc == -1)
1358 return -1;
1360 rc = check_confirmation(ctx, req, rsp, rc);
1361 if (rc == -1)
1362 return -1;
1364 offset = ctx->backend->header_length;
1366 for (i = 0; i < rc; i++) {
1367 /* shift reg hi_byte to temp OR with lo_byte */
1368 dest[i] = (rsp[offset + 2 + (i << 1)] << 8) | rsp[offset + 3 + (i << 1)];
1372 return rc;
1375 /* Reads the holding registers of remote device and put the data into an
1376 array */
1377 int modbus_read_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest)
1379 int status;
1381 if (ctx == NULL) {
1382 errno = EINVAL;
1383 return -1;
1386 if (nb > MODBUS_MAX_READ_REGISTERS) {
1387 if (ctx->debug) {
1388 fprintf(stderr,
1389 "ERROR Too many registers requested (%d > %d)\n",
1391 MODBUS_MAX_READ_REGISTERS);
1393 errno = EMBMDATA;
1394 return -1;
1397 status = read_registers(ctx, MODBUS_FC_READ_HOLDING_REGISTERS, addr, nb, dest);
1398 return status;
1401 /* Reads the input registers of remote device and put the data into an array */
1402 int modbus_read_input_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest)
1404 int status;
1406 if (ctx == NULL) {
1407 errno = EINVAL;
1408 return -1;
1411 if (nb > MODBUS_MAX_READ_REGISTERS) {
1412 if (ctx->debug) {
1413 fprintf(stderr,
1414 "ERROR Too many input registers requested (%d > %d)\n",
1416 MODBUS_MAX_READ_REGISTERS);
1418 errno = EMBMDATA;
1419 return -1;
1422 status = read_registers(ctx, MODBUS_FC_READ_INPUT_REGISTERS, addr, nb, dest);
1424 return status;
1427 /* Write a value to the specified register of the remote device.
1428 Used by write_bit and write_register */
1429 static int write_single(modbus_t *ctx, int function, int addr, const uint16_t value)
1431 int rc;
1432 int req_length;
1433 uint8_t req[_MIN_REQ_LENGTH];
1435 if (ctx == NULL) {
1436 errno = EINVAL;
1437 return -1;
1440 req_length = ctx->backend->build_request_basis(ctx, function, addr, (int) value, req);
1442 rc = send_msg(ctx, req, req_length);
1443 if (rc > 0) {
1444 /* Used by write_bit and write_register */
1445 uint8_t rsp[MAX_MESSAGE_LENGTH];
1447 rc = _modbus_receive_msg(ctx, rsp, MSG_CONFIRMATION);
1448 if (rc == -1)
1449 return -1;
1451 rc = check_confirmation(ctx, req, rsp, rc);
1454 return rc;
1457 /* Turns ON or OFF a single bit of the remote device */
1458 int modbus_write_bit(modbus_t *ctx, int addr, int status)
1460 if (ctx == NULL) {
1461 errno = EINVAL;
1462 return -1;
1465 return write_single(ctx, MODBUS_FC_WRITE_SINGLE_COIL, addr, status ? 0xFF00 : 0);
1468 /* Writes a value in one register of the remote device */
1469 int modbus_write_register(modbus_t *ctx, int addr, const uint16_t value)
1471 if (ctx == NULL) {
1472 errno = EINVAL;
1473 return -1;
1476 return write_single(ctx, MODBUS_FC_WRITE_SINGLE_REGISTER, addr, value);
1479 /* Write the bits of the array in the remote device */
1480 int modbus_write_bits(modbus_t *ctx, int addr, int nb, const uint8_t *src)
1482 int rc;
1483 int i;
1484 int byte_count;
1485 int req_length;
1486 int bit_check = 0;
1487 int pos = 0;
1488 uint8_t req[MAX_MESSAGE_LENGTH];
1490 if (ctx == NULL) {
1491 errno = EINVAL;
1492 return -1;
1495 if (nb > MODBUS_MAX_WRITE_BITS) {
1496 if (ctx->debug) {
1497 fprintf(stderr,
1498 "ERROR Writing too many bits (%d > %d)\n",
1500 MODBUS_MAX_WRITE_BITS);
1502 errno = EMBMDATA;
1503 return -1;
1506 req_length = ctx->backend->build_request_basis(
1507 ctx, MODBUS_FC_WRITE_MULTIPLE_COILS, addr, nb, req);
1508 byte_count = (nb / 8) + ((nb % 8) ? 1 : 0);
1509 req[req_length++] = byte_count;
1511 for (i = 0; i < byte_count; i++) {
1512 int bit;
1514 bit = 0x01;
1515 req[req_length] = 0;
1517 while ((bit & 0xFF) && (bit_check++ < nb)) {
1518 if (src[pos++])
1519 req[req_length] |= bit;
1520 else
1521 req[req_length] &= ~bit;
1523 bit = bit << 1;
1525 req_length++;
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 /* Write the values from the array to the registers of the remote device */
1543 int modbus_write_registers(modbus_t *ctx, int addr, int nb, const uint16_t *src)
1545 int rc;
1546 int i;
1547 int req_length;
1548 int byte_count;
1549 uint8_t req[MAX_MESSAGE_LENGTH];
1551 if (ctx == NULL) {
1552 errno = EINVAL;
1553 return -1;
1556 if (nb > MODBUS_MAX_WRITE_REGISTERS) {
1557 if (ctx->debug) {
1558 fprintf(stderr,
1559 "ERROR Trying to write to too many registers (%d > %d)\n",
1561 MODBUS_MAX_WRITE_REGISTERS);
1563 errno = EMBMDATA;
1564 return -1;
1567 req_length = ctx->backend->build_request_basis(
1568 ctx, MODBUS_FC_WRITE_MULTIPLE_REGISTERS, addr, nb, req);
1569 byte_count = nb * 2;
1570 req[req_length++] = byte_count;
1572 for (i = 0; i < nb; i++) {
1573 req[req_length++] = src[i] >> 8;
1574 req[req_length++] = src[i] & 0x00FF;
1577 rc = send_msg(ctx, req, req_length);
1578 if (rc > 0) {
1579 uint8_t rsp[MAX_MESSAGE_LENGTH];
1581 rc = _modbus_receive_msg(ctx, rsp, MSG_CONFIRMATION);
1582 if (rc == -1)
1583 return -1;
1585 rc = check_confirmation(ctx, req, rsp, rc);
1588 return rc;
1591 int modbus_mask_write_register(modbus_t *ctx,
1592 int addr,
1593 uint16_t and_mask,
1594 uint16_t or_mask)
1596 int rc;
1597 int req_length;
1598 /* The request length can not exceed _MIN_REQ_LENGTH - 2 and 4 bytes to
1599 * store the masks. The ugly substraction is there to remove the 'nb' value
1600 * (2 bytes) which is not used. */
1601 uint8_t req[_MIN_REQ_LENGTH + 2];
1603 req_length = ctx->backend->build_request_basis(
1604 ctx, MODBUS_FC_MASK_WRITE_REGISTER, addr, 0, req);
1606 /* HACKISH, count is not used */
1607 req_length -= 2;
1609 req[req_length++] = and_mask >> 8;
1610 req[req_length++] = and_mask & 0x00ff;
1611 req[req_length++] = or_mask >> 8;
1612 req[req_length++] = or_mask & 0x00ff;
1614 rc = send_msg(ctx, req, req_length);
1615 if (rc > 0) {
1616 /* Used by write_bit and write_register */
1617 uint8_t rsp[MAX_MESSAGE_LENGTH];
1619 rc = _modbus_receive_msg(ctx, rsp, MSG_CONFIRMATION);
1620 if (rc == -1)
1621 return -1;
1623 rc = check_confirmation(ctx, req, rsp, rc);
1626 return rc;
1629 /* Write multiple registers from src array to remote device and read multiple
1630 registers from remote device to dest array. */
1631 int modbus_write_and_read_registers(modbus_t *ctx,
1632 int write_addr,
1633 int write_nb,
1634 const uint16_t *src,
1635 int read_addr,
1636 int read_nb,
1637 uint16_t *dest)
1640 int rc;
1641 int req_length;
1642 int i;
1643 int byte_count;
1644 uint8_t req[MAX_MESSAGE_LENGTH];
1645 uint8_t rsp[MAX_MESSAGE_LENGTH];
1647 if (ctx == NULL) {
1648 errno = EINVAL;
1649 return -1;
1652 if (write_nb > MODBUS_MAX_WR_WRITE_REGISTERS) {
1653 if (ctx->debug) {
1654 fprintf(stderr,
1655 "ERROR Too many registers to write (%d > %d)\n",
1656 write_nb,
1657 MODBUS_MAX_WR_WRITE_REGISTERS);
1659 errno = EMBMDATA;
1660 return -1;
1663 if (read_nb > MODBUS_MAX_WR_READ_REGISTERS) {
1664 if (ctx->debug) {
1665 fprintf(stderr,
1666 "ERROR Too many registers requested (%d > %d)\n",
1667 read_nb,
1668 MODBUS_MAX_WR_READ_REGISTERS);
1670 errno = EMBMDATA;
1671 return -1;
1673 req_length = ctx->backend->build_request_basis(
1674 ctx, MODBUS_FC_WRITE_AND_READ_REGISTERS, read_addr, read_nb, req);
1676 req[req_length++] = write_addr >> 8;
1677 req[req_length++] = write_addr & 0x00ff;
1678 req[req_length++] = write_nb >> 8;
1679 req[req_length++] = write_nb & 0x00ff;
1680 byte_count = write_nb * 2;
1681 req[req_length++] = byte_count;
1683 for (i = 0; i < write_nb; i++) {
1684 req[req_length++] = src[i] >> 8;
1685 req[req_length++] = src[i] & 0x00FF;
1688 rc = send_msg(ctx, req, req_length);
1689 if (rc > 0) {
1690 unsigned int offset;
1692 rc = _modbus_receive_msg(ctx, rsp, MSG_CONFIRMATION);
1693 if (rc == -1)
1694 return -1;
1696 rc = check_confirmation(ctx, req, rsp, rc);
1697 if (rc == -1)
1698 return -1;
1700 offset = ctx->backend->header_length;
1701 for (i = 0; i < rc; i++) {
1702 /* shift reg hi_byte to temp OR with lo_byte */
1703 dest[i] = (rsp[offset + 2 + (i << 1)] << 8) | rsp[offset + 3 + (i << 1)];
1707 return rc;
1710 /* Send a request to get the slave ID of the device (only available in serial
1711 communication). */
1712 int modbus_report_slave_id(modbus_t *ctx, int max_dest, uint8_t *dest)
1714 int rc;
1715 int req_length;
1716 uint8_t req[_MIN_REQ_LENGTH];
1718 if (ctx == NULL || max_dest <= 0) {
1719 errno = EINVAL;
1720 return -1;
1723 req_length =
1724 ctx->backend->build_request_basis(ctx, MODBUS_FC_REPORT_SLAVE_ID, 0, 0, req);
1726 /* HACKISH, addr and count are not used */
1727 req_length -= 4;
1729 rc = send_msg(ctx, req, req_length);
1730 if (rc > 0) {
1731 int i;
1732 unsigned int offset;
1733 uint8_t rsp[MAX_MESSAGE_LENGTH];
1735 rc = _modbus_receive_msg(ctx, rsp, MSG_CONFIRMATION);
1736 if (rc == -1)
1737 return -1;
1739 rc = check_confirmation(ctx, req, rsp, rc);
1740 if (rc == -1)
1741 return -1;
1743 offset = ctx->backend->header_length + 2;
1745 /* Byte count, slave id, run indicator status and
1746 additional data. Truncate copy to max_dest. */
1747 for (i = 0; i < rc && i < max_dest; i++) {
1748 dest[i] = rsp[offset + i];
1752 return rc;
1755 void _modbus_init_common(modbus_t *ctx)
1757 /* Slave and socket are initialized to -1 */
1758 ctx->slave = -1;
1759 ctx->s = -1;
1761 ctx->debug = FALSE;
1762 ctx->error_recovery = MODBUS_ERROR_RECOVERY_NONE;
1763 ctx->quirks = MODBUS_QUIRK_NONE;
1765 ctx->response_timeout.tv_sec = 0;
1766 ctx->response_timeout.tv_usec = _RESPONSE_TIMEOUT;
1768 ctx->byte_timeout.tv_sec = 0;
1769 ctx->byte_timeout.tv_usec = _BYTE_TIMEOUT;
1771 ctx->indication_timeout.tv_sec = 0;
1772 ctx->indication_timeout.tv_usec = 0;
1775 /* Define the slave number */
1776 int modbus_set_slave(modbus_t *ctx, int slave)
1778 if (ctx == NULL) {
1779 errno = EINVAL;
1780 return -1;
1783 return ctx->backend->set_slave(ctx, slave);
1786 int modbus_get_slave(modbus_t *ctx)
1788 if (ctx == NULL) {
1789 errno = EINVAL;
1790 return -1;
1793 return ctx->slave;
1796 int modbus_set_error_recovery(modbus_t *ctx, modbus_error_recovery_mode error_recovery)
1798 if (ctx == NULL) {
1799 errno = EINVAL;
1800 return -1;
1803 /* The type of modbus_error_recovery_mode is unsigned enum */
1804 ctx->error_recovery = (uint8_t) error_recovery;
1805 return 0;
1808 // FIXME Doesn't work under Windows RTU
1809 int modbus_set_socket(modbus_t *ctx, int s)
1811 if (ctx == NULL) {
1812 errno = EINVAL;
1813 return -1;
1816 ctx->s = s;
1817 return 0;
1820 int modbus_get_socket(modbus_t *ctx)
1822 if (ctx == NULL) {
1823 errno = EINVAL;
1824 return -1;
1827 return ctx->s;
1830 /* Get the timeout interval used to wait for a response */
1831 int modbus_get_response_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->response_timeout.tv_sec;
1839 *to_usec = ctx->response_timeout.tv_usec;
1840 return 0;
1843 int modbus_set_response_timeout(modbus_t *ctx, uint32_t to_sec, uint32_t to_usec)
1845 if (ctx == NULL || (to_sec == 0 && to_usec == 0) || to_usec > 999999) {
1846 errno = EINVAL;
1847 return -1;
1850 ctx->response_timeout.tv_sec = to_sec;
1851 ctx->response_timeout.tv_usec = to_usec;
1852 return 0;
1855 /* Get the timeout interval between two consecutive bytes of a message */
1856 int modbus_get_byte_timeout(modbus_t *ctx, uint32_t *to_sec, uint32_t *to_usec)
1858 if (ctx == NULL) {
1859 errno = EINVAL;
1860 return -1;
1863 *to_sec = ctx->byte_timeout.tv_sec;
1864 *to_usec = ctx->byte_timeout.tv_usec;
1865 return 0;
1868 int modbus_set_byte_timeout(modbus_t *ctx, uint32_t to_sec, uint32_t to_usec)
1870 /* Byte timeout can be disabled when both values are zero */
1871 if (ctx == NULL || to_usec > 999999) {
1872 errno = EINVAL;
1873 return -1;
1876 ctx->byte_timeout.tv_sec = to_sec;
1877 ctx->byte_timeout.tv_usec = to_usec;
1878 return 0;
1881 /* Get the timeout interval used by the server to wait for an indication from a client
1883 int modbus_get_indication_timeout(modbus_t *ctx, uint32_t *to_sec, uint32_t *to_usec)
1885 if (ctx == NULL) {
1886 errno = EINVAL;
1887 return -1;
1890 *to_sec = ctx->indication_timeout.tv_sec;
1891 *to_usec = ctx->indication_timeout.tv_usec;
1892 return 0;
1895 int modbus_set_indication_timeout(modbus_t *ctx, uint32_t to_sec, uint32_t to_usec)
1897 /* Indication timeout can be disabled when both values are zero */
1898 if (ctx == NULL || to_usec > 999999) {
1899 errno = EINVAL;
1900 return -1;
1903 ctx->indication_timeout.tv_sec = to_sec;
1904 ctx->indication_timeout.tv_usec = to_usec;
1905 return 0;
1908 int modbus_get_header_length(modbus_t *ctx)
1910 if (ctx == NULL) {
1911 errno = EINVAL;
1912 return -1;
1915 return ctx->backend->header_length;
1918 int modbus_enable_quirks(modbus_t *ctx, unsigned int quirks_mask)
1920 if (ctx == NULL) {
1921 errno = EINVAL;
1922 return -1;
1925 /* Enable quirks that have a true value at their index in the mask */
1926 ctx->quirks |= quirks_mask;
1927 return 0;
1930 int modbus_disable_quirks(modbus_t *ctx, unsigned int quirks_mask)
1932 if (ctx == NULL) {
1933 errno = EINVAL;
1934 return -1;
1937 /* Disable quirks that have a true value at ther index in the mask */
1938 ctx->quirks &= ~quirks_mask;
1939 return 0;
1942 int modbus_connect(modbus_t *ctx)
1944 if (ctx == NULL) {
1945 errno = EINVAL;
1946 return -1;
1949 return ctx->backend->connect(ctx);
1952 void modbus_close(modbus_t *ctx)
1954 if (ctx == NULL)
1955 return;
1957 ctx->backend->close(ctx);
1960 void modbus_free(modbus_t *ctx)
1962 if (ctx == NULL)
1963 return;
1965 ctx->backend->free(ctx);
1968 int modbus_set_debug(modbus_t *ctx, int flag)
1970 if (ctx == NULL) {
1971 errno = EINVAL;
1972 return -1;
1975 ctx->debug = flag;
1976 return 0;
1979 /* Allocates 4 arrays to store bits, input bits, registers and inputs
1980 registers. The pointers are stored in modbus_mapping structure.
1982 The modbus_mapping_new_start_address() function shall return the new allocated
1983 structure if successful. Otherwise it shall return NULL and set errno to
1984 ENOMEM. */
1985 modbus_mapping_t *modbus_mapping_new_start_address(unsigned int start_bits,
1986 unsigned int nb_bits,
1987 unsigned int start_input_bits,
1988 unsigned int nb_input_bits,
1989 unsigned int start_registers,
1990 unsigned int nb_registers,
1991 unsigned int start_input_registers,
1992 unsigned int nb_input_registers)
1994 modbus_mapping_t *mb_mapping;
1996 mb_mapping = (modbus_mapping_t *) malloc(sizeof(modbus_mapping_t));
1997 if (mb_mapping == NULL) {
1998 return NULL;
2001 /* 0X */
2002 mb_mapping->nb_bits = nb_bits;
2003 mb_mapping->start_bits = start_bits;
2004 if (nb_bits == 0) {
2005 mb_mapping->tab_bits = NULL;
2006 } else {
2007 /* Negative number raises a POSIX error */
2008 mb_mapping->tab_bits = (uint8_t *) malloc(nb_bits * sizeof(uint8_t));
2009 if (mb_mapping->tab_bits == NULL) {
2010 free(mb_mapping);
2011 return NULL;
2013 memset(mb_mapping->tab_bits, 0, nb_bits * sizeof(uint8_t));
2016 /* 1X */
2017 mb_mapping->nb_input_bits = nb_input_bits;
2018 mb_mapping->start_input_bits = start_input_bits;
2019 if (nb_input_bits == 0) {
2020 mb_mapping->tab_input_bits = NULL;
2021 } else {
2022 mb_mapping->tab_input_bits = (uint8_t *) malloc(nb_input_bits * sizeof(uint8_t));
2023 if (mb_mapping->tab_input_bits == NULL) {
2024 free(mb_mapping->tab_bits);
2025 free(mb_mapping);
2026 return NULL;
2028 memset(mb_mapping->tab_input_bits, 0, nb_input_bits * sizeof(uint8_t));
2031 /* 4X */
2032 mb_mapping->nb_registers = nb_registers;
2033 mb_mapping->start_registers = start_registers;
2034 if (nb_registers == 0) {
2035 mb_mapping->tab_registers = NULL;
2036 } else {
2037 mb_mapping->tab_registers = (uint16_t *) malloc(nb_registers * sizeof(uint16_t));
2038 if (mb_mapping->tab_registers == NULL) {
2039 free(mb_mapping->tab_input_bits);
2040 free(mb_mapping->tab_bits);
2041 free(mb_mapping);
2042 return NULL;
2044 memset(mb_mapping->tab_registers, 0, nb_registers * sizeof(uint16_t));
2047 /* 3X */
2048 mb_mapping->nb_input_registers = nb_input_registers;
2049 mb_mapping->start_input_registers = start_input_registers;
2050 if (nb_input_registers == 0) {
2051 mb_mapping->tab_input_registers = NULL;
2052 } else {
2053 mb_mapping->tab_input_registers =
2054 (uint16_t *) malloc(nb_input_registers * sizeof(uint16_t));
2055 if (mb_mapping->tab_input_registers == NULL) {
2056 free(mb_mapping->tab_registers);
2057 free(mb_mapping->tab_input_bits);
2058 free(mb_mapping->tab_bits);
2059 free(mb_mapping);
2060 return NULL;
2062 memset(mb_mapping->tab_input_registers, 0, nb_input_registers * sizeof(uint16_t));
2065 return mb_mapping;
2068 modbus_mapping_t *modbus_mapping_new(int nb_bits,
2069 int nb_input_bits,
2070 int nb_registers,
2071 int nb_input_registers)
2073 return modbus_mapping_new_start_address(
2074 0, nb_bits, 0, nb_input_bits, 0, nb_registers, 0, nb_input_registers);
2077 /* Frees the 4 arrays */
2078 void modbus_mapping_free(modbus_mapping_t *mb_mapping)
2080 if (mb_mapping == NULL) {
2081 return;
2084 free(mb_mapping->tab_input_registers);
2085 free(mb_mapping->tab_registers);
2086 free(mb_mapping->tab_input_bits);
2087 free(mb_mapping->tab_bits);
2088 free(mb_mapping);
2091 #ifndef HAVE_STRLCPY
2093 * Function strlcpy was originally developed by
2094 * Todd C. Miller <Todd.Miller@courtesan.com> to simplify writing secure code.
2095 * See ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/strlcpy.3
2096 * for more information.
2098 * Thank you Ulrich Drepper... not!
2100 * Copy src to string dest of size dest_size. At most dest_size-1 characters
2101 * will be copied. Always NUL terminates (unless dest_size == 0). Returns
2102 * strlen(src); if retval >= dest_size, truncation occurred.
2104 size_t strlcpy(char *dest, const char *src, size_t dest_size)
2106 register char *d = dest;
2107 register const char *s = src;
2108 register size_t n = dest_size;
2110 /* Copy as many bytes as will fit */
2111 if (n != 0 && --n != 0) {
2112 do {
2113 if ((*d++ = *s++) == 0)
2114 break;
2115 } while (--n != 0);
2118 /* Not enough room in dest, add NUL and traverse rest of src */
2119 if (n == 0) {
2120 if (dest_size != 0)
2121 *d = '\0'; /* NUL-terminate dest */
2122 while (*s++)
2126 return (s - src - 1); /* count does not include NUL */
2128 #endif