Diff between bd48d4b7dd772366c86a13141cf49a9ae8ecb6df and d4a6604e8d07671ad628a734d6a04d54c08041f0

Changed Files

File Additions Deletions Status
src/agent.c +3 -64 modified
src/device.c +56 -0 modified

Full Patch

diff --git a/src/agent.c b/src/agent.c
index 607d8c2..9b942e8 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 3be328d..4372a8d 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) {