diff --git a/hald/linux/probing/probe-net-bluetooth.c b/hald/linux/probing/probe-net-bluetooth.c new file mode 100644 index 0000000..d016224 --- /dev/null +++ b/hald/linux/probing/probe-net-bluetooth.c @@ -0,0 +1,233 @@ +/*************************************************************************** + * CVSID: $Id$ + * + * probe-net-bluetooth.c : Probe bluetooth network devices + * + * Copyright (C) 2007 Luiz Augusto von Dentz, + * + * 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 +#endif + +#include + +#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 const char * +get_property (DBusConnection *conn, const char *id, const char *path, + const char *method) +{ + DBusMessage *msg; + DBusMessage *reply = NULL; + DBusError error; + const char *ret = NULL; + + dbus_error_init (&error); + + msg = dbus_message_new_method_call (id, path, + BLUEZ_NET_CONNECTION_IFACE, + method); + + if (msg == NULL) + goto out; + + HAL_INFO (("%s.%s()", BLUEZ_NET_CONNECTION_IFACE, method)); + 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_get_args (reply, &error, DBUS_TYPE_STRING, + &ret, DBUS_TYPE_INVALID); + if (dbus_error_is_set (&error)) { + dbus_error_free (&error); + goto out; + } + + HAL_INFO (("reply: %s", ret)); + +out: + if (msg) + dbus_message_unref (msg); + if (reply) + dbus_message_unref (reply); + return ret; +} + +int +main (int argc, char *argv[]) +{ + char *udi; + char *iface; + char *id; + char **connections; + const char *name; + const char *description; + const char *uuid; + char network[8] = "network"; + const char *pnetwork = network; + int i; + 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, + "ListConnections"); + + if (msg == NULL) + goto out; + + HAL_INFO (("%s.ListConnections()", BLUEZ_NET_MANAGER_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_unref (msg); + msg = NULL; + + dbus_message_get_args (reply, &error, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, + &connections, &i, DBUS_TYPE_INVALID); + if (dbus_error_is_set (&error)) { + dbus_error_free (&error); + goto out; + } + + dbus_message_unref (reply); + reply = NULL; + + i--; + for (; i >= 0; i--) { + const char *connection; + + connection = get_property (conn, id, connections[i], "GetInterface"); + + if (connection && (strcmp (connection, iface) == 0)) + break; + } + + if (i < 0) + goto out; + + name = get_property (conn, id, connections[i], "GetName"); + if (name == NULL) + goto out; + + libhal_device_set_property_string (ctx, udi, "net.bluetooth.name", name, + &error); + + description = get_property (conn, id, connections[i], "GetDescription"); + if (description == NULL) + goto out; + + libhal_device_set_property_string (ctx, udi, "net.bluetooth.description", + description, &error); + + uuid = get_property (conn, id, connections[i], "GetUUID"); + if (uuid == NULL) + goto out; + + libhal_device_set_property_string (ctx, udi, "net.bluetooth.uuid", + uuid, &error); + +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; +} -- 1.4.4.2