+static struct sr_dev_inst *probe_device_enum(struct hid_device_info *dev)
+{
+ return probe_device_common(dev->path, 0, 0,
+ dev->manufacturer_string, dev->product_string);
+}
+
+static struct sr_dev_inst *probe_device_conn(const char *path)
+{
+ char vid_pid[12];
+ uint16_t vid, pid;
+ const char *s;
+ char *endp;
+ unsigned long num;
+ hid_device *dev;
+ gboolean ok;
+ int ret;
+ wchar_t vendor[32], product[32];
+
+ /*
+ * The hidapi(3) library's API strives for maximum portability,
+ * thus won't provide ways of getting a path from alternative
+ * presentations like VID:PID pairs, bus.addr specs, etc. The
+ * typical V-USB setup neither provides reliable serial numbers
+ * (that USB enumeration would cover). So this driver's support
+ * for conn= specs beyond Unix style path names is limited, too.
+ * This implementation tries "VID.PID" then assumes "path". The
+ * inability to even get the path for a successfully opened HID
+ * results in redundancy across the places which open devices.
+ */
+
+ /* Check for "<vid>.<pid>" specs. */
+ vid = pid = 0;
+ s = path;
+ ret = sr_atoul_base(s, &num, &endp, 16);
+ if (ret == SR_OK && endp && endp == s + 4 && *endp == '.' && num) {
+ vid = num;
+ s = ++endp;
+ }
+ ret = sr_atoul_base(s, &num, &endp, 16);
+ if (ret == SR_OK && endp && endp == s + 4 && *endp == '\0' && num) {
+ pid = num;
+ s = ++endp;
+ }
+ if (vid && pid) {
+ snprintf(vid_pid, sizeof(vid_pid), "%04x.%04x", vid, pid);
+ path = vid_pid;
+ sr_dbg("Using VID.PID %s.", path);
+ }
+
+ /* Open the device, get vendor and product strings. */
+ if (vid && pid)
+ dev = hid_open(vid, pid, NULL);
+ else
+ dev = hid_open_path(path);
+ if (!dev) {
+ sr_err("Cannot open %s.", path);
+ return NULL;
+ }
+ ok = TRUE;
+ ret = hid_get_manufacturer_string(dev, vendor, ARRAY_SIZE(vendor));
+ if (ret != 0)
+ ok = FALSE;
+ if (!wcslen(vendor))
+ ok = FALSE;
+ ret = hid_get_product_string(dev, product, ARRAY_SIZE(product));
+ if (ret != 0)
+ ok = FALSE;
+ if (!wcslen(product))
+ ok = FALSE;
+ hid_close(dev);
+ if (!ok)
+ return NULL;
+
+ return probe_device_common(path, vid, pid, vendor, product);
+}
+