2 * Copyright © 2009-2010 Stéphane Raimbault <stephane.raimbault@gmail.com>
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
30 #include <sys/socket.h>
31 #include <netinet/in.h>
32 #include <arpa/inet.h>
35 #define NB_CONNECTION 5
39 modbus_mapping_t
*mb_mapping
;
41 static void close_sigint(int dummy
)
45 modbus_mapping_free(mb_mapping
);
57 /* Maximum file descriptor number */
60 ctx
= modbus_new_tcp("127.0.0.1", 1502);
62 mb_mapping
= modbus_mapping_new(MODBUS_MAX_READ_BITS
, 0,
63 MODBUS_MAX_READ_REGISTERS
, 0);
64 if (mb_mapping
== NULL
) {
65 fprintf(stderr
, "Failed to allocate the mapping: %s\n",
66 modbus_strerror(errno
));
71 server_socket
= modbus_tcp_listen(ctx
, NB_CONNECTION
);
73 signal(SIGINT
, close_sigint
);
75 /* Clear the reference set of socket */
77 /* Add the server socket */
78 FD_SET(server_socket
, &refset
);
80 /* Keep track of the max file descriptor */
81 fdmax
= server_socket
;
85 if (select(fdmax
+1, &rdset
, NULL
, NULL
, NULL
) == -1) {
86 perror("Server select() failure.");
90 /* Run through the existing connections looking for data to be
92 for (master_socket
= 0; master_socket
<= fdmax
; master_socket
++) {
94 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
), clientaddr
.sin_port
, newfd
);
118 /* An already connected master has sent a new query */
119 uint8_t query
[MODBUS_TCP_MAX_ADU_LENGTH
];
121 rc
= modbus_receive_from(ctx
, master_socket
, query
);
123 modbus_reply(ctx
, query
, rc
, mb_mapping
);
125 /* Connection closed by the client, end of server */
126 printf("Connection closed on socket %d\n", master_socket
);
127 close(master_socket
);
129 /* Remove from reference set */
130 FD_CLR(master_socket
, &refset
);
132 if (master_socket
== fdmax
) {