Wireless mouse battery level patch

Matthew Williams mrw7mrw at yahoo.ca
Fri Sep 15 10:34:54 PDT 2006


I've put together a patch that fixes a problem with hal being unable to read
the battery level of wireless mice.

The root problem is that libusb used to populate its internal data
structures by looking at the /proc/bus/usb directory structure, which uses
zero-padded 3 digit hex numbers to identify USB buses and devices.  I.e. the
third device on bus two would be known as '002/003'W.

Libusb now either populates itself using /dev/bus/usb or /proc/bus/usb with
the former being preferred.  /dev/bus/usb doesn't zero-pad and it uses
decimal numbers, not hex.  The code in addon-usb-csr.c assumed the old
behaviour and used string comparisons to try to find the right device.  This
would obviously fail as the new way of describing the above device is '2/3'
which != '002/003'.

The patch simply looks at the bus number and if it is 3 digits, assumes old
libusb behaviour, else it assumes the new behaviour.  The device number
comparison is even easier as the device number is also stored as an unsigned
char.

Matt
-------------- next part --------------
--- addon-usb-csr.c	2005-11-02 10:38:14.000000000 -0500
+++ addon-usb-csr.c.new	2006-09-15 13:04:15.000000000 -0400
@@ -27,6 +27,7 @@
 #include <config.h>
 #include <stdio.h>
 #include <usb.h>
+#include <string.h>
 
 #include <glib/gmain.h>
 #include <dbus/dbus-glib.h>
@@ -167,29 +168,40 @@
 find_device (const char *hal_device_udi, PropertyCacheItem *pci)
 {
 	struct usb_bus* curr_bus;
-	char LUdirname[5];
-	char LUfname[5];
 
 	if (!(pci->bus_no_present && pci->port_no_present)) {
 		/* no sysfs path */
 		fprintf (stderr, "No hal bus number and/or port number");
 		return NULL;
 	}
-	snprintf (LUdirname, sizeof (LUdirname), "%03d", pci->bus_no);
-	snprintf (LUfname, sizeof (LUfname), "%03d",pci->port_no);
-	dbg ("Looking for: [%s][%s]", LUdirname, LUfname);
+	dbg ("Looking for: [%d][%d]", pci->bus_no, pci->port_no);
 
+	int busnum=0;
 	for (curr_bus = usb_busses; curr_bus != NULL; curr_bus = curr_bus->next) {
  		struct usb_device *curr_device;
 		/* dbg ("Checking bus: [%s]", curr_bus->dirname); */
-		if (g_strcasecmp (LUdirname, curr_bus->dirname))
+		/* older versions of libusb return zero padded 3 hex digit
+		   dirnames and newer versions return non zero padded decimal
+		   dirnames */
+		if (strlen(curr_bus->dirname) == 3) {
+			if (sscanf(curr_bus->dirname,"%03x",&busnum) != 1) {
+				continue;
+			}
+		} else {
+			if (sscanf(curr_bus->dirname,"%d",&busnum) != 1) {
+				continue;
+			}
+		}
+		if (busnum != pci->bus_no) {
 			continue;
+		}
 
  		for (curr_device = curr_bus->devices; curr_device != NULL; 
 		     curr_device = curr_device->next) {
 			/* dbg ("Checking port: [%s]", curr_device->filename); */
-			if (g_strcasecmp (LUfname, curr_device->filename))
+			if (pci->port_no != curr_device->devnum) {
 				continue;
+			}
 			dbg ("Matched device: [%s][%s][%04X:%04X]", curr_bus->dirname, 
 				curr_device->filename, 
 				curr_device->descriptor.idVendor, 


More information about the hal mailing list