X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=src%2Fhardware%2Fdcttech-usbrelay%2Fapi.c;h=deeb234a95eb2e72e640e6a3d0bcc8e2b9e328a6;hb=77ee3168d0ae88c92a127999d890fff0511ca31e;hp=a24025ec84376878d17c778bb4808f4fd622547a;hpb=8e5dbaf6e9940cfcc95eeb4fd6708b6fffd02acf;p=libsigrok.git diff --git a/src/hardware/dcttech-usbrelay/api.c b/src/hardware/dcttech-usbrelay/api.c index a24025ec..deeb234a 100644 --- a/src/hardware/dcttech-usbrelay/api.c +++ b/src/hardware/dcttech-usbrelay/api.c @@ -45,7 +45,7 @@ static const uint32_t devopts_cg[] = { static struct sr_dev_driver dcttech_usbrelay_driver_info; static struct sr_dev_inst *probe_device_common(const char *path, - uint16_t vid, uint16_t pid, + uint16_t vid, uint16_t pid, const char *want_serno, const wchar_t *vendor, const wchar_t *product) { char nonws[16], *s, *endp; @@ -63,6 +63,7 @@ static struct sr_dev_inst *probe_device_common(const char *path, struct channel_group_context *cgc; size_t idx, nr; struct sr_channel_group *cg; + char cg_name[24]; /* * Get relay count from product string. Weak condition, @@ -128,6 +129,12 @@ static struct sr_dev_inst *probe_device_common(const char *path, sr_info("HID report data: serial number %s, relay state 0x%02x.", serno, curr_state); + /* Optionally filter by serial number. */ + if (want_serno && *want_serno && strcmp(serno, want_serno) != 0) { + sr_dbg("Serial number does not match user spec. Skipping."); + return NULL; + } + /* Create a device instance. */ sdi = g_malloc0(sizeof(*sdi)); sdi->vendor = g_strdup_printf("%ls", vendor); @@ -147,20 +154,20 @@ static struct sr_dev_inst *probe_device_common(const char *path, devc->relay_mask = (1U << relay_count) - 1; for (idx = 0; idx < devc->relay_count; idx++) { nr = idx + 1; - cg = g_malloc0(sizeof(*cg)); - cg->name = g_strdup_printf("R%zu", nr); + snprintf(cg_name, sizeof(cg_name), "R%zu", nr); cgc = g_malloc0(sizeof(*cgc)); - cg->priv = cgc; cgc->number = nr; - sdi->channel_groups = g_slist_append(sdi->channel_groups, cg); + cg = sr_channel_group_new(sdi, cg_name, cgc); + (void)cg; } return sdi; } -static struct sr_dev_inst *probe_device_enum(struct hid_device_info *dev) +static struct sr_dev_inst *probe_device_enum(struct hid_device_info *dev, + const char *want_serno) { - return probe_device_common(dev->path, 0, 0, + return probe_device_common(dev->path, 0, 0, want_serno, dev->manufacturer_string, dev->product_string); } @@ -231,7 +238,7 @@ static struct sr_dev_inst *probe_device_conn(const char *path) if (!ok) return NULL; - return probe_device_common(path, vid, pid, vendor, product); + return probe_device_common(path, vid, pid, NULL, vendor, product); } static GSList *scan(struct sr_dev_driver *di, GSList *options) @@ -239,6 +246,7 @@ static GSList *scan(struct sr_dev_driver *di, GSList *options) const char *conn; GSList *devices; struct drv_context *drvc; + char want_serno[SERNO_LENGTH + 1]; struct hid_device_info *devs, *curdev; wchar_t *ws; char nonws[32]; @@ -257,14 +265,25 @@ static GSList *scan(struct sr_dev_driver *di, GSList *options) /* * The firmware is V-USB based. The USB VID:PID identification * is shared across several projects. Need to inspect the vendor - * and product _strings_ to actually identify the device. The - * USB serial number need not be present nor reliable. The HID - * report content will carry the board's serial number. + * and product _strings_ to actually identify the device. + * + * The USB serial number need not be present nor reliable. The + * HID report content will carry the board's serial number. + * When users specify "sn=..." connection strings, then run a + * regular USB enumation, and filter the result set by serial + * numbers which only become available with HID reports. * - * When conn= was specified, then have HIDAPI open _this_ device - * and skip the enumeration. Which allows users to specify paths - * that need not match the enumeration's details. + * When other connection strings were specified, then have + * HIDAPI open _this_ device and skip the enumeration. Which + * allows users to specify paths that need not match the + * enumeration's details. */ + memset(want_serno, 0, sizeof(want_serno)); + if (conn && g_str_has_prefix(conn, "sn=")) { + conn += strlen("sn="); + snprintf(want_serno, sizeof(want_serno), "%s", conn); + conn = NULL; + } if (conn) { sr_info("Checking HID path %s.", conn); sdi = probe_device_conn(conn); @@ -303,11 +322,9 @@ static GSList *scan(struct sr_dev_driver *di, GSList *options) /* Identify device by communicating to it. */ sr_info("Checking HID path %s.", curdev->path); - sdi = probe_device_enum(curdev); - if (!sdi) { - sr_warn("Failed to communicate to %s.", curdev->path); + sdi = probe_device_enum(curdev, want_serno); + if (!sdi) continue; - } devices = g_slist_append(devices, sdi); } hid_free_enumeration(devs);