[PATCH 0/3] WOL: Add Wake On LAN support

Holger Macht hmacht at suse.de
Fri Aug 17 03:01:01 PDT 2007


On Tue 14. Aug - 14:57:49, Bastien Nocera wrote:
> On Tue, 2007-08-14 at 15:44 +0200, Holger Macht wrote:
> > On Tue 14. Aug - 14:34:11, Bastien Nocera wrote:
> > > On Tue, 2007-08-14 at 15:21 +0200, Holger Macht wrote:
> > > > The following patch series adds support for Wake On LAN (WOL) to HAL. In
> > > > this context, adding Wake On LAN support means adding support for ethtool,
> > > > which is supported by various drivers.
> > > > 
> > > > I was surprised to see for how many systems this actually works. The
> > > > common problem is just that it's not configured correctly on most distros,
> > > > and that there is no easy way to enable/disable it from the desktop if
> > > > supported.
> > > > 
> > > > The patches add the following new interface to any network device with the
> > > > capability 'net.80203':
> > > > 
> > > >  org.freedesktop.Hal.Device.WakeOnLan
> > > > 
> > > > The interface provides the following methods:
> > > > 
> > > >  GetSupported(void)
> > > 
> > > As whether the device supports it is unlikely to change, why not make
> > > this a property?
> > > 
> > > You'd probably need to add the detection in the coldplug routine of HAL.

Patch inline. Net interfaces had probe-net-bluetooth.c as their prober
application. You can only add one prober, so I renamed it to a more
general probe-net.c prober which now also contains the wake on LAN support
check which adds a 'wake_on_lan' capability to the device if appropriate.

BTW: The header of probe-bluetooth-net.c is somehow broken ;-)

Signed-off-by: Holger Macht <hmacht at suse.de>
---

diff --git a/hald/linux/device.c b/hald/linux/device.c
index c6e9942..e3ec662 100644
--- a/hald/linux/device.c
+++ b/hald/linux/device.c
@@ -562,14 +562,7 @@ error:
 static const char *
 net_get_prober (HalDevice *d)
 {
-	const char *prober = NULL;
-
-	/* run prober only for bluetooth devices */
-	if (hal_device_has_capability (d, "net.bluetooth")) {
-		prober = "hald-probe-net-bluetooth";
-	}
-
-	return prober;
+	return "hald-probe-net";
 }
 
 static gboolean
diff --git a/hald/linux/probing/Makefile.am b/hald/linux/probing/Makefile.am
index 9b2f1bd..6d16182 100644
--- a/hald/linux/probing/Makefile.am
+++ b/hald/linux/probing/Makefile.am
@@ -10,7 +10,7 @@ AM_CPPFLAGS = \
 
 if HALD_COMPILE_LINUX
 libexec_PROGRAMS = hald-probe-input hald-probe-hiddev hald-probe-storage hald-probe-volume hald-probe-printer \
-	           hald-probe-pc-floppy hald-probe-smbios hald-probe-serial hald-probe-ieee1394-unit hald-probe-net-bluetooth
+	           hald-probe-pc-floppy hald-probe-smbios hald-probe-serial hald-probe-ieee1394-unit hald-probe-net
 endif
 
 hald_probe_smbios_SOURCES = probe-smbios.c ../../logger.c
@@ -40,5 +40,5 @@ hald_probe_volume_LDADD = $(top_builddir)/libhal/libhal.la $(top_builddir)/partu
 hald_probe_ieee1394_unit_SOURCES = probe-ieee1394-unit.c ../../logger.c
 hald_probe_ieee1394_unit_LDADD = $(top_builddir)/libhal/libhal.la
 
-hald_probe_net_bluetooth_SOURCES = probe-net-bluetooth.c ../../logger.c
-hald_probe_net_bluetooth_LDADD = $(top_builddir)/libhal/libhal.la
+hald_probe_net_SOURCES = probe-net.c ../../logger.c
+hald_probe_net_LDADD = $(top_builddir)/libhal/libhal.la
diff --git a/hald/linux/probing/probe-net-bluetooth.c b/hald/linux/probing/probe-net-bluetooth.c
deleted file mode 100644
index 854e8e7..0000000
--- a/hald/linux/probing/probe-net-bluetooth.c
+++ /dev/null
@@ -1,233 +0,0 @@
-/***************************************************************************
- * CVSID: $Id$
- *
- * probe-net-bluetooth.c : Probe bluetooth network devices
- *
- * Copyright (C) 2007 Luiz Augusto von Dentz, <luiz.dentz at indt.org.br>
- *
- * Licensed under the Academic Free License version 2.1
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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
- * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- **************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#  include <config.h>
-#endif
-
-#include <string.h>
-
-#include "../../logger.h"
-#include "libhal/libhal.h"
-
-#define BLUEZ_SERVICE "org.bluez"
-#define BLUEZ_PATH "/org/bluez"
-#define BLUEZ_MANAGER_IFACE "org.bluez.Manager"
-#define BLUEZ_NET_PATH "/org/bluez/network"
-#define BLUEZ_NET_MANAGER_IFACE "org.bluez.network.Manager"
-#define BLUEZ_NET_CONNECTION_IFACE "org.bluez.network.Connection"
-#define BLUEZ_NET_SERVER_IFACE "org.bluez.network.Server"
-
-static void
-get_properties (DBusConnection *conn, LibHalContext *ctx, const char *udi,
-				const char *id, const char *path)
-{
-	DBusMessage *msg;
-	DBusMessage *reply = NULL;
-	DBusMessageIter reply_iter;
-	DBusMessageIter dict_iter;
-	DBusError error;
-
-	dbus_error_init (&error);
-
-	msg = dbus_message_new_method_call (id, path,
-										BLUEZ_NET_CONNECTION_IFACE,
-										"GetInfo");
-
-	if (msg == NULL)
-		goto out;
-
-	HAL_INFO (("%s.GetInfo()", BLUEZ_NET_CONNECTION_IFACE));
-	reply = dbus_connection_send_with_reply_and_block (conn, msg, -1, &error);
-
-	if (dbus_error_is_set (&error) || dbus_set_error_from_message (&error,
-		reply)) {
-		dbus_error_free (&error);
-		goto out;
-	}
-
-	dbus_message_iter_init (reply, &reply_iter);
-
-	if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_ARRAY  &&
-	    dbus_message_iter_get_element_type (&reply_iter) != DBUS_TYPE_DICT_ENTRY) {
-		goto out;
-	}
-
-	dbus_message_iter_recurse (&reply_iter, &dict_iter);
-
-	while (dbus_message_iter_get_arg_type (&dict_iter) == DBUS_TYPE_DICT_ENTRY) {
-		DBusMessageIter dict_entry_iter, var_iter;
-		const char *key;
-		char prop[32];
-
-		dbus_message_iter_recurse (&dict_iter, &dict_entry_iter);
-		dbus_message_iter_get_basic (&dict_entry_iter, &key);
-
-		dbus_message_iter_next (&dict_entry_iter);
-		dbus_message_iter_recurse (&dict_entry_iter, &var_iter);
-
-                snprintf(prop, sizeof (prop), "net.bluetooth.%s", key);
-
-		/* Make any property found annouced by hal */
-		switch (dbus_message_iter_get_arg_type (&var_iter)) {
-		case DBUS_TYPE_STRING:
-		{
-			const char *value;
-
-			dbus_message_iter_get_basic (&var_iter, &value);
-
-			HAL_INFO (("reply: %s:%s", key, value));
-
-			libhal_device_set_property_string (ctx, udi, prop, value, &error);
-			break;
-		}
-		case DBUS_TYPE_INT32:
-		{
-			dbus_int32_t value;
-
-			dbus_message_iter_get_basic (&var_iter, &value);
-
-			HAL_INFO (("reply: %s:%d", key, value));
-
-			libhal_device_set_property_int (ctx, udi, prop, value, &error);
-			break;
-		}
-		default:
-			break;
-		}
-		dbus_message_iter_next (&dict_iter);
-	}
-
-out:
-	if (msg)
-		dbus_message_unref (msg);
-	if (reply)
-		dbus_message_unref (reply);
-	return;
-}
-
-int
-main (int argc, char *argv[])
-{
-	char *udi;
-	char *iface;
-	char *id;
-	const char *connection;
-	char network[8] = "network";
-	const char *pnetwork = network;
-	LibHalContext *ctx = NULL;
-	DBusConnection *conn;
-	DBusMessage *msg = NULL;
-	DBusMessage *reply = NULL;
-	DBusError error;
-
-	udi = getenv ("UDI");
-	if (udi == NULL)
-		goto out;
-
-	dbus_error_init (&error);
-	if ((ctx = libhal_ctx_init_direct (&error)) == NULL)
-		goto out;
-
-	iface = libhal_device_get_property_string (ctx, udi, "net.interface", NULL);
-
-	HAL_INFO (("Investigating '%s'", iface));
-
-	if (iface == NULL)
-		goto out;
-
-	if ((conn = dbus_bus_get (DBUS_BUS_SYSTEM, &error)) == NULL)
-		goto out;
-
-	msg = dbus_message_new_method_call (BLUEZ_SERVICE, BLUEZ_PATH, BLUEZ_MANAGER_IFACE, "ActivateService");
-
-	if (msg == NULL)
-		goto out;
-
-	HAL_INFO (("%s.ActivateService('%s')", BLUEZ_MANAGER_IFACE, pnetwork));
-	dbus_message_append_args (msg, DBUS_TYPE_STRING, &pnetwork,
-								DBUS_TYPE_INVALID);
-	reply = dbus_connection_send_with_reply_and_block (conn, msg, -1, &error);
-
-	if (dbus_error_is_set (&error) || dbus_set_error_from_message (&error, reply)) {
-		dbus_error_free (&error);
-		goto out;
-	}
-
-	dbus_message_unref (msg);
-	msg = NULL;
-
-	dbus_message_get_args (reply, &error, DBUS_TYPE_STRING, &id, DBUS_TYPE_INVALID);
-	if (dbus_error_is_set (&error)) {
-		dbus_error_free (&error);
-		goto out;
-	}
-
-	dbus_message_unref (reply);
-	reply = NULL;
-
-	HAL_INFO (("Found Bluez Network service '%s'", id));
-
-	msg = dbus_message_new_method_call (id, BLUEZ_NET_PATH, BLUEZ_NET_MANAGER_IFACE, "FindConnection");
-
-	if (msg == NULL)
-		goto out;
-
-	HAL_INFO (("%s.FindConnection('%s')", BLUEZ_NET_MANAGER_IFACE, iface));
-	dbus_message_append_args (msg, DBUS_TYPE_STRING, &iface,
-							DBUS_TYPE_INVALID);
-	reply = dbus_connection_send_with_reply_and_block (conn, msg, -1, &error);
-
-	if (dbus_error_is_set (&error) || dbus_set_error_from_message (&error,
-		reply)) {
-		dbus_error_free (&error);
-		goto out;
-	}
-
-	dbus_message_unref (msg);
-	msg = NULL;
-
-	dbus_message_get_args (reply, &error, DBUS_TYPE_STRING, &connection,
-							DBUS_TYPE_INVALID);
-	if (dbus_error_is_set (&error)) {
-		dbus_error_free (&error);
-		goto out;
-	}
-
-	get_properties (conn, ctx, udi, id, connection);
-
-out:
-	if (msg)
-		dbus_message_unref (msg);
-	if (reply)
-		dbus_message_unref (reply);
-	if (ctx != NULL) {
-		dbus_error_init (&error);
-		libhal_ctx_shutdown (ctx, &error);
-		libhal_ctx_free (ctx);
-	}
-
-	return 0;
-}
diff --git a/hald/linux/probing/probe-net.c b/hald/linux/probing/probe-net.c
new file mode 100644
index 0000000..8f3d672
--- /dev/null
+++ b/hald/linux/probing/probe-net.c
@@ -0,0 +1,296 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * probe-net.c : Probe bluetooth network devices and wake on lan properties
+ *
+ * Copyright (C) 2007 Luiz Augusto von Dentz, <luiz.dentz at indt.org.br>
+ * Copyright (C) 2007 Holger Macht <holger at homac.de>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <string.h>
+
+#include "../../logger.h"
+#include "libhal/libhal.h"
+
+#define BLUEZ_SERVICE "org.bluez"
+#define BLUEZ_PATH "/org/bluez"
+#define BLUEZ_MANAGER_IFACE "org.bluez.Manager"
+#define BLUEZ_NET_PATH "/org/bluez/network"
+#define BLUEZ_NET_MANAGER_IFACE "org.bluez.network.Manager"
+#define BLUEZ_NET_CONNECTION_IFACE "org.bluez.network.Connection"
+#define BLUEZ_NET_SERVER_IFACE "org.bluez.network.Server"
+
+/**************************** WAKE ON LAN ****************************/
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <net/if.h>
+
+#define SIOCETHTOOL	0x8946
+#define WAKE_MAGIC	(1 << 5)
+#define ETHTOOL_GWOL	0x00000005 /* Get wake-on-lan options. */
+
+#define SOPASS_MAX	6
+struct wolinfo {
+	int	cmd;
+	int	supported;
+	int	wolopts;
+	int	sopass[SOPASS_MAX]; /* SecureOn(tm) password */
+};
+
+static int
+wol_supported (const char *dev)
+{
+	struct ifreq	ifr;
+	int		fd;
+	int		ret;
+	struct wolinfo	wol;
+
+	/* Setup our control structures. */
+	memset (&ifr, 0, sizeof(ifr));
+	strcpy (ifr.ifr_name, dev);
+
+	fd = socket (AF_INET, SOCK_DGRAM, 0);
+	if (fd < 0) {
+		HAL_WARNING (("Cannot get control socket"));
+		return -1;
+	}
+
+	wol.cmd = ETHTOOL_GWOL;
+	ifr.ifr_data = (caddr_t)&wol;
+	if (ioctl (fd, SIOCETHTOOL, &ifr)) {
+		HAL_WARNING (("Cannot get wake-on-lan settings"));
+		ret = -1;
+		goto out;
+	}
+
+	if (wol.supported & WAKE_MAGIC)
+		ret = 1;
+	else
+		ret = 0;
+
+out:
+	close (fd);
+	return ret;
+}
+/**************************** WAKE ON LAN ****************************/
+
+static void
+get_properties (DBusConnection *conn, LibHalContext *ctx, const char *udi,
+				const char *id, const char *path)
+{
+	DBusMessage *msg;
+	DBusMessage *reply = NULL;
+	DBusMessageIter reply_iter;
+	DBusMessageIter dict_iter;
+	DBusError error;
+
+	dbus_error_init (&error);
+
+	msg = dbus_message_new_method_call (id, path,
+										BLUEZ_NET_CONNECTION_IFACE,
+										"GetInfo");
+
+	if (msg == NULL)
+		goto out;
+
+	HAL_INFO (("%s.GetInfo()", BLUEZ_NET_CONNECTION_IFACE));
+	reply = dbus_connection_send_with_reply_and_block (conn, msg, -1, &error);
+
+	if (dbus_error_is_set (&error) || dbus_set_error_from_message (&error,
+		reply)) {
+		dbus_error_free (&error);
+		goto out;
+	}
+
+	dbus_message_iter_init (reply, &reply_iter);
+
+	if (dbus_message_iter_get_arg_type (&reply_iter) != DBUS_TYPE_ARRAY  &&
+	    dbus_message_iter_get_element_type (&reply_iter) != DBUS_TYPE_DICT_ENTRY) {
+		goto out;
+	}
+
+	dbus_message_iter_recurse (&reply_iter, &dict_iter);
+
+	while (dbus_message_iter_get_arg_type (&dict_iter) == DBUS_TYPE_DICT_ENTRY) {
+		DBusMessageIter dict_entry_iter, var_iter;
+		const char *key;
+		char prop[32];
+
+		dbus_message_iter_recurse (&dict_iter, &dict_entry_iter);
+		dbus_message_iter_get_basic (&dict_entry_iter, &key);
+
+		dbus_message_iter_next (&dict_entry_iter);
+		dbus_message_iter_recurse (&dict_entry_iter, &var_iter);
+
+                snprintf(prop, sizeof (prop), "net.bluetooth.%s", key);
+
+		/* Make any property found annouced by hal */
+		switch (dbus_message_iter_get_arg_type (&var_iter)) {
+		case DBUS_TYPE_STRING:
+		{
+			const char *value;
+
+			dbus_message_iter_get_basic (&var_iter, &value);
+
+			HAL_INFO (("reply: %s:%s", key, value));
+
+			libhal_device_set_property_string (ctx, udi, prop, value, &error);
+			break;
+		}
+		case DBUS_TYPE_INT32:
+		{
+			dbus_int32_t value;
+
+			dbus_message_iter_get_basic (&var_iter, &value);
+
+			HAL_INFO (("reply: %s:%d", key, value));
+
+			libhal_device_set_property_int (ctx, udi, prop, value, &error);
+			break;
+		}
+		default:
+			break;
+		}
+		dbus_message_iter_next (&dict_iter);
+	}
+
+out:
+	if (msg)
+		dbus_message_unref (msg);
+	if (reply)
+		dbus_message_unref (reply);
+	return;
+}
+
+int
+main (int argc, char *argv[])
+{
+	char *udi;
+	char *iface;
+	char *id;
+	const char *connection;
+	char network[8] = "network";
+	const char *pnetwork = network;
+	LibHalContext *ctx = NULL;
+	DBusConnection *conn;
+	DBusMessage *msg = NULL;
+	DBusMessage *reply = NULL;
+	DBusError error;
+
+	udi = getenv ("UDI");
+	if (udi == NULL)
+		goto out;
+
+	dbus_error_init (&error);
+	if ((ctx = libhal_ctx_init_direct (&error)) == NULL)
+		goto out;
+
+	iface = libhal_device_get_property_string (ctx, udi, "net.interface", NULL);
+
+	HAL_INFO (("Investigating '%s'", iface));
+
+	if (iface == NULL)
+		goto out;
+
+	if ((conn = dbus_bus_get (DBUS_BUS_SYSTEM, &error)) == NULL)
+		goto out;
+
+	if (wol_supported (iface) == 1) {
+		libhal_device_add_capability (ctx, udi, "wake_on_lan", &error);
+		if (dbus_error_is_set (&error)) {
+			HAL_WARNING (("Could not add wake_on_lan capability"));
+			dbus_error_free (&error);
+		}
+	}
+
+	msg = dbus_message_new_method_call (BLUEZ_SERVICE, BLUEZ_PATH, BLUEZ_MANAGER_IFACE, "ActivateService");
+
+	if (msg == NULL)
+		goto out;
+
+	HAL_INFO (("%s.ActivateService('%s')", BLUEZ_MANAGER_IFACE, pnetwork));
+	dbus_message_append_args (msg, DBUS_TYPE_STRING, &pnetwork,
+								DBUS_TYPE_INVALID);
+	reply = dbus_connection_send_with_reply_and_block (conn, msg, -1, &error);
+
+	if (dbus_error_is_set (&error) || dbus_set_error_from_message (&error, reply)) {
+		dbus_error_free (&error);
+		goto out;
+	}
+
+	dbus_message_unref (msg);
+	msg = NULL;
+
+	dbus_message_get_args (reply, &error, DBUS_TYPE_STRING, &id, DBUS_TYPE_INVALID);
+	if (dbus_error_is_set (&error)) {
+		dbus_error_free (&error);
+		goto out;
+	}
+
+	dbus_message_unref (reply);
+	reply = NULL;
+
+	HAL_INFO (("Found Bluez Network service '%s'", id));
+
+	msg = dbus_message_new_method_call (id, BLUEZ_NET_PATH, BLUEZ_NET_MANAGER_IFACE, "FindConnection");
+
+	if (msg == NULL)
+		goto out;
+
+	HAL_INFO (("%s.FindConnection('%s')", BLUEZ_NET_MANAGER_IFACE, iface));
+	dbus_message_append_args (msg, DBUS_TYPE_STRING, &iface,
+							DBUS_TYPE_INVALID);
+	reply = dbus_connection_send_with_reply_and_block (conn, msg, -1, &error);
+
+	if (dbus_error_is_set (&error) || dbus_set_error_from_message (&error,
+		reply)) {
+		dbus_error_free (&error);
+		goto out;
+	}
+
+	dbus_message_unref (msg);
+	msg = NULL;
+
+	dbus_message_get_args (reply, &error, DBUS_TYPE_STRING, &connection,
+							DBUS_TYPE_INVALID);
+	if (dbus_error_is_set (&error)) {
+		dbus_error_free (&error);
+		goto out;
+	}
+
+	get_properties (conn, ctx, udi, id, connection);
+
+out:
+	if (msg)
+		dbus_message_unref (msg);
+	if (reply)
+		dbus_message_unref (reply);
+	if (ctx != NULL) {
+		dbus_error_init (&error);
+		libhal_ctx_shutdown (ctx, &error);
+		libhal_ctx_free (ctx);
+	}
+
+	return 0;
+}


More information about the hal mailing list