[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