Commit f410aea2f72fb1205803b10e5cec4a322601a82b

Authored by Stéphane Raimbault
1 parent 50fa79da

Isolate RTU and TCP headers and simplify Win32 detection

- move termios header in RTU backend
- move TCP headers in TCP backend
- use native serial on Win32 for Cygwin
- avoid too many defines
configure.ac
... ... @@ -47,15 +47,13 @@ LIBMODBUS_LT_VERSION_INFO=$LIBMODBUS_LD_CURRENT:$LIBMODBUS_LD_REVISION:$LIBMODBU
47 47 AC_SUBST(LIBMODBUS_LT_VERSION_INFO)
48 48  
49 49 # Check whether we are building for Win32
50   -build_win32="false"
51   -case "${host}" in
  50 +os_win32="false"
  51 +case "${target}" in
52 52 *mingw32)
53   - AC_DEFINE([BUILD_WIN32], [], [Build libmodbus for Win32])
54   - build_win32="true"
  53 + os_win32="true"
55 54 ;;
56 55 esac
57   -
58   -AM_CONDITIONAL(BUILD_WIN32, test "$build_win32" = "true")
  56 +AM_CONDITIONAL(OS_WIN32, test "$os_win32" = "true")
59 57  
60 58 # Checks for programs.
61 59 AC_PROG_CC
... ...
src/Makefile.am
... ... @@ -11,7 +11,8 @@ libmodbus_la_SOURCES = \
11 11 modbus-tcp.h \
12 12 modbus-tcp-private.h \
13 13 modbus-version.h
14   -if BUILD_WIN32
  14 +
  15 +if OS_WIN32
15 16 libmodbus_la_LIBADD = -lwsock32
16 17 endif
17 18  
... ...
src/modbus-rtu-private.h
... ... @@ -19,7 +19,12 @@
19 19 #define _MODBUS_RTU_PRIVATE_H_
20 20  
21 21 #include <stdint.h>
  22 +
  23 +#if defined(_WIN32)
  24 +#include <windows.h>
  25 +#else
22 26 #include <termios.h>
  27 +#endif
23 28  
24 29 #define _MODBUS_RTU_HEADER_LENGTH 1
25 30 #define _MODBUS_RTU_PRESET_REQ_LENGTH 6
... ... @@ -27,11 +32,7 @@
27 32  
28 33 #define _MODBUS_RTU_CHECKSUM_LENGTH 2
29 34  
30   -#ifdef NATIVE_WIN32
31   -
32   -#define WIN32_LEAN_AND_MEAN
33   -#include <windows.h>
34   -
  35 +#if defined(_WIN32)
35 36 /* WIN32: struct containing serial handle and a receive buffer */
36 37 #define PY_BUF_SIZE 512
37 38 struct win32_ser {
... ... @@ -42,7 +43,7 @@ struct win32_ser {
42 43 /* Received chars */
43 44 DWORD n_bytes;
44 45 };
45   -#endif /* NATIVE_WIN32 */
  46 +#endif /* _WIN32 */
46 47  
47 48 typedef struct _modbus_rtu {
48 49 /* Device: "/dev/ttyS0", "/dev/ttyUSB0" or "/dev/tty.USA19*" on Mac OS X for
... ... @@ -50,7 +51,7 @@ typedef struct _modbus_rtu {
50 51 as the directory+file name was bigger than 19 bytes. Making it 67 bytes
51 52 for now, but OS X does support 256 byte file names. May become a problem
52 53 in the future. */
53   -#ifdef __APPLE_CC__
  54 +#if defined(__APPLE_CC__)
54 55 char device[64];
55 56 #else
56 57 char device[16];
... ... @@ -63,7 +64,7 @@ typedef struct _modbus_rtu {
63 64 uint8_t stop_bit;
64 65 /* Parity: 'N', 'O', 'E' */
65 66 char parity;
66   -#ifdef NATIVE_WIN32
  67 +#if defined(_WIN32)
67 68 struct win32_ser w_ser;
68 69 DCB old_dcb;
69 70 #else
... ...
src/modbus-rtu.c
... ... @@ -22,7 +22,6 @@
22 22 #include <string.h>
23 23 #include <unistd.h>
24 24  
25   -#include "modbus.h"
26 25 #include "modbus-private.h"
27 26  
28 27 #include "modbus-rtu.h"
... ... @@ -156,7 +155,7 @@ int _modbus_rtu_send_msg_pre(uint8_t *req, int req_length)
156 155 return req_length;
157 156 }
158 157  
159   -#ifdef NATIVE_WIN32
  158 +#if defined(_WIN32)
160 159 /* This simple implementation is sort of a substitute of the select() call, working
161 160 * this way: the win32_ser_select() call tries to read some data from the serial port,
162 161 * setting the timeout as the select() call would. Data read is stored into the
... ... @@ -233,7 +232,7 @@ static int win32_ser_read(struct win32_ser *ws, uint8_t *p_msg, unsigned int max
233 232  
234 233 ssize_t _modbus_rtu_send(modbus_t *ctx, const uint8_t *req, int req_length)
235 234 {
236   -#ifdef NATIVE_WIN32
  235 +#if defined(_WIN32)
237 236 modbus_rtu_t *ctx_rtu = ctx->backend_data;
238 237 DWORD n_bytes = 0;
239 238 return (WriteFile(ctx_rtu->w_ser.fd, req, req_length, &n_bytes, NULL)) ? n_bytes : -1;
... ... @@ -244,7 +243,7 @@ ssize_t _modbus_rtu_send(modbus_t *ctx, const uint8_t *req, int req_length)
244 243  
245 244 ssize_t _modbus_rtu_recv(modbus_t *ctx, uint8_t *rsp, int rsp_length)
246 245 {
247   -#ifdef NATIVE_WIN32
  246 +#if defined(_WIN32)
248 247 return win32_ser_read(&((modbus_rtu_t *)ctx->backend_data)->w_ser, rsp, rsp_length);
249 248 #else
250 249 return read(ctx->s, rsp, rsp_length);
... ... @@ -283,7 +282,7 @@ int _modbus_rtu_check_integrity(modbus_t *ctx, uint8_t *msg,
283 282 /* Sets up a serial port for RTU communications */
284 283 static int _modbus_rtu_connect(modbus_t *ctx)
285 284 {
286   -#ifdef NATIVE_WIN32
  285 +#if defined(_WIN32)
287 286 DCB dcb;
288 287 #else
289 288 struct termios tios;
... ... @@ -297,7 +296,7 @@ static int _modbus_rtu_connect(modbus_t *ctx)
297 296 ctx_rtu->data_bit, ctx_rtu->stop_bit);
298 297 }
299 298  
300   -#ifdef NATIVE_WIN32
  299 +#if defined(_WIN32)
301 300 /* Some references here:
302 301 * http://msdn.microsoft.com/en-us/library/aa450602.aspx
303 302 */
... ... @@ -681,7 +680,7 @@ void _modbus_rtu_close(modbus_t *ctx)
681 680 /* Closes the file descriptor in RTU mode */
682 681 modbus_rtu_t *ctx_rtu = ctx->backend_data;
683 682  
684   -#ifdef NATIVE_WIN32
  683 +#if defined(_WIN32)
685 684 /* Revert settings */
686 685 if (!SetCommState(ctx_rtu->w_ser.fd, &ctx_rtu->old_dcb))
687 686 fprintf(stderr, "ERROR Couldn't revert to configuration (LastError %d)\n",
... ... @@ -698,7 +697,7 @@ void _modbus_rtu_close(modbus_t *ctx)
698 697  
699 698 int _modbus_rtu_flush(modbus_t *ctx)
700 699 {
701   -#ifdef NATIVE_WIN32
  700 +#if defined(_WIN32)
702 701 modbus_rtu_t *ctx_rtu = ctx->backend_data;
703 702 ctx_rtu->w_ser.n_bytes = 0;
704 703 return ( FlushFileBuffers(ctx_rtu->w_ser.fd) == FALSE );
... ... @@ -730,7 +729,7 @@ int _modbus_rtu_accept(modbus_t *ctx, int *socket)
730 729 int _modbus_rtu_select(modbus_t *ctx, fd_set *rfds, struct timeval *tv, int msg_length_computed, int msg_length)
731 730 {
732 731 int s_rc;
733   -#ifdef NATIVE_WIN32
  732 +#if defined(_WIN32)
734 733 s_rc = win32_ser_select(&(((modbus_rtu_t*)ctx->backend_data)->w_ser), msg_length_computed, tv);
735 734 if (s_rc == 0) {
736 735 errno = ETIMEDOUT;
... ...
src/modbus-tcp.c
... ... @@ -15,29 +15,44 @@
15 15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 16 */
17 17  
18   -#include "modbus.h"
19   -#include "modbus-private.h"
20   -
21 18 #include <stdio.h>
22 19 #include <stdlib.h>
23 20 #include <string.h>
24 21 #include <errno.h>
25 22 #include <unistd.h>
26   -
27 23 #include <sys/types.h>
28 24  
29   -#ifdef NATIVE_WIN32
30   -#include <ws2tcpip.h>
  25 +#if defined(_WIN32)
  26 +# define OS_WIN32
  27 +# include <winsock2.h>
  28 +# include <ws2tcpip.h>
  29 +# define SHUT_RDWR 2
31 30 #else
32   -#include <sys/socket.h>
33   -#include <sys/ioctl.h>
  31 +# include <sys/socket.h>
  32 +# include <sys/ioctl.h>
  33 +
  34 +#if defined(OpenBSD) || (defined(__FreeBSD__) && __FreeBSD__ < 5)
  35 +# define OS_BSD
  36 +# include <netinet/in_systm.h>
  37 +#endif
  38 +
  39 +# include <netinet/in.h>
  40 +# include <netinet/ip.h>
  41 +# include <netinet/tcp.h>
  42 +# include <arpa/inet.h>
  43 +#endif
  44 +
  45 +#if !defined(MSG_NOSIGNAL)
  46 +#define MSG_NOSIGNAL 0
34 47 #endif
35 48  
  49 +#include "modbus-private.h"
  50 +
36 51 #include "modbus-tcp.h"
37 52 #include "modbus-tcp-private.h"
38 53  
39   -#ifdef NATIVE_WIN32
40   -static int _modbus_tcp_init_win32()
  54 +#ifdef OS_WIN32
  55 +static int _modbus_tcp_init_win32(void)
41 56 {
42 57 // Initialise Win32 Socket API
43 58 WORD wVersionRequested;
... ... @@ -174,7 +189,7 @@ static int _modbus_tcp_connect(modbus_t *ctx)
174 189 struct sockaddr_in addr;
175 190 modbus_tcp_t *ctx_tcp = ctx->backend_data;
176 191  
177   -#ifdef NATIVE_WIN32
  192 +#ifdef OS_WIN32
178 193 if (_modbus_tcp_init_win32() == -1) {
179 194 return -1;
180 195 }
... ... @@ -195,7 +210,7 @@ static int _modbus_tcp_connect(modbus_t *ctx)
195 210 return -1;
196 211 }
197 212  
198   -#ifndef NATIVE_WIN32
  213 +#ifndef OS_WIN32
199 214 /**
200 215 * Cygwin defines IPTOS_LOWDELAY but can't handle that flag so it's
201 216 * necessary to workaround that problem.
... ... @@ -241,7 +256,7 @@ int _modbus_tcp_flush(modbus_t *ctx)
241 256 do {
242 257 /* Extract the garbage from the socket */
243 258 char devnull[MODBUS_TCP_MAX_ADU_LENGTH];
244   -#ifndef NATIVE_WIN32
  259 +#ifndef OS_WIN32
245 260 rc = recv(ctx->s, devnull, MODBUS_TCP_MAX_ADU_LENGTH, MSG_DONTWAIT);
246 261 #else
247 262 /* On Win32, it's a bit more complicated to not wait */
... ... @@ -275,7 +290,7 @@ int _modbus_tcp_listen(modbus_t *ctx, int nb_connection)
275 290 struct sockaddr_in addr;
276 291 modbus_tcp_t *ctx_tcp = ctx->backend_data;
277 292  
278   -#ifdef NATIVE_WIN32
  293 +#ifdef OS_WIN32
279 294 if (_modbus_tcp_init_win32() == -1) {
280 295 return -1;
281 296 }
... ...
src/modbus-tcp.h
... ... @@ -20,6 +20,15 @@
20 20  
21 21 #include "modbus.h"
22 22  
  23 +#if defined(_WIN32) && !defined(__CYGWIN__)
  24 +/* Win32 with MinGW, supplement to <errno.h> */
  25 +#include <winsock2.h>
  26 +#define ECONNRESET WSAECONNRESET
  27 +#define ECONNREFUSED WSAECONNREFUSED
  28 +#define ETIMEDOUT WSAETIMEDOUT
  29 +#define ENOPROTOOPT WSAENOPROTOOPT
  30 +#endif
  31 +
23 32 #define MODBUS_TCP_DEFAULT_PORT 502
24 33 #define MODBUS_TCP_SLAVE 0xFF
25 34  
... ...
src/modbus.h
... ... @@ -20,35 +20,12 @@
20 20  
21 21 #include <config.h>
22 22  
23   -/* If win32 and no cygwin, suppose it's MinGW or any other native windows compiler. */
24   -#if defined(WIN32) && !defined(__CYGWIN__)
25   -#define NATIVE_WIN32
26   -#define MSG_NOSIGNAL 0
27   -#define ECONNRESET WSAECONNRESET
28   -#define ECONNREFUSED WSAECONNREFUSED
29   -#define ETIMEDOUT WSAETIMEDOUT
30   -#define ENOPROTOOPT WSAENOPROTOOPT
31   -#define SHUT_RDWR 2
32   -#include <winsock2.h>
33   -#endif /* win32 and no cygwin */
34   -
35 23 /* Add this for macros that defined unix flavor */
36 24 #if (defined(__unix__) || defined(unix)) && !defined(USG)
37 25 #include <sys/param.h>
38 26 #endif
39   -#include <stdint.h>
40   -#ifndef NATIVE_WIN32
41   -
42   -#include <termios.h>
43 27  
44   -#if defined(OpenBSD) || (defined(__FreeBSD__) && __FreeBSD__ < 5)
45   -#include <netinet/in_systm.h>
46   -#endif
47   -#include <netinet/in.h>
48   -#include <netinet/ip.h>
49   -#include <netinet/tcp.h>
50   -#include <arpa/inet.h>
51   -#endif
  28 +#include <stdint.h>
52 29 #include <sys/time.h>
53 30  
54 31 #include "modbus-version.h"
... ...
tests/bandwidth-server-many-up.c
... ... @@ -24,8 +24,10 @@
24 24  
25 25 #include <modbus.h>
26 26  
27   -#ifdef NATIVE_WIN32
  27 +#if defined(_WIN32)
28 28 #include <ws2tcpip.h>
  29 +#else
  30 +#include <netinet/in.h>
29 31 #endif
30 32  
31 33 #define NB_CONNECTION 5
... ...