2 * Copyright © Stéphane Raimbault <stephane.raimbault@gmail.com>
4 * SPDX-License-Identifier: BSD-3-Clause
19 #include <arpa/inet.h>
20 #include <netinet/in.h>
21 #include <sys/select.h>
22 #include <sys/socket.h>
25 #define NB_CONNECTION 5
27 static modbus_t
*ctx
= NULL
;
28 static modbus_mapping_t
*mb_mapping
;
30 static int server_socket
= -1;
32 static void close_sigint(int dummy
)
34 if (server_socket
!= -1) {
38 modbus_mapping_free(mb_mapping
);
45 uint8_t query
[MODBUS_TCP_MAX_ADU_LENGTH
];
50 /* Maximum file descriptor number */
53 ctx
= modbus_new_tcp("127.0.0.1", 1502);
56 modbus_mapping_new(MODBUS_MAX_READ_BITS
, 0, MODBUS_MAX_READ_REGISTERS
, 0);
57 if (mb_mapping
== NULL
) {
58 fprintf(stderr
, "Failed to allocate the mapping: %s\n", modbus_strerror(errno
));
63 server_socket
= modbus_tcp_listen(ctx
, NB_CONNECTION
);
64 if (server_socket
== -1) {
65 fprintf(stderr
, "Unable to listen TCP connection\n");
70 signal(SIGINT
, close_sigint
);
72 /* Clear the reference set of socket */
74 /* Add the server socket */
75 FD_SET(server_socket
, &refset
);
77 /* Keep track of the max file descriptor */
78 fdmax
= server_socket
;
82 if (select(fdmax
+ 1, &rdset
, NULL
, NULL
, NULL
) == -1) {
83 perror("Server select() failure.");
87 /* Run through the existing connections looking for data to be
89 for (master_socket
= 0; master_socket
<= fdmax
; master_socket
++) {
91 if (!FD_ISSET(master_socket
, &rdset
)) {
95 if (master_socket
== server_socket
) {
96 /* A client is asking a new connection */
98 struct sockaddr_in clientaddr
;
101 /* Handle new connections */
102 addrlen
= sizeof(clientaddr
);
103 memset(&clientaddr
, 0, sizeof(clientaddr
));
104 newfd
= accept(server_socket
, (struct sockaddr
*) &clientaddr
, &addrlen
);
106 perror("Server accept() error");
108 FD_SET(newfd
, &refset
);
111 /* Keep track of the maximum */
114 printf("New connection from %s:%d on socket %d\n",
115 inet_ntoa(clientaddr
.sin_addr
),
120 modbus_set_socket(ctx
, master_socket
);
121 rc
= modbus_receive(ctx
, query
);
123 modbus_reply(ctx
, query
, rc
, mb_mapping
);
124 } else if (rc
== -1) {
125 /* This example server in ended on connection closing or
127 printf("Connection closed on socket %d\n", master_socket
);
128 close(master_socket
);
130 /* Remove from reference set */
131 FD_CLR(master_socket
, &refset
);
133 if (master_socket
== fdmax
) {