From: Gerhard Sittig Date: Sun, 26 Mar 2017 14:48:36 +0000 (+0100) Subject: serial: prepare serial over HID in common layer and build support X-Git-Url: https://sigrok.org/gitaction?a=commitdiff_plain;h=4417074c68ce998c2d666fc8a034204a1b74fc2f;p=libsigrok.git serial: prepare serial over HID in common layer and build support Search for the optional HIDAPI library. Call the library's init and exit routine, and print version information. Extend the common serial layer's code paths for open, list, and find USB to also support serial over HID. This commit prepares serial over HID, but the HIDAPI specific transport for serial communication still is empty in this implementation. --- diff --git a/Makefile.am b/Makefile.am index 9dbe3e43..130d84d6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -119,6 +119,7 @@ endif if NEED_SERIAL libsigrok_la_SOURCES += \ src/serial.c \ + src/serial_hid.c \ src/serial_libsp.c \ src/scpi/scpi_serial.c endif diff --git a/README b/README index 154c4928..a902e665 100644 --- a/README +++ b/README @@ -41,6 +41,7 @@ Requirements for the C library: - libserialport >= 0.1.1 (optional, used by some drivers) - librevisa >= 0.0.20130412 (optional, used by some drivers) - libusb-1.0 >= 1.0.16 (optional, used by some drivers) + - hidapi >= 0.8.0 (optional, used for some HID based "serial cables") - libftdi1 >= 1.0 (optional, used by some drivers) - libgpib (optional, used by some drivers) - libieee1284 (optional, used by some drivers) diff --git a/configure.ac b/configure.ac index 6b9a1a66..1d146283 100644 --- a/configure.ac +++ b/configure.ac @@ -101,6 +101,9 @@ SR_ARG_OPT_PKG([libserialport], [LIBSERIALPORT], , SR_ARG_OPT_PKG([libftdi], [LIBFTDI], , [libftdi1 >= 1.0]) +SR_ARG_OPT_PKG([libhidapi], [LIBHIDAPI], , + [hidapi >= 0.8.0], [hidapi-hidraw >= 0.8.0], [hidapi-libusb >= 0.8.0]) + # FreeBSD comes with an "integrated" libusb-1.0-style USB API. # This means libusb-1.0 is always available; no need to check for it. # On Windows, require the latest version we can get our hands on, @@ -130,7 +133,7 @@ SR_ARG_OPT_CHECK([libieee1284], [LIBIEEE1284],, [ AS_IF([test "x$sr_have_libieee1284" = xyes], [SR_PREPEND([SR_EXTRA_LIBS], [-lieee1284])]) -AS_IF([test "x$sr_have_libserialport" = xyes], +AS_IF([test "x$sr_have_libserialport" = xyes -o "x$sr_have_libhidapi" = xyes], sr_have_serial_comm=yes, sr_have_serial_comm=no) AS_IF([test "x$sr_have_serial_comm" = xyes], [AC_DEFINE([HAVE_SERIAL_COMM], [1], [Specifies whether serial communication is supported.])]) @@ -612,6 +615,7 @@ $sr_driver_summary Enabled serial communication transports: - serial comm ................... $sr_have_serial_comm - libserialport ................. $sr_have_libserialport + - hidapi ........................ $sr_have_libhidapi Enabled SCPI backends: - TCP............................. yes diff --git a/src/backend.c b/src/backend.c index a5d5749b..3e488ca7 100644 --- a/src/backend.c +++ b/src/backend.c @@ -164,6 +164,11 @@ SR_API GSList *sr_buildinfo_libs_get(void) #endif l = g_slist_append(l, m); #endif +#ifdef HAVE_LIBHIDAPI + m = g_slist_append(NULL, g_strdup("hidapi")); + m = g_slist_append(m, g_strdup_printf("%s", CONF_LIBHIDAPI_VERSION)); + l = g_slist_append(l, m); +#endif #ifdef HAVE_LIBFTDI m = g_slist_append(NULL, g_strdup("libftdi")); m = g_slist_append(m, g_strdup_printf("%s", CONF_LIBFTDI_VERSION)); @@ -591,6 +596,20 @@ SR_API int sr_init(struct sr_context **ctx) ret = SR_ERR; goto done; } +#endif +#ifdef HAVE_LIBHIDAPI + /* + * According to , the hid_init() routine just returns + * zero or non-zero, and hid_error() appears to relate to calls + * for a specific device after hid_open(). Which means that there + * is no more detailled information available beyond success/fail + * at this point in time. + */ + if (hid_init() != 0) { + sr_err("HIDAPI hid_init() failed."); + ret = SR_ERR; + goto done; + } #endif sr_resource_set_hooks(context, NULL, NULL, NULL, NULL); @@ -626,6 +645,9 @@ SR_API int sr_exit(struct sr_context *ctx) WSACleanup(); #endif +#ifdef HAVE_LIBHIDAPI + hid_exit(); +#endif #ifdef HAVE_LIBUSB_1_0 libusb_exit(ctx->libusb_ctx); #endif diff --git a/src/libsigrok-internal.h b/src/libsigrok-internal.h index e1623f62..48e89acd 100644 --- a/src/libsigrok-internal.h +++ b/src/libsigrok-internal.h @@ -29,6 +29,9 @@ #include "config.h" #include +#ifdef HAVE_LIBHIDAPI +#include +#endif #ifdef HAVE_LIBSERIALPORT #include #endif @@ -744,6 +747,10 @@ struct sr_serial_dev_inst { /** libserialport port handle */ struct sp_port *sp_data; #endif +#ifdef HAVE_LIBHIDAPI + /* TODO */ + hid_device *hid_dev; +#endif }; #endif @@ -1177,6 +1184,8 @@ struct ser_lib_functions { size_t (*get_rx_avail)(struct sr_serial_dev_inst *serial); }; extern SR_PRIV struct ser_lib_functions *ser_lib_funcs_libsp; +SR_PRIV int ser_name_is_hid(struct sr_serial_dev_inst *serial); +extern SR_PRIV struct ser_lib_functions *ser_lib_funcs_hid; #endif /*--- ezusb.c ---------------------------------------------------------------*/ diff --git a/src/serial.c b/src/serial.c index b1e21eec..acee0dca 100644 --- a/src/serial.c +++ b/src/serial.c @@ -91,8 +91,15 @@ SR_PRIV int serial_open(struct sr_serial_dev_inst *serial, int flags) sr_spew("Opening serial port '%s' (flags %d).", serial->port, flags); - /* Default to the libserialport transport layer. */ - serial->lib_funcs = ser_lib_funcs_libsp; + /* + * Determine which serial transport library to use. Derive the + * variant from the serial port's name. Default to libserialport + * for backwards compatibility. + */ + if (ser_name_is_hid(serial)) + serial->lib_funcs = ser_lib_funcs_hid; + else + serial->lib_funcs = ser_lib_funcs_libsp; if (!serial->lib_funcs) return SR_ERR_NA; @@ -930,6 +937,10 @@ SR_API GSList *sr_serial_list(const struct sr_dev_driver *driver) list_func = ser_lib_funcs_libsp->list; tty_devs = list_func(tty_devs, append_port_list); } + if (ser_lib_funcs_hid && ser_lib_funcs_hid->list) { + list_func = ser_lib_funcs_hid->list; + tty_devs = list_func(tty_devs, append_port_list); + } return tty_devs; } @@ -966,6 +977,11 @@ SR_PRIV GSList *sr_serial_find_usb(uint16_t vendor_id, uint16_t product_id) tty_devs = find_func(tty_devs, append_port_find, vendor_id, product_id); } + if (ser_lib_funcs_hid && ser_lib_funcs_hid->find_usb) { + find_func = ser_lib_funcs_hid->find_usb; + tty_devs = find_func(tty_devs, append_port_find, + vendor_id, product_id); + } return tty_devs; } diff --git a/src/serial_hid.c b/src/serial_hid.c new file mode 100644 index 00000000..bb0dcc2f --- /dev/null +++ b/src/serial_hid.c @@ -0,0 +1,35 @@ +/* + * This file is part of the libsigrok project. + * + * Copyright (C) 2017-2019 Gerhard Sittig + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "config.h" +#include +#include "libsigrok-internal.h" + +/** @cond PRIVATE */ +#define LOG_PREFIX "serial-hid" +/** @endcond */ + +SR_PRIV int ser_name_is_hid(struct sr_serial_dev_inst *serial) +{ + (void)serial; + + return 0; +} + +SR_PRIV struct ser_lib_functions *ser_lib_funcs_hid = NULL;