diff options
Diffstat (limited to 'src/modules/bluetooth/module-bluetooth-discover.c')
-rw-r--r-- | src/modules/bluetooth/module-bluetooth-discover.c | 55 |
1 files changed, 44 insertions, 11 deletions
diff --git a/src/modules/bluetooth/module-bluetooth-discover.c b/src/modules/bluetooth/module-bluetooth-discover.c index 0601e9a3..a33ca648 100644 --- a/src/modules/bluetooth/module-bluetooth-discover.c +++ b/src/modules/bluetooth/module-bluetooth-discover.c @@ -91,6 +91,16 @@ static void module_free(struct module *m) { pa_xfree(m); } +static struct module* module_find(struct device *d, const char *profile) { + struct module *m; + + for (m = d->module_list; d; d = d->next) + if (pa_streq(m->profile, profile)) + return m; + + return NULL; +} + static struct uuid *uuid_new(const char *uuid) { struct uuid *node; @@ -345,6 +355,21 @@ static void load_module_for_device(struct userdata *u, struct device *d, const c PA_LLIST_PREPEND(struct module, d->module_list, m); } +static void unload_module_for_device(struct userdata *u, struct device *d, const char *profile) { + struct module *m; + + pa_assert(u); + pa_assert(d); + + if (!(m = module_find(d, profile))) + return; + + pa_module_unload_request(m->pa_m, TRUE); + + PA_LLIST_REMOVE(struct module, d->module_list, m); + module_free(m); +} + static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *msg, void *userdata) { DBusMessageIter arg_i; DBusError err; @@ -387,6 +412,7 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *msg, void * struct device *d; const char *profile; DBusMessageIter variant_i; + dbus_bool_t connected; if (!dbus_message_iter_init(msg, &arg_i)) { pa_log("dbus: message has no parameters"); @@ -400,6 +426,9 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *msg, void * dbus_message_iter_get_basic(&arg_i, &value); + if (!pa_streq(value, "Connected")) + goto done; + if (!dbus_message_iter_next(&arg_i)) { pa_log("Property value missing"); goto done; @@ -412,25 +441,29 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *msg, void * dbus_message_iter_recurse(&arg_i, &variant_i); - if (dbus_message_iter_get_arg_type(&variant_i) == DBUS_TYPE_BOOLEAN) { - dbus_bool_t connected; - dbus_message_iter_get_basic(&variant_i, &connected); - - if (!pa_streq(value, "Connected") || !connected) - goto done; + if (dbus_message_iter_get_arg_type(&variant_i) != DBUS_TYPE_BOOLEAN) { + pa_log("Property value not a boolean."); + goto done; } - if (!(d = device_find(u, dbus_message_get_path(msg)))) { - d = device_new(dbus_message_get_path(msg)); - PA_LLIST_PREPEND(struct device, u->device_list, d); - } + dbus_message_iter_get_basic(&variant_i, &connected); if (dbus_message_is_signal(msg, "org.bluez.Headset", "PropertyChanged")) profile = "hsp"; else profile = "a2dp"; - load_module_for_device(u, d, profile); + d = device_find(u, dbus_message_get_path(msg)); + + if (connected) { + if (!d) { + d = device_new(dbus_message_get_path(msg)); + PA_LLIST_PREPEND(struct device, u->device_list, d); + } + + load_module_for_device(u, d, profile); + } else if (d) + unload_module_for_device(u, d, profile); } done: |