]> sigrok.org Git - libsigrok.git/commitdiff
serial: prepare serial over HID in common layer and build support
authorGerhard Sittig <redacted>
Sun, 26 Mar 2017 14:48:36 +0000 (15:48 +0100)
committerUwe Hermann <redacted>
Sun, 2 Jun 2019 18:39:02 +0000 (20:39 +0200)
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.

Makefile.am
README
configure.ac
src/backend.c
src/libsigrok-internal.h
src/serial.c
src/serial_hid.c [new file with mode: 0644]

index 9dbe3e4331333a07bc2e8a25876dfd65e77abf14..130d84d6b162421064b8ee037e11443bc8b8aa16 100644 (file)
@@ -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 154c4928929c5eb6763d8c04523cf4c01d1e5893..a902e66523725e076a470d0637dca64188015482 100644 (file)
--- 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)
index 6b9a1a6624fa45e20ef623f064b234b966d8c004..1d1462839545ce09d8dcc1607b785cd38834e013 100644 (file)
@@ -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
index a5d5749bcd51e24ba04d5571fb8f6113ad98a557..3e488ca7d9a00a35aa27a12d149198f7cfb1f63e 100644 (file)
@@ -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 <hidapi.h>, 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
index e1623f629b0e2c675cf59386eea95d542e8bf5bb..48e89acd8e7609418eef230a9fef647a5b0febe9 100644 (file)
@@ -29,6 +29,9 @@
 #include "config.h"
 
 #include <glib.h>
+#ifdef HAVE_LIBHIDAPI
+#include <hidapi.h>
+#endif
 #ifdef HAVE_LIBSERIALPORT
 #include <libserialport.h>
 #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 ---------------------------------------------------------------*/
index b1e21eecbcbd69a3e21ffcd28620f76d122be444..acee0dcacca6e4960c888596b70095480957afd7 100644 (file)
@@ -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 (file)
index 0000000..bb0dcc2
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * This file is part of the libsigrok project.
+ *
+ * Copyright (C) 2017-2019 Gerhard Sittig <gerhard.sittig@gmx.net>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+#include <libsigrok/libsigrok.h>
+#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;