Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,23 @@ if test "x$with_libusb" != "xno"; then
LIBUSB_LIBS="-lusb-1.0"
AC_DEFINE(HAVE_LIBUSB, 1, [defined if libusb is available])
have_libusb=yes

AC_MSG_CHECKING([for libusb pollfd accessibility])
AC_LANG_PUSH([C])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
#include <libusb-1.0/libusb.h>
],[
libusb_context *ctx = NULL;
const struct libusb_pollfd** list = libusb_get_pollfds(ctx);
/* Do not care about actual return value in this test,
* normally check for non-zero meaning to look in errno */
]
)],
[AC_DEFINE(HAVE_LIBUSB_POLLFD, 1, [defined if libusb pollfd is available])
AC_MSG_RESULT([ok])
],
[AC_MSG_RESULT([no])]
)
], [
AC_MSG_ERROR(["libusb-1.0 not found. Please install libusb-1.0."])
])
Expand Down
30 changes: 29 additions & 1 deletion src/modbus-rtu-usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -546,7 +546,35 @@ static int _modbus_rtu_usb_connect(modbus_t *ctx)
}

ctx_rtu_usb->device_handle = dev_handle;

#if defined HAVE_LIBUSB_POLLFD && HAVE_LIBUSB_POLLFD
if (usb_ctx) {
const struct libusb_pollfd** pollfds = libusb_get_pollfds(usb_ctx);
if (pollfds) {
unsigned j;
for (j=0; pollfds[j] != NULL; j++) {}
if (ctx->debug) {
printf("Got a list of %u libusb file descriptors to poll\n", j);
}
/* FIXME: We might get more than one FD here.
* Some research is needed to check if they
* all should be polled. In that case maybe
* libmodbus should move from single ctx->s
* to an array of file descriptors/sockets.
*/
if (j == 1) {
ctx->s = pollfds[0]->fd;
}
} else if (ctx->debug) {
printf("Got no list of libusb file descriptors to poll\n");
}
} else if (ctx->debug) {
printf("Got no libusb context to query for file descriptors to poll\n");
}
#else
if (ctx->debug) {
printf("Can not get a list of libusb file descriptors to poll from this libusb version\n");
}
#endif /* HAVE_LIBUSB_POLLFD */
break;
}

Expand Down
16 changes: 14 additions & 2 deletions src/modbus.c
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,14 @@ int _modbus_receive_msg(modbus_t *ctx, uint8_t *msg, msg_type_t msg_type)

/* Add a file descriptor to the set */
FD_ZERO(&rset);
FD_SET(ctx->s, &rset);
if (ctx->s < 0) {
if (ctx->debug) {
/* we may not have an FD with e.g. libusb usage */
fprintf(stderr, "Using a backend without a file descriptor, will not select() on it.\n");
}
} else {
FD_SET(ctx->s, &rset);
}

/* We need to analyse the message step by step. At the first step, we want
* to reach the function code because all packets contain this
Expand Down Expand Up @@ -430,7 +437,12 @@ int _modbus_receive_msg(modbus_t *ctx, uint8_t *msg, msg_type_t msg_type)
errno = saved_errno;
#endif
}
return -1;
if (ctx->s >= 0) {
return -1;
}
// else: We have at most tried some default FD's but not
// the (lacking) one for the backend, so fall through for
// its recv method anyway (e.g. query libusb directly).
}

rc = ctx->backend->recv(ctx, msg + msg_length, length_to_read);
Expand Down