bluetooth: Remove data in all situations
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Mon, 4 Jul 2011 07:32:16 +0000 (10:32 +0300)
committerDenis Kenzior <denkenz@gmail.com>
Wed, 6 Jul 2011 02:11:08 +0000 (21:11 -0500)
If an adapter or device is removed any data associate should be removed,
otherwise the next time they appear/are created the drivers may not
asssociate again.

plugins/bluetooth.c
plugins/bluetooth.h
plugins/hfp_hf.c

index 7e0705f..1fdb579 100644 (file)
@@ -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",
index ff0ea52..7f9f810 100644 (file)
@@ -32,9 +32,9 @@
 
 struct bluetooth_profile {
        const char *name;
-       int (*create)(const char *device, const char *dev_addr,
+       int (*probe)(const char *device, const char *dev_addr,
                        const char *adapter_addr, const char *alias);
-       void (*remove_all)(void);
+       void (*remove)(const char *prefix);
        void (*set_alias)(const char *device, const char *);
 };
 
index 8a76701..b0b1ccf 100644 (file)
@@ -393,7 +393,7 @@ static GDBusMethodTable agent_methods[] = {
        { NULL, NULL, NULL, NULL }
 };
 
-static int hfp_create_modem(const char *device, const char *dev_addr,
+static int hfp_hf_probe(const char *device, const char *dev_addr,
                                const char *adapter_addr, const char *alias)
 {
        struct ofono_modem *modem;
@@ -443,25 +443,33 @@ free:
        return -ENOMEM;
 }
 
-static gboolean hfp_remove_each_modem(gpointer key, gpointer value,
+static gboolean hfp_remove_modem(gpointer key, gpointer value,
                                        gpointer user_data)
 {
        struct ofono_modem *modem = value;
+       const char *device = key;
+       const char *prefix = user_data;
+
+       if (prefix && g_str_has_prefix(device, prefix) == FALSE)
+               return FALSE;
 
        ofono_modem_remove(modem);
 
        return TRUE;
 }
 
-static void hfp_remove_all_modem(void)
+static void hfp_hf_remove(const char *prefix)
 {
+       DBG("%s", prefix);
+
        if (modem_hash == NULL)
                return;
 
-       g_hash_table_foreach_remove(modem_hash, hfp_remove_each_modem, NULL);
+       g_hash_table_foreach_remove(modem_hash, hfp_remove_modem,
+                                                       (gpointer) prefix);
 }
 
-static void hfp_set_alias(const char *device, const char *alias)
+static void hfp_hf_set_alias(const char *device, const char *alias)
 {
        struct ofono_modem *modem;
 
@@ -675,11 +683,11 @@ static struct ofono_modem_driver hfp_driver = {
        .post_sim       = hfp_post_sim,
 };
 
-static struct bluetooth_profile hfp_profile = {
-       .name           = "hfp",
-       .create         = hfp_create_modem,
-       .remove_all     = hfp_remove_all_modem,
-       .set_alias      = hfp_set_alias,
+static struct bluetooth_profile hfp_hf = {
+       .name           = "hfp_hf",
+       .probe          = hfp_hf_probe,
+       .remove         = hfp_hf_remove,
+       .set_alias      = hfp_hf_set_alias,
 };
 
 static int hfp_init(void)
@@ -695,7 +703,7 @@ static int hfp_init(void)
        if (err < 0)
                return err;
 
-       err = bluetooth_register_uuid(HFP_AG_UUID, &hfp_profile);
+       err = bluetooth_register_uuid(HFP_AG_UUID, &hfp_hf);
        if (err < 0) {
                ofono_modem_driver_unregister(&hfp_driver);
                return err;