diff options
author | Johan Hedberg <johan.hedberg@intel.com> | 2011-09-21 00:21:16 +0900 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@intel.com> | 2011-09-21 00:21:16 +0900 |
commit | d4a6604e8d07671ad628a734d6a04d54c08041f0 (patch) | |
tree | 479dc585776a6d3f8d9fd3670d51c4ead3c3a46d | |
parent | bd48d4b7dd772366c86a13141cf49a9ae8ecb6df (diff) |
Fix agent fall-back mechanism
We can't change the agent for a request internally within agent.c since
externally code may depend on a specific agent being used so that
agent_cancel work properly. This patch exports the fall-back behavior
from agent.c into device.c.
-rw-r--r-- | src/agent.c | 67 | ||||
-rw-r--r-- | src/device.c | 56 |
2 files changed, 59 insertions, 64 deletions
diff --git a/src/agent.c b/src/agent.c index 607d8c29..9b942e88 100644 --- a/src/agent.c +++ b/src/agent.c @@ -79,9 +79,6 @@ struct agent_request { static DBusConnection *connection = NULL; -static int request_fallback(struct agent_request *req, - DBusPendingCallNotifyFunction function); - static void agent_release(struct agent *agent) { DBusMessage *message; @@ -258,13 +255,6 @@ static void simple_agent_reply(DBusPendingCall *call, void *user_data) dbus_error_init(&err); if (dbus_set_error_from_message(&err, message)) { - if ((g_str_equal(DBUS_ERROR_UNKNOWN_METHOD, err.name) || - g_str_equal(DBUS_ERROR_NO_REPLY, err.name)) && - request_fallback(req, simple_agent_reply) == 0) { - dbus_error_free(&err); - return; - } - error("Agent replied with an error: %s, %s", err.name, err.message); @@ -374,15 +364,8 @@ static void pincode_reply(DBusPendingCall *call, void *user_data) dbus_error_init(&err); if (dbus_set_error_from_message(&err, message)) { - if ((g_str_equal(DBUS_ERROR_UNKNOWN_METHOD, err.name) || - g_str_equal(DBUS_ERROR_NO_REPLY, err.name)) && - request_fallback(req, pincode_reply) == 0) { - dbus_error_free(&err); - return; - } - - error("Agent replied with an error: %s, %s", - err.name, err.message); + error("Agent %s replied with an error: %s, %s", + agent->path, err.name, err.message); cb(agent, &err, NULL, req->user_data); dbus_error_free(&err); @@ -547,15 +530,8 @@ static void passkey_reply(DBusPendingCall *call, void *user_data) dbus_error_init(&err); if (dbus_set_error_from_message(&err, message)) { - if ((g_str_equal(DBUS_ERROR_UNKNOWN_METHOD, err.name) || - g_str_equal(DBUS_ERROR_NO_REPLY, err.name)) && - request_fallback(req, passkey_reply) == 0) { - dbus_error_free(&err); - return; - } - error("Agent replied with an error: %s, %s", - err.name, err.message); + err.name, err.message); cb(agent, &err, 0, req->user_data); dbus_error_free(&err); goto done; @@ -696,43 +672,6 @@ failed: return err; } -static int request_fallback(struct agent_request *req, - DBusPendingCallNotifyFunction function) -{ - struct btd_adapter *adapter = req->agent->adapter; - struct agent *adapter_agent = adapter_get_agent(adapter); - DBusMessage *msg; - - if (req->agent == adapter_agent || adapter_agent == NULL) - return -EINVAL; - - dbus_pending_call_cancel(req->call); - dbus_pending_call_unref(req->call); - - msg = dbus_message_copy(req->msg); - - dbus_message_set_destination(msg, adapter_agent->name); - dbus_message_set_path(msg, adapter_agent->path); - - if (dbus_connection_send_with_reply(connection, msg, - &req->call, REQUEST_TIMEOUT) == FALSE) { - error("D-Bus send failed"); - dbus_message_unref(msg); - return -EIO; - } - - req->agent->request = NULL; - req->agent = adapter_agent; - req->agent->request = req; - - dbus_message_unref(req->msg); - req->msg = msg; - - dbus_pending_call_set_notify(req->call, function, req, NULL); - - return 0; -} - int agent_display_passkey(struct agent *agent, struct btd_device *device, uint32_t passkey) { diff --git a/src/device.c b/src/device.c index 3be328d1..4372a8da 100644 --- a/src/device.c +++ b/src/device.c @@ -89,6 +89,8 @@ struct authentication_req { void *cb; struct agent *agent; struct btd_device *device; + uint32_t passkey; + gboolean secure; }; struct browse_req { @@ -2304,7 +2306,24 @@ static void pincode_cb(struct agent *agent, DBusError *err, { struct authentication_req *auth = data; struct btd_device *device = auth->device; + struct btd_adapter *adapter = device_get_adapter(device); + struct agent *adapter_agent = adapter_get_agent(adapter); + + if (err && (g_str_equal(DBUS_ERROR_UNKNOWN_METHOD, err->name) || + g_str_equal(DBUS_ERROR_NO_REPLY, err->name))) { + + if (auth->agent == adapter_agent || adapter_agent == NULL) + goto done; + if (agent_request_pincode(adapter_agent, device, pincode_cb, + auth->secure, auth, NULL) < 0) + goto done; + + auth->agent = adapter_agent; + return; + } + +done: /* No need to reply anything if the authentication already failed */ if (auth->cb == NULL) return; @@ -2319,7 +2338,25 @@ static void confirm_cb(struct agent *agent, DBusError *err, void *data) { struct authentication_req *auth = data; struct btd_device *device = auth->device; + struct btd_adapter *adapter = device_get_adapter(device); + struct agent *adapter_agent = adapter_get_agent(adapter); + + if (err && (g_str_equal(DBUS_ERROR_UNKNOWN_METHOD, err->name) || + g_str_equal(DBUS_ERROR_NO_REPLY, err->name))) { + + if (auth->agent == adapter_agent || adapter_agent == NULL) + goto done; + + if (agent_request_confirmation(adapter_agent, device, + auth->passkey, confirm_cb, + auth, NULL) < 0) + goto done; + + auth->agent = adapter_agent; + return; + } +done: /* No need to reply anything if the authentication already failed */ if (auth->cb == NULL) return; @@ -2335,7 +2372,24 @@ static void passkey_cb(struct agent *agent, DBusError *err, { struct authentication_req *auth = data; struct btd_device *device = auth->device; + struct btd_adapter *adapter = device_get_adapter(device); + struct agent *adapter_agent = adapter_get_agent(adapter); + if (err && (g_str_equal(DBUS_ERROR_UNKNOWN_METHOD, err->name) || + g_str_equal(DBUS_ERROR_NO_REPLY, err->name))) { + + if (auth->agent == adapter_agent || adapter_agent == NULL) + goto done; + + if (agent_request_passkey(adapter_agent, device, passkey_cb, + auth, NULL) < 0) + goto done; + + auth->agent = adapter_agent; + return; + } + +done: /* No need to reply anything if the authentication already failed */ if (auth->cb == NULL) return; @@ -2373,6 +2427,8 @@ int device_request_authentication(struct btd_device *device, auth_type_t type, auth->device = device; auth->cb = cb; auth->type = type; + auth->passkey = passkey; + auth->secure = secure; device->authr = auth; switch (type) { |