diff options
Diffstat (limited to 'plugins/bluetooth.c')
-rw-r--r-- | plugins/bluetooth.c | 79 |
1 files changed, 57 insertions, 22 deletions
diff --git a/plugins/bluetooth.c b/plugins/bluetooth.c index 7e0705fd..1fdb579d 100644 --- a/plugins/bluetooth.c +++ b/plugins/bluetooth.c @@ -258,6 +258,28 @@ static void parse_string(DBusMessageIter *iter, gpointer user_data) dbus_message_iter_get_basic(iter, str); } +static void bluetooth_probe(GSList *uuids, const char *path, + const char *device, const char *adapter, + const char *alias) +{ + for (; uuids; uuids = uuids->next) { + struct bluetooth_profile *driver; + const char *uuid = uuids->data; + int err; + + driver = g_hash_table_lookup(uuid_hash, uuid); + if (driver == NULL) + continue; + + err = driver->probe(path, device, adapter, alias); + if (err == 0) + continue; + + ofono_error("%s probe: %s (%d)", driver->name, strerror(-err), + -err); + } +} + static void device_properties_cb(DBusPendingCall *call, gpointer user_data) { DBusMessage *reply; @@ -291,19 +313,10 @@ static void device_properties_cb(DBusPendingCall *call, gpointer user_data) adapter_addr = g_hash_table_lookup(adapter_address_hash, adapter); - if (!device_addr && !adapter_addr) + if (!device_addr || !adapter_addr) goto done; - for (; uuids; uuids = uuids->next) { - struct bluetooth_profile *profile; - const char *uuid = uuids->data; - - profile = g_hash_table_lookup(uuid_hash, uuid); - if (profile == NULL || profile->create == NULL) - continue; - - profile->create(path, device_addr, adapter_addr, alias); - } + bluetooth_probe(uuids, path, device_addr, adapter_addr, alias); done: g_slist_free(uuids); @@ -697,14 +710,38 @@ static gboolean adapter_added(DBusConnection *connection, DBusMessage *message, return TRUE; } +static void bluetooth_remove(gpointer key, gpointer value, gpointer user_data) +{ + struct bluetooth_profile *profile = value; + + profile->remove(user_data); +} + static gboolean adapter_removed(DBusConnection *connection, DBusMessage *message, void *user_data) { const char *path; if (dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &path, - DBUS_TYPE_INVALID) == TRUE) - g_hash_table_remove(adapter_address_hash, path); + DBUS_TYPE_INVALID) == FALSE) + return FALSE; + + g_hash_table_foreach(uuid_hash, bluetooth_remove, (gpointer) path); + g_hash_table_remove(adapter_address_hash, path); + + return TRUE; +} + +static gboolean device_removed(DBusConnection *connection, + DBusMessage *message, void *user_data) +{ + const char *path; + + if (dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_INVALID) == FALSE) + return FALSE; + + g_hash_table_foreach(uuid_hash, bluetooth_remove, (gpointer) path); return TRUE; } @@ -761,14 +798,6 @@ done: dbus_message_unref(reply); } -static void bluetooth_remove_all_modem(gpointer key, gpointer value, - gpointer user_data) -{ - struct bluetooth_profile *profile = value; - - profile->remove_all(); -} - static void bluetooth_connect(DBusConnection *connection, void *user_data) { bluetooth_send_with_reply("/", BLUEZ_MANAGER_INTERFACE, "GetProperties", @@ -786,7 +815,7 @@ static void bluetooth_disconnect(DBusConnection *connection, void *user_data) if (uuid_hash == NULL) return; - g_hash_table_foreach(uuid_hash, bluetooth_remove_all_modem, NULL); + g_hash_table_foreach(uuid_hash, bluetooth_remove, NULL); g_slist_foreach(server_list, (GFunc) remove_service_handle, NULL); } @@ -794,6 +823,7 @@ static void bluetooth_disconnect(DBusConnection *connection, void *user_data) static guint bluetooth_watch; static guint adapter_added_watch; static guint adapter_removed_watch; +static guint device_removed_watch; static guint property_watch; static void bluetooth_ref(void) @@ -817,6 +847,11 @@ static void bluetooth_ref(void) "AdapterRemoved", adapter_removed, NULL, NULL); + device_removed_watch = g_dbus_add_signal_watch(connection, NULL, NULL, + BLUEZ_ADAPTER_INTERFACE, + "DeviceRemoved", + device_removed, NULL, NULL); + property_watch = g_dbus_add_signal_watch(connection, NULL, NULL, BLUEZ_DEVICE_INTERFACE, "PropertyChanged", |