diff options
author | Patrik Flykt <patrik.flykt@linux.intel.com> | 2013-01-28 17:44:39 +0200 |
---|---|---|
committer | Patrik Flykt <patrik.flykt@linux.intel.com> | 2013-01-30 10:28:07 +0200 |
commit | 8935565c0d822d81bbe9ec77cfc4de9b2963bfd9 (patch) | |
tree | 821762ac480f833e8de90b90f0a47dd253c99517 /plugins | |
parent | e1168968df38ff6bd75208c782a51d716efdf3b9 (diff) | |
download | connman-8935565c0d822d81bbe9ec77cfc4de9b2963bfd9.tar.gz connman-8935565c0d822d81bbe9ec77cfc4de9b2963bfd9.tar.bz2 connman-8935565c0d822d81bbe9ec77cfc4de9b2963bfd9.zip |
bluetooth: Keep track of Bluez 5 org.bluez.Network1 objects
Set up functions monitoring Bluez 5 org.bluez.Network1 objects being
added and removed. Add a GDBusProxy for the org.bluez.Device1 object
that corresponds to the Network1 object. Set up functions monitoring
Network1 'Connected' and Device1 'UUID' properties.
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/bluetooth.c | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/plugins/bluetooth.c b/plugins/bluetooth.c index f1ea66c2..05bc916d 100644 --- a/plugins/bluetooth.c +++ b/plugins/bluetooth.c @@ -31,16 +31,24 @@ #include <connman/dbus.h> #include <connman/technology.h> #include <connman/device.h> +#include <connman/inet.h> #include <gdbus.h> #define BLUEZ_SERVICE "org.bluez" #define BLUEZ_PATH "/org/bluez" +#define BLUETOOTH_PAN_NAP "00001116-0000-1000-8000-00805f9b34fb" #define BLUETOOTH_ADDR_LEN 6 static DBusConnection *connection; static GDBusClient *client; static GHashTable *devices; +static GHashTable *networks; + +struct bluetooth_pan { + GDBusProxy *btdevice_proxy; + GDBusProxy *btnetwork_proxy; +}; static void address2ident(const char *address, char *ident) { @@ -75,6 +83,141 @@ static connman_bool_t proxy_get_bool(GDBusProxy *proxy, const char *property) return value; } +static connman_bool_t proxy_get_nap(GDBusProxy *proxy) +{ + DBusMessageIter iter, value; + + if (proxy == NULL) + return FALSE; + + if (g_dbus_proxy_get_property(proxy, "UUIDs", &iter) == FALSE) + return FALSE; + + dbus_message_iter_recurse(&iter, &value); + while (dbus_message_iter_get_arg_type(&value) == DBUS_TYPE_STRING) { + const char *uuid; + + dbus_message_iter_get_basic(&value, &uuid); + if (strcmp(uuid, BLUETOOTH_PAN_NAP) == 0) + return TRUE; + + dbus_message_iter_next(&value); + } + return FALSE; +} + +static int bluetooth_pan_probe(struct connman_network *network) +{ + return 0; +} + +static void bluetooth_pan_remove(struct connman_network *network) +{ + +} + +static int bluetooth_pan_connect(struct connman_network *network) +{ + return -EIO; +} + +static int bluetooth_pan_disconnect(struct connman_network *network) +{ + return -EIO; +} + +static void btnetwork_property_change(GDBusProxy *proxy, const char *name, + DBusMessageIter *iter, void *user_data) +{ + struct bluetooth_pan *pan; + connman_bool_t proxy_connected; + + if (strcmp(name, "Connected") != 0) + return; + + pan = g_hash_table_lookup(networks, g_dbus_proxy_get_path(proxy)); + if (pan == NULL) + return; + + dbus_message_iter_get_basic(iter, &proxy_connected); + + DBG("proxy connected %d", proxy_connected); +} + +static void btdevice_property_change(GDBusProxy *proxy, const char *name, + DBusMessageIter *iter, void *user_data) +{ + struct bluetooth_pan *pan; + + if (strcmp(name, "UUIDs") != 0) + return; + + pan = g_hash_table_lookup(networks, g_dbus_proxy_get_path(proxy)); + if (pan == NULL) + return; + + DBG("proxy nap %d", proxy_get_nap(pan->btdevice_proxy)); +} + +static void pan_free(gpointer data) +{ + struct bluetooth_pan *pan = data; + + if (pan->btnetwork_proxy != NULL) { + g_dbus_proxy_unref(pan->btnetwork_proxy); + pan->btnetwork_proxy = NULL; + } + + if (pan->btdevice_proxy != NULL) { + g_dbus_proxy_unref(pan->btdevice_proxy); + pan->btdevice_proxy = NULL; + } + + g_free(pan); +} + +static void pan_create(GDBusProxy *network_proxy) +{ + const char *path = g_dbus_proxy_get_path(network_proxy); + struct bluetooth_pan *pan; + + pan = g_try_new0(struct bluetooth_pan, 1); + + if (pan == NULL) { + connman_error("Out of memory creating PAN NAP"); + return; + } + + g_hash_table_replace(networks, g_strdup(path), pan); + + pan->btnetwork_proxy = g_dbus_proxy_ref(network_proxy); + pan->btdevice_proxy = g_dbus_proxy_new(client, path, + "org.bluez.Device1"); + + if (pan->btdevice_proxy == NULL) { + connman_error("Cannot create BT PAN watcher %s", path); + g_hash_table_remove(networks, path); + return; + } + + g_dbus_proxy_set_property_watch(pan->btnetwork_proxy, + btnetwork_property_change, NULL); + + g_dbus_proxy_set_property_watch(pan->btdevice_proxy, + btdevice_property_change, NULL); + + DBG("pan %p %s nap %d", pan, path, proxy_get_nap(pan->btdevice_proxy)); +} + +static struct connman_network_driver network_driver = { + .name = "bluetooth", + .type = CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN, + .probe = bluetooth_pan_probe, + .remove = bluetooth_pan_remove, + .connect = bluetooth_pan_connect, + .disconnect = bluetooth_pan_disconnect, +}; + static void device_enable_cb(const DBusError *error, void *user_data) { char *path = user_data; @@ -193,6 +336,7 @@ static void adapter_property_change(GDBusProxy *proxy, const char *name, device_powered, adapter_powered); if (device_powered != adapter_powered) { + DBG("powering adapter"); if (device_powered == TRUE) bluetooth_device_enable(device); else @@ -264,6 +408,11 @@ static void object_added(GDBusProxy *proxy, void *user_data) return; } + if (strcmp(interface, "org.bluez.Network1") == 0) { + DBG("%s %s", interface, g_dbus_proxy_get_path(proxy)); + pan_create(proxy); + return; + } } static void object_removed(GDBusProxy *proxy, void *user_data) @@ -278,6 +427,14 @@ static void object_removed(GDBusProxy *proxy, void *user_data) g_hash_table_remove(devices, path); } + + if (strcmp(interface, "org.bluez.Network1") == 0) { + path = g_dbus_proxy_get_path(proxy); + DBG("%s %s", interface, path); + + g_hash_table_remove(networks, path); + } + } static int bluetooth_device_probe(struct connman_device *device) @@ -349,6 +506,15 @@ static int bluetooth_init(void) goto out; } + if (connman_network_driver_register(&network_driver) < 0) { + connman_technology_driver_unregister(&tech_driver); + connman_device_driver_unregister(&device_driver); + goto out; + } + + networks = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, + pan_free); + client = g_dbus_client_new(connection, BLUEZ_SERVICE, BLUEZ_PATH); if (client == NULL) { connman_warn("Failed to initialize D-Bus client for " @@ -362,6 +528,9 @@ static int bluetooth_init(void) return 0; out: + if (networks != NULL) + g_hash_table_destroy(networks); + if (devices != NULL) g_hash_table_destroy(devices); @@ -376,6 +545,9 @@ out: static void bluetooth_exit(void) { + connman_network_driver_unregister(&network_driver); + g_hash_table_destroy(networks); + connman_device_driver_unregister(&device_driver); g_hash_table_destroy(devices); |