diff mbox series

[BlueZ,v2] device: Reply br-connection-key-missing on connection bonding error

Message ID 20250515163448.189497-1-frederic.danis@collabora.com
State New
Headers show
Series [BlueZ,v2] device: Reply br-connection-key-missing on connection bonding error | expand

Commit Message

Frédéric Danis May 15, 2025, 4:34 p.m. UTC
Currently when connection is removed while the client is waiting for
Connect() the failed message is br-connection-canceled, even if this
is due to bonding error.

Implement to reply with br-connection-key-missing, when the connection
request fails due to a bonding authentication error, allowing the client
to differentiate connection failure reasons.

This has been tested by:
- pair a device
- disconnect
- edit pairing info to change last character of Key entry of [LinkKey] in
  /var/lib/bluetooth/<adapter_address>/<device_address>?info
- restart bluetoothd
- in bluetoothctl, connect <device_address>
---
v1->v2:
	- Improve commit message.
	- Reply br-connection-key-missing only on authentication error.
	- Request disconnection on authentication error instead of waiting for
	  normal disconnection.

 src/device.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/src/device.c b/src/device.c
index c364d72c3..d230af0a8 100644
--- a/src/device.c
+++ b/src/device.c
@@ -246,6 +246,7 @@  struct btd_device {
 	struct browse_req *browse;		/* service discover request */
 	struct bonding_req *bonding;
 	struct authentication_req *authr;	/* authentication request */
+	uint8_t		bonding_status;
 	GSList		*disconnects;		/* disconnects message */
 	DBusMessage	*connect;		/* connect message */
 	DBusMessage	*disconnect;		/* disconnect message */
@@ -1917,10 +1918,17 @@  void device_request_disconnect(struct btd_device *device, DBusMessage *msg)
 	}
 
 	if (device->connect) {
-		DBusMessage *reply = btd_error_failed(device->connect,
-						ERR_BREDR_CONN_CANCELED);
+		const char *err_str;
+		DBusMessage *reply;
+
+		if (device->bonding_status == MGMT_STATUS_AUTH_FAILED)
+			err_str = ERR_BREDR_CONN_KEY_MISSING;
+		else
+			err_str = ERR_BREDR_CONN_CANCELED;
+		reply = btd_error_failed(device->connect, err_str);
 		g_dbus_send_message(dbus_conn, reply);
 		dbus_message_unref(device->connect);
+		device->bonding_status = 0;
 		device->connect = NULL;
 	}
 
@@ -6763,6 +6771,10 @@  void device_bonding_complete(struct btd_device *device, uint8_t bdaddr_type,
 
 	DBG("bonding %p status 0x%02x", bonding, status);
 
+	device->bonding_status = status;
+	if (status == MGMT_STATUS_AUTH_FAILED)
+		device_request_disconnect(device, NULL);
+
 	if (auth && auth->agent)
 		agent_cancel(auth->agent);