Change in libosmocore[master]: usb: Add osmo_libusb_find_matching_dev_{path, serial}

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

laforge gerrit-no-reply at lists.osmocom.org
Sun Jan 12 21:52:20 UTC 2020


laforge has uploaded this change for review. ( https://gerrit.osmocom.org/c/libosmocore/+/16830 )


Change subject: usb: Add osmo_libusb_find_matching_dev_{path,serial}
......................................................................

usb: Add osmo_libusb_find_matching_dev_{path,serial}

Thise two helper functions allow the user application to find
a unique match among the existing USB devices, using either a user-
provided iSerial string, or a user-provided physical USB path.

Change-Id: I8ff3fb3e1a77e10cb313473480ce5e7673749a93
---
M include/osmocom/usb/libusb.h
M src/usb/osmo_libusb.c
2 files changed, 154 insertions(+), 0 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/30/16830/1

diff --git a/include/osmocom/usb/libusb.h b/include/osmocom/usb/libusb.h
index 382c86e..2220e03 100644
--- a/include/osmocom/usb/libusb.h
+++ b/include/osmocom/usb/libusb.h
@@ -62,6 +62,14 @@
 libusb_device **osmo_libusb_find_matching_usb_devs(void *ctx, struct libusb_context *luctx,
 						   const struct dev_id *dev_ids);
 
+libusb_device *osmo_libusb_find_matching_dev_path(struct libusb_context *luctx,
+						  const struct dev_id *dev_ids,
+						  const char *path);
+
+libusb_device *osmo_libusb_find_matching_dev_serial(struct libusb_context *luctx,
+						    const struct dev_id *dev_ids,
+						    const char *serial);
+
 int osmo_libusb_dev_find_matching_interfaces(libusb_device *dev, int class, int sub_class,
 					     int protocol, struct usb_interface_match *out,
 					     unsigned int out_len);
diff --git a/src/usb/osmo_libusb.c b/src/usb/osmo_libusb.c
index b10f5be..9ad6240 100644
--- a/src/usb/osmo_libusb.c
+++ b/src/usb/osmo_libusb.c
@@ -220,6 +220,152 @@
 	return out;
 }
 
+/*! Find a USB device of matching VendorID/ProductID at given path.
+ *  \param[in] luctx libusb context on which to operate
+ *  \param[in] dev_ids zer-oterminated array of VendorId/ProductId tuples
+ *  \param[in] path string representation of USB path
+ *  \returns libusb_device if there was exactly one match; NULL otherwise */
+libusb_device *osmo_libusb_find_matching_dev_path(struct libusb_context *luctx,
+						  const struct dev_id *dev_ids,
+						  const char *path)
+{
+	libusb_device **list;
+	libusb_device *match = NULL;
+	unsigned int i;
+	int rc;
+
+	rc = libusb_get_device_list(luctx, &list);
+	if (rc <= 0)
+		return NULL;
+
+	for (i = 0; list[i] != NULL; i++) {
+		struct libusb_device_descriptor dev_desc;
+		libusb_device *dev = list[i];
+		char pathbuf[128];
+
+		rc = libusb_get_device_descriptor(dev, &dev_desc);
+		if (rc < 0) {
+			LOGP(DLUSB, LOGL_ERROR, "couldn't get device descriptor\n");
+			continue;
+		}
+
+		/* check if device doesn't match */
+		if (!match_dev_ids(&dev_desc, dev_ids))
+			continue;
+
+		/* check if path doesn't match */
+		if (path) {
+			osmo_libusb_dev_get_path_buf(pathbuf, sizeof(pathbuf), dev);
+			if (strcmp(pathbuf, path))
+				continue;
+		}
+
+		if (match) {
+			/* we already have a match, but now found a second -> FAIL */
+			libusb_free_device_list(list, 1);
+			LOGP(DLUSB, LOGL_ERROR, "Found more than one matching USB device\n");
+			return NULL;
+		} else
+			match = dev;
+	}
+
+	if (!match) {
+		/* no match: free the list with automatic unref of all devices */
+		libusb_free_device_list(list, 1);
+		return NULL;
+	}
+
+	/* unref all devices *except* the match we found */
+	for (i = 0; list[i] != NULL; i++) {
+		libusb_device *dev = list[i];
+		if (dev != match)
+			libusb_unref_device(dev);
+	}
+	/* free the list *without* automatic unref of all devices */
+	libusb_free_device_list(list, 0);
+	return match;
+}
+
+/*! Find a USB device of matching VendorID/ProductID and given iSerial string.
+ *  \param[in] luctx libusb context on which to operate
+ *  \param[in] dev_ids zer-oterminated array of VendorId/ProductId tuples
+ *  \param[in] serial string representation of serial number
+ *  \returns libusb_device if there was exactly one match; NULL otherwise */
+libusb_device *osmo_libusb_find_matching_dev_serial(struct libusb_context *luctx,
+						    const struct dev_id *dev_ids,
+						    const char *serial)
+{
+	libusb_device **list;
+	libusb_device *match = NULL;
+	unsigned int i;
+	int rc;
+
+	rc = libusb_get_device_list(luctx, &list);
+	if (rc <= 0)
+		return NULL;
+
+	for (i = 0; list[i] != NULL; i++) {
+		struct libusb_device_descriptor dev_desc;
+		libusb_device *dev = list[i];
+
+		rc = libusb_get_device_descriptor(dev, &dev_desc);
+		if (rc < 0) {
+			LOGP(DLUSB, LOGL_ERROR, "couldn't get device descriptor\n");
+			continue;
+		}
+
+		/* check if device doesn't match */
+		if (!match_dev_ids(&dev_desc, dev_ids))
+			continue;
+
+		/* check if serial number string doesn't match */
+		if (serial) {
+			char strbuf[256];
+			libusb_device_handle *devh;
+			rc = libusb_open(dev, &devh);
+			if (rc < 0) {
+				LOGP(DLUSB, LOGL_ERROR, "Cannot open USB Device: %s\n",
+					libusb_strerror(rc));
+				/* there's no point in continuing here, as we don't know if there
+				 * are multiple matches if we cannot read the iSerial string of all
+				 * devices with matching vid/pid */
+				libusb_free_device_list(list, 1);
+				return NULL;
+			}
+			rc = libusb_get_string_descriptor_ascii(devh, dev_desc.iSerialNumber,
+								(uint8_t *) strbuf, sizeof(strbuf));
+			libusb_close(devh);
+			if (strcmp(strbuf, serial))
+				continue;
+		}
+
+		if (match) {
+			/* we already have a match, but now found a second -> FAIL */
+			libusb_free_device_list(list, 1);
+			LOGP(DLUSB, LOGL_ERROR, "Found more than one matching USB device\n");
+			return NULL;
+		} else
+			match = dev;
+	}
+
+	if (!match) {
+		/* no match: free the list with automatic unref of all devices */
+		libusb_free_device_list(list, 1);
+		return NULL;
+	}
+
+	/* unref all devices *except* the match we found */
+	for (i = 0; list[i] != NULL; i++) {
+		libusb_device *dev = list[i];
+		if (dev != match)
+			libusb_unref_device(dev);
+	}
+	/* free the list *without* automatic unref of all devices */
+	libusb_free_device_list(list, 0);
+	return match;
+}
+
+
 /*! find a matching interface among all interfaces of the given USB device.
  *  \param[in] dev USB device in which we shall search
  *  \param[in] class USB Interface Class to look for

-- 
To view, visit https://gerrit.osmocom.org/c/libosmocore/+/16830
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: libosmocore
Gerrit-Branch: master
Gerrit-Change-Id: I8ff3fb3e1a77e10cb313473480ce5e7673749a93
Gerrit-Change-Number: 16830
Gerrit-PatchSet: 1
Gerrit-Owner: laforge <laforge at osmocom.org>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20200112/8357bd63/attachment.htm>


More information about the gerrit-log mailing list