summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuiz Augusto von Dentz <luiz.dentz@openbossa.org>2008-12-22 19:33:41 -0300
committerJohan Hedberg <johan.hedberg@nokia.com>2008-12-22 11:36:21 +0200
commitad37d886cc54a9a975f0f5322165bbb2855dac7f (patch)
tree7958db7c3960c9ab35a4a886cc3fc92335ec9d1b
parent2310cdaf70c36422a95c0b1832decf86deb894bf (diff)
Cleanup adapters on exit.
When bluetoothd is terminated any remaining registered adapters should be unregistered (including proper D-Bus signal emition) and have their drivers removed. The adapters should also be brought down unless they were already up upon initialization.
-rw-r--r--src/adapter.c16
-rw-r--r--src/adapter.h3
-rw-r--r--src/dbus-common.c3
-rw-r--r--src/main.c18
-rw-r--r--src/manager.c90
-rw-r--r--src/manager.h2
6 files changed, 77 insertions, 55 deletions
diff --git a/src/adapter.c b/src/adapter.c
index 5eaf729a..dc6f8e9c 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -120,6 +120,7 @@ struct btd_adapter {
gboolean pairable; /* pairable state */
gboolean initialized;
+ gboolean already_up; /* adapter was already up on init */
};
static void adapter_set_pairable_timeout(struct btd_adapter *adapter,
@@ -2912,7 +2913,8 @@ static void adapter_free(gpointer user_data)
return;
}
-struct btd_adapter *adapter_create(DBusConnection *conn, int id)
+struct btd_adapter *adapter_create(DBusConnection *conn, int id,
+ gboolean devup)
{
char path[MAX_PATH_LENGTH];
struct btd_adapter *adapter;
@@ -2933,6 +2935,7 @@ struct btd_adapter *adapter_create(DBusConnection *conn, int id)
adapter->dev_id = id;
adapter->state |= RESOLVE_NAME;
adapter->path = g_strdup(path);
+ adapter->already_up = devup;
if (!g_dbus_register_interface(conn, path, ADAPTER_INTERFACE,
adapter_methods, adapter_signals, NULL,
@@ -2958,6 +2961,17 @@ void adapter_remove(struct btd_adapter *adapter)
device_remove(connection, l->data);
g_slist_free(adapter->devices);
+ /* Return adapter to down state if it was not up on init */
+ if (adapter->up && !adapter->already_up) {
+ int dd = hci_open_dev(adapter->dev_id);
+ if (dd < 0)
+ goto done;
+
+ ioctl(dd, HCIDEVDOWN, adapter->dev_id);
+ hci_close_dev(dd);
+ }
+
+done:
g_dbus_unregister_interface(connection, path, ADAPTER_INTERFACE);
g_free(path);
diff --git a/src/adapter.h b/src/adapter.h
index 118ec4f9..d6f8b6c7 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -129,7 +129,8 @@ void adapter_remove_auth_request(struct btd_adapter *adapter, bdaddr_t *dba);
struct pending_auth_info *adapter_new_auth_request(struct btd_adapter *adapter,
bdaddr_t *dba,
auth_type_t type);
-struct btd_adapter *adapter_create(DBusConnection *conn, int id);
+struct btd_adapter *adapter_create(DBusConnection *conn, int id,
+ gboolean devup);
void adapter_remove(struct btd_adapter *adapter);
uint16_t adapter_get_dev_id(struct btd_adapter *adapter);
const gchar *adapter_get_path(struct btd_adapter *adapter);
diff --git a/src/dbus-common.c b/src/dbus-common.c
index de42769e..e4587256 100644
--- a/src/dbus-common.c
+++ b/src/dbus-common.c
@@ -143,8 +143,9 @@ static gboolean system_bus_reconnect(void *data)
/* reset the default device */
manager_set_default_adapter(-1);
+ /* FIXME: it shouldn't be needed to register adapters again */
for (i = 0; i < dl->dev_num; i++, dr++)
- manager_register_adapter(dr->dev_id);
+ manager_register_adapter(dr->dev_id, TRUE);
ret_val = FALSE;
diff --git a/src/main.c b/src/main.c
index fb917c89..d67a2477 100644
--- a/src/main.c
+++ b/src/main.c
@@ -474,7 +474,7 @@ fail:
exit(1);
}
-static void device_devreg_setup(int dev_id)
+static void device_devreg_setup(int dev_id, gboolean devup)
{
struct hci_dev_info di;
@@ -484,7 +484,7 @@ static void device_devreg_setup(int dev_id)
return;
if (!hci_test_bit(HCI_RAW, &di.flags))
- manager_register_adapter(dev_id);
+ manager_register_adapter(dev_id, devup);
}
static void device_devup_setup(int dev_id)
@@ -521,9 +521,13 @@ static void init_all_devices(int ctl)
}
for (i = 0; i < dl->dev_num; i++, dr++) {
+ gboolean devup;
+
+ devup = hci_test_bit(HCI_UP, &dr->dev_opt);
+
info("HCI dev %d registered", dr->dev_id);
- device_devreg_setup(dr->dev_id);
- if (hci_test_bit(HCI_UP, &dr->dev_opt)) {
+ device_devreg_setup(dr->dev_id, devup);
+ if (devup) {
info("HCI dev %d already up", dr->dev_id);
device_devup_setup(dr->dev_id);
}
@@ -553,7 +557,7 @@ static inline void device_event(GIOChannel *chan, evt_stack_internal *si)
switch (sd->event) {
case HCI_DEV_REG:
info("HCI dev %d registered", sd->dev_id);
- device_devreg_setup(sd->dev_id);
+ device_devreg_setup(sd->dev_id, FALSE);
break;
case HCI_DEV_UNREG:
@@ -767,14 +771,14 @@ int main(int argc, char *argv[])
hcid_dbus_unregister();
+ hcid_dbus_exit();
+
plugin_cleanup();
stop_sdp_server();
agent_exit();
- hcid_dbus_exit();
-
g_main_loop_unref(event_loop);
if (config)
diff --git a/src/manager.c b/src/manager.c
index f9263ae8..b0ba429c 100644
--- a/src/manager.c
+++ b/src/manager.c
@@ -326,8 +326,52 @@ dbus_bool_t manager_init(DBusConnection *conn, const char *path)
NULL, NULL, NULL);
}
+static void manager_update_adapters(void)
+{
+ GSList *list;
+ char **array;
+ int i;
+
+ array = g_new0(char *, g_slist_length(adapters) + 1);
+ for (i = 0, list = adapters; list; list = list->next, i++) {
+ struct btd_adapter *adapter = list->data;
+ array[i] = (char *) adapter_get_path(adapter);
+ }
+
+ emit_array_property_changed(connection, "/",
+ MANAGER_INTERFACE, "Adapters",
+ DBUS_TYPE_OBJECT_PATH, &array);
+
+ g_free(array);
+}
+
+static void manager_remove_adapter(struct btd_adapter *adapter)
+{
+ uint16_t dev_id = adapter_get_dev_id(adapter);
+ const gchar *path = adapter_get_path(adapter);
+
+ manager_update_adapters();
+
+ g_dbus_emit_signal(connection, "/",
+ MANAGER_INTERFACE, "AdapterRemoved",
+ DBUS_TYPE_OBJECT_PATH, &path,
+ DBUS_TYPE_INVALID);
+
+ if (default_adapter_id == dev_id || default_adapter_id < 0) {
+ int new_default = hci_get_route(NULL);
+
+ manager_set_default_adapter(new_default);
+ }
+
+ adapters = g_slist_remove(adapters, adapter);
+ adapter_remove(adapter);
+}
+
void manager_cleanup(DBusConnection *conn, const char *path)
{
+ g_slist_foreach(adapters, (GFunc) manager_remove_adapter, NULL);
+ g_slist_free(adapters);
+
g_dbus_unregister_interface(conn, "/", MANAGER_INTERFACE);
}
@@ -403,25 +447,6 @@ GSList *manager_get_adapters(void)
return adapters;
}
-static void manager_update_adapters(void)
-{
- GSList *list;
- char **array;
- int i;
-
- array = g_new0(char *, g_slist_length(adapters) + 1);
- for (i = 0, list = adapters; list; list = list->next, i++) {
- struct btd_adapter *adapter = list->data;
- array[i] = (char *) adapter_get_path(adapter);
- }
-
- emit_array_property_changed(connection, "/",
- MANAGER_INTERFACE, "Adapters",
- DBUS_TYPE_OBJECT_PATH, &array);
-
- g_free(array);
-}
-
static void manager_add_adapter(struct btd_adapter *adapter)
{
const gchar *path = adapter_get_path(adapter);
@@ -442,30 +467,9 @@ static void manager_add_adapter(struct btd_adapter *adapter)
manager_update_adapters();
}
-static void manager_remove_adapter(struct btd_adapter *adapter)
-{
- uint16_t dev_id = adapter_get_dev_id(adapter);
- const gchar *path = adapter_get_path(adapter);
-
- manager_update_adapters();
-
- g_dbus_emit_signal(connection, "/",
- MANAGER_INTERFACE, "AdapterRemoved",
- DBUS_TYPE_OBJECT_PATH, &path,
- DBUS_TYPE_INVALID);
-
- if (default_adapter_id == dev_id || default_adapter_id < 0) {
- int new_default = hci_get_route(NULL);
-
- manager_set_default_adapter(new_default);
- }
-
- adapters = g_slist_remove(adapters, adapter);
-}
-
-int manager_register_adapter(int id)
+int manager_register_adapter(int id, gboolean devup)
{
- struct btd_adapter *adapter = adapter_create(connection, id);
+ struct btd_adapter *adapter = adapter_create(connection, id, devup);
if (!adapter)
return -1;
@@ -490,8 +494,6 @@ int manager_unregister_adapter(int id)
manager_remove_adapter(adapter);
- adapter_remove(adapter);
-
return 0;
}
diff --git a/src/manager.h b/src/manager.h
index d0e30a89..eb087b95 100644
--- a/src/manager.h
+++ b/src/manager.h
@@ -32,7 +32,7 @@ struct btd_adapter *manager_find_adapter(const bdaddr_t *sba);
struct btd_adapter *manager_find_adapter_by_path(const char *path);
struct btd_adapter *manager_find_adapter_by_id(int id);
GSList *manager_get_adapters(void);
-int manager_register_adapter(int id);
+int manager_register_adapter(int id, gboolean devup);
int manager_unregister_adapter(int id);
int manager_start_adapter(int id);
int manager_stop_adapter(int id);