@@ -45,6 +45,7 @@ static const uint32_t devopts_cg[] = {
4545static struct sr_dev_driver dcttech_usbrelay_driver_info ;
4646
4747static struct sr_dev_inst * probe_device_common (const char * path ,
48+ uint16_t vid , uint16_t pid ,
4849 const wchar_t * vendor , const wchar_t * product )
4950{
5051 char nonws [16 ], * s , * endp ;
@@ -80,7 +81,10 @@ static struct sr_dev_inst *probe_device_common(const char *path,
8081 sr_info ("Relay count %lu from product string %s." , relay_count , nonws );
8182
8283 /* Open device, need to communicate to identify. */
83- hid = hid_open_path (path );
84+ if (vid && pid )
85+ hid = hid_open (vid , pid , NULL );
86+ else
87+ hid = hid_open_path (path );
8488 if (!hid ) {
8589 sr_err ("Cannot open %s." , path );
8690 return NULL ;
@@ -137,6 +141,8 @@ static struct sr_dev_inst *probe_device_common(const char *path,
137141 devc = g_malloc0 (sizeof (* devc ));
138142 sdi -> priv = devc ;
139143 devc -> hid_path = g_strdup (path );
144+ devc -> usb_vid = vid ;
145+ devc -> usb_pid = pid ;
140146 devc -> relay_count = relay_count ;
141147 devc -> relay_mask = (1U << relay_count ) - 1 ;
142148 for (idx = 0 ; idx < devc -> relay_count ; idx ++ ) {
@@ -154,33 +160,62 @@ static struct sr_dev_inst *probe_device_common(const char *path,
154160
155161static struct sr_dev_inst * probe_device_enum (struct hid_device_info * dev )
156162{
157- return probe_device_common (dev -> path ,
163+ return probe_device_common (dev -> path , 0 , 0 ,
158164 dev -> manufacturer_string , dev -> product_string );
159165}
160166
161- static struct sr_dev_inst * probe_device_path (const char * path )
167+ static struct sr_dev_inst * probe_device_conn (const char * path )
162168{
169+ char vid_pid [12 ];
170+ uint16_t vid , pid ;
171+ const char * s ;
172+ char * endp ;
173+ unsigned long num ;
163174 hid_device * dev ;
164175 gboolean ok ;
165176 int ret ;
166177 wchar_t vendor [32 ], product [32 ];
167178
168179 /*
169- * TODO Accept different types of conn= specs? Either paths that
170- * hidapi(3) can open. Or bus.addr specs that we can check for
171- * during USB enumeration and derive a hidapi(3) compatible path
172- * from? Is some "unescaping" desirable for platforms which have
173- * colons in hidapi(3) paths that collide with how conn= specs
174- * are passed in sigrok? This would be the place to translate
175- * the 'path' to a canonical format.
180+ * The hidapi(3) library's API strives for maximum portability,
181+ * thus won't provide ways of getting a path from alternative
182+ * presentations like VID:PID pairs, bus.addr specs, etc. The
183+ * typical V-USB setup neither provides reliable serial numbers
184+ * (that USB enumeration would cover). So this driver's support
185+ * for conn= specs beyond Unix style path names is limited, too.
186+ * This implementation tries "VID.PID" then assumes "path". The
187+ * inability to even get the path for a successfully opened HID
188+ * results in redundancy across the places which open devices.
176189 */
177190
178- dev = hid_open_path (path );
191+ /* Check for "<vid>.<pid>" specs. */
192+ vid = pid = 0 ;
193+ s = path ;
194+ ret = sr_atoul_base (s , & num , & endp , 16 );
195+ if (ret == SR_OK && endp && endp == s + 4 && * endp == '.' && num ) {
196+ vid = num ;
197+ s = ++ endp ;
198+ }
199+ ret = sr_atoul_base (s , & num , & endp , 16 );
200+ if (ret == SR_OK && endp && endp == s + 4 && * endp == '\0' && num ) {
201+ pid = num ;
202+ s = ++ endp ;
203+ }
204+ if (vid && pid ) {
205+ snprintf (vid_pid , sizeof (vid_pid ), "%04x.%04x" , vid , pid );
206+ path = vid_pid ;
207+ sr_dbg ("Using VID.PID %s." , path );
208+ }
209+
210+ /* Open the device, get vendor and product strings. */
211+ if (vid && pid )
212+ dev = hid_open (vid , pid , NULL );
213+ else
214+ dev = hid_open_path (path );
179215 if (!dev ) {
180216 sr_err ("Cannot open %s." , path );
181217 return NULL ;
182218 }
183-
184219 ok = TRUE;
185220 ret = hid_get_manufacturer_string (dev , vendor , ARRAY_SIZE (vendor ));
186221 if (ret != 0 )
@@ -196,7 +231,7 @@ static struct sr_dev_inst *probe_device_path(const char *path)
196231 if (!ok )
197232 return NULL ;
198233
199- return probe_device_common (path , vendor , product );
234+ return probe_device_common (path , vid , pid , vendor , product );
200235}
201236
202237static GSList * scan (struct sr_dev_driver * di , GSList * options )
@@ -232,7 +267,7 @@ static GSList *scan(struct sr_dev_driver *di, GSList *options)
232267 */
233268 if (conn ) {
234269 sr_info ("Checking HID path %s." , conn );
235- sdi = probe_device_path (conn );
270+ sdi = probe_device_conn (conn );
236271 if (!sdi )
237272 sr_warn ("Failed to communicate to %s." , conn );
238273 else
@@ -291,7 +326,10 @@ static int dev_open(struct sr_dev_inst *sdi)
291326 devc -> hid_dev = NULL ;
292327 }
293328
294- devc -> hid_dev = hid_open_path (devc -> hid_path );
329+ if (devc -> usb_vid && devc -> usb_pid )
330+ devc -> hid_dev = hid_open (devc -> usb_vid , devc -> usb_pid , NULL );
331+ else
332+ devc -> hid_dev = hid_open_path (devc -> hid_path );
295333 if (!devc -> hid_dev )
296334 return SR_ERR_IO ;
297335
0 commit comments