diff options
author | Johan Hedberg <johan.hedberg@nokia.com> | 2009-09-06 02:44:34 +0300 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@nokia.com> | 2009-09-06 02:44:34 +0300 |
commit | 74624288fb67b31e99fdf9a44db19055340815f0 (patch) | |
tree | d31adf42499076d3013f76e1e7ec151df87a402f | |
parent | 86aeac39b244f9f9ca5ad22fa9a82118cfaed004 (diff) | |
download | bluez-74624288fb67b31e99fdf9a44db19055340815f0.tar.gz |
Use an idle callback for trusted device authorization
The caller of btd_request_authorization could assume that it's
callback will be called in a separate mainloop iteration as opposed to
from within the actual btd_request_authorization function. It's therefore
better to use an idle callback to make the trusted device callback
behavior similar to that of untrusted devices.
-rw-r--r-- | src/adapter.c | 60 |
1 files changed, 44 insertions, 16 deletions
diff --git a/src/adapter.c b/src/adapter.c index 0ecf62ac8..048bfad75 100644 --- a/src/adapter.c +++ b/src/adapter.c @@ -93,6 +93,7 @@ struct service_auth { service_auth_cb cb; void *user_data; struct btd_device *device; + struct btd_adapter *adapter; }; struct btd_adapter { @@ -116,6 +117,7 @@ struct btd_adapter { DBusMessage *discovery_cancel; /* discovery cancel message request */ GSList *passkey_agents; struct agent *agent; /* For the new API */ + guint auth_idle_id; /* Ongoing authorization */ GSList *connections; /* Connected devices */ GSList *devices; /* Devices structure pointers */ GSList *mode_sessions; /* Request Mode sessions */ @@ -2388,6 +2390,9 @@ static void adapter_free(gpointer user_data) debug("adapter_free(%p)", adapter); + if (adapter->auth_idle_id) + g_source_remove(adapter->auth_idle_id); + g_free(adapter->path); g_free(adapter); } @@ -2878,6 +2883,18 @@ static void agent_auth_cb(struct agent *agent, DBusError *derr, auth->cb(derr, auth->user_data); } +static gboolean auth_idle_cb(gpointer user_data) +{ + struct service_auth *auth = user_data; + struct btd_adapter *adapter = auth->adapter; + + adapter->auth_idle_id = 0; + + auth->cb(NULL, auth->user_data); + + return FALSE; +} + static int btd_adapter_authorize(struct btd_adapter *adapter, const bdaddr_t *dst, const char *uuid, @@ -2900,38 +2917,43 @@ static int btd_adapter_authorize(struct btd_adapter *adapter, if (!g_slist_find(adapter->connections, device)) return -ENOTCONN; + if (adapter->auth_idle_id) + return -EBUSY; + + auth = g_try_new0(struct service_auth, 1); + if (!auth) + return -ENOMEM; + + auth->cb = cb; + auth->user_data = user_data; + auth->device = device; + auth->adapter = adapter; + trusted = read_trust(&adapter->bdaddr, address, GLOBAL_TRUST); if (trusted) { - cb(NULL, user_data); + adapter->auth_idle_id = g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, + auth_idle_cb, auth, + g_free); return 0; } - device = adapter_find_device(adapter, address); - if (!device) - return -EPERM; - agent = device_get_agent(device); if (!agent) agent = adapter->agent; - if (!agent) + if (!agent) { + g_free(auth); return -EPERM; - - auth = g_try_new0(struct service_auth, 1); - if (!auth) - return -ENOMEM; - - auth->cb = cb; - auth->user_data = user_data; - auth->device = device; + } dev_path = device_get_path(device); err = agent_authorize(agent, dev_path, uuid, agent_auth_cb, auth, g_free); - - if (err == 0) + if (err < 0) + g_free(auth); + else device_set_authorizing(device, TRUE); return err; @@ -2987,6 +3009,12 @@ int btd_cancel_authorization(const bdaddr_t *src, const bdaddr_t *dst) if (!device) return -EPERM; + if (adapter->auth_idle_id) { + g_source_remove(adapter->auth_idle_id); + adapter->auth_idle_id = 0; + return 0; + } + /* * FIXME: Cancel fails if authorization is requested to adapter's * agent and in the meanwhile CreatePairedDevice is called. |