├── ModbusSlave_Poll ├── 3rdparty │ ├── libmodbus │ │ ├── README.md │ │ ├── config.h │ │ └── src │ │ │ ├── Makefile.am │ │ │ ├── modbus-ascii-private.h │ │ │ ├── modbus-ascii.c │ │ │ ├── modbus-ascii.h │ │ │ ├── modbus-data.c │ │ │ ├── modbus-private.h │ │ │ ├── modbus-rtu-private.h │ │ │ ├── modbus-rtu.c │ │ │ ├── modbus-rtu.h │ │ │ ├── modbus-tcp-private.h │ │ │ ├── modbus-tcp.c │ │ │ ├── modbus-tcp.h │ │ │ ├── modbus-version.h │ │ │ ├── modbus-version.h.in │ │ │ ├── modbus.c │ │ │ ├── modbus.h │ │ │ └── win32 │ │ │ ├── Make-tests │ │ │ ├── README.win32 │ │ │ ├── config.h.win32 │ │ │ ├── configure.js │ │ │ ├── modbus-9.sln │ │ │ ├── modbus.dll.manifest.in │ │ │ ├── modbus.rc │ │ │ └── modbus.vcproj │ └── qextserialport │ │ ├── posix_qextserialport.cpp │ │ ├── qextserialenumerator.h │ │ ├── qextserialenumerator_osx.cpp │ │ ├── qextserialenumerator_unix.cpp │ │ ├── qextserialenumerator_win.cpp │ │ ├── qextserialport.cpp │ │ ├── qextserialport.h │ │ ├── qextserialport_global.h │ │ ├── qwineventnotifier_p.h │ │ └── win_qextserialport.cpp ├── ModbusSlave_Poll.pro ├── main.cpp ├── mainwindow.cpp ├── mainwindow.h ├── mainwindow.ui ├── modbuspollthread.cpp ├── modbuspollthread.h ├── modbusslavethread.cpp └── modbusslavethread.h ├── README.md ├── qmodbus-master.zip └── 工具 └── modbusTool ├── ModbusPollSetup.exe ├── ModbusSlaveSetup-431.exe ├── VirtualSerialPortDriver8.rar └── modbuspoll注册码.txt /ModbusSlave_Poll/3rdparty/libmodbus/README.md: -------------------------------------------------------------------------------- 1 | A groovy modbus library 2 | ======================= 3 | 4 | Overview 5 | -------- 6 | 7 | libmodbus is a free software library to send/receive data with a device which 8 | respects the Modbus protocol. This library can use a serial port or an Ethernet 9 | connection. 10 | 11 | The functions included in the library have been derived from the Modicon Modbus 12 | Protocol Reference Guide which can be obtained from Schneider at 13 | [www.schneiderautomation.com](http://www.schneiderautomation.com). 14 | 15 | The license of libmodbus is *LGPL v2.1 or later*. 16 | 17 | The documentation is available as manual pages (`man libmodbus` to read general 18 | description and list of available functions) or Web pages 19 | [www.libmodbus.org/documentation/](http://libmodbus.org/documentation/). The 20 | documentation is licensed under the Creative Commons Attribution-ShareAlike 21 | License 3.0 (Unported) (). 22 | 23 | The official website is [www.libmodbus.org](http://www.libmodbus.org). 24 | 25 | The library is written in C and designed to run on Linux, Mac OS X, FreeBSD and 26 | QNX and Windows. 27 | 28 | Installation 29 | ------------ 30 | 31 | You will only need to install automake, autoconf, libtool and a C compiler (gcc 32 | or clang) to compile the library and asciidoc and xmlto to generate the 33 | documentation (optional). 34 | 35 | To install, just run the usual dance, `./configure && make install`. Run 36 | `./autogen.sh` first to generate the `configure` script if required. 37 | 38 | You can change installation directory with prefix option, eg. `./configure 39 | --prefix=/usr/local/`. You have to check that the installation library path is 40 | properly set up on your system (`/etc/ld.so.conf.d`) and library cache is up to 41 | date (run `ldconfig` as root if required). 42 | 43 | The library provides a `libmodbus.pc` file to use with `pkg-config` to ease your 44 | program compilation and linking. 45 | 46 | If you want to compile with Microsoft Visual Studio, you need to install 47 | to fill the absence of stdint.h. 48 | 49 | To compile under Windows, install [MinGW](http://www.mingw.org/) and MSYS then 50 | select the common packages (gcc, automake, libtool, etc). The directory 51 | `./src/win32/` contains a Visual C project. 52 | 53 | To compile under OS X with [homebrew](http://mxcl.github.com/homebrew/), you will need 54 | to install the following dependencies first: `brew install autoconf automake libtool`. 55 | 56 | Testing 57 | ------- 58 | 59 | Some tests are provided in *tests* directory, you can freely edit the source 60 | code to fit your needs (it's Free Software :). 61 | 62 | See *tests/README* for a description of each program. 63 | 64 | For a quick test of libmodbus, you can run the following programs in two shells: 65 | 66 | 1. ./unit-test-server 67 | 2. ./unit-test-client 68 | 69 | By default, all TCP unit tests will be executed (see --help for options). 70 | 71 | Report a Bug 72 | ------------ 73 | 74 | Before reporting a bug, take care to read the documentation (RTFM!) and to 75 | provide enough information: 76 | 77 | 1. libmodbus version 78 | 2. OS/environment/architecture 79 | 3. libmodbus backend (TCP, RTU, IPv6) 80 | 3. Modbus messages when running in debug mode (`man modbus_set_debug`) 81 | 82 | To report your problem, you can: 83 | 84 | * fill a bug report on the issue tracker . 85 | * or send an email to the libmodbus mailing list [libmodbus@googlegroups.com](https://groups.google.com/forum/#!forum/libmodbus). 86 | 87 | If your prefer live talk when your're looking for help or to offer contribution, 88 | there is also a channel called #libmodbus on Freenode. 89 | -------------------------------------------------------------------------------- /ModbusSlave_Poll/3rdparty/libmodbus/config.h: -------------------------------------------------------------------------------- 1 | /* config.h. Generated from config.h.in by configure. */ 2 | /* config.h.in. Generated from configure.ac by autoheader. */ 3 | 4 | /* Define to 1 if you have the `accept4' function. */ 5 | //#define HAVE_ACCEPT4 1 6 | 7 | /* Define to 1 if you have the header file. */ 8 | #define HAVE_ARPA_INET_H 1 9 | 10 | /* Define to 1 if you have the header file. */ 11 | #define HAVE_BYTESWAP_H 1 12 | 13 | /* Define to 1 if you have the declaration of `TIOCM_RTS', and to 0 if you 14 | don't. */ 15 | //#define HAVE_DECL_TIOCM_RTS 1 16 | 17 | /* Define to 1 if you have the declaration of `TIOCSRS485', and to 0 if you 18 | don't. */ 19 | //#define HAVE_DECL_TIOCSRS485 1 20 | 21 | /* Define to 1 if you have the declaration of `__CYGWIN__', and to 0 if you 22 | don't. */ 23 | #define HAVE_DECL___CYGWIN__ 0 24 | 25 | /* Define to 1 if you have the header file. */ 26 | #define HAVE_DLFCN_H 1 27 | 28 | /* Define to 1 if you have the header file. */ 29 | #define HAVE_ERRNO_H 1 30 | 31 | /* Define to 1 if you have the header file. */ 32 | #define HAVE_FCNTL_H 1 33 | 34 | /* Define to 1 if you have the `fork' function. */ 35 | #define HAVE_FORK 1 36 | 37 | /* Define to 1 if you have the `getaddrinfo' function. */ 38 | #define HAVE_GETADDRINFO 1 39 | 40 | /* Define to 1 if you have the `gettimeofday' function. */ 41 | #define HAVE_GETTIMEOFDAY 1 42 | 43 | /* Define to 1 if you have the `inet_ntoa' function. */ 44 | #define HAVE_INET_NTOA 1 45 | 46 | /* Define to 1 if you have the header file. */ 47 | #define HAVE_INTTYPES_H 1 48 | 49 | /* Define to 1 if you have the header file. */ 50 | #define HAVE_LIMITS_H 1 51 | 52 | /* Define to 1 if you have the header file. */ 53 | #define HAVE_LINUX_SERIAL_H 1 54 | 55 | /* Define to 1 if you have the header file. */ 56 | #define HAVE_MEMORY_H 1 57 | 58 | /* Define to 1 if you have the `memset' function. */ 59 | #define HAVE_MEMSET 1 60 | 61 | /* Define to 1 if you have the header file. */ 62 | #define HAVE_NETDB_H 1 63 | 64 | /* Define to 1 if you have the header file. */ 65 | #define HAVE_NETINET_IN_H 1 66 | 67 | /* Define to 1 if you have the header file. */ 68 | #define HAVE_NETINET_TCP_H 1 69 | 70 | /* Define to 1 if you have the `select' function. */ 71 | #define HAVE_SELECT 1 72 | 73 | /* Define to 1 if you have the `socket' function. */ 74 | #define HAVE_SOCKET 1 75 | 76 | /* Define to 1 if you have the header file. */ 77 | #define HAVE_STDINT_H 1 78 | 79 | /* Define to 1 if you have the header file. */ 80 | #define HAVE_STDLIB_H 1 81 | 82 | /* Define to 1 if you have the `strerror' function. */ 83 | #define HAVE_STRERROR 1 84 | 85 | /* Define to 1 if you have the header file. */ 86 | #define HAVE_STRINGS_H 1 87 | 88 | /* Define to 1 if you have the header file. */ 89 | #define HAVE_STRING_H 1 90 | 91 | /* Define to 1 if you have the `strlcpy' function. */ 92 | /* #undef HAVE_STRLCPY */ 93 | 94 | /* Define to 1 if you have the header file. */ 95 | #define HAVE_SYS_IOCTL_H 1 96 | 97 | /* Define to 1 if you have the header file. */ 98 | #define HAVE_SYS_SOCKET_H 1 99 | 100 | /* Define to 1 if you have the header file. */ 101 | #define HAVE_SYS_STAT_H 1 102 | 103 | /* Define to 1 if you have the header file. */ 104 | #define HAVE_SYS_TIME_H 1 105 | 106 | /* Define to 1 if you have the header file. */ 107 | #define HAVE_SYS_TYPES_H 1 108 | 109 | /* Define to 1 if you have the header file. */ 110 | #define HAVE_TERMIOS_H 1 111 | 112 | /* Define to 1 if you have the header file. */ 113 | #define HAVE_TIME_H 1 114 | 115 | /* Define to 1 if you have the header file. */ 116 | #define HAVE_UNISTD_H 1 117 | 118 | /* Define to 1 if you have the `vfork' function. */ 119 | #define HAVE_VFORK 1 120 | 121 | /* Define to 1 if you have the header file. */ 122 | /* #undef HAVE_VFORK_H */ 123 | 124 | /* Define to 1 if you have the header file. */ 125 | /* #undef HAVE_WINSOCK2_H */ 126 | 127 | /* Define to 1 if `fork' works. */ 128 | #define HAVE_WORKING_FORK 1 129 | 130 | /* Define to 1 if `vfork' works. */ 131 | #define HAVE_WORKING_VFORK 1 132 | 133 | /* Define to the sub-directory in which libtool stores uninstalled libraries. 134 | */ 135 | #define LT_OBJDIR ".libs/" 136 | 137 | /* Name of package */ 138 | #define PACKAGE "libmodbus" 139 | 140 | /* Define to the address where bug reports for this package should be sent. */ 141 | #define PACKAGE_BUGREPORT "https://github.com/stephane/libmodbus/issues" 142 | 143 | /* Define to the full name of this package. */ 144 | #define PACKAGE_NAME "libmodbus" 145 | 146 | /* Define to the full name and version of this package. */ 147 | #define PACKAGE_STRING "libmodbus 3.1.1" 148 | 149 | /* Define to the one symbol short name of this package. */ 150 | #define PACKAGE_TARNAME "libmodbus" 151 | 152 | /* Define to the home page for this package. */ 153 | #define PACKAGE_URL "http://libmodbus.org/" 154 | 155 | /* Define to the version of this package. */ 156 | #define PACKAGE_VERSION "3.1.1" 157 | 158 | /* Define to 1 if you have the ANSI C header files. */ 159 | #define STDC_HEADERS 1 160 | 161 | /* Enable extensions on AIX 3, Interix. */ 162 | #ifndef _ALL_SOURCE 163 | # define _ALL_SOURCE 1 164 | #endif 165 | /* Enable GNU extensions on systems that have them. */ 166 | #ifndef _GNU_SOURCE 167 | # define _GNU_SOURCE 1 168 | #endif 169 | /* Enable threading extensions on Solaris. */ 170 | #ifndef _POSIX_PTHREAD_SEMANTICS 171 | # define _POSIX_PTHREAD_SEMANTICS 1 172 | #endif 173 | /* Enable extensions on HP NonStop. */ 174 | #ifndef _TANDEM_SOURCE 175 | # define _TANDEM_SOURCE 1 176 | #endif 177 | /* Enable general extensions on Solaris. */ 178 | #ifndef __EXTENSIONS__ 179 | # define __EXTENSIONS__ 1 180 | #endif 181 | 182 | 183 | /* Version number of package */ 184 | #define VERSION "3.1.1" 185 | 186 | /* _ */ 187 | //#define WINVER 0x0501 188 | 189 | /* Number of bits in a file offset, on hosts where this is settable. */ 190 | /* #undef _FILE_OFFSET_BITS */ 191 | 192 | /* Define for large files, on AIX-style hosts. */ 193 | /* #undef _LARGE_FILES */ 194 | 195 | /* Define to 1 if on MINIX. */ 196 | /* #undef _MINIX */ 197 | 198 | /* Define to 2 if the system does not provide POSIX.1 features except with 199 | this defined. */ 200 | /* #undef _POSIX_1_SOURCE */ 201 | 202 | /* Define to 1 if you need to in order for `stat' and other things to work. */ 203 | /* #undef _POSIX_SOURCE */ 204 | 205 | /* Define to `int' if does not define. */ 206 | /* #undef pid_t */ 207 | 208 | /* Define as `fork' if `vfork' does not work. */ 209 | /* #undef vfork */ 210 | -------------------------------------------------------------------------------- /ModbusSlave_Poll/3rdparty/libmodbus/src/Makefile.am: -------------------------------------------------------------------------------- 1 | EXTRA_DIST = 2 | pkginclude_HEADERS = modbus.h 3 | lib_LTLIBRARIES = libmodbus.la 4 | 5 | AM_CPPFLAGS = \ 6 | -include $(top_builddir)/config.h \ 7 | -DSYSCONFDIR=\""$(sysconfdir)"\" \ 8 | -DLIBEXECDIR=\""$(libexecdir)"\" \ 9 | -I${top_srcdir}/src 10 | 11 | AM_CFLAGS = ${my_CFLAGS} 12 | 13 | libmodbus_la_SOURCES = \ 14 | modbus.c \ 15 | modbus.h \ 16 | modbus-data.c \ 17 | modbus-private.h \ 18 | modbus-rtu.c \ 19 | modbus-rtu.h \ 20 | modbus-rtu-private.h \ 21 | modbus-ascii.c \ 22 | modbus-ascii.h \ 23 | modbus-ascii-private.h \ 24 | modbus-tcp.c \ 25 | modbus-tcp.h \ 26 | modbus-tcp-private.h \ 27 | modbus-version.h 28 | 29 | libmodbus_la_LDFLAGS = -no-undefined \ 30 | -version-info $(LIBMODBUS_LT_VERSION_INFO) 31 | 32 | if OS_WIN32 33 | libmodbus_la_LIBADD = -lwsock32 34 | endif 35 | 36 | if OS_QNX 37 | libmodbus_la_LIBADD = -lsocket 38 | endif 39 | 40 | # Header files to install 41 | libmodbusincludedir = $(includedir)/modbus 42 | libmodbusinclude_HEADERS = modbus.h modbus-version.h modbus-rtu.h modbus-tcp.h 43 | 44 | DISTCLEANFILES = modbus-version.h 45 | EXTRA_DIST += modbus-version.h.in 46 | CLEANFILES = *~ 47 | -------------------------------------------------------------------------------- /ModbusSlave_Poll/3rdparty/libmodbus/src/modbus-ascii-private.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2001-2011 Stéphane Raimbault 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library 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 GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #ifndef _MODBUS_ASCII_PRIVATE_H_ 20 | #define _MODBUS_ASCII_PRIVATE_H_ 21 | 22 | #ifndef _MSC_VER 23 | #include 24 | #else 25 | #include "stdint.h" 26 | #endif 27 | 28 | #if defined(_WIN32) 29 | #include 30 | #else 31 | #include 32 | #endif 33 | 34 | #define _MODBUS_ASCII_HEADER_LENGTH 2 35 | #define _MODBUS_ASCII_PRESET_REQ_LENGTH 7 36 | #define _MODBUS_ASCII_PRESET_RSP_LENGTH 2 37 | 38 | #define _MODBUS_ASCII_CHECKSUM_LENGTH 3 /* lcr8 + \r\n */ 39 | 40 | #if defined(_WIN32) 41 | #if !defined(ENOTSUP) 42 | #define ENOTSUP WSAEOPNOTSUPP 43 | #endif 44 | 45 | /* WIN32: struct containing serial handle and a receive buffer */ 46 | #define PY_BUF_SIZE 512 47 | struct win32_ser { 48 | /* File handle */ 49 | HANDLE fd; 50 | /* Receive buffer */ 51 | uint8_t buf[PY_BUF_SIZE]; 52 | /* Received chars */ 53 | DWORD n_bytes; 54 | }; 55 | #endif /* _WIN32 */ 56 | 57 | typedef struct _modbus_rtu { 58 | /* Device: "/dev/ttyS0", "/dev/ttyUSB0" or "/dev/tty.USA19*" on Mac OS X. */ 59 | char *device; 60 | /* Bauds: 9600, 19200, 57600, 115200, etc */ 61 | int baud; 62 | /* Data bit */ 63 | uint8_t data_bit; 64 | /* Stop bit */ 65 | uint8_t stop_bit; 66 | /* Parity: 'N', 'O', 'E' */ 67 | char parity; 68 | #if defined(_WIN32) 69 | struct win32_ser w_ser; 70 | DCB old_dcb; 71 | #else 72 | /* Save old termios settings */ 73 | struct termios old_tios; 74 | #endif 75 | #if HAVE_DECL_TIOCSRS485 76 | int serial_mode; 77 | #endif 78 | #if HAVE_DECL_TIOCM_RTS 79 | int rts; 80 | int onebyte_time; 81 | #endif 82 | /* To handle many slaves on the same link */ 83 | int confirmation_to_ignore; 84 | } modbus_ascii_t; 85 | 86 | #endif /* _MODBUS_RTU_PRIVATE_H_ */ 87 | -------------------------------------------------------------------------------- /ModbusSlave_Poll/3rdparty/libmodbus/src/modbus-ascii.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2001-2011 Stéphane Raimbault 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library 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 GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #ifndef _MODBUS_ASCII_H_ 20 | #define _MODBUS_ASCII_H_ 21 | 22 | #include "modbus.h" 23 | 24 | MODBUS_BEGIN_DECLS 25 | 26 | /* Modbus_Application_Protocol_V1_1b.pdf Chapter 4 Section 1 Page 5 27 | * RS232 / RS485 ADU = 253 bytes + slave (1 byte) + CRC (2 bytes) = 256 bytes 28 | */ 29 | #define MODBUS_ASCII_MAX_ADU_LENGTH 256 30 | 31 | MODBUS_API modbus_t* modbus_new_ascii(const char *device, int baud, char parity, 32 | int data_bit, int stop_bit); 33 | 34 | #define MODBUS_ASCII_RS232 0 35 | #define MODBUS_ASCII_RS485 1 36 | 37 | MODBUS_API int modbus_ascii_set_serial_mode(modbus_t *ctx, int mode); 38 | MODBUS_API int modbus_ascii_get_serial_mode(modbus_t *ctx); 39 | 40 | MODBUS_END_DECLS 41 | 42 | #endif /* _MODBUS_ASCII_H_ */ 43 | -------------------------------------------------------------------------------- /ModbusSlave_Poll/3rdparty/libmodbus/src/modbus-data.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2010-2011 Stéphane Raimbault 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library 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 GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #include 20 | #ifndef _MSC_VER 21 | #include 22 | #else 23 | #include "stdint.h" 24 | #endif 25 | #include 26 | #include 27 | 28 | #include "modbus.h" 29 | 30 | #if defined(HAVE_BYTESWAP_H) 31 | # include 32 | #endif 33 | 34 | #if defined(__GNUC__) 35 | # define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__ * 10) 36 | # if GCC_VERSION >= 430 37 | // Since GCC >= 4.30, GCC provides __builtin_bswapXX() alternatives so we switch to them 38 | # undef bswap_32 39 | # define bswap_32 __builtin_bswap32 40 | # endif 41 | #endif 42 | #if defined(_MSC_VER) && (_MSC_VER >= 1400) 43 | # define bswap_32 _byteswap_ulong 44 | #endif 45 | 46 | #if !defined(bswap_32) 47 | 48 | #if !defined(bswap_16) 49 | # warning "Fallback on C functions for bswap_16" 50 | static inline uint16_t bswap_16(uint16_t x) 51 | { 52 | return (x >> 8) | (x << 8); 53 | } 54 | #endif 55 | 56 | # warning "Fallback on C functions for bswap_32" 57 | static inline uint32_t bswap_32(uint32_t x) 58 | { 59 | return (bswap_16(x & 0xffff) << 16) | (bswap_16(x >> 16)); 60 | } 61 | #endif 62 | 63 | /* Sets many bits from a single byte value (all 8 bits of the byte value are 64 | set) */ 65 | void modbus_set_bits_from_byte(uint8_t *dest, int idx, const uint8_t value) 66 | { 67 | int i; 68 | 69 | for (i=0; i < 8; i++) { 70 | dest[idx+i] = (value & (1 << i)) ? 1 : 0; 71 | } 72 | } 73 | 74 | /* Sets many bits from a table of bytes (only the bits between idx and 75 | idx + nb_bits are set) */ 76 | void modbus_set_bits_from_bytes(uint8_t *dest, int idx, unsigned int nb_bits, 77 | const uint8_t *tab_byte) 78 | { 79 | unsigned int i; 80 | int shift = 0; 81 | 82 | for (i = idx; i < idx + nb_bits; i++) { 83 | dest[i] = tab_byte[(i - idx) / 8] & (1 << shift) ? 1 : 0; 84 | /* gcc doesn't like: shift = (++shift) % 8; */ 85 | shift++; 86 | shift %= 8; 87 | } 88 | } 89 | 90 | /* Gets the byte value from many bits. 91 | To obtain a full byte, set nb_bits to 8. */ 92 | uint8_t modbus_get_byte_from_bits(const uint8_t *src, int idx, 93 | unsigned int nb_bits) 94 | { 95 | unsigned int i; 96 | uint8_t value = 0; 97 | 98 | if (nb_bits > 8) { 99 | /* Assert is ignored if NDEBUG is set */ 100 | assert(nb_bits < 8); 101 | nb_bits = 8; 102 | } 103 | 104 | for (i=0; i < nb_bits; i++) { 105 | value |= (src[idx+i] << i); 106 | } 107 | 108 | return value; 109 | } 110 | 111 | /* Get a float from 4 bytes in Modbus format (ABCD) */ 112 | float modbus_get_float(const uint16_t *src) 113 | { 114 | float f; 115 | uint32_t i; 116 | 117 | i = (((uint32_t)src[1]) << 16) + src[0]; 118 | memcpy(&f, &i, sizeof(float)); 119 | 120 | return f; 121 | } 122 | 123 | /* Get a float from 4 bytes in inversed Modbus format (DCBA) */ 124 | float modbus_get_float_dcba(const uint16_t *src) 125 | { 126 | float f; 127 | uint32_t i; 128 | 129 | i = bswap_32((((uint32_t)src[1]) << 16) + src[0]); 130 | memcpy(&f, &i, sizeof(float)); 131 | 132 | return f; 133 | } 134 | 135 | /* Set a float to 4 bytes in Modbus format (ABCD) */ 136 | void modbus_set_float(float f, uint16_t *dest) 137 | { 138 | uint32_t i; 139 | 140 | memcpy(&i, &f, sizeof(uint32_t)); 141 | dest[0] = (uint16_t)i; 142 | dest[1] = (uint16_t)(i >> 16); 143 | } 144 | 145 | /* Set a float to 4 bytes in inversed Modbus format (DCBA) */ 146 | void modbus_set_float_dcba(float f, uint16_t *dest) 147 | { 148 | uint32_t i; 149 | 150 | memcpy(&i, &f, sizeof(uint32_t)); 151 | i = bswap_32(i); 152 | dest[0] = (uint16_t)i; 153 | dest[1] = (uint16_t)(i >> 16); 154 | } 155 | -------------------------------------------------------------------------------- /ModbusSlave_Poll/3rdparty/libmodbus/src/modbus-private.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2010-2012 Stéphane Raimbault 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library 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 GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #ifndef MODBUS_PRIVATE_H 20 | #define MODBUS_PRIVATE_H 21 | 22 | #ifndef _MSC_VER 23 | # include 24 | # include 25 | #else 26 | # include "stdint.h" 27 | # include 28 | typedef int ssize_t; 29 | #endif 30 | #include 31 | #include <3rdparty/libmodbus/config.h> 32 | #include "modbus.h" 33 | 34 | MODBUS_BEGIN_DECLS 35 | 36 | /* It's not really the minimal length (the real one is report slave ID 37 | * in RTU (4 bytes)) but it's a convenient size to use in RTU or TCP 38 | * communications to read many values or write a single one. 39 | * Maximum between : 40 | * - HEADER_LENGTH_TCP (7) + function (1) + address (2) + number (2) 41 | * - HEADER_LENGTH_RTU (1) + function (1) + address (2) + number (2) + CRC (2) 42 | */ 43 | #define _MIN_REQ_LENGTH 12 44 | 45 | #define _REPORT_SLAVE_ID 180 46 | 47 | #define _MODBUS_EXCEPTION_RSP_LENGTH 5 48 | 49 | /* Timeouts in microsecond (0.5 s) */ 50 | #define _RESPONSE_TIMEOUT 500000 51 | #define _BYTE_TIMEOUT 500000 52 | 53 | typedef enum { 54 | _MODBUS_BACKEND_TYPE_RTU=0, 55 | _MODBUS_BACKEND_TYPE_TCP, 56 | _MODBUS_BACKEND_TYPE_ASCII 57 | } modbus_backend_type_t; 58 | 59 | /* 60 | * ---------- Request Indication ---------- 61 | * | Client | ---------------------->| Server | 62 | * ---------- Confirmation Response ---------- 63 | */ 64 | typedef enum { 65 | /* Request message on the server side */ 66 | MSG_INDICATION, 67 | /* Request message on the client side */ 68 | MSG_CONFIRMATION 69 | } msg_type_t; 70 | 71 | /* This structure reduces the number of params in functions and so 72 | * optimizes the speed of execution (~ 37%). */ 73 | typedef struct _sft { 74 | int slave; 75 | int function; 76 | int t_id; 77 | } sft_t; 78 | 79 | typedef struct _modbus_backend { 80 | unsigned int backend_type; 81 | unsigned int header_length; 82 | unsigned int checksum_length; 83 | unsigned int max_adu_length; 84 | int (*set_slave) (modbus_t *ctx, int slave); 85 | int (*build_request_basis) (modbus_t *ctx, int function, int addr, 86 | int nb, uint8_t *req); 87 | int (*build_response_basis) (sft_t *sft, uint8_t *rsp); 88 | int (*prepare_response_tid) (const uint8_t *req, int *req_length); 89 | int (*send_msg_pre) (uint8_t *req, int req_length); 90 | ssize_t (*send) (modbus_t *ctx, const uint8_t *req, int req_length); 91 | int (*receive) (modbus_t *ctx, uint8_t *req); 92 | ssize_t (*recv) (modbus_t *ctx, uint8_t *rsp, int rsp_length); 93 | int (*check_integrity) (modbus_t *ctx, uint8_t *msg, 94 | const int msg_length); 95 | int (*pre_check_confirmation) (modbus_t *ctx, const uint8_t *req, 96 | const uint8_t *rsp, int rsp_length); 97 | int (*connect) (modbus_t *ctx); 98 | void (*close) (modbus_t *ctx); 99 | int (*flush) (modbus_t *ctx); 100 | int (*select) (modbus_t *ctx, fd_set *rset, struct timeval *tv, int msg_length); 101 | void (*free) (modbus_t *ctx); 102 | } modbus_backend_t; 103 | 104 | struct _modbus { 105 | /* Slave address */ 106 | int slave; 107 | /* Socket or file descriptor */ 108 | int s; 109 | int debug; 110 | int error_recovery; 111 | struct timeval response_timeout; 112 | struct timeval byte_timeout; 113 | uint16_t last_crc_expected; 114 | uint16_t last_crc_received; 115 | const modbus_backend_t *backend; 116 | void *backend_data; 117 | modbus_monitor_add_item_fnc_t monitor_add_item; 118 | modbus_monitor_raw_data_fnc_t monitor_raw_data; 119 | }; 120 | 121 | void _modbus_init_common(modbus_t *ctx); 122 | void _error_print(modbus_t *ctx, const char *context); 123 | int _modbus_receive_msg(modbus_t *ctx, uint8_t *msg, msg_type_t msg_type); 124 | 125 | #ifndef HAVE_STRLCPY 126 | size_t strlcpy(char *dest, const char *src, size_t dest_size); 127 | #endif 128 | 129 | MODBUS_END_DECLS 130 | 131 | #endif /* MODBUS_PRIVATE_H */ 132 | -------------------------------------------------------------------------------- /ModbusSlave_Poll/3rdparty/libmodbus/src/modbus-rtu-private.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2001-2011 Stéphane Raimbault 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library 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 GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #ifndef MODBUS_RTU_PRIVATE_H 20 | #define MODBUS_RTU_PRIVATE_H 21 | 22 | #ifndef _MSC_VER 23 | #include 24 | #else 25 | #include "stdint.h" 26 | #endif 27 | 28 | #if defined(_WIN32) 29 | #include 30 | #else 31 | #include 32 | #endif 33 | 34 | #define _MODBUS_RTU_HEADER_LENGTH 1 35 | #define _MODBUS_RTU_PRESET_REQ_LENGTH 6 36 | #define _MODBUS_RTU_PRESET_RSP_LENGTH 2 37 | 38 | #define _MODBUS_RTU_CHECKSUM_LENGTH 2 39 | 40 | /* Time waited beetween the RTS switch before transmit data or after transmit 41 | data before to read */ 42 | #define _MODBUS_RTU_TIME_BETWEEN_RTS_SWITCH 10000 43 | 44 | #if defined(_WIN32) 45 | #if !defined(ENOTSUP) 46 | #define ENOTSUP WSAEOPNOTSUPP 47 | #endif 48 | 49 | /* WIN32: struct containing serial handle and a receive buffer */ 50 | #define PY_BUF_SIZE 512 51 | struct win32_ser { 52 | /* File handle */ 53 | HANDLE fd; 54 | /* Receive buffer */ 55 | uint8_t buf[PY_BUF_SIZE]; 56 | /* Received chars */ 57 | DWORD n_bytes; 58 | }; 59 | #endif /* _WIN32 */ 60 | 61 | typedef struct _modbus_rtu { 62 | /* Device: "/dev/ttyS0", "/dev/ttyUSB0" or "/dev/tty.USA19*" on Mac OS X. */ 63 | char *device; 64 | /* Bauds: 9600, 19200, 57600, 115200, etc */ 65 | int baud; 66 | /* Data bit */ 67 | uint8_t data_bit; 68 | /* Stop bit */ 69 | uint8_t stop_bit; 70 | /* Parity: 'N', 'O', 'E' */ 71 | char parity; 72 | #if defined(_WIN32) 73 | struct win32_ser w_ser; 74 | DCB old_dcb; 75 | #else 76 | /* Save old termios settings */ 77 | struct termios old_tios; 78 | #endif 79 | #if HAVE_DECL_TIOCSRS485 80 | int serial_mode; 81 | #endif 82 | #if HAVE_DECL_TIOCM_RTS 83 | int rts; 84 | int onebyte_time; 85 | #endif 86 | /* To handle many slaves on the same link */ 87 | int confirmation_to_ignore; 88 | } modbus_rtu_t; 89 | 90 | #endif /* MODBUS_RTU_PRIVATE_H */ 91 | -------------------------------------------------------------------------------- /ModbusSlave_Poll/3rdparty/libmodbus/src/modbus-rtu.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2001-2011 Stéphane Raimbault 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library 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 GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #ifndef MODBUS_RTU_H 20 | #define MODBUS_RTU_H 21 | 22 | #include "modbus.h" 23 | 24 | MODBUS_BEGIN_DECLS 25 | 26 | /* Modbus_Application_Protocol_V1_1b.pdf Chapter 4 Section 1 Page 5 27 | * RS232 / RS485 ADU = 253 bytes + slave (1 byte) + CRC (2 bytes) = 256 bytes 28 | */ 29 | #define MODBUS_RTU_MAX_ADU_LENGTH 256 30 | 31 | MODBUS_API modbus_t* modbus_new_rtu(const char *device, int baud, char parity, 32 | int data_bit, int stop_bit); 33 | 34 | #define MODBUS_RTU_RS232 0 35 | #define MODBUS_RTU_RS485 1 36 | 37 | MODBUS_API int modbus_rtu_set_serial_mode(modbus_t *ctx, int mode); 38 | MODBUS_API int modbus_rtu_get_serial_mode(modbus_t *ctx); 39 | 40 | #define MODBUS_RTU_RTS_NONE 0 41 | #define MODBUS_RTU_RTS_UP 1 42 | #define MODBUS_RTU_RTS_DOWN 2 43 | 44 | MODBUS_API int modbus_rtu_set_rts(modbus_t *ctx, int mode); 45 | MODBUS_API int modbus_rtu_get_rts(modbus_t *ctx); 46 | 47 | MODBUS_END_DECLS 48 | 49 | #endif /* MODBUS_RTU_H */ 50 | -------------------------------------------------------------------------------- /ModbusSlave_Poll/3rdparty/libmodbus/src/modbus-tcp-private.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2001-2011 Stéphane Raimbault 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library 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 GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #ifndef MODBUS_TCP_PRIVATE_H 20 | #define MODBUS_TCP_PRIVATE_H 21 | 22 | #define _MODBUS_TCP_HEADER_LENGTH 7 23 | #define _MODBUS_TCP_PRESET_REQ_LENGTH 12 24 | #define _MODBUS_TCP_PRESET_RSP_LENGTH 8 25 | 26 | #define _MODBUS_TCP_CHECKSUM_LENGTH 0 27 | 28 | /* In both structures, the transaction ID must be placed on first position 29 | to have a quick access not dependant of the TCP backend */ 30 | typedef struct _modbus_tcp { 31 | /* Extract from MODBUS Messaging on TCP/IP Implementation Guide V1.0b 32 | (page 23/46): 33 | The transaction identifier is used to associate the future response 34 | with the request. This identifier is unique on each TCP connection. */ 35 | uint16_t t_id; 36 | /* TCP port */ 37 | int port; 38 | /* IP address */ 39 | char ip[16]; 40 | } modbus_tcp_t; 41 | 42 | #define _MODBUS_TCP_PI_NODE_LENGTH 1025 43 | #define _MODBUS_TCP_PI_SERVICE_LENGTH 32 44 | 45 | typedef struct _modbus_tcp_pi { 46 | /* Transaction ID */ 47 | uint16_t t_id; 48 | /* TCP port */ 49 | int port; 50 | /* Node */ 51 | char node[_MODBUS_TCP_PI_NODE_LENGTH]; 52 | /* Service */ 53 | char service[_MODBUS_TCP_PI_SERVICE_LENGTH]; 54 | } modbus_tcp_pi_t; 55 | 56 | #endif /* MODBUS_TCP_PRIVATE_H */ 57 | -------------------------------------------------------------------------------- /ModbusSlave_Poll/3rdparty/libmodbus/src/modbus-tcp.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2001-2013 Stéphane Raimbault 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library 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 GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #ifndef _MSC_VER 24 | #include 25 | #endif 26 | #include 27 | #include 28 | 29 | #if defined(_WIN32) 30 | # define OS_WIN32 31 | /* ws2_32.dll has getaddrinfo and freeaddrinfo on Windows XP and later. 32 | * minwg32 headers check WINVER before allowing the use of these */ 33 | # ifndef WINVER 34 | # define WINVER 0x0501 35 | # endif 36 | /* Already set in modbus-tcp.h but it seems order matters in VS2005 */ 37 | # include 38 | # include 39 | # define SHUT_RDWR 2 40 | # define close closesocket 41 | #define ENOTCONN WSAENOTCONN 42 | #else 43 | #define __USE_GNU 44 | # include 45 | # include 46 | 47 | #if defined(__OpenBSD__) || (defined(__FreeBSD__) && __FreeBSD__ < 5) 48 | # define OS_BSD 49 | # include 50 | #endif 51 | 52 | # include 53 | # include 54 | # include 55 | # include 56 | # include 57 | #endif 58 | 59 | #if !defined(MSG_NOSIGNAL) 60 | #define MSG_NOSIGNAL 0 61 | #endif 62 | 63 | #include "modbus-private.h" 64 | 65 | #include "modbus-tcp.h" 66 | #include "modbus-tcp-private.h" 67 | 68 | #ifdef OS_WIN32 69 | static int _modbus_tcp_init_win32(void) 70 | { 71 | /* Initialise Windows Socket API */ 72 | WSADATA wsaData; 73 | 74 | if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { 75 | fprintf(stderr, "WSAStartup() returned error code %d\n", 76 | (unsigned int)GetLastError()); 77 | errno = EIO; 78 | return -1; 79 | } 80 | return 0; 81 | } 82 | #endif 83 | 84 | static int _modbus_set_slave(modbus_t *ctx, int slave) 85 | { 86 | /* Broadcast address is 0 (MODBUS_BROADCAST_ADDRESS) */ 87 | if (slave >= 0 && slave <= 247) { 88 | ctx->slave = slave; 89 | } else if (slave == MODBUS_TCP_SLAVE) { 90 | /* The special value MODBUS_TCP_SLAVE (0xFF) can be used in TCP mode to 91 | * restore the default value. */ 92 | ctx->slave = slave; 93 | } else { 94 | errno = EINVAL; 95 | return -1; 96 | } 97 | 98 | return 0; 99 | } 100 | 101 | /* Builds a TCP request header */ 102 | static int _modbus_tcp_build_request_basis(modbus_t *ctx, int function, 103 | int addr, int nb, 104 | uint8_t *req) 105 | { 106 | modbus_tcp_t *ctx_tcp = ctx->backend_data; 107 | 108 | /* Increase transaction ID */ 109 | if (ctx_tcp->t_id < UINT16_MAX) 110 | ctx_tcp->t_id++; 111 | else 112 | ctx_tcp->t_id = 0; 113 | req[0] = ctx_tcp->t_id >> 8; 114 | req[1] = ctx_tcp->t_id & 0x00ff; 115 | 116 | /* Protocol Modbus */ 117 | req[2] = 0; 118 | req[3] = 0; 119 | 120 | /* Length will be defined later by set_req_length_tcp at offsets 4 121 | and 5 */ 122 | 123 | req[6] = ctx->slave; 124 | req[7] = function; 125 | req[8] = addr >> 8; 126 | req[9] = addr & 0x00ff; 127 | req[10] = nb >> 8; 128 | req[11] = nb & 0x00ff; 129 | 130 | return _MODBUS_TCP_PRESET_REQ_LENGTH; 131 | } 132 | 133 | /* Builds a TCP response header */ 134 | static int _modbus_tcp_build_response_basis(sft_t *sft, uint8_t *rsp) 135 | { 136 | /* Extract from MODBUS Messaging on TCP/IP Implementation 137 | Guide V1.0b (page 23/46): 138 | The transaction identifier is used to associate the future 139 | response with the request. */ 140 | rsp[0] = sft->t_id >> 8; 141 | rsp[1] = sft->t_id & 0x00ff; 142 | 143 | /* Protocol Modbus */ 144 | rsp[2] = 0; 145 | rsp[3] = 0; 146 | 147 | /* Length will be set later by send_msg (4 and 5) */ 148 | 149 | /* The slave ID is copied from the indication */ 150 | rsp[6] = sft->slave; 151 | rsp[7] = sft->function; 152 | 153 | return _MODBUS_TCP_PRESET_RSP_LENGTH; 154 | } 155 | 156 | 157 | static int _modbus_tcp_prepare_response_tid(const uint8_t *req, int *req_length) 158 | { 159 | return (req[0] << 8) + req[1]; 160 | } 161 | 162 | static int _modbus_tcp_send_msg_pre(uint8_t *req, int req_length) 163 | { 164 | /* Substract the header length to the message length */ 165 | int mbap_length = req_length - 6; 166 | 167 | req[4] = mbap_length >> 8; 168 | req[5] = mbap_length & 0x00FF; 169 | 170 | return req_length; 171 | } 172 | 173 | static ssize_t _modbus_tcp_send(modbus_t *ctx, const uint8_t *req, int req_length) 174 | { 175 | /* MSG_NOSIGNAL 176 | Requests not to send SIGPIPE on errors on stream oriented 177 | sockets when the other end breaks the connection. The EPIPE 178 | error is still returned. */ 179 | return send(ctx->s, (const char*)req, req_length, MSG_NOSIGNAL); 180 | } 181 | 182 | static int _modbus_tcp_receive(modbus_t *ctx, uint8_t *req) { 183 | return _modbus_receive_msg(ctx, req, MSG_INDICATION); 184 | } 185 | 186 | static ssize_t _modbus_tcp_recv(modbus_t *ctx, uint8_t *rsp, int rsp_length) { 187 | return recv(ctx->s, (char *)rsp, rsp_length, 0); 188 | } 189 | 190 | static int _modbus_tcp_check_integrity(modbus_t *ctx, uint8_t *msg, const int msg_length) 191 | { 192 | return msg_length; 193 | } 194 | 195 | static int _modbus_tcp_pre_check_confirmation(modbus_t *ctx, const uint8_t *req, 196 | const uint8_t *rsp, int rsp_length) 197 | { 198 | /* Check transaction ID */ 199 | if (req[0] != rsp[0] || req[1] != rsp[1]) { 200 | if (ctx->debug) { 201 | fprintf(stderr, "Invalid transaction ID received 0x%X (not 0x%X)\n", 202 | (rsp[0] << 8) + rsp[1], (req[0] << 8) + req[1]); 203 | } 204 | errno = EMBBADDATA; 205 | return -1; 206 | } 207 | 208 | /* Check protocol ID */ 209 | if (rsp[2] != 0x0 && rsp[3] != 0x0) { 210 | if (ctx->debug) { 211 | fprintf(stderr, "Invalid protocol ID received 0x%X (not 0x0)\n", 212 | (rsp[2] << 8) + rsp[3]); 213 | } 214 | errno = EMBBADDATA; 215 | return -1; 216 | } 217 | 218 | return 0; 219 | } 220 | 221 | static int _modbus_tcp_set_ipv4_options(int s) 222 | { 223 | int rc; 224 | int option; 225 | 226 | /* Set the TCP no delay flag */ 227 | /* SOL_TCP = IPPROTO_TCP */ 228 | option = 1; 229 | rc = setsockopt(s, IPPROTO_TCP, TCP_NODELAY, 230 | (const void *)&option, sizeof(int)); 231 | if (rc == -1) { 232 | return -1; 233 | } 234 | 235 | /* If the OS does not offer SOCK_NONBLOCK, fall back to setting FIONBIO to 236 | * make sockets non-blocking */ 237 | /* Do not care about the return value, this is optional */ 238 | option = 1; 239 | #if !defined(SOCK_NONBLOCK) && defined(FIONBIO) 240 | #ifdef OS_WIN32 241 | { 242 | /* Setting FIONBIO expects an unsigned long according to MSDN */ 243 | u_long loption = 1; 244 | ioctlsocket(s, FIONBIO, &loption); 245 | } 246 | #else 247 | ioctl(s, FIONBIO, &option); 248 | #endif 249 | #endif 250 | 251 | #ifndef OS_WIN32 252 | /** 253 | * Cygwin defines IPTOS_LOWDELAY but can't handle that flag so it's 254 | * necessary to workaround that problem. 255 | **/ 256 | /* Set the IP low delay option */ 257 | option = IPTOS_LOWDELAY; 258 | rc = setsockopt(s, IPPROTO_IP, IP_TOS, 259 | (const void *)&option, sizeof(int)); 260 | if (rc == -1) { 261 | return -1; 262 | } 263 | #endif 264 | 265 | return 0; 266 | } 267 | 268 | static int _connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen, 269 | const struct timeval *ro_tv) 270 | { 271 | int rc = connect(sockfd, addr, addrlen); 272 | 273 | #ifdef OS_WIN32 274 | int wsaError = 0; 275 | if (rc == -1) { 276 | wsaError = WSAGetLastError(); 277 | } 278 | 279 | if (wsaError == WSAEWOULDBLOCK || wsaError == WSAEINPROGRESS) { 280 | #else 281 | if (rc == -1 && errno == EINPROGRESS) { 282 | #endif 283 | fd_set wset; 284 | int optval; 285 | socklen_t optlen = sizeof(optval); 286 | struct timeval tv = *ro_tv; 287 | 288 | /* Wait to be available in writing */ 289 | FD_ZERO(&wset); 290 | FD_SET(sockfd, &wset); 291 | rc = select(sockfd + 1, NULL, &wset, NULL, &tv); 292 | if (rc <= 0) { 293 | /* Timeout or fail */ 294 | return -1; 295 | } 296 | 297 | /* The connection is established if SO_ERROR and optval are set to 0 */ 298 | rc = getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (void *)&optval, &optlen); 299 | if (rc == 0 && optval == 0) { 300 | return 0; 301 | } else { 302 | errno = ECONNREFUSED; 303 | return -1; 304 | } 305 | } 306 | return rc; 307 | } 308 | 309 | /* Establishes a modbus TCP connection with a Modbus server. */ 310 | static int _modbus_tcp_connect(modbus_t *ctx) 311 | { 312 | int rc; 313 | /* Specialized version of sockaddr for Internet socket address (same size) */ 314 | struct sockaddr_in addr; 315 | modbus_tcp_t *ctx_tcp = ctx->backend_data; 316 | int flags = SOCK_STREAM; 317 | 318 | #ifdef OS_WIN32 319 | if (_modbus_tcp_init_win32() == -1) { 320 | return -1; 321 | } 322 | #endif 323 | 324 | #ifdef SOCK_CLOEXEC 325 | flags |= SOCK_CLOEXEC; 326 | #endif 327 | 328 | #ifdef SOCK_NONBLOCK 329 | flags |= SOCK_NONBLOCK; 330 | #endif 331 | 332 | ctx->s = socket(PF_INET, flags, 0); 333 | if (ctx->s == -1) { 334 | return -1; 335 | } 336 | 337 | rc = _modbus_tcp_set_ipv4_options(ctx->s); 338 | if (rc == -1) { 339 | close(ctx->s); 340 | ctx->s = -1; 341 | return -1; 342 | } 343 | 344 | if (ctx->debug) { 345 | printf("Connecting to %s:%d\n", ctx_tcp->ip, ctx_tcp->port); 346 | } 347 | 348 | addr.sin_family = AF_INET; 349 | addr.sin_port = htons(ctx_tcp->port); 350 | addr.sin_addr.s_addr = inet_addr(ctx_tcp->ip); 351 | rc = _connect(ctx->s, (struct sockaddr *)&addr, sizeof(addr), &ctx->response_timeout); 352 | if (rc == -1) { 353 | close(ctx->s); 354 | ctx->s = -1; 355 | return -1; 356 | } 357 | 358 | return 0; 359 | } 360 | 361 | /* Establishes a modbus TCP PI connection with a Modbus server. */ 362 | static int _modbus_tcp_pi_connect(modbus_t *ctx) 363 | { 364 | int rc; 365 | struct addrinfo *ai_list; 366 | struct addrinfo *ai_ptr; 367 | struct addrinfo ai_hints; 368 | modbus_tcp_pi_t *ctx_tcp_pi = ctx->backend_data; 369 | 370 | #ifdef OS_WIN32 371 | if (_modbus_tcp_init_win32() == -1) { 372 | return -1; 373 | } 374 | #endif 375 | 376 | memset(&ai_hints, 0, sizeof(ai_hints)); 377 | #ifdef AI_ADDRCONFIG 378 | ai_hints.ai_flags |= AI_ADDRCONFIG; 379 | #endif 380 | ai_hints.ai_family = AF_UNSPEC; 381 | ai_hints.ai_socktype = SOCK_STREAM; 382 | ai_hints.ai_addr = NULL; 383 | ai_hints.ai_canonname = NULL; 384 | ai_hints.ai_next = NULL; 385 | 386 | ai_list = NULL; 387 | rc = getaddrinfo(ctx_tcp_pi->node, ctx_tcp_pi->service, 388 | &ai_hints, &ai_list); 389 | if (rc != 0) { 390 | if (ctx->debug) { 391 | fprintf(stderr, "Error returned by getaddrinfo: %s\n", gai_strerror(rc)); 392 | } 393 | errno = ECONNREFUSED; 394 | return -1; 395 | } 396 | 397 | for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next) { 398 | int flags = ai_ptr->ai_socktype; 399 | int s; 400 | 401 | #ifdef SOCK_CLOEXEC 402 | flags |= SOCK_CLOEXEC; 403 | #endif 404 | 405 | #ifdef SOCK_NONBLOCK 406 | flags |= SOCK_NONBLOCK; 407 | #endif 408 | 409 | s = socket(ai_ptr->ai_family, flags, ai_ptr->ai_protocol); 410 | if (s < 0) 411 | continue; 412 | 413 | if (ai_ptr->ai_family == AF_INET) 414 | _modbus_tcp_set_ipv4_options(s); 415 | 416 | if (ctx->debug) { 417 | printf("Connecting to [%s]:%s\n", ctx_tcp_pi->node, ctx_tcp_pi->service); 418 | } 419 | 420 | rc = _connect(s, ai_ptr->ai_addr, ai_ptr->ai_addrlen, &ctx->response_timeout); 421 | if (rc == -1) { 422 | close(s); 423 | continue; 424 | } 425 | 426 | ctx->s = s; 427 | break; 428 | } 429 | 430 | freeaddrinfo(ai_list); 431 | 432 | if (ctx->s < 0) { 433 | return -1; 434 | } 435 | 436 | return 0; 437 | } 438 | 439 | /* Closes the network connection and socket in TCP mode */ 440 | static void _modbus_tcp_close(modbus_t *ctx) 441 | { 442 | if (ctx->s != -1) { 443 | shutdown(ctx->s, SHUT_RDWR); 444 | close(ctx->s); 445 | ctx->s = -1; 446 | } 447 | } 448 | 449 | static int _modbus_tcp_flush(modbus_t *ctx) 450 | { 451 | int rc; 452 | int rc_sum = 0; 453 | 454 | do { 455 | /* Extract the garbage from the socket */ 456 | char devnull[MODBUS_TCP_MAX_ADU_LENGTH]; 457 | #ifndef OS_WIN32 458 | rc = recv(ctx->s, devnull, MODBUS_TCP_MAX_ADU_LENGTH, MSG_DONTWAIT); 459 | #else 460 | /* On Win32, it's a bit more complicated to not wait */ 461 | fd_set rset; 462 | struct timeval tv; 463 | 464 | tv.tv_sec = 0; 465 | tv.tv_usec = 0; 466 | FD_ZERO(&rset); 467 | FD_SET(ctx->s, &rset); 468 | rc = select(ctx->s+1, &rset, NULL, NULL, &tv); 469 | if (rc == -1) { 470 | return -1; 471 | } 472 | 473 | if (rc == 1) { 474 | /* There is data to flush */ 475 | rc = recv(ctx->s, devnull, MODBUS_TCP_MAX_ADU_LENGTH, 0); 476 | } 477 | #endif 478 | if (rc > 0) { 479 | rc_sum += rc; 480 | } 481 | } while (rc == MODBUS_TCP_MAX_ADU_LENGTH); 482 | 483 | return rc_sum; 484 | } 485 | 486 | /* Listens for any request from one or many modbus masters in TCP */ 487 | int modbus_tcp_listen(modbus_t *ctx, int nb_connection) 488 | { 489 | int new_s; 490 | int yes; 491 | struct sockaddr_in addr; 492 | modbus_tcp_t *ctx_tcp; 493 | 494 | if (ctx == NULL) { 495 | errno = EINVAL; 496 | return -1; 497 | } 498 | 499 | ctx_tcp = ctx->backend_data; 500 | 501 | #ifdef OS_WIN32 502 | if (_modbus_tcp_init_win32() == -1) { 503 | return -1; 504 | } 505 | #endif 506 | 507 | new_s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); 508 | if (new_s == -1) { 509 | return -1; 510 | } 511 | 512 | yes = 1; 513 | if (setsockopt(new_s, SOL_SOCKET, SO_REUSEADDR, 514 | (char *) &yes, sizeof(yes)) == -1) { 515 | close(new_s); 516 | return -1; 517 | } 518 | 519 | memset(&addr, 0, sizeof(addr)); 520 | addr.sin_family = AF_INET; 521 | /* If the modbus port is < to 1024, we need the setuid root. */ 522 | addr.sin_port = htons(ctx_tcp->port); 523 | if (ctx_tcp->ip[0] == '0') { 524 | /* Listen any addresses */ 525 | addr.sin_addr.s_addr = htonl(INADDR_ANY); 526 | } else { 527 | /* Listen only specified IP address */ 528 | addr.sin_addr.s_addr = inet_addr(ctx_tcp->ip); 529 | } 530 | if (bind(new_s, (struct sockaddr *)&addr, sizeof(addr)) == -1) { 531 | close(new_s); 532 | return -1; 533 | } 534 | 535 | if (listen(new_s, nb_connection) == -1) { 536 | close(new_s); 537 | return -1; 538 | } 539 | 540 | return new_s; 541 | } 542 | 543 | int modbus_tcp_pi_listen(modbus_t *ctx, int nb_connection) 544 | { 545 | int rc; 546 | struct addrinfo *ai_list; 547 | struct addrinfo *ai_ptr; 548 | struct addrinfo ai_hints; 549 | const char *node; 550 | const char *service; 551 | int new_s; 552 | modbus_tcp_pi_t *ctx_tcp_pi; 553 | 554 | if (ctx == NULL) { 555 | errno = EINVAL; 556 | return -1; 557 | } 558 | 559 | ctx_tcp_pi = ctx->backend_data; 560 | 561 | #ifdef OS_WIN32 562 | if (_modbus_tcp_init_win32() == -1) { 563 | return -1; 564 | } 565 | #endif 566 | 567 | if (ctx_tcp_pi->node[0] == 0) { 568 | node = NULL; /* == any */ 569 | } else { 570 | node = ctx_tcp_pi->node; 571 | } 572 | 573 | if (ctx_tcp_pi->service[0] == 0) { 574 | service = "502"; 575 | } else { 576 | service = ctx_tcp_pi->service; 577 | } 578 | 579 | memset(&ai_hints, 0, sizeof (ai_hints)); 580 | /* If node is not NULL, than the AI_PASSIVE flag is ignored. */ 581 | ai_hints.ai_flags |= AI_PASSIVE; 582 | #ifdef AI_ADDRCONFIG 583 | ai_hints.ai_flags |= AI_ADDRCONFIG; 584 | #endif 585 | ai_hints.ai_family = AF_UNSPEC; 586 | ai_hints.ai_socktype = SOCK_STREAM; 587 | ai_hints.ai_addr = NULL; 588 | ai_hints.ai_canonname = NULL; 589 | ai_hints.ai_next = NULL; 590 | 591 | ai_list = NULL; 592 | rc = getaddrinfo(node, service, &ai_hints, &ai_list); 593 | if (rc != 0) { 594 | if (ctx->debug) { 595 | fprintf(stderr, "Error returned by getaddrinfo: %s\n", gai_strerror(rc)); 596 | } 597 | errno = ECONNREFUSED; 598 | return -1; 599 | } 600 | 601 | new_s = -1; 602 | for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next) { 603 | int s; 604 | 605 | s = socket(ai_ptr->ai_family, ai_ptr->ai_socktype, 606 | ai_ptr->ai_protocol); 607 | if (s < 0) { 608 | if (ctx->debug) { 609 | perror("socket"); 610 | } 611 | continue; 612 | } else { 613 | int yes = 1; 614 | rc = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, 615 | (void *) &yes, sizeof (yes)); 616 | if (rc != 0) { 617 | close(s); 618 | if (ctx->debug) { 619 | perror("setsockopt"); 620 | } 621 | continue; 622 | } 623 | } 624 | 625 | rc = bind(s, ai_ptr->ai_addr, ai_ptr->ai_addrlen); 626 | if (rc != 0) { 627 | close(s); 628 | if (ctx->debug) { 629 | perror("bind"); 630 | } 631 | continue; 632 | } 633 | 634 | rc = listen(s, nb_connection); 635 | if (rc != 0) { 636 | close(s); 637 | if (ctx->debug) { 638 | perror("listen"); 639 | } 640 | continue; 641 | } 642 | 643 | new_s = s; 644 | break; 645 | } 646 | freeaddrinfo(ai_list); 647 | 648 | if (new_s < 0) { 649 | return -1; 650 | } 651 | 652 | return new_s; 653 | } 654 | 655 | int modbus_tcp_accept(modbus_t *ctx, int *s) 656 | { 657 | struct sockaddr_in addr; 658 | socklen_t addrlen; 659 | 660 | if (ctx == NULL) { 661 | errno = EINVAL; 662 | return -1; 663 | } 664 | 665 | addrlen = sizeof(addr); 666 | #ifdef HAVE_ACCEPT4 667 | /* Inherit socket flags and use accept4 call */ 668 | ctx->s = accept4(*s, (struct sockaddr *)&addr, &addrlen, SOCK_CLOEXEC); 669 | #else 670 | ctx->s = accept(*s, (struct sockaddr *)&addr, &addrlen); 671 | #endif 672 | 673 | if (ctx->s == -1) { 674 | close(*s); 675 | *s = -1; 676 | return -1; 677 | } 678 | 679 | if (ctx->debug) { 680 | printf("The client connection from %s is accepted\n", 681 | inet_ntoa(addr.sin_addr)); 682 | } 683 | 684 | return ctx->s; 685 | } 686 | 687 | int modbus_tcp_pi_accept(modbus_t *ctx, int *s) 688 | { 689 | struct sockaddr_storage addr; 690 | socklen_t addrlen; 691 | 692 | if (ctx == NULL) { 693 | errno = EINVAL; 694 | return -1; 695 | } 696 | 697 | addrlen = sizeof(addr); 698 | #ifdef HAVE_ACCEPT4 699 | /* Inherit socket flags and use accept4 call */ 700 | ctx->s = accept4(*s, (struct sockaddr *)&addr, &addrlen, SOCK_CLOEXEC); 701 | #else 702 | ctx->s = accept(*s, (struct sockaddr *)&addr, &addrlen); 703 | #endif 704 | if (ctx->s == -1) { 705 | close(*s); 706 | *s = -1; 707 | } 708 | 709 | if (ctx->debug) { 710 | printf("The client connection is accepted.\n"); 711 | } 712 | 713 | return ctx->s; 714 | } 715 | 716 | static int _modbus_tcp_select(modbus_t *ctx, fd_set *rset, struct timeval *tv, int length_to_read) 717 | { 718 | int s_rc; 719 | while ((s_rc = select(ctx->s+1, rset, NULL, NULL, tv)) == -1) { 720 | if (errno == EINTR) { 721 | if (ctx->debug) { 722 | fprintf(stderr, "A non blocked signal was caught\n"); 723 | } 724 | /* Necessary after an error */ 725 | FD_ZERO(rset); 726 | FD_SET(ctx->s, rset); 727 | } else { 728 | return -1; 729 | } 730 | } 731 | 732 | if (s_rc == 0) { 733 | errno = ETIMEDOUT; 734 | return -1; 735 | } 736 | 737 | return s_rc; 738 | } 739 | 740 | static void _modbus_tcp_free(modbus_t *ctx) { 741 | free(ctx->backend_data); 742 | free(ctx); 743 | } 744 | 745 | const modbus_backend_t _modbus_tcp_backend = { 746 | _MODBUS_BACKEND_TYPE_TCP, 747 | _MODBUS_TCP_HEADER_LENGTH, 748 | _MODBUS_TCP_CHECKSUM_LENGTH, 749 | MODBUS_TCP_MAX_ADU_LENGTH, 750 | _modbus_set_slave, 751 | _modbus_tcp_build_request_basis, 752 | _modbus_tcp_build_response_basis, 753 | _modbus_tcp_prepare_response_tid, 754 | _modbus_tcp_send_msg_pre, 755 | _modbus_tcp_send, 756 | _modbus_tcp_receive, 757 | _modbus_tcp_recv, 758 | _modbus_tcp_check_integrity, 759 | _modbus_tcp_pre_check_confirmation, 760 | _modbus_tcp_connect, 761 | _modbus_tcp_close, 762 | _modbus_tcp_flush, 763 | _modbus_tcp_select, 764 | _modbus_tcp_free 765 | }; 766 | 767 | 768 | const modbus_backend_t _modbus_tcp_pi_backend = { 769 | _MODBUS_BACKEND_TYPE_TCP, 770 | _MODBUS_TCP_HEADER_LENGTH, 771 | _MODBUS_TCP_CHECKSUM_LENGTH, 772 | MODBUS_TCP_MAX_ADU_LENGTH, 773 | _modbus_set_slave, 774 | _modbus_tcp_build_request_basis, 775 | _modbus_tcp_build_response_basis, 776 | _modbus_tcp_prepare_response_tid, 777 | _modbus_tcp_send_msg_pre, 778 | _modbus_tcp_send, 779 | _modbus_tcp_receive, 780 | _modbus_tcp_recv, 781 | _modbus_tcp_check_integrity, 782 | _modbus_tcp_pre_check_confirmation, 783 | _modbus_tcp_pi_connect, 784 | _modbus_tcp_close, 785 | _modbus_tcp_flush, 786 | _modbus_tcp_select, 787 | _modbus_tcp_free 788 | }; 789 | 790 | modbus_t* modbus_new_tcp(const char *ip, int port) 791 | { 792 | modbus_t *ctx; 793 | modbus_tcp_t *ctx_tcp; 794 | size_t dest_size; 795 | size_t ret_size; 796 | 797 | #if defined(OS_BSD) 798 | /* MSG_NOSIGNAL is unsupported on *BSD so we install an ignore 799 | handler for SIGPIPE. */ 800 | struct sigaction sa; 801 | 802 | sa.sa_handler = SIG_IGN; 803 | if (sigaction(SIGPIPE, &sa, NULL) < 0) { 804 | /* The debug flag can't be set here... */ 805 | fprintf(stderr, "Coud not install SIGPIPE handler.\n"); 806 | return NULL; 807 | } 808 | #endif 809 | 810 | ctx = (modbus_t *) malloc(sizeof(modbus_t)); 811 | _modbus_init_common(ctx); 812 | 813 | /* Could be changed after to reach a remote serial Modbus device */ 814 | ctx->slave = MODBUS_TCP_SLAVE; 815 | 816 | ctx->backend = &(_modbus_tcp_backend); 817 | 818 | ctx->backend_data = (modbus_tcp_t *) malloc(sizeof(modbus_tcp_t)); 819 | ctx_tcp = (modbus_tcp_t *)ctx->backend_data; 820 | 821 | if (ip != NULL) { 822 | dest_size = sizeof(char) * 16; 823 | ret_size = strlcpy(ctx_tcp->ip, ip, dest_size); 824 | if (ret_size == 0) { 825 | fprintf(stderr, "The IP string is empty\n"); 826 | modbus_free(ctx); 827 | errno = EINVAL; 828 | return NULL; 829 | } 830 | 831 | if (ret_size >= dest_size) { 832 | fprintf(stderr, "The IP string has been truncated\n"); 833 | modbus_free(ctx); 834 | errno = EINVAL; 835 | return NULL; 836 | } 837 | } else { 838 | ctx_tcp->ip[0] = '0'; 839 | } 840 | ctx_tcp->port = port; 841 | ctx_tcp->t_id = 0; 842 | 843 | return ctx; 844 | } 845 | 846 | 847 | modbus_t* modbus_new_tcp_pi(const char *node, const char *service) 848 | { 849 | modbus_t *ctx; 850 | modbus_tcp_pi_t *ctx_tcp_pi; 851 | size_t dest_size; 852 | size_t ret_size; 853 | 854 | ctx = (modbus_t *) malloc(sizeof(modbus_t)); 855 | _modbus_init_common(ctx); 856 | 857 | /* Could be changed after to reach a remote serial Modbus device */ 858 | ctx->slave = MODBUS_TCP_SLAVE; 859 | 860 | ctx->backend = &(_modbus_tcp_pi_backend); 861 | 862 | ctx->backend_data = (modbus_tcp_pi_t *) malloc(sizeof(modbus_tcp_pi_t)); 863 | ctx_tcp_pi = (modbus_tcp_pi_t *)ctx->backend_data; 864 | 865 | if (node == NULL) { 866 | /* The node argument can be empty to indicate any hosts */ 867 | ctx_tcp_pi->node[0] = '0'; 868 | } else { 869 | dest_size = sizeof(char) * _MODBUS_TCP_PI_NODE_LENGTH; 870 | ret_size = strlcpy(ctx_tcp_pi->node, node, dest_size); 871 | if (ret_size == 0) { 872 | fprintf(stderr, "The node string is empty\n"); 873 | modbus_free(ctx); 874 | errno = EINVAL; 875 | return NULL; 876 | } 877 | 878 | if (ret_size >= dest_size) { 879 | fprintf(stderr, "The node string has been truncated\n"); 880 | modbus_free(ctx); 881 | errno = EINVAL; 882 | return NULL; 883 | } 884 | } 885 | 886 | if (service != NULL) { 887 | dest_size = sizeof(char) * _MODBUS_TCP_PI_SERVICE_LENGTH; 888 | ret_size = strlcpy(ctx_tcp_pi->service, service, dest_size); 889 | } else { 890 | /* Empty service is not allowed, error catched below. */ 891 | ret_size = 0; 892 | } 893 | 894 | if (ret_size == 0) { 895 | fprintf(stderr, "The service string is empty\n"); 896 | modbus_free(ctx); 897 | errno = EINVAL; 898 | return NULL; 899 | } 900 | 901 | if (ret_size >= dest_size) { 902 | fprintf(stderr, "The service string has been truncated\n"); 903 | modbus_free(ctx); 904 | errno = EINVAL; 905 | return NULL; 906 | } 907 | 908 | ctx_tcp_pi->t_id = 0; 909 | 910 | return ctx; 911 | } 912 | -------------------------------------------------------------------------------- /ModbusSlave_Poll/3rdparty/libmodbus/src/modbus-tcp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2001-2010 Stéphane Raimbault 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library 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 GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #ifndef MODBUS_TCP_H 20 | #define MODBUS_TCP_H 21 | 22 | #include "modbus.h" 23 | 24 | MODBUS_BEGIN_DECLS 25 | 26 | #if defined(_WIN32) && !defined(__CYGWIN__) 27 | /* Win32 with MinGW, supplement to */ 28 | #include 29 | #if !defined(ECONNRESET) 30 | #define ECONNRESET WSAECONNRESET 31 | #endif 32 | #if !defined(ECONNREFUSED) 33 | #define ECONNREFUSED WSAECONNREFUSED 34 | #endif 35 | #if !defined(ETIMEDOUT) 36 | #define ETIMEDOUT WSAETIMEDOUT 37 | #endif 38 | #if !defined(ENOPROTOOPT) 39 | #define ENOPROTOOPT WSAENOPROTOOPT 40 | #endif 41 | #if !defined(EINPROGRESS) 42 | #define EINPROGRESS WSAEINPROGRESS 43 | #endif 44 | #endif 45 | 46 | #define MODBUS_TCP_DEFAULT_PORT 502 47 | #define MODBUS_TCP_SLAVE 0xFF 48 | 49 | /* Modbus_Application_Protocol_V1_1b.pdf Chapter 4 Section 1 Page 5 50 | * TCP MODBUS ADU = 253 bytes + MBAP (7 bytes) = 260 bytes 51 | */ 52 | #define MODBUS_TCP_MAX_ADU_LENGTH 260 53 | 54 | MODBUS_API modbus_t* modbus_new_tcp(const char *ip_address, int port); 55 | MODBUS_API int modbus_tcp_listen(modbus_t *ctx, int nb_connection); 56 | MODBUS_API int modbus_tcp_accept(modbus_t *ctx, int *s); 57 | 58 | MODBUS_API modbus_t* modbus_new_tcp_pi(const char *node, const char *service); 59 | MODBUS_API int modbus_tcp_pi_listen(modbus_t *ctx, int nb_connection); 60 | MODBUS_API int modbus_tcp_pi_accept(modbus_t *ctx, int *s); 61 | 62 | MODBUS_END_DECLS 63 | 64 | #endif /* MODBUS_TCP_H */ 65 | -------------------------------------------------------------------------------- /ModbusSlave_Poll/3rdparty/libmodbus/src/modbus-version.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2010 Stéphane Raimbault 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 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 Lesser Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef MODBUS_VERSION_H 19 | #define MODBUS_VERSION_H 20 | 21 | /* The major version, (1, if %LIBMODBUS_VERSION is 1.2.3) */ 22 | #define LIBMODBUS_VERSION_MAJOR (3) 23 | 24 | /* The minor version (2, if %LIBMODBUS_VERSION is 1.2.3) */ 25 | #define LIBMODBUS_VERSION_MINOR (1) 26 | 27 | /* The micro version (3, if %LIBMODBUS_VERSION is 1.2.3) */ 28 | #define LIBMODBUS_VERSION_MICRO (1) 29 | 30 | /* The full version, like 1.2.3 */ 31 | #define LIBMODBUS_VERSION 3.1.1 32 | 33 | /* The full version, in string form (suited for string concatenation) 34 | */ 35 | #define LIBMODBUS_VERSION_STRING "3.1.1" 36 | 37 | /* Numerically encoded version, like 0x010203 */ 38 | #define LIBMODBUS_VERSION_HEX ((LIBMODBUS_VERSION_MAJOR << 24) | \ 39 | (LIBMODBUS_VERSION_MINOR << 16) | \ 40 | (LIBMODBUS_VERSION_MICRO << 8)) 41 | 42 | /* Evaluates to True if the version is greater than @major, @minor and @micro 43 | */ 44 | #define LIBMODBUS_VERSION_CHECK(major,minor,micro) \ 45 | (LIBMODBUS_VERSION_MAJOR > (major) || \ 46 | (LIBMODBUS_VERSION_MAJOR == (major) && \ 47 | LIBMODBUS_VERSION_MINOR > (minor)) || \ 48 | (LIBMODBUS_VERSION_MAJOR == (major) && \ 49 | LIBMODBUS_VERSION_MINOR == (minor) && \ 50 | LIBMODBUS_VERSION_MICRO >= (micro))) 51 | 52 | #endif /* MODBUS_VERSION_H */ 53 | -------------------------------------------------------------------------------- /ModbusSlave_Poll/3rdparty/libmodbus/src/modbus-version.h.in: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2010 Stéphane Raimbault 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 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 Lesser Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | #ifndef MODBUS_VERSION_H 19 | #define MODBUS_VERSION_H 20 | 21 | /* The major version, (1, if %LIBMODBUS_VERSION is 1.2.3) */ 22 | #define LIBMODBUS_VERSION_MAJOR (@LIBMODBUS_VERSION_MAJOR@) 23 | 24 | /* The minor version (2, if %LIBMODBUS_VERSION is 1.2.3) */ 25 | #define LIBMODBUS_VERSION_MINOR (@LIBMODBUS_VERSION_MINOR@) 26 | 27 | /* The micro version (3, if %LIBMODBUS_VERSION is 1.2.3) */ 28 | #define LIBMODBUS_VERSION_MICRO (@LIBMODBUS_VERSION_MICRO@) 29 | 30 | /* The full version, like 1.2.3 */ 31 | #define LIBMODBUS_VERSION @LIBMODBUS_VERSION@ 32 | 33 | /* The full version, in string form (suited for string concatenation) 34 | */ 35 | #define LIBMODBUS_VERSION_STRING "@LIBMODBUS_VERSION@" 36 | 37 | /* Numerically encoded version, like 0x010203 */ 38 | #define LIBMODBUS_VERSION_HEX ((LIBMODBUS_VERSION_MAJOR << 24) | \ 39 | (LIBMODBUS_VERSION_MINOR << 16) | \ 40 | (LIBMODBUS_VERSION_MICRO << 8)) 41 | 42 | /* Evaluates to True if the version is greater than @major, @minor and @micro 43 | */ 44 | #define LIBMODBUS_VERSION_CHECK(major,minor,micro) \ 45 | (LIBMODBUS_VERSION_MAJOR > (major) || \ 46 | (LIBMODBUS_VERSION_MAJOR == (major) && \ 47 | LIBMODBUS_VERSION_MINOR > (minor)) || \ 48 | (LIBMODBUS_VERSION_MAJOR == (major) && \ 49 | LIBMODBUS_VERSION_MINOR == (minor) && \ 50 | LIBMODBUS_VERSION_MICRO >= (micro))) 51 | 52 | #endif /* MODBUS_VERSION_H */ 53 | -------------------------------------------------------------------------------- /ModbusSlave_Poll/3rdparty/libmodbus/src/modbus.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2001-2013 Stéphane Raimbault 3 | * 4 | * This library is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU Lesser General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2.1 of the License, or (at your option) any later version. 8 | * 9 | * This library 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 GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public 15 | * License along with this library; if not, write to the Free Software 16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #ifndef MODBUS_H 20 | #define MODBUS_H 21 | 22 | /* Add this for macros that defined unix flavor */ 23 | #if (defined(__unix__) || defined(unix)) && !defined(USG) 24 | #include 25 | #endif 26 | 27 | #ifndef _MSC_VER 28 | #include 29 | #else 30 | #include "stdint.h" 31 | #endif 32 | 33 | #include "modbus-version.h" 34 | 35 | #if defined(_MSC_VER) 36 | # if defined(DLLBUILD) 37 | /* define DLLBUILD when building the DLL */ 38 | # define MODBUS_API __declspec(dllexport) 39 | # else 40 | # define MODBUS_API __declspec(dllimport) 41 | # endif 42 | #else 43 | # define MODBUS_API 44 | #endif 45 | 46 | #ifdef __cplusplus 47 | # define MODBUS_BEGIN_DECLS extern "C" { 48 | # define MODBUS_END_DECLS } 49 | #else 50 | # define MODBUS_BEGIN_DECLS 51 | # define MODBUS_END_DECLS 52 | #endif 53 | 54 | MODBUS_BEGIN_DECLS 55 | 56 | #ifndef FALSE 57 | #define FALSE 0 58 | #endif 59 | 60 | #ifndef TRUE 61 | #define TRUE 1 62 | #endif 63 | 64 | #ifndef OFF 65 | #define OFF 0 66 | #endif 67 | 68 | #ifndef ON 69 | #define ON 1 70 | #endif 71 | 72 | /* Modbus function codes */ 73 | #define MODBUS_FC_READ_COILS 0x01 74 | #define MODBUS_FC_READ_DISCRETE_INPUTS 0x02 75 | #define MODBUS_FC_READ_HOLDING_REGISTERS 0x03 76 | #define MODBUS_FC_READ_INPUT_REGISTERS 0x04 77 | #define MODBUS_FC_WRITE_SINGLE_COIL 0x05 78 | #define MODBUS_FC_WRITE_SINGLE_REGISTER 0x06 79 | #define MODBUS_FC_READ_EXCEPTION_STATUS 0x07 80 | #define MODBUS_FC_WRITE_MULTIPLE_COILS 0x0F 81 | #define MODBUS_FC_WRITE_MULTIPLE_REGISTERS 0x10 82 | #define MODBUS_FC_REPORT_SLAVE_ID 0x11 83 | #define MODBUS_FC_MASK_WRITE_REGISTER 0x16 84 | #define MODBUS_FC_WRITE_AND_READ_REGISTERS 0x17 85 | 86 | #define MODBUS_BROADCAST_ADDRESS 0 87 | 88 | /* Modbus_Application_Protocol_V1_1b.pdf (chapter 6 section 1 page 12) 89 | * Quantity of Coils to read (2 bytes): 1 to 2000 (0x7D0) 90 | * (chapter 6 section 11 page 29) 91 | * Quantity of Coils to write (2 bytes): 1 to 1968 (0x7B0) 92 | */ 93 | #define MODBUS_MAX_READ_BITS 2000 94 | #define MODBUS_MAX_WRITE_BITS 1968 95 | 96 | /* Modbus_Application_Protocol_V1_1b.pdf (chapter 6 section 3 page 15) 97 | * Quantity of Registers to read (2 bytes): 1 to 125 (0x7D) 98 | * (chapter 6 section 12 page 31) 99 | * Quantity of Registers to write (2 bytes) 1 to 123 (0x7B) 100 | * (chapter 6 section 17 page 38) 101 | * Quantity of Registers to write in R/W registers (2 bytes) 1 to 121 (0x79) 102 | */ 103 | #define MODBUS_MAX_READ_REGISTERS 125 104 | #define MODBUS_MAX_WRITE_REGISTERS 123 105 | #define MODBUS_MAX_WR_WRITE_REGISTERS 121 106 | #define MODBUS_MAX_WR_READ_REGISTERS 125 107 | 108 | /* The size of the MODBUS PDU is limited by the size constraint inherited from 109 | * the first MODBUS implementation on Serial Line network (max. RS485 ADU = 256 110 | * bytes). Therefore, MODBUS PDU for serial line communication = 256 - Server 111 | * address (1 byte) - CRC (2 bytes) = 253 bytes. 112 | * 113 | * Consequently: 114 | * - RS232 / RS485 ADU = 253 bytes + Server address (1 byte) + CRC (2 bytes) = 115 | * 256 bytes. 116 | * - TCP MODBUS ADU = 253 bytes + MBAP (7 bytes) = 260 bytes. 117 | */ 118 | #define MODBUS_MAX_PDU_LENGTH 253 119 | 120 | /* Random number to avoid errno conflicts */ 121 | #define MODBUS_ENOBASE 112345678 122 | 123 | /* Protocol exceptions */ 124 | enum { 125 | MODBUS_EXCEPTION_ILLEGAL_FUNCTION = 0x01, 126 | MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS, 127 | MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE, 128 | MODBUS_EXCEPTION_SLAVE_OR_SERVER_FAILURE, 129 | MODBUS_EXCEPTION_ACKNOWLEDGE, 130 | MODBUS_EXCEPTION_SLAVE_OR_SERVER_BUSY, 131 | MODBUS_EXCEPTION_NEGATIVE_ACKNOWLEDGE, 132 | MODBUS_EXCEPTION_MEMORY_PARITY, 133 | MODBUS_EXCEPTION_NOT_DEFINED, 134 | MODBUS_EXCEPTION_GATEWAY_PATH, 135 | MODBUS_EXCEPTION_GATEWAY_TARGET, 136 | MODBUS_EXCEPTION_MAX 137 | }; 138 | 139 | #define EMBXILFUN (MODBUS_ENOBASE + MODBUS_EXCEPTION_ILLEGAL_FUNCTION) 140 | #define EMBXILADD (MODBUS_ENOBASE + MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS) 141 | #define EMBXILVAL (MODBUS_ENOBASE + MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE) 142 | #define EMBXSFAIL (MODBUS_ENOBASE + MODBUS_EXCEPTION_SLAVE_OR_SERVER_FAILURE) 143 | #define EMBXACK (MODBUS_ENOBASE + MODBUS_EXCEPTION_ACKNOWLEDGE) 144 | #define EMBXSBUSY (MODBUS_ENOBASE + MODBUS_EXCEPTION_SLAVE_OR_SERVER_BUSY) 145 | #define EMBXNACK (MODBUS_ENOBASE + MODBUS_EXCEPTION_NEGATIVE_ACKNOWLEDGE) 146 | #define EMBXMEMPAR (MODBUS_ENOBASE + MODBUS_EXCEPTION_MEMORY_PARITY) 147 | #define EMBXGPATH (MODBUS_ENOBASE + MODBUS_EXCEPTION_GATEWAY_PATH) 148 | #define EMBXGTAR (MODBUS_ENOBASE + MODBUS_EXCEPTION_GATEWAY_TARGET) 149 | 150 | /* Native libmodbus error codes */ 151 | #define EMBBADCRC (EMBXGTAR + 1) 152 | #define EMBBADDATA (EMBXGTAR + 2) 153 | #define EMBBADEXC (EMBXGTAR + 3) 154 | #define EMBUNKEXC (EMBXGTAR + 4) 155 | #define EMBMDATA (EMBXGTAR + 5) 156 | #define EMBBADSLAVE (EMBXGTAR + 6) 157 | 158 | extern const unsigned int libmodbus_version_major; 159 | extern const unsigned int libmodbus_version_minor; 160 | extern const unsigned int libmodbus_version_micro; 161 | 162 | typedef struct _modbus modbus_t; 163 | 164 | typedef struct { 165 | int nb_bits; 166 | int nb_input_bits; 167 | int nb_input_registers; 168 | int nb_registers; 169 | uint8_t *tab_bits; 170 | uint8_t *tab_input_bits; 171 | uint16_t *tab_input_registers; 172 | uint16_t *tab_registers; 173 | } modbus_mapping_t; 174 | 175 | typedef enum 176 | { 177 | MODBUS_ERROR_RECOVERY_NONE = 0, 178 | MODBUS_ERROR_RECOVERY_LINK = (1<<1), 179 | MODBUS_ERROR_RECOVERY_PROTOCOL = (1<<2) 180 | } modbus_error_recovery_mode; 181 | 182 | typedef void (*modbus_monitor_add_item_fnc_t)(modbus_t *ctx, 183 | uint8_t isOut, uint8_t slave, uint8_t func, uint16_t addr, uint16_t nb, 184 | uint16_t expectedCRC, uint16_t actualCRC ); 185 | typedef void (*modbus_monitor_raw_data_fnc_t)(modbus_t *ctx, 186 | uint8_t *data, uint8_t dataLen, uint8_t addNewline,uint8_t); 187 | 188 | MODBUS_API int modbus_set_slave(modbus_t *ctx, int slave); 189 | MODBUS_API int modbus_set_error_recovery(modbus_t *ctx, modbus_error_recovery_mode error_recovery); 190 | MODBUS_API int modbus_set_socket(modbus_t *ctx, int s); 191 | MODBUS_API int modbus_get_socket(modbus_t *ctx); 192 | 193 | MODBUS_API int modbus_get_response_timeout(modbus_t *ctx, uint32_t *to_sec, uint32_t *to_usec); 194 | MODBUS_API int modbus_set_response_timeout(modbus_t *ctx, uint32_t to_sec, uint32_t to_usec); 195 | 196 | MODBUS_API int modbus_get_byte_timeout(modbus_t *ctx, uint32_t *to_sec, uint32_t *to_usec); 197 | MODBUS_API int modbus_set_byte_timeout(modbus_t *ctx, uint32_t to_sec, uint32_t to_usec); 198 | 199 | MODBUS_API int modbus_get_header_length(modbus_t *ctx); 200 | 201 | MODBUS_API int modbus_connect(modbus_t *ctx); 202 | MODBUS_API void modbus_close(modbus_t *ctx); 203 | 204 | MODBUS_API void modbus_free(modbus_t *ctx); 205 | 206 | MODBUS_API int modbus_flush(modbus_t *ctx); 207 | MODBUS_API int modbus_set_debug(modbus_t *ctx, int flag); 208 | 209 | MODBUS_API const char *modbus_strerror(int errnum); 210 | 211 | MODBUS_API int modbus_read_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest); 212 | MODBUS_API int modbus_read_input_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest); 213 | MODBUS_API int modbus_read_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest); 214 | MODBUS_API int modbus_read_input_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest); 215 | MODBUS_API int modbus_write_bit(modbus_t *ctx, int coil_addr, int status); 216 | MODBUS_API int modbus_write_register(modbus_t *ctx, int reg_addr, int value); 217 | MODBUS_API int modbus_write_bits(modbus_t *ctx, int addr, int nb, const uint8_t *data); 218 | MODBUS_API int modbus_write_registers(modbus_t *ctx, int addr, int nb, const uint16_t *data); 219 | MODBUS_API int modbus_mask_write_register(modbus_t *ctx, int addr, uint16_t and_mask, uint16_t or_mask); 220 | MODBUS_API int modbus_write_and_read_registers(modbus_t *ctx, int write_addr, int write_nb, 221 | const uint16_t *src, int read_addr, int read_nb, 222 | uint16_t *dest); 223 | MODBUS_API int modbus_report_slave_id(modbus_t *ctx, int max_dest, uint8_t *dest); 224 | 225 | MODBUS_API modbus_mapping_t* modbus_mapping_new(int nb_bits, int nb_input_bits, 226 | int nb_registers, int nb_input_registers); 227 | MODBUS_API void modbus_mapping_free(modbus_mapping_t *mb_mapping); 228 | 229 | MODBUS_API int modbus_send_raw_request(modbus_t *ctx, uint8_t *raw_req, int raw_req_length); 230 | 231 | MODBUS_API int modbus_receive(modbus_t *ctx, uint8_t *req); 232 | 233 | MODBUS_API int modbus_receive_confirmation(modbus_t *ctx, uint8_t *rsp); 234 | 235 | MODBUS_API int modbus_reply(modbus_t *ctx, const uint8_t *req, 236 | int req_length, modbus_mapping_t *mb_mapping); 237 | MODBUS_API int modbus_reply_exception(modbus_t *ctx, const uint8_t *req, 238 | unsigned int exception_code); 239 | MODBUS_API void modbus_register_monitor_add_item_fnc(modbus_t *ctx, 240 | modbus_monitor_add_item_fnc_t cb); 241 | MODBUS_API void modbus_register_monitor_raw_data_fnc(modbus_t *ctx, 242 | modbus_monitor_raw_data_fnc_t cb); 243 | 244 | void modbus_poll(modbus_t *ctx); 245 | 246 | 247 | /** 248 | * UTILS FUNCTIONS 249 | **/ 250 | 251 | #define MODBUS_GET_HIGH_BYTE(data) (((data) >> 8) & 0xFF) 252 | #define MODBUS_GET_LOW_BYTE(data) ((data) & 0xFF) 253 | #define MODBUS_GET_INT32_FROM_INT16(tab_int16, index) ((tab_int16[(index)] << 16) + tab_int16[(index) + 1]) 254 | #define MODBUS_GET_INT16_FROM_INT8(tab_int8, index) ((tab_int8[(index)] << 8) + tab_int8[(index) + 1]) 255 | #define MODBUS_SET_INT16_TO_INT8(tab_int8, index, value) \ 256 | do { \ 257 | tab_int8[(index)] = (value) >> 8; \ 258 | tab_int8[(index) + 1] = (value) & 0xFF; \ 259 | } while (0) 260 | 261 | MODBUS_API void modbus_set_bits_from_byte(uint8_t *dest, int idx, const uint8_t value); 262 | MODBUS_API void modbus_set_bits_from_bytes(uint8_t *dest, int idx, unsigned int nb_bits, 263 | const uint8_t *tab_byte); 264 | MODBUS_API uint8_t modbus_get_byte_from_bits(const uint8_t *src, int idx, unsigned int nb_bits); 265 | MODBUS_API float modbus_get_float(const uint16_t *src); 266 | MODBUS_API float modbus_get_float_dcba(const uint16_t *src); 267 | MODBUS_API void modbus_set_float(float f, uint16_t *dest); 268 | MODBUS_API void modbus_set_float_dcba(float f, uint16_t *dest); 269 | 270 | #include "modbus-tcp.h" 271 | #include "modbus-rtu.h" 272 | #include "modbus-ascii.h" 273 | 274 | MODBUS_END_DECLS 275 | 276 | #endif /* MODBUS_H */ 277 | -------------------------------------------------------------------------------- /ModbusSlave_Poll/3rdparty/libmodbus/src/win32/Make-tests: -------------------------------------------------------------------------------- 1 | # Windows makefile 2 | # -- 3 | # use mingw make 4 | # Get make-3.82-5-mingw32-bin.tar.lzma from 5 | # http://sourceforge.net/projects/mingw/files/MinGW/Extension/make/make-3.82-mingw32/ 6 | # -- 7 | # Set CC=gcc or CC=cl for the pre-defined compilers 8 | # before using this Makefile 9 | # -- 10 | # Compile and link the bandwidth and random tests. 11 | # Build modbus.dll and the import library before building the tests 12 | # modbus.lib/libmodbus.a (the import library) should be in this directory 13 | # modbus.dll should be in this directory or in path 14 | 15 | INCLUDES:=-I../.. -I.. -I. 16 | 17 | ifeq ($(CC),cl) 18 | DEFS+=-D_CRT_SECURE_NO_DEPRECATE=1 -D_CRT_NONSTDC_NO_DEPRECATE=1 19 | CFLAGS=-Zi -W3 -MT -ID:/include/msvc_std 20 | LDOPTS=-link -incremental:NO 21 | LDLIBS=-Fe$@ ws2_32.lib modbus.lib $(LDOPTS) 22 | RES:=res 23 | RCOUT= 24 | endif 25 | 26 | ifeq ($(CC),gcc) 27 | CFLAGS=-g -Wall -O -static -static-libgcc 28 | LDLIBS=-o$@ -lws2_32 -luser32 -L. -lmodbus 29 | LDOPTS= 30 | RES:=o 31 | RCOUT=-o$@ 32 | endif 33 | 34 | CFLAGS+=-DHAVE_CONFIG_H $(DEFS) $(INCLUDES) 35 | 36 | .SUFFIXES: 37 | .SUFFIXES: .c .rc .$(RES) .$(oo) 38 | 39 | # pattern rule for resources 40 | %.$(RES) : %.rc 41 | $(RC) $< $(RCOUT) 42 | 43 | vpath %.c ../../tests 44 | vpath %.h ../src 45 | 46 | all: random-test-client random-test-server bandwidth-client bandwidth-server-one 47 | 48 | random-test-client: random-test-client.c 49 | $(LINK.c) $^ $(LDLIBS) 50 | 51 | random-test-server: random-test-server.c 52 | $(LINK.c) $^ $(LDLIBS) 53 | 54 | bandwidth-server-one: bandwidth-server-one.c 55 | $(LINK.c) $^ $(LDLIBS) 56 | 57 | bandwidth-client: bandwidth-client.c 58 | $(LINK.c) $^ $(LDLIBS) 59 | 60 | 61 | clean: 62 | -@cmd "/c del /Q /S $(OBJS) *.o *.obj *.exe *.pdb *.ilk *.ncb *.res *.dll *.exp *.lib *.ncb *.a *.map *.asm" > NUL: 2>&1 63 | -------------------------------------------------------------------------------- /ModbusSlave_Poll/3rdparty/libmodbus/src/win32/README.win32: -------------------------------------------------------------------------------- 1 | Intro 2 | ----- 3 | 4 | This directory contains the project file for Visual Studio 2008 to build 5 | modbus.dll and the import library modbus.lib. 6 | 7 | The project file looks for D:/include/msvc_std to find stdint.h. 8 | See ../../README.md file. 9 | 10 | config.h and ../modbus-version.h are generated using configure.js. 11 | 12 | Run 13 | cscript configure.js 14 | or 15 | wscript configure.js 16 | or 17 | double click configure.js to generate these files. 18 | 19 | To get project file for Visual Studio 2005 open copy of file modbus.vcproj in 20 | editor and change attribute `Version` of `VisualStudioProject` tag to "8,00". -------------------------------------------------------------------------------- /ModbusSlave_Poll/3rdparty/libmodbus/src/win32/config.h.win32: -------------------------------------------------------------------------------- 1 | /* config.h. Generated from config.h.in by configure. */ 2 | /* config.h.in. Generated from configure.ac by autoheader. */ 3 | 4 | /* Define to 1 if you have the header file. */ 5 | /* #undef HAVE_ARPA_INET_H */ 6 | 7 | /* Define to 1 if you have the declaration of `TIOCSRS485', and to 0 if you 8 | don't. */ 9 | /* #undef HAVE_DECL_TIOCSRS485 */ 10 | 11 | /* Define to 1 if you have the declaration of `__CYGWIN__', and to 0 if you 12 | don't. */ 13 | /* #undef HAVE_DECL___CYGWIN__ */ 14 | 15 | /* Define to 1 if you have the header file. */ 16 | /* #undef HAVE_DLFCN_H */ 17 | 18 | /* Define to 1 if you have the header file. */ 19 | #define HAVE_ERRNO_H 1 20 | 21 | /* Define to 1 if you have the header file. */ 22 | #define HAVE_FCNTL_H 1 23 | 24 | /* Define to 1 if you have the `fork' function. */ 25 | /* #undef HAVE_FORK */ 26 | 27 | /* Define to 1 if you have the `getaddrinfo' function. */ 28 | /* #undef HAVE_GETADDRINFO */ 29 | 30 | /* Define to 1 if you have the `gettimeofday' function. */ 31 | /* #undef HAVE_GETTIMEOFDAY */ 32 | 33 | /* Define to 1 if you have the `inet_ntoa' function. */ 34 | /* #undef HAVE_INET_NTOA */ 35 | 36 | /* Define to 1 if you have the header file. */ 37 | #define HAVE_INTTYPES_H 1 38 | 39 | /* Define to 1 if you have the header file. */ 40 | #define HAVE_LIMITS_H 1 41 | 42 | /* Define to 1 if you have the header file. */ 43 | /* #undef HAVE_LINUX_SERIAL_H */ 44 | 45 | /* Define to 1 if you have the header file. */ 46 | #define HAVE_MEMORY_H 1 47 | 48 | /* Define to 1 if you have the `memset' function. */ 49 | #define HAVE_MEMSET 1 50 | 51 | /* Define to 1 if you have the header file. */ 52 | /* #undef HAVE_NETDB_H */ 53 | 54 | /* Define to 1 if you have the header file. */ 55 | /* #undef HAVE_NETINET_IN_H */ 56 | 57 | /* Define to 1 if you have the header file. */ 58 | /* #undef HAVE_NETINET_TCP_H */ 59 | 60 | /* Define to 1 if you have the `select' function. */ 61 | /* #undef HAVE_SELECT */ 62 | 63 | /* Define to 1 if you have the `socket' function. */ 64 | /* #undef HAVE_SOCKET */ 65 | 66 | /* Define to 1 if you have the header file. */ 67 | #define HAVE_STDINT_H 1 68 | 69 | /* Define to 1 if you have the header file. */ 70 | #define HAVE_STDLIB_H 1 71 | 72 | /* Define to 1 if you have the `strerror' function. */ 73 | #define HAVE_STRERROR 1 74 | 75 | /* Define to 1 if you have the header file. */ 76 | /* #undef HAVE_STRINGS_H */ 77 | 78 | /* Define to 1 if you have the header file. */ 79 | #define HAVE_STRING_H 1 80 | 81 | /* Define to 1 if you have the `strlcpy' function. */ 82 | /* #undef HAVE_STRLCPY */ 83 | 84 | /* Define to 1 if you have the header file. */ 85 | /* #undef HAVE_SYS_IOCTL_H */ 86 | 87 | /* Define to 1 if you have the header file. */ 88 | /* #undef HAVE_SYS_SOCKET_H */ 89 | 90 | /* Define to 1 if you have the header file. */ 91 | #define HAVE_SYS_STAT_H 1 92 | 93 | /* Define to 1 if you have the header file. */ 94 | /* #undef HAVE_SYS_TIME_H */ 95 | 96 | /* Define to 1 if you have the header file. */ 97 | #define HAVE_SYS_TYPES_H 1 98 | 99 | /* Define to 1 if you have the header file. */ 100 | /* #undef HAVE_TERMIOS_H */ 101 | 102 | /* Define to 1 if you have the header file. */ 103 | #define HAVE_TIME_H 1 104 | 105 | /* Define to 1 if you have the header file. */ 106 | /* #undef HAVE_UNISTD_H */ 107 | 108 | /* Define to 1 if you have the `vfork' function. */ 109 | /* #undef HAVE_VFORK */ 110 | 111 | /* Define to 1 if you have the header file. */ 112 | /* #undef HAVE_VFORK_H */ 113 | 114 | /* Define to 1 if you have the header file. */ 115 | #define HAVE_WINSOCK2_H 1 116 | 117 | /* Define to 1 if `fork' works. */ 118 | /* #undef HAVE_WORKING_FORK */ 119 | 120 | /* Define to 1 if `vfork' works. */ 121 | /* #undef HAVE_WORKING_VFORK */ 122 | 123 | /* Define to the sub-directory in which libtool stores uninstalled libraries. 124 | */ 125 | /* #undef LT_OBJDIR */ 126 | 127 | /* Name of package */ 128 | #define PACKAGE "libmodbus" 129 | 130 | /* Define to the address where bug reports for this package should be sent. */ 131 | #define PACKAGE_BUGREPORT "https://github.com/stephane/libmodbus/issues" 132 | 133 | /* Define to the full name of this package. */ 134 | #define PACKAGE_NAME "libmodbus" 135 | 136 | /* Define to the full name and version of this package. */ 137 | #define PACKAGE_STRING "libmodbus @LIBMODBUS_VERSION@" 138 | 139 | /* Define to the one symbol short name of this package. */ 140 | #define PACKAGE_TARNAME "libmodbus" 141 | 142 | /* Define to the home page for this package. */ 143 | #define PACKAGE_URL "" 144 | 145 | /* Define to the version of this package. */ 146 | #define PACKAGE_VERSION "@LIBMODBUS_VERSION@" 147 | 148 | /* Define to 1 if you have the ANSI C header files. */ 149 | #define STDC_HEADERS 1 150 | 151 | /* Define to 1 if you can safely include both and . */ 152 | /* #undef TIME_WITH_SYS_TIME */ 153 | 154 | /* Version number of package */ 155 | #define VERSION "@LIBMODBUS_VERSION@" 156 | 157 | /* Define to empty if `const' does not conform to ANSI C. */ 158 | /* #undef const */ 159 | 160 | /* Define to `int' if does not define. */ 161 | /* #undef pid_t */ 162 | 163 | /* Define to `unsigned int' if does not define. */ 164 | /* #undef size_t */ 165 | 166 | /* Define as `fork' if `vfork' does not work. */ 167 | #define vfork fork 168 | -------------------------------------------------------------------------------- /ModbusSlave_Poll/3rdparty/libmodbus/src/win32/configure.js: -------------------------------------------------------------------------------- 1 | /* Configure script for modbus.dll, specific for Windows with Scripting Host. 2 | * 3 | * Inspired by configure.js from libxml2 4 | * 5 | * oldfaber < oldfaber _at_ gmail _dot_ com > 6 | * 7 | */ 8 | 9 | /* The source directory, relative to the one where this file resides. */ 10 | var srcDir = ".."; 11 | /* Base name of what we are building. */ 12 | var baseName = "modbus"; 13 | /* Configure file template and output file */ 14 | var configFile = srcDir + "\\..\\configure.ac"; 15 | /* Input and output files for the modbus-version.h include */ 16 | var newfile; 17 | /* Version strings for the binary distribution. Will be filled later in the code. */ 18 | var verMajor; 19 | var verMinor; 20 | var verMicro; 21 | /* modbus features. */ 22 | var dryRun = false; 23 | /* Win32 build options. NOT used yet */ 24 | var compiler = "msvc"; 25 | /* Local stuff */ 26 | var error = 0; 27 | /* Filename */ 28 | var newFile; 29 | 30 | /* Displays the details about how to use this script. */ 31 | function usage() { 32 | var txt; 33 | 34 | txt = "Usage:\n"; 35 | txt += " cscript " + WScript.ScriptName + " \n"; 36 | txt += " cscript " + WScript.ScriptName + " help\n\n"; 37 | txt += "Options can be specified in the form