Diff between 36ac32c5e8efbf0a141b431fe46d7263914ef38b and 916791b0348534a72b25fd59a8e0917d0a65eeb5

Changed Files

File Additions Deletions Status
src/agent.c +58 -0 modified
src/agent.h +4 -0 modified
src/device.c +8 -2 modified
src/device.h +2 -1 modified
src/mgmt.c +2 -35 modified

Full Patch

diff --git a/src/agent.c b/src/agent.c
index bb4b619..3d234c2 100644
--- a/src/agent.c
+++ b/src/agent.c
@@ -52,6 +52,7 @@
 typedef enum {
 	AGENT_REQUEST_PASSKEY,
 	AGENT_REQUEST_CONFIRMATION,
+	AGENT_REQUEST_AUTHORIZATION,
 	AGENT_REQUEST_PINCODE,
 	AGENT_REQUEST_AUTHORIZE_SERVICE,
 	AGENT_REQUEST_CONFIRM_MODE,
@@ -669,6 +670,63 @@ failed:
 	return err;
 }
 
+static int authorization_request_new(struct agent_request *req,
+						const char *device_path)
+{
+	struct agent *agent = req->agent;
+
+	req->msg = dbus_message_new_method_call(agent->name, agent->path,
+				"org.bluez.Agent", "RequestAuthorization");
+	if (req->msg == NULL) {
+		error("Couldn't allocate D-Bus message");
+		return -ENOMEM;
+	}
+
+	dbus_message_append_args(req->msg,
+				DBUS_TYPE_OBJECT_PATH, &device_path,
+				DBUS_TYPE_INVALID);
+
+	if (dbus_connection_send_with_reply(btd_get_dbus_connection(), req->msg,
+				&req->call, REQUEST_TIMEOUT) == FALSE) {
+		error("D-Bus send failed");
+		return -EIO;
+	}
+
+	dbus_pending_call_set_notify(req->call, simple_agent_reply, req, NULL);
+
+	return 0;
+}
+
+int agent_request_authorization(struct agent *agent, struct btd_device *device,
+						agent_cb cb, void *user_data,
+						GDestroyNotify destroy)
+{
+	struct agent_request *req;
+	const gchar *dev_path = device_get_path(device);
+	int err;
+
+	if (agent->request)
+		return -EBUSY;
+
+	DBG("Calling Agent.RequestAuthorization: name=%s, path=%s",
+						agent->name, agent->path);
+
+	req = agent_request_new(agent, AGENT_REQUEST_AUTHORIZATION, cb,
+				user_data, destroy);
+
+	err = authorization_request_new(req, dev_path);
+	if (err < 0)
+		goto failed;
+
+	agent->request = req;
+
+	return 0;
+
+failed:
+	agent_request_free(req, FALSE);
+	return err;
+}
+
 int agent_display_passkey(struct agent *agent, struct btd_device *device,
 				uint32_t passkey, uint16_t entered)
 {
diff --git a/src/agent.h b/src/agent.h
index 3b817d4..2b011b7 100644
--- a/src/agent.h
+++ b/src/agent.h
@@ -61,6 +61,10 @@ int agent_request_confirmation(struct agent *agent, struct btd_device *device,
 				uint32_t passkey, agent_cb cb,
 				void *user_data, GDestroyNotify destroy);
 
+int agent_request_authorization(struct agent *agent, struct btd_device *device,
+						agent_cb cb, void *user_data,
+						GDestroyNotify destroy);
+
 int agent_display_passkey(struct agent *agent, struct btd_device *device,
 				uint32_t passkey, uint16_t entered);
 
diff --git a/src/device.c b/src/device.c
index 254aa77..8c00a59 100644
--- a/src/device.c
+++ b/src/device.c
@@ -3755,7 +3755,8 @@ int device_request_passkey(struct btd_device *device)
 	return err;
 }
 
-int device_confirm_passkey(struct btd_device *device, uint32_t passkey)
+int device_confirm_passkey(struct btd_device *device, uint32_t passkey,
+							uint8_t confirm_hint)
 
 {
 	struct authentication_req *auth;
@@ -3767,8 +3768,13 @@ int device_confirm_passkey(struct btd_device *device, uint32_t passkey)
 
 	auth->passkey = passkey;
 
-	err = agent_request_confirmation(auth->agent, device, passkey,
+	if (confirm_hint)
+		err = agent_request_authorization(auth->agent, device,
 						confirm_cb, auth, NULL);
+	else
+		err = agent_request_confirmation(auth->agent, device, passkey,
+						confirm_cb, auth, NULL);
+
 	if (err < 0) {
 		error("Failed requesting authentication");
 		device_auth_req_free(device);
diff --git a/src/device.h b/src/device.h
index 7c8765d..1d7f54f 100644
--- a/src/device.h
+++ b/src/device.h
@@ -86,7 +86,8 @@ gboolean device_is_bonding(struct btd_device *device, const char *sender);
 void device_cancel_bonding(struct btd_device *device, uint8_t status);
 int device_request_pincode(struct btd_device *device, gboolean secure);
 int device_request_passkey(struct btd_device *device);
-int device_confirm_passkey(struct btd_device *device, uint32_t passkey);
+int device_confirm_passkey(struct btd_device *device, uint32_t passkey,
+							uint8_t confirm_hint);
 int device_notify_passkey(struct btd_device *device, uint32_t passkey,
 							uint8_t entered);
 int device_notify_pincode(struct btd_device *device, gboolean secure,
diff --git a/src/mgmt.c b/src/mgmt.c
index 4196bdd..95b7433 100644
--- a/src/mgmt.c
+++ b/src/mgmt.c
@@ -938,27 +938,6 @@ static void mgmt_passkey_notify(int sk, uint16_t index, void *buf, size_t len)
 		error("device_notify_passkey: %s", strerror(-err));
 }
 
-struct confirm_data {
-	int index;
-	bdaddr_t bdaddr;
-	uint8_t type;
-};
-
-static gboolean confirm_accept(gpointer user_data)
-{
-	struct confirm_data *data = user_data;
-	struct controller_info *info = &controllers[data->index];
-
-	DBG("auto-accepting incoming pairing request");
-
-	if (data->index > max_index || !info->valid)
-		return FALSE;
-
-	mgmt_confirm_reply(data->index, &data->bdaddr, data->type, TRUE);
-
-	return FALSE;
-}
-
 static void mgmt_user_confirm_request(int sk, uint16_t index, void *buf,
 								size_t len)
 {
@@ -984,26 +963,14 @@ static void mgmt_user_confirm_request(int sk, uint16_t index, void *buf,
 		return;
 	}
 
-	if (ev->confirm_hint) {
-		struct confirm_data *data;
-
-		data = g_new0(struct confirm_data, 1);
-		data->index = index;
-		bacpy(&data->bdaddr, &ev->addr.bdaddr);
-		data->type = ev->addr.type;
-
-		g_timeout_add_seconds_full(G_PRIORITY_DEFAULT, 1,
-						confirm_accept, data, g_free);
-		return;
-	}
-
 	info = &controllers[index];
 
 	if (!get_adapter_and_device(&info->bdaddr, &ev->addr.bdaddr,
 						&adapter, &device, true))
 		return;
 
-	err = device_confirm_passkey(device, btohl(ev->value));
+	err = device_confirm_passkey(device, btohl(ev->value),
+							ev->confirm_hint);
 	if (err < 0) {
 		error("device_confirm_passkey: %s", strerror(-err));
 		mgmt_confirm_reply(index, &ev->addr.bdaddr, ev->addr.type,