From: <ek...@gm...> - 2012-03-27 13:46:35
|
From: Keith Mok <ek...@gm...> Add a function to retrieve a unique location string among all USB devices in the system, which will not be changed on a system reboot unless the topology of the usb bus itself changes. Signed-off-by: Keith Mok <ek...@gm...> --- examples/listdevs.c | 1 + libusb/core.c | 15 +++++++++++++++ libusb/libusb-1.0.def | 2 ++ libusb/libusb.h | 1 + libusb/libusbi.h | 1 + libusb/os/darwin_usb.c | 4 ++++ libusb/os/linux_usbfs.c | 3 +++ 7 files changed, 27 insertions(+), 0 deletions(-) diff --git a/examples/listdevs.c b/examples/listdevs.c index 6ab8917..0a13181 100644 --- a/examples/listdevs.c +++ b/examples/listdevs.c @@ -38,6 +38,7 @@ static void print_devs(libusb_device **devs) printf("%04x:%04x (bus %d, device %d)\n", desc.idVendor, desc.idProduct, libusb_get_bus_number(dev), libusb_get_device_address(dev)); + printf("Physical address: %s\n", libusb_get_physical_address(dev)); } } diff --git a/libusb/core.c b/libusb/core.c index 142c6d4..96df4ac 100644 --- a/libusb/core.c +++ b/libusb/core.c @@ -690,6 +690,19 @@ uint8_t API_EXPORTED libusb_get_device_address(libusb_device *dev) } /** \ingroup dev + * Get string to represent the unique physical address among all USB devices of + * the system, and which will not change on a system reboot unless the + * topology of the usb changes. + * \param dev a device + * \returns the physical address, or NULL if platform not supported + */ +DEFAULT_VISIBILITY +const char * LIBUSB_CALL libusb_get_physical_address(libusb_device *dev) +{ + return dev->physical_address; +} + +/** \ingroup dev * Get the negotiated connection speed for a device. * \param dev a device * \returns a \ref libusb_speed code, where LIBUSB_SPEED_UNKNOWN means that @@ -862,6 +875,8 @@ void API_EXPORTED libusb_unref_device(libusb_device *dev) usbi_mutex_unlock(&dev->ctx->usb_devs_lock); usbi_mutex_destroy(&dev->lock); + if (dev->physical_address) + free(dev->physical_address); free(dev); } } diff --git a/libusb/libusb-1.0.def b/libusb/libusb-1.0.def index 96abd17..f863dcf 100644 --- a/libusb/libusb-1.0.def +++ b/libusb/libusb-1.0.def @@ -58,6 +58,8 @@ EXPORTS libusb_get_max_packet_size@8 = libusb_get_max_packet_size libusb_get_next_timeout libusb_get_next_timeout@8 = libusb_get_next_timeout + libusb_get_physical_address + libusb_get_physical_address@4 = libusb_get_physical_address libusb_get_pollfds libusb_get_pollfds@4 = libusb_get_pollfds libusb_get_string_descriptor_ascii diff --git a/libusb/libusb.h b/libusb/libusb.h index 4141a8e..0251fd2 100644 --- a/libusb/libusb.h +++ b/libusb/libusb.h @@ -953,6 +953,7 @@ void LIBUSB_CALL libusb_free_config_descriptor( struct libusb_config_descriptor *config); uint8_t LIBUSB_CALL libusb_get_bus_number(libusb_device *dev); uint8_t LIBUSB_CALL libusb_get_device_address(libusb_device *dev); +const char* LIBUSB_CALL libusb_get_physical_address(libusb_device *dev); int LIBUSB_CALL libusb_get_device_speed(libusb_device *dev); int LIBUSB_CALL libusb_get_max_packet_size(libusb_device *dev, unsigned char endpoint); diff --git a/libusb/libusbi.h b/libusb/libusbi.h index 335df11..b7932d0 100644 --- a/libusb/libusbi.h +++ b/libusb/libusbi.h @@ -281,6 +281,7 @@ struct libusb_device { uint8_t bus_number; uint8_t device_address; + char *physical_address; uint8_t num_configurations; enum libusb_speed speed; diff --git a/libusb/os/darwin_usb.c b/libusb/os/darwin_usb.c index e112cf5..3945931 100644 --- a/libusb/os/darwin_usb.c +++ b/libusb/os/darwin_usb.c @@ -728,6 +728,10 @@ static int process_new_device (struct libusb_context *ctx, usb_device_t **device dev->bus_number = locationID >> 24; dev->device_address = address; + if (asprintf(&dev->physical_address, "%08x", locationID) < 0) { + ret = LIBUSB_ERROR_NO_MEM; + break; + } (*device)->GetDeviceSpeed (device, &devSpeed); diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c index ad3c37a..ed4f755 100644 --- a/libusb/os/linux_usbfs.c +++ b/libusb/os/linux_usbfs.c @@ -822,6 +822,9 @@ static int initialize_device(struct libusb_device *dev, uint8_t busnum, if (!priv->sysfs_dir) return LIBUSB_ERROR_NO_MEM; strcpy(priv->sysfs_dir, sysfs_dir); + dev->physical_address = strdup(sysfs_dir); + if (!dev->physical_address) + return LIBUSB_ERROR_NO_MEM; /* Note speed can contain 1.5, in this case __read_sysfs_attr will stop parsing at the '.' and return 1 */ -- 1.7.4.1 |
From: Xiaofan C. <xia...@gm...> - 2012-04-03 22:46:10
|
On Tue, Mar 27, 2012 at 9:45 PM, <ek...@gm...> wrote: > From: Keith Mok <ek...@gm...> > > Add a function to retrieve a unique location string among all USB devices > in the system, which will not be changed on a system reboot unless the > topology of the usb bus itself changes. > How does this compared to previous topology works under libusb-pbatard branch? http://git.libusb.org/?p=libusb-pbatard.git;a=commit;h=11352921ecccf32217e14229579a8bafefd5d1c5;js=1 http://git.libusb.org/?p=libusb-pbatard.git;a=commit;h=e2eac96e80c047f2f2f32dd656e5039b7d9a5caf;js=1 -- Xiaofan |
From: Xiaofan C. <xia...@gm...> - 2012-04-05 09:56:02
|
Please always reply to the list. Thanks. On Thu, Apr 5, 2012 at 10:52 AM, Keith Mok <ek...@gm...> wrote: >> How does this compared to previous topology works under >> libusb-pbatard branch? > > This patch only give application an unique string for a particular > physical port that will not be changed upon reboot (if usb topology > remains the same,) > It does not give u the usb topology information. By storing that > unique string with a configuration file in application, application > can easily identify an usb device is connected to the same physical > port or not. > > The currently problem is that libusb_get_port_number is meaningless > for application especially in Linux arch. > That port number will increased by one when the same usb device is > plug and unplug to the same physical port, so application cannot know > the same usb device is connected to the same physical port or not. > Thanks for the explanation. Yes I know the above under Linux. Just wondering if you can use the method in libusb-pbatard to achieve what you want to achieve or not. And I am not so sure if what you do can be under Windows now that libusb-1.0 mainline git supports Windows. -- Xiaofan |
From: Keith M. <ek...@gm...> - 2012-04-05 15:25:21
|
> Just wondering if you can use the method in libusb-pbatard to > achieve what you want to achieve or not. The only reliable way I know for darwin to retrieve the physical address is via GetLocationID system call. But I did not see libusb-pbatard using this information. > And I am not so sure if what you do can be under > Windows now that libusb-1.0 mainline git supports > Windows. The unique physical address can be retrieved via the filename opened using CreateFileA function. Will provide separate patch after fully tested and after okayed with this patch. - Keith |
From: Peter S. <pe...@st...> - 2012-04-19 02:31:40
|
Hi Keith, ek...@gm... wrote: > From: Keith Mok <ek...@gm...> > > Add a function to retrieve a unique location string among all USB devices > in the system, which will not be changed on a system reboot unless the > topology of the usb bus itself changes. > > Signed-off-by: Keith Mok <ek...@gm...> > --- > examples/listdevs.c | 1 + > libusb/core.c | 15 +++++++++++++++ > libusb/libusb-1.0.def | 2 ++ > libusb/libusb.h | 1 + > libusb/libusbi.h | 1 + > libusb/os/darwin_usb.c | 4 ++++ > libusb/os/linux_usbfs.c | 3 +++ > 7 files changed, 27 insertions(+), 0 deletions(-) Please include implementations for all supported systems in the same commit, or create one commit for the new API, followed by a single commit for the implementation of each platform. I don't care much which way you do it, but it's all or nothing. > diff --git a/examples/listdevs.c b/examples/listdevs.c > index 6ab8917..0a13181 100644 > --- a/examples/listdevs.c > +++ b/examples/listdevs.c > @@ -38,6 +38,7 @@ static void print_devs(libusb_device **devs) > printf("%04x:%04x (bus %d, device %d)\n", > desc.idVendor, desc.idProduct, > libusb_get_bus_number(dev), libusb_get_device_address(dev)); > + printf("Physical address: %s\n", libusb_get_physical_address(dev)); Please just add the address into the existing printf so that the program still outputs a single line per device. > +++ b/libusb/core.c > @@ -690,6 +690,19 @@ uint8_t API_EXPORTED libusb_get_device_address(libusb_device *dev) > } > > /** \ingroup dev > + * Get string to represent the unique physical address among all USB devices of > + * the system, and which will not change on a system reboot unless the > + * topology of the usb changes. > + * \param dev a device > + * \returns the physical address, or NULL if platform not supported > + */ The API must be portable. Meaning that given two different operating systems on the same physical machine with the same USB device in the same port the API must return the same value. I don't think a string is a good way to implement this API. Is there any platform where we can not find the actual topology, and return a uint8_t port[7] with each element in the array being the port number on the hub for that topology level, with trailing elements set to 0? > +++ b/libusb/libusb.h > @@ -953,6 +953,7 @@ void LIBUSB_CALL libusb_free_config_descriptor( > struct libusb_config_descriptor *config); > uint8_t LIBUSB_CALL libusb_get_bus_number(libusb_device *dev); > uint8_t LIBUSB_CALL libusb_get_device_address(libusb_device *dev); > +const char* LIBUSB_CALL libusb_get_physical_address(libusb_device *dev); Add a space between char and * here for all char * APIs. Keith Mok wrote: > > Just wondering if you can use the method in libusb-pbatard to > > achieve what you want to achieve or not. > The only reliable way I know for darwin to retrieve the physical > address is via GetLocationID system call. > But I did not see libusb-pbatard using this information. Can't get actual topology? > > And I am not so sure if what you do can be under > > Windows now that libusb-1.0 mainline git supports > > Windows. > The unique physical address can be retrieved via the filename > opened using CreateFileA function. No, if the value will survive reboots then it must also survive across operating systems. > Will provide separate patch after fully tested and after okayed > with this patch. See above. Either one big patch for all backends or one patch that adds API and followup patches per backend. //Peter |