hal/hald/linux2/addons addon-usb-csr.c,1.6,1.7

David Zeuthen david at freedesktop.org
Fri Jul 29 13:21:56 PDT 2005


Update of /cvs/hal/hal/hald/linux2/addons
In directory gabe:/tmp/cvs-serv1379/hald/linux2/addons

Modified Files:
	addon-usb-csr.c 
Log Message:
2005-07-29  David Zeuthen  <davidz at redhat.com>

        Patch from Richard Hughes <richard at hughsie.com>.

        * hald/linux2/addons/addon-usb-csr.c: Change default polling to 30
        seconds as mice discharge *very* slowly and do not need to be polled
        once every 10 seconds.
        Add to addon-usb-csr the key battery.charge_level.percentage so we can
        provide a better interface to programs that use this data.
        Also reformat this file so that it matches the rest of the HAL source
        in style, and get rid of the spaces-for-tabs.



Index: addon-usb-csr.c
===================================================================
RCS file: /cvs/hal/hal/hald/linux2/addons/addon-usb-csr.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- addon-usb-csr.c	12 May 2005 20:26:48 -0000	1.6
+++ addon-usb-csr.c	29 Jul 2005 20:21:54 -0000	1.7
@@ -4,6 +4,7 @@
  * hal_addon_usb_csr.c : daemon handling CSR-based wireless mice
  *
  * Copyright (C) 2004 Sergey V. Udaltsov <svu at gnome.org>
+ * Copyright (C) 2005 Richard Hughes <richard at hughsie.com>
  *
  * Licensed under the Academic Free License version 2.0
  *
@@ -14,19 +15,17 @@
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  *
  **************************************************************************/
 
 #include <config.h>
-
 #include <stdio.h>
-
 #include <usb.h>
 
 #include <glib/gmain.h>
@@ -36,248 +35,142 @@
 #include "libhal/libhal.h"
 #include "../probing/shared.h"
 
-#define CMD_IFACE_PROPERTY "battery.command_interface"
-#define BUS_NO_PROPERTY "usb_device.bus_number"
-/* linux!!! */
-#define PORT_NO_PROPERTY "usb_device.linux.device_number"
-
+#define TIMEOUT         30L
 
-#define CSR_IS_DUAL_PROPERTY "battery.csr.is_dual"
-#define CURRENT_CHARGE_PROPERTY "battery.charge_level.current"
+/* Internal CSR registered, I presume - for some reason not addressed directly */
+#define P6  (buf[0])
+#define P0  (buf[1])
+#define P4  (buf[2])
+#define P5  (buf[3])
+#define P8  (buf[4])
+#define P9  (buf[5])
+#define PB0 (buf[6])
+#define PB1 (buf[7])
 
 typedef struct _PropertyCacheItem
 {
 	gboolean bus_no_present;
 	int bus_no;
-
 	gboolean port_no_present;
 	int port_no;
-
 	gboolean csr_is_dual_present;
 	gboolean csr_is_dual;
-
 	gboolean current_charge_present;
 	int current_charge;
 } PropertyCacheItem;
 
-static PropertyCacheItem * dev_props = NULL;
-
-static LibHalContext * hal_context = NULL;
-
-static GMainLoop* main_loop;
-
-static const char* the_device_udi;
-
-#define TIMEOUT         0x1000
-
-static void update_properties (void)
-{
-#if 0
-          <merge key="info.category" type="string">battery</merge>
-          <merge key="info.capabilities" type="string">battery</merge>
-          <merge key="battery.charge_level.maximum.specified" type="int">7</merge>
-          <merge key="battery.is_rechargeable" type="bool">false</merge>
-#endif
-	DBusError err;
-	dbus_error_init (&err);
-
-	libhal_device_set_property_bool (hal_context, 
-					 the_device_udi, 
-					 "battery.present", TRUE,
-					 &err);
-	if (!libhal_device_property_exists (hal_context,
-					   the_device_udi,
-					   "battery.is_rechargeable",
-					    &err)) {
-		libhal_device_set_property_bool (hal_context, 
-						 the_device_udi, 
-						 "battery.is_rechargeable", FALSE,
-						 &err);
-	}
-	libhal_device_set_property_int (hal_context, 
-					the_device_udi, 
-					"battery.charge_level.design", 7,
-					&err);
-	libhal_device_set_property_int (hal_context, 
-					the_device_udi, 
-					"battery.charge_level.last_full", 7,
-					&err);
-
-	libhal_device_set_property_string (hal_context, 
-					   the_device_udi, 
-					   "info.category", "battery",
-					   &err);
-
-	libhal_device_set_property_string (hal_context, 
-					   the_device_udi, 
-					   "battery.command_interface", "csr",
-					   &err);
-}
+/* globals */
+static PropertyCacheItem *dev_props = NULL;
+static LibHalContext *halctx = NULL;
+static GMainLoop *main_loop;
+static const char *device_udi;
 
-static void add_capability (void)
-{
-	DBusError err;
-	dbus_error_init (&err);
-	libhal_device_add_capability (hal_context, 
-				      the_device_udi, 
-				      "battery",
-				      &err);
-}
+/* prototypes */
+static struct usb_device *find_device (const char *hal_device_udi, PropertyCacheItem *pci);
 
 static PropertyCacheItem* 
-property_cache_item_get (const char * hal_device_udi)
+property_cache_item_get (const char *hal_device_udi)
 {
 	PropertyCacheItem * pci = g_new0 (PropertyCacheItem,1);
 	DBusError err;
 	dbus_error_init (&err);
 
-	pci->bus_no_present = libhal_device_property_exists (hal_context,
-							     hal_device_udi,
-							     BUS_NO_PROPERTY,
-							     &err);
+	pci->bus_no_present = libhal_device_property_exists (halctx, hal_device_udi, 
+			"usb_device.bus_number", &err);
 	if (dbus_error_is_set (&err))
-	{
 		dbg ("Error: [%s]/[%s]", err.name, err.message);	
-	}
 
 	if (pci->bus_no_present)
-		pci->bus_no = libhal_device_get_property_int (hal_context,
-							      hal_device_udi,
-							      BUS_NO_PROPERTY,
-							      &err);
+		pci->bus_no = libhal_device_get_property_int (halctx, hal_device_udi, 
+			"usb_device.bus_number", &err);
 
-	pci->port_no_present = libhal_device_property_exists (hal_context,
-							      hal_device_udi,
-							      PORT_NO_PROPERTY,
-							      &err);
+	pci->port_no_present = libhal_device_property_exists (halctx, hal_device_udi, 
+			"usb_device.linux.device_number", &err);
 	if (pci->port_no_present)
-		pci->port_no = libhal_device_get_property_int (hal_context,
-							       hal_device_udi,
-							       PORT_NO_PROPERTY,
-							       &err);
-
+		pci->port_no = libhal_device_get_property_int (halctx, hal_device_udi, 
+			"usb_device.linux.device_number", &err);
 
-	pci->csr_is_dual_present = libhal_device_property_exists (hal_context,
-								  hal_device_udi,
-								  CSR_IS_DUAL_PROPERTY,
-								  &err);
+	pci->csr_is_dual_present = libhal_device_property_exists (halctx, hal_device_udi,
+			"battery.csr.is_dual",  &err);
 	if (pci->csr_is_dual_present)
-		pci->csr_is_dual = libhal_device_get_property_bool (hal_context,
-								    hal_device_udi,
-								    CSR_IS_DUAL_PROPERTY,
-								    &err);
-
+		pci->csr_is_dual = libhal_device_get_property_bool (halctx, hal_device_udi,
+			"battery.csr.is_dual",  &err);
 
-	pci->current_charge_present = libhal_device_property_exists (hal_context,
-								     hal_device_udi,
-								     CURRENT_CHARGE_PROPERTY,
-							             &err);
+	pci->current_charge_present = libhal_device_property_exists (halctx, hal_device_udi, 
+			"battery.charge_level.current", &err);
 	if (pci->current_charge_present)
-		pci->current_charge = libhal_device_get_property_int (hal_context,
-								      hal_device_udi,
-								      CURRENT_CHARGE_PROPERTY,
-							              &err);
+		pci->current_charge = libhal_device_get_property_int (halctx, hal_device_udi, 
+			"battery.charge_level.current", &err);
 
 	return pci;
 }
 
-static void
-property_cache_item_free (PropertyCacheItem* pci)
-{
-	if (pci == NULL)
-		return;
-	g_free (pci);
-}
-
-static struct usb_device* 
-find_device (const char * hal_device_udi, PropertyCacheItem * pci);
-
 /* Thanks to lmctl code. I'd LOVE, REALLY LOVE to see some docs though... */
 static void 
-check_battery (const char * hal_device_udi, PropertyCacheItem * pci)
+check_battery (const char *hal_device_udi, PropertyCacheItem *pci)
 {
-	struct usb_device *current_usb_device;
-        usb_dev_handle * handle;
-        unsigned char buf[80];
+	struct usb_device *curr_device;
+	usb_dev_handle *handle;
+	char buf[80];
 	DBusError err;
-/* Internal CSR registered, I presume - for some reason not addressed directly */
-#define P6  (buf[0])
-#define P0  (buf[1])
-#define P4  (buf[2])
-#define P5  (buf[3])
-#define P8  (buf[4])
-#define P9  (buf[5])
-#define PB0 (buf[6])
-#define PB1 (buf[7])
-        unsigned int  addr;
+	unsigned int addr;
 	int is_dual = 0;
+	int percentage = 0;
 
 	if (pci == NULL)
 		return;
 
 	dbg ("CSR device: [%s]", hal_device_udi);
-
 	is_dual = pci->csr_is_dual;
 
 	/* Which of subdevices to address */
 	dbg ("Is dual: %d", is_dual);
-        addr = is_dual? 1<<8 : 0;
+	addr = is_dual? 1<<8 : 0;
 
-	current_usb_device = find_device (hal_device_udi, pci);
-	if (current_usb_device == NULL)
-	{
+	curr_device = find_device (hal_device_udi, pci);
+	if (curr_device == NULL)	{
 		fprintf (stderr, "Device %s not found", hal_device_udi);
 		return;
 	}
 
-        handle = usb_open (current_usb_device);
-	if (handle == NULL)
-	{
+	handle = usb_open (curr_device);
+	if (handle == NULL) {
 		perror ("Could not open usb device");
 		return;
 	}
 
 	if (!usb_control_msg (handle, 0xc0, 0x09, 0x03|addr, 0x00|addr,
-			      buf, 8, TIMEOUT) != 8)
-	{
-		if ((P0 == 0x3b) && (P4 == 0))
-		{
+			 buf, 8, TIMEOUT) != 8)	{
+		if ((P0 == 0x3b) && (P4 == 0)) {
 			dbg ("Receiver busy, trying again later");
-		} else
-		{
+		} else {
 			int current_charge = P5 & 0x07;
 
-			dbg ("Charge level: %d->%d", 
-				pci->current_charge, current_charge);
-			if (current_charge != pci->current_charge)
-			{
-				pci->current_charge = current_charge;
-				dbus_error_init (&err);
-		    		libhal_device_set_property_int (hal_context, 
-							        hal_device_udi, 
-							        CURRENT_CHARGE_PROPERTY,
-							        current_charge,
-							        &err);
+			dbg ("Charge level: %d->%d", pci->current_charge, current_charge);
+			if (current_charge != pci->current_charge) { 
+			pci->current_charge = current_charge; dbus_error_init (&err);
+		 		libhal_device_set_property_int (halctx, hal_device_udi, 
+		 			"battery.charge_level.current", current_charge, &err);
+		 		if (current_charge != 0)
+		 			percentage = (100.0 / 7.0) * current_charge;
+		 		libhal_device_set_property_int (halctx, hal_device_udi, 
+		 			"battery.charge_level.percentage", percentage, &err);
 			}
 		}
 	} else
-	{
 		perror ("Writing to USB device");
-        }
-
 	usb_close (handle);
 }
 
 /* TODO: Is it linux-specific way to find the device? */
 static struct usb_device* 
-find_device (const char * hal_device_udi, PropertyCacheItem * pci)
+find_device (const char *hal_device_udi, PropertyCacheItem *pci)
 {
-	struct usb_bus* current_usb_bus;
+	struct usb_bus* curr_bus;
 	char LUdirname[5];
 	char LUfname[5];
 
-	if (!(pci->bus_no_present && pci->port_no_present))
-	{
+	if (!(pci->bus_no_present && pci->port_no_present)) {
 		/* no sysfs path */
 		fprintf (stderr, "No hal bus number and/or port number");
 		return NULL;
@@ -286,28 +179,22 @@
 	snprintf (LUfname, sizeof (LUfname), "%03d",pci->port_no);
 	dbg ("Looking for: [%s][%s]", LUdirname, LUfname);
 
-	for (current_usb_bus = usb_busses; 
-	     current_usb_bus != NULL; 
-	     current_usb_bus = current_usb_bus->next)
-	{
-        	struct usb_device *current_usb_device;
-		/* dbg ("Checking bus: [%s]", current_usb_bus->dirname); */
-		if (g_strcasecmp (LUdirname, current_usb_bus->dirname))
+	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))
 			continue;
 
-        	for (current_usb_device = current_usb_bus->devices; 
-		     current_usb_device != NULL; 
-		     current_usb_device = current_usb_device->next) 
-		{
-			/* dbg ("Checking port: [%s]", current_usb_device->filename); */
-			if (g_strcasecmp (LUfname, current_usb_device->filename))
+ 		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))
 				continue;
-			dbg ("Matched device: [%s][%s][%04X:%04X]", 
-				current_usb_bus->dirname, 
-				current_usb_device->filename,
-				current_usb_device->descriptor.idVendor,
-				current_usb_device->descriptor.idProduct);
-			return current_usb_device;
+			dbg ("Matched device: [%s][%s][%04X:%04X]", curr_bus->dirname, 
+				curr_device->filename, 
+				curr_device->descriptor.idVendor, 
+				curr_device->descriptor.idProduct);
+			return curr_device;
 		}
 	}
 	return NULL;
@@ -317,122 +204,119 @@
 check_all_batteries (gpointer data)
 {
 	dbg ("** Check batteries");
-
 	/* TODO: make it configurable (not to rescan every time) */
 	usb_find_busses ();
 	usb_find_devices ();
-
-	check_battery (the_device_udi, dev_props);
-
+	check_battery (device_udi, dev_props);
 	return TRUE;
 }
 
 static gboolean 
 is_the_device (const char *hal_device_udi)
 {
-	return !g_ascii_strcasecmp (the_device_udi, hal_device_udi);
+	return !g_ascii_strcasecmp (device_udi, hal_device_udi);
 }
 
 static void
 device_removed (LibHalContext *ctx, const char *hal_device_udi)
 {
 	/* this device is removed */
-	if (is_the_device (hal_device_udi))
-	{
-		dbg ("** The device %s removed, exit", the_device_udi);
+	if (is_the_device (hal_device_udi)) {
+		dbg ("** The device %s removed, exit", device_udi);
 		g_main_loop_quit (main_loop);
 	}
 }
 
 static void 
 property_modified (LibHalContext *ctx,
-		   const char *hal_device_udi,
-		   const char *key,
-		   dbus_bool_t is_removed,
-		   dbus_bool_t is_added)
+		 const char *hal_device_udi,
+		 const char *key,
+		 dbus_bool_t is_removed,
+		 dbus_bool_t is_added)
 {
 	/* "Key" property modified */
-	if (!g_ascii_strcasecmp (key, CMD_IFACE_PROPERTY))
-	{
-		if (is_removed)
-		{
+	if (!g_ascii_strcasecmp (key, "battery.command_interface")) {
+		if (is_removed) {
 			dbg ("** Main Property %s removed: %s", key, hal_device_udi);
 			/* probably we'll have to exit if this is our device */
 			device_removed (ctx, hal_device_udi);
 		}
 	} else
-	/* "Secondary" property modified */
-	if (is_the_device (hal_device_udi))
-	{
-		if (!(g_ascii_strcasecmp (key, BUS_NO_PROPERTY) &&
-		      g_ascii_strcasecmp (key, PORT_NO_PROPERTY) &&
-	    	      g_ascii_strcasecmp (key, CSR_IS_DUAL_PROPERTY)))
+		/* "Secondary" property modified */
+		if (is_the_device (hal_device_udi))
 		{
-			dbg ("** Property %s added/changed: %s", 
-				key, hal_device_udi);
-			property_cache_item_free (dev_props);
-			dev_props = property_cache_item_get (hal_device_udi);
+			if (!(g_ascii_strcasecmp (key, "usb_device.bus_number") &&
+			      g_ascii_strcasecmp (key, "usb_device.linux.device_number") &&
+	 		      g_ascii_strcasecmp (key, "battery.csr.is_dual"))) {
+				dbg ("** Property %s added/changed: %s", key, hal_device_udi);
+				if (dev_props)
+					g_free (dev_props);
+				dev_props = property_cache_item_get (hal_device_udi);
+			}
 		}
-	}
-}
-
-static void
-initial_fillup (void)
-{
-	dbg ("** Initial fillup");
-	dev_props = property_cache_item_get (the_device_udi);
-	dbg ("** Initial fillup done");
 }
 
 int
 main (int argc, char *argv[])
 {
-	/* TODO: make it configurable*/
-	long check_interval = 10L;
-        DBusConnection *conn;
 	DBusError err;
 	
-        if ((getenv ("HALD_VERBOSE")) != NULL)
-                is_verbose = TRUE;
+	if ((getenv ("HALD_VERBOSE")) != NULL)
+		is_verbose = TRUE;
 
-	the_device_udi = getenv ("UDI");
+	device_udi = getenv ("UDI");
 
-	dbg ("device:[%s]", the_device_udi);
-	if (the_device_udi == NULL)
-	{
+	dbg ("device:[%s]", device_udi);
+	if (device_udi == NULL) {
 		fprintf (stderr, "No device specified");
 		return -2;
 	}
 
 	dbus_error_init (&err);
-	if ((hal_context = libhal_ctx_init_direct (&err)) == NULL) {
+	if ((halctx = libhal_ctx_init_direct (&err)) == NULL) {
 		fprintf (stderr, "Cannot connect to hald");
 		return -3;
 	}
 
-	update_properties ();
+	/* update_properties */
+	dbus_error_init (&err);
+	libhal_device_set_property_bool (halctx, device_udi, 
+			"battery.present", TRUE, &err);
+	if (!libhal_device_property_exists (halctx, device_udi, 
+			"battery.is_rechargeable", &err))
+		libhal_device_set_property_bool (halctx, device_udi, 
+			"battery.is_rechargeable", FALSE, &err);
+	libhal_device_set_property_int (halctx, device_udi, 
+			"battery.charge_level.design", 7, &err);
+	libhal_device_set_property_int (halctx, device_udi, 
+			"battery.charge_level.last_full", 7, &err);
+	libhal_device_set_property_string (halctx, device_udi, 
+			"info.category", "battery", &err);
+	libhal_device_set_property_string (halctx, device_udi, 
+			"battery.command_interface", "csr", &err);
 
-	libhal_ctx_set_device_property_modified (hal_context, property_modified);
+	/* monitor change */
+	libhal_ctx_set_device_property_modified (halctx, property_modified);
 
-	initial_fillup ();
+	/* Initial fillup */
+	dev_props = property_cache_item_get (device_udi);
+	dbg ("** Initial fillup done");
 
+	/* init usb */
 	usb_init ();
 	
-	dbg ("** Addon started");
-
 	/* do coldplug */
 	check_all_batteries (NULL);
 
 	/* only add capability when initial charge_level key has been set */
-	add_capability ();
+	dbus_error_init (&err);
+	libhal_device_add_capability (halctx, device_udi, "battery", &err);
 
 	main_loop = g_main_loop_new (NULL, FALSE);
-
-	g_timeout_add (1000L * check_interval, check_all_batteries, NULL);
-
+	g_timeout_add (1000L * TIMEOUT, check_all_batteries, NULL);
 	g_main_loop_run (main_loop);
 
-	libhal_ctx_shutdown (hal_context, &err);
+	libhal_ctx_shutdown (halctx, &err);
 	dbg ("** Addon exits normally");
 	return 0;
 }




More information about the hal-commit mailing list