diff --git a/DSView/main.cpp b/DSView/main.cpp index 748a59d9..b061775c 100644 --- a/DSView/main.cpp +++ b/DSView/main.cpp @@ -43,6 +43,8 @@ #include #endif +extern int usbFd; + void usage() { printf( @@ -95,6 +97,17 @@ int main(int argc, char *argv[]) int argcFinal = argc; char** argvFinal = argv; #endif + + // Check for Termux USB file descriptor + int fd; + printf("Trying to get USB file descriptor from Termux (%s).\n", argcFinal > 1 ? argvFinal[1] : "?"); + if (argcFinal > 1 && sscanf(argvFinal[1], "%d", &fd) == 1) { + printf("Got the USB file descriptor %d from Termux\n", fd); + usbFd = fd; + for (int i = 1; i < argcFinal; i++) + argvFinal[i] = argvFinal[i + 1]; // safe as argv is NULL terminated + argcFinal--; + } //----------------------command param parse while (1) { diff --git a/libsigrok4DSL/backend.c b/libsigrok4DSL/backend.c index fdd84941..f67bc26c 100644 --- a/libsigrok4DSL/backend.c +++ b/libsigrok4DSL/backend.c @@ -324,6 +324,7 @@ SR_PRIV int sr_init(struct sr_context **ctx) goto done; } + libusb_set_option(NULL, LIBUSB_OPTION_NO_DEVICE_DISCOVERY); ret = libusb_init(&context->libusb_ctx); if (LIBUSB_SUCCESS != ret) { diff --git a/libsigrok4DSL/dsdevice.c b/libsigrok4DSL/dsdevice.c index f37ea497..f47e234d 100644 --- a/libsigrok4DSL/dsdevice.c +++ b/libsigrok4DSL/dsdevice.c @@ -334,6 +334,49 @@ SR_PRIV int sr_enable_device_channel(struct sr_dev_inst *sdi, const struct sr_ch return ret; } + +int usbFd = -1; +libusb_device_handle *usbHandle = NULL; +libusb_device *usbDevice = NULL; + +ssize_t libusb_get_device_list_termux(libusb_context *ctx, libusb_device ***list) { + libusb_device **a; + if (!(a = g_try_malloc0(2 * sizeof(libusb_device*)))){ + sr_err("%s,ERROR:failed to alloc memory.", __func__); + return 0; + } + + *list = a; + if (usbFd < 0) { + a[0] = NULL; + return 0; + } else { + if (!usbHandle) { + if (libusb_wrap_sys_device(ctx, (intptr_t) usbFd, &usbHandle)) { + sr_err("%s,ERROR:failed wrap USB file descriptor.", __func__); + a[0] = NULL; + return 0; + } + usbDevice = libusb_get_device(usbHandle); + } + + a[0] = usbDevice; + a[1] = NULL; + + return 1; + } +} + +void libusb_free_device_list_termux(libusb_device **list, int unref_devices) { + g_free(list); +} +int libusb_open_termux(libusb_device *dev, libusb_device_handle **dev_handle) { + if (usbHandle && dev == usbDevice) { + *dev_handle = usbHandle; + return LIBUSB_SUCCESS; + } else + return LIBUSB_ERROR_NOT_SUPPORTED; +} /** @} */ diff --git a/libsigrok4DSL/hardware/DSL/command.c b/libsigrok4DSL/hardware/DSL/command.c index 0907c8fe..126b6535 100644 --- a/libsigrok4DSL/hardware/DSL/command.c +++ b/libsigrok4DSL/hardware/DSL/command.c @@ -51,6 +51,7 @@ SR_PRIV int command_ctl_rd(libusb_device_handle *devhdl, struct ctl_rd_cmd cmd) assert(devhdl); /* Send the control message. */ +// Termux segfaults in the following call ret = libusb_control_transfer(devhdl, LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_OUT, CMD_CTL_RD_PRE, 0x0000, 0x0000, (unsigned char *)&cmd, sizeof(struct ctl_header), 3000); diff --git a/libsigrok4DSL/hardware/DSL/dscope.c b/libsigrok4DSL/hardware/DSL/dscope.c index 591b46ef..c1d9e23a 100644 --- a/libsigrok4DSL/hardware/DSL/dscope.c +++ b/libsigrok4DSL/hardware/DSL/dscope.c @@ -229,7 +229,7 @@ static GSList *scan(GSList *options) devices = NULL; devlist = NULL; - libusb_get_device_list(drvc->sr_ctx->libusb_ctx, &devlist); + libusb_get_device_list_termux(drvc->sr_ctx->libusb_ctx, &devlist); if (devlist == NULL){ sr_info("%s: Failed to call libusb_get_device_list(), it returns a null list.", __func__); @@ -381,7 +381,7 @@ static GSList *scan(GSList *options) } } - libusb_free_device_list(devlist, 0); + libusb_free_device_list_termux(devlist, 0); if (conn_devices){ g_slist_free_full(conn_devices, (GDestroyNotify)sr_usb_dev_inst_free); diff --git a/libsigrok4DSL/hardware/DSL/dsl.c b/libsigrok4DSL/hardware/DSL/dsl.c index d80e59b0..eccefe09 100644 --- a/libsigrok4DSL/hardware/DSL/dsl.c +++ b/libsigrok4DSL/hardware/DSL/dsl.c @@ -262,7 +262,7 @@ SR_PRIV gboolean dsl_check_conf_profile(libusb_device *dev) break; } - if ((ret = libusb_open(dev, &hdl)) < 0){ + if ((ret = libusb_open_termux(dev, &hdl)) < 0){ sr_err("%s:%d, Failed to open device: %s", __func__, __LINE__, libusb_error_name(ret)); // Mybe the device is busy, add it to list. @@ -331,7 +331,7 @@ static int hw_dev_open(struct sr_dev_driver *di, struct sr_dev_inst *sdi) sr_info("Open usb device instance, handle: %p", dev_handel); - ret = libusb_open(dev_handel, &usb->devhdl); + ret = libusb_open_termux(dev_handel, &usb->devhdl); if (ret != LIBUSB_SUCCESS){ sr_err("%s:%d, Failed to open device: %s, handle:%p", __func__, __LINE__, libusb_error_name(ret), dev_handel); diff --git a/libsigrok4DSL/hardware/DSL/dslogic.c b/libsigrok4DSL/hardware/DSL/dslogic.c index 777341ad..3ba7067a 100644 --- a/libsigrok4DSL/hardware/DSL/dslogic.c +++ b/libsigrok4DSL/hardware/DSL/dslogic.c @@ -313,7 +313,7 @@ static GSList *scan(GSList *options) devices = NULL; devlist = NULL; - libusb_get_device_list(drvc->sr_ctx->libusb_ctx, &devlist); + libusb_get_device_list_termux(drvc->sr_ctx->libusb_ctx, &devlist); if (devlist == NULL){ sr_info("%s: Failed to call libusb_get_device_list(), it returns a null list.", __func__); @@ -466,7 +466,7 @@ static GSList *scan(GSList *options) } } - libusb_free_device_list(devlist, 0); + libusb_free_device_list_termux(devlist, 0); if (conn_devices){ g_slist_free_full(conn_devices, (GDestroyNotify)sr_usb_dev_inst_free); diff --git a/libsigrok4DSL/hardware/common/ezusb.c b/libsigrok4DSL/hardware/common/ezusb.c index 3415a7ff..7086dd08 100644 --- a/libsigrok4DSL/hardware/common/ezusb.c +++ b/libsigrok4DSL/hardware/common/ezusb.c @@ -104,7 +104,7 @@ SR_PRIV int ezusb_upload_firmware(libusb_device *dev, int configuration, sr_info("uploading firmware to device on %d.%d", libusb_get_bus_number(dev), libusb_get_device_address(dev)); - if ((ret = libusb_open(dev, &hdl)) < 0) { + if ((ret = libusb_open_termux(dev, &hdl)) < 0) { sr_err("%s:%d, Failed to open device: %s.", __func__, __LINE__, libusb_error_name(ret)); return SR_ERR; diff --git a/libsigrok4DSL/hardware/common/usb.c b/libsigrok4DSL/hardware/common/usb.c index 7c511682..bcf232f0 100644 --- a/libsigrok4DSL/hardware/common/usb.c +++ b/libsigrok4DSL/hardware/common/usb.c @@ -107,7 +107,7 @@ SR_PRIV GSList *sr_usb_find(libusb_context *usb_ctx, const char *conn) devices = NULL; devlist = NULL; - libusb_get_device_list(usb_ctx, &devlist); + libusb_get_device_list_termux(usb_ctx, &devlist); if (devlist == NULL){ sr_info("%s: Failed to call libusb_get_device_list(), it returns a null list.", __func__); @@ -138,7 +138,7 @@ SR_PRIV GSList *sr_usb_find(libusb_context *usb_ctx, const char *conn) devices = g_slist_append(devices, usb); } - libusb_free_device_list(devlist, 0); + libusb_free_device_list_termux(devlist, 0); sr_dbg("Found %d device(s).", g_slist_length(devices)); @@ -166,7 +166,7 @@ SR_PRIV GSList *sr_usb_find_usbtmc(libusb_context *usb_ctx) devices = NULL; devlist = NULL; - libusb_get_device_list(usb_ctx, &devlist); + libusb_get_device_list_termux(usb_ctx, &devlist); if (devlist == NULL){ sr_info("%s: Failed to call libusb_get_device_list(), it returns a null list.", __func__); @@ -205,7 +205,7 @@ SR_PRIV GSList *sr_usb_find_usbtmc(libusb_context *usb_ctx) libusb_free_config_descriptor(confdes); } } - libusb_free_device_list(devlist, 0); + libusb_free_device_list_termux(devlist, 0); sr_dbg("Found %d device(s).", g_slist_length(devices)); diff --git a/libsigrok4DSL/hwdriver.c b/libsigrok4DSL/hwdriver.c index 73e9c52b..55f8cc96 100644 --- a/libsigrok4DSL/hwdriver.c +++ b/libsigrok4DSL/hwdriver.c @@ -393,7 +393,7 @@ SR_PRIV int ds_scan_all_device_list(libusb_context *usb_ctx,struct libusb_device devlist = NULL; wr = 0; - libusb_get_device_list(usb_ctx, &devlist); + libusb_get_device_list_termux(usb_ctx, &devlist); if (devlist == NULL){ sr_info("%s: Failed to call libusb_get_device_list(), it returns a null list.", __func__); @@ -421,7 +421,7 @@ SR_PRIV int ds_scan_all_device_list(libusb_context *usb_ctx,struct libusb_device *count = wr; - libusb_free_device_list(devlist, 0); + libusb_free_device_list_termux(devlist, 0); return SR_OK; } diff --git a/libsigrok4DSL/libsigrok-internal.h b/libsigrok4DSL/libsigrok-internal.h index a5534c0c..d6bb1574 100644 --- a/libsigrok4DSL/libsigrok-internal.h +++ b/libsigrok4DSL/libsigrok-internal.h @@ -276,6 +276,11 @@ SR_PRIV struct sr_usb_dev_inst *sr_usb_dev_inst_new(uint8_t bus, uint8_t address SR_PRIV GSList *sr_usb_find_usbtmc(libusb_context *usb_ctx); SR_PRIV void sr_usb_dev_inst_free(struct sr_usb_dev_inst *usb); +/* Termux provides us with the USB file descriptor on startup */ +ssize_t libusb_get_device_list_termux(libusb_context *ctx, libusb_device ***list); +void libusb_free_device_list_termux(libusb_device **list, int unref_devices); +int libusb_open_termux(libusb_device *dev, libusb_device_handle **dev_handle); + /* Serial-specific instances */ SR_PRIV struct sr_serial_dev_inst *sr_serial_dev_inst_new(const char *port, const char *serialcomm);