public inbox for linux-bluetooth@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH BlueZ 0/2] Cable pairing support for DualSense
@ 2025-06-03  9:56 Egor Vorontsov
  2025-06-03  9:56 ` [PATCH BlueZ 1/2] profiles/input: Add cable pairing constants " Egor Vorontsov
                   ` (2 more replies)
  0 siblings, 3 replies; 16+ messages in thread
From: Egor Vorontsov @ 2025-06-03  9:56 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Egor Vorontsov

I have figured out the DualSense pairing to be pretty similar to that
of DualShock 4. Successfully tested with a DualSense, from CLI and
via GNOME Control Center.

As a side discussion, don't we also have to add the DS4 constant
at L398 (that's with this patch) for it to be supported as well?
An article at Gentoo Wiki [1] suggests that DS4 pairing cannot
currently be done the cable way. I don't currently have a way to
verify this myself, though.

[1]: https://wiki.gentoo.org/wiki/Sony_DualShock#DualShock_4

Egor Vorontsov (2):
  profiles/input: Add cable pairing constants for DualSense
  plugins/sixaxis: Implement cable pairing for DualSense

 plugins/sixaxis.c        | 107 +++++++++++++++++++++++++++++++++++++--
 profiles/input/server.c  |   3 +-
 profiles/input/sixaxis.h |  25 +++++++++
 3 files changed, 131 insertions(+), 4 deletions(-)

-- 
2.49.0


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH BlueZ 1/2] profiles/input: Add cable pairing constants for DualSense
  2025-06-03  9:56 [PATCH BlueZ 0/2] Cable pairing support for DualSense Egor Vorontsov
@ 2025-06-03  9:56 ` Egor Vorontsov
  2025-06-03 11:32   ` Cable pairing support " bluez.test.bot
  2025-08-21 13:11   ` [PATCH BlueZ 1/2] profiles/input: Add cable pairing constants " Bastien Nocera
  2025-06-03  9:56 ` [PATCH BlueZ 2/2] plugins/sixaxis: Implement cable pairing " Egor Vorontsov
  2025-08-21 13:00 ` [PATCH BlueZ 0/2] Cable pairing support " Bastien Nocera
  2 siblings, 2 replies; 16+ messages in thread
From: Egor Vorontsov @ 2025-06-03  9:56 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Egor Vorontsov

Sony DualSense & DualSense Edge controllers support cable pairing
the same way as previous Sixaxis controller generations do.

This patch prepares their input profile for its implementation.
---
 profiles/input/server.c  |  3 ++-
 profiles/input/sixaxis.h | 25 +++++++++++++++++++++++++
 2 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/profiles/input/server.c b/profiles/input/server.c
index c8be445c7..68105d48c 100644
--- a/profiles/input/server.c
+++ b/profiles/input/server.c
@@ -122,7 +122,8 @@ static bool dev_is_sixaxis(const bdaddr_t *src, const bdaddr_t *dst)
 
 	cp = get_pairing(vid, pid, NULL);
 	if (cp && (cp->type == CABLE_PAIRING_SIXAXIS ||
-					cp->type == CABLE_PAIRING_DS4))
+					cp->type == CABLE_PAIRING_DS4 ||
+					cp->type == CABLE_PAIRING_DUALSENSE))
 		return true;
 
 	return false;
diff --git a/profiles/input/sixaxis.h b/profiles/input/sixaxis.h
index ab8831995..ac7e75223 100644
--- a/profiles/input/sixaxis.h
+++ b/profiles/input/sixaxis.h
@@ -17,6 +17,7 @@ typedef enum {
 	CABLE_PAIRING_UNSUPPORTED = 0,
 	CABLE_PAIRING_SIXAXIS,
 	CABLE_PAIRING_DS4,
+	CABLE_PAIRING_DUALSENSE,
 } CablePairingType;
 
 struct cable_pairing {
@@ -72,6 +73,30 @@ get_pairing(uint16_t vid, uint16_t pid, const char *name)
 			.version = 0x0001,
 			.type = CABLE_PAIRING_DS4,
 		},
+		{
+			.name = "Sony Interactive Entertainment Wireless Controller",
+			.source = 0x0002,
+			.vid = 0x054c,
+			.pid = 0x0ce6,
+			.version = 0x0001,
+			.type = CABLE_PAIRING_DUALSENSE,
+		},
+		{
+			.name = "Sony Interactive Entertainment DualSense Wireless Controller",
+			.source = 0x0002,
+			.vid = 0x054c,
+			.pid = 0x0ce6,
+			.version = 0x0001,
+			.type = CABLE_PAIRING_DUALSENSE,
+		},
+		{
+			.name = "Sony Interactive Entertainment DualSense Edge Wireless Controller",
+			.source = 0x0002,
+			.vid = 0x054c,
+			.pid = 0x0df2,
+			.version = 0x0001,
+			.type = CABLE_PAIRING_DUALSENSE,
+		},
 	};
 	guint i;
 
-- 
2.49.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH BlueZ 2/2] plugins/sixaxis: Implement cable pairing for DualSense
  2025-06-03  9:56 [PATCH BlueZ 0/2] Cable pairing support for DualSense Egor Vorontsov
  2025-06-03  9:56 ` [PATCH BlueZ 1/2] profiles/input: Add cable pairing constants " Egor Vorontsov
@ 2025-06-03  9:56 ` Egor Vorontsov
  2025-06-03 14:40   ` Luiz Augusto von Dentz
  2025-08-21 13:12   ` Bastien Nocera
  2025-08-21 13:00 ` [PATCH BlueZ 0/2] Cable pairing support " Bastien Nocera
  2 siblings, 2 replies; 16+ messages in thread
From: Egor Vorontsov @ 2025-06-03  9:56 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Egor Vorontsov

The code is very similar to that for DS4, but I found it's better
to separate the matters instead of generalizing it via constants.

Also added a request to enable Bluetooth on the controller to initiate
pairing without the need to disconnect it and power on again wirelessly,
basically emulating what PS itself does. Only for DualSense family now,
but can be expanded to DS4 too (I don't have one at hand to test this).
---
 plugins/sixaxis.c | 107 ++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 104 insertions(+), 3 deletions(-)

diff --git a/plugins/sixaxis.c b/plugins/sixaxis.c
index 1fab8ae59..a583c8b82 100644
--- a/plugins/sixaxis.c
+++ b/plugins/sixaxis.c
@@ -131,12 +131,36 @@ static int ds4_get_device_bdaddr(int fd, bdaddr_t *bdaddr)
 	return 0;
 }
 
+static int dualsense_get_device_bdaddr(int fd, bdaddr_t *bdaddr)
+{
+	uint8_t buf[20];
+	int ret;
+
+	memset(buf, 0, sizeof(buf));
+
+	buf[0] = 0x09;
+
+	ret = ioctl(fd, HIDIOCGFEATURE(sizeof(buf)), buf);
+	if (ret < 0) {
+		error("sixaxis: failed to read DualSense device address (%s)",
+		      strerror(errno));
+		return ret;
+	}
+
+	/* address is little-endian on DualSense */
+	bacpy(bdaddr, (bdaddr_t*) (buf + 1));
+
+	return 0;
+}
+
 static int get_device_bdaddr(int fd, bdaddr_t *bdaddr, CablePairingType type)
 {
 	if (type == CABLE_PAIRING_SIXAXIS)
 		return sixaxis_get_device_bdaddr(fd, bdaddr);
 	else if (type == CABLE_PAIRING_DS4)
 		return ds4_get_device_bdaddr(fd, bdaddr);
+	else if (type == CABLE_PAIRING_DUALSENSE)
+		return dualsense_get_device_bdaddr(fd, bdaddr);
 	return -1;
 }
 
@@ -183,12 +207,36 @@ static int ds4_get_central_bdaddr(int fd, bdaddr_t *bdaddr)
 	return 0;
 }
 
+static int dualsense_get_central_bdaddr(int fd, bdaddr_t *bdaddr)
+{
+	uint8_t buf[20];
+	int ret;
+
+	memset(buf, 0, sizeof(buf));
+
+	buf[0] = 0x09;
+
+	ret = ioctl(fd, HIDIOCGFEATURE(sizeof(buf)), buf);
+	if (ret < 0) {
+		error("sixaxis: failed to read DualSense central address (%s)",
+		      strerror(errno));
+		return ret;
+	}
+
+	/* address is little-endian on DualSense */
+	bacpy(bdaddr, (bdaddr_t*) (buf + 10));
+
+	return 0;
+}
+
 static int get_central_bdaddr(int fd, bdaddr_t *bdaddr, CablePairingType type)
 {
 	if (type == CABLE_PAIRING_SIXAXIS)
 		return sixaxis_get_central_bdaddr(fd, bdaddr);
 	else if (type == CABLE_PAIRING_DS4)
 		return ds4_get_central_bdaddr(fd, bdaddr);
+	else if (type == CABLE_PAIRING_DUALSENSE)
+		return dualsense_get_central_bdaddr(fd, bdaddr);
 	return -1;
 }
 
@@ -230,6 +278,26 @@ static int ds4_set_central_bdaddr(int fd, const bdaddr_t *bdaddr)
 	return ret;
 }
 
+static int dualsense_set_central_bdaddr(int fd, const bdaddr_t *bdaddr)
+{
+	uint8_t buf[27];
+	int ret;
+
+	buf[0] = 0x0A;
+	bacpy((bdaddr_t*) (buf + 1), bdaddr);
+	/* TODO: we could put the key here but
+	   there is no way to force a re-loading
+	   of link keys to the kernel from here. */
+	memset(buf + 7, 0, 16);
+
+	ret = ioctl(fd, HIDIOCSFEATURE(sizeof(buf)), buf);
+	if (ret < 0)
+		error("sixaxis: failed to write DualSense central address (%s)",
+		      strerror(errno));
+
+	return ret;
+}
+
 static int set_central_bdaddr(int fd, const bdaddr_t *bdaddr,
 					CablePairingType type)
 {
@@ -237,6 +305,32 @@ static int set_central_bdaddr(int fd, const bdaddr_t *bdaddr,
 		return sixaxis_set_central_bdaddr(fd, bdaddr);
 	else if (type == CABLE_PAIRING_DS4)
 		return ds4_set_central_bdaddr(fd, bdaddr);
+	else if (type == CABLE_PAIRING_DUALSENSE)
+		return dualsense_set_central_bdaddr(fd, bdaddr);
+	return -1;
+}
+
+static int dualsense_set_bluetooth_state(int fd, bool state)
+{
+	uint8_t buf[48];
+	int ret;
+
+	buf[0] = 0x08;
+	buf[1] = state?1:2;
+
+	ret = ioctl(fd, HIDIOCSFEATURE(sizeof(buf)), buf);
+	if (ret < 0)
+		error("sixaxis: failed to set DualSense Bluetooth state (%s)",
+		      strerror(errno));
+
+	return ret;
+}
+
+static int set_bluetooth_state(int fd, CablePairingType type,
+					bool state)
+{
+	if (type == CABLE_PAIRING_DUALSENSE)
+		return dualsense_set_bluetooth_state(fd, state);
 	return -1;
 }
 
@@ -297,12 +391,13 @@ static void agent_auth_cb(DBusError *derr, void *user_data)
 	remove_device = false;
 	btd_device_set_temporary(closure->device, false);
 
-	if (closure->type == CABLE_PAIRING_SIXAXIS) {
+	if (closure->type == CABLE_PAIRING_SIXAXIS)
 		btd_device_set_record(closure->device, HID_UUID,
 						 SIXAXIS_HID_SDP_RECORD);
 
+	if (closure->type == CABLE_PAIRING_SIXAXIS ||
+				closure->type == CABLE_PAIRING_DUALSENSE) {
 		device_set_cable_pairing(closure->device, true);
-
 		server_set_cable_pairing(adapter_bdaddr, true);
 	}
 
@@ -312,6 +407,11 @@ static void agent_auth_cb(DBusError *derr, void *user_data)
 	DBG("remote %s old_central %s new_central %s",
 				device_addr, central_addr, adapter_addr);
 
+	if (closure->type == CABLE_PAIRING_DUALSENSE) {
+		DBG("Enabling Bluetooth connection on the device");
+		set_bluetooth_state(closure->fd, closure->type, true);
+	}
+
 out:
 	g_hash_table_steal(pending_auths, closure->sysfs_path);
 
@@ -432,7 +532,8 @@ static void device_added(struct udev_device *udevice)
 
 	cp = get_pairing_type_for_device(udevice, &bus, &sysfs_path);
 	if (!cp || (cp->type != CABLE_PAIRING_SIXAXIS &&
-				cp->type != CABLE_PAIRING_DS4)) {
+				cp->type != CABLE_PAIRING_DS4 &&
+				cp->type != CABLE_PAIRING_DUALSENSE)) {
 		g_free(sysfs_path);
 		return;
 	}
-- 
2.49.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* RE: Cable pairing support for DualSense
  2025-06-03  9:56 ` [PATCH BlueZ 1/2] profiles/input: Add cable pairing constants " Egor Vorontsov
@ 2025-06-03 11:32   ` bluez.test.bot
  2025-08-21 13:11   ` [PATCH BlueZ 1/2] profiles/input: Add cable pairing constants " Bastien Nocera
  1 sibling, 0 replies; 16+ messages in thread
From: bluez.test.bot @ 2025-06-03 11:32 UTC (permalink / raw)
  To: linux-bluetooth, sdoregor

[-- Attachment #1: Type: text/plain, Size: 1261 bytes --]

This is automated email and please do not reply to this email!

Dear submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=968245

---Test result---

Test Summary:
CheckPatch                    PENDING   0.19 seconds
GitLint                       PENDING   0.27 seconds
BuildEll                      PASS      20.40 seconds
BluezMake                     PASS      2784.95 seconds
MakeCheck                     PASS      20.42 seconds
MakeDistcheck                 PASS      207.03 seconds
CheckValgrind                 PASS      281.95 seconds
CheckSmatch                   PASS      304.96 seconds
bluezmakeextell               PASS      130.81 seconds
IncrementalBuild              PENDING   0.19 seconds
ScanBuild                     PASS      932.48 seconds

Details
##############################
Test: CheckPatch - PENDING
Desc: Run checkpatch.pl script
Output:

##############################
Test: GitLint - PENDING
Desc: Run gitlint
Output:

##############################
Test: IncrementalBuild - PENDING
Desc: Incremental build with the patches in the series
Output:



---
Regards,
Linux Bluetooth


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH BlueZ 2/2] plugins/sixaxis: Implement cable pairing for DualSense
  2025-06-03  9:56 ` [PATCH BlueZ 2/2] plugins/sixaxis: Implement cable pairing " Egor Vorontsov
@ 2025-06-03 14:40   ` Luiz Augusto von Dentz
  2025-06-03 14:55     ` Egor Vorontsov
  2025-08-21 13:12   ` Bastien Nocera
  1 sibling, 1 reply; 16+ messages in thread
From: Luiz Augusto von Dentz @ 2025-06-03 14:40 UTC (permalink / raw)
  To: Egor Vorontsov; +Cc: linux-bluetooth

Hi Egor,

On Tue, Jun 3, 2025 at 6:05 AM Egor Vorontsov <sdoregor@sdore.me> wrote:
>
> The code is very similar to that for DS4, but I found it's better
> to separate the matters instead of generalizing it via constants.
>
> Also added a request to enable Bluetooth on the controller to initiate
> pairing without the need to disconnect it and power on again wirelessly,
> basically emulating what PS itself does. Only for DualSense family now,
> but can be expanded to DS4 too (I don't have one at hand to test this).
> ---
>  plugins/sixaxis.c | 107 ++++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 104 insertions(+), 3 deletions(-)
>
> diff --git a/plugins/sixaxis.c b/plugins/sixaxis.c
> index 1fab8ae59..a583c8b82 100644
> --- a/plugins/sixaxis.c
> +++ b/plugins/sixaxis.c
> @@ -131,12 +131,36 @@ static int ds4_get_device_bdaddr(int fd, bdaddr_t *bdaddr)
>         return 0;
>  }
>
> +static int dualsense_get_device_bdaddr(int fd, bdaddr_t *bdaddr)
> +{
> +       uint8_t buf[20];
> +       int ret;
> +
> +       memset(buf, 0, sizeof(buf));
> +
> +       buf[0] = 0x09;
> +
> +       ret = ioctl(fd, HIDIOCGFEATURE(sizeof(buf)), buf);
> +       if (ret < 0) {
> +               error("sixaxis: failed to read DualSense device address (%s)",
> +                     strerror(errno));
> +               return ret;
> +       }
> +
> +       /* address is little-endian on DualSense */
> +       bacpy(bdaddr, (bdaddr_t*) (buf + 1));
> +
> +       return 0;
> +}
> +
>  static int get_device_bdaddr(int fd, bdaddr_t *bdaddr, CablePairingType type)
>  {
>         if (type == CABLE_PAIRING_SIXAXIS)
>                 return sixaxis_get_device_bdaddr(fd, bdaddr);
>         else if (type == CABLE_PAIRING_DS4)
>                 return ds4_get_device_bdaddr(fd, bdaddr);
> +       else if (type == CABLE_PAIRING_DUALSENSE)
> +               return dualsense_get_device_bdaddr(fd, bdaddr);
>         return -1;
>  }
>
> @@ -183,12 +207,36 @@ static int ds4_get_central_bdaddr(int fd, bdaddr_t *bdaddr)
>         return 0;
>  }
>
> +static int dualsense_get_central_bdaddr(int fd, bdaddr_t *bdaddr)
> +{
> +       uint8_t buf[20];
> +       int ret;
> +
> +       memset(buf, 0, sizeof(buf));
> +
> +       buf[0] = 0x09;
> +
> +       ret = ioctl(fd, HIDIOCGFEATURE(sizeof(buf)), buf);
> +       if (ret < 0) {
> +               error("sixaxis: failed to read DualSense central address (%s)",
> +                     strerror(errno));
> +               return ret;
> +       }
> +
> +       /* address is little-endian on DualSense */
> +       bacpy(bdaddr, (bdaddr_t*) (buf + 10));
> +
> +       return 0;
> +}
> +
>  static int get_central_bdaddr(int fd, bdaddr_t *bdaddr, CablePairingType type)
>  {
>         if (type == CABLE_PAIRING_SIXAXIS)
>                 return sixaxis_get_central_bdaddr(fd, bdaddr);
>         else if (type == CABLE_PAIRING_DS4)
>                 return ds4_get_central_bdaddr(fd, bdaddr);
> +       else if (type == CABLE_PAIRING_DUALSENSE)
> +               return dualsense_get_central_bdaddr(fd, bdaddr);
>         return -1;
>  }
>
> @@ -230,6 +278,26 @@ static int ds4_set_central_bdaddr(int fd, const bdaddr_t *bdaddr)
>         return ret;
>  }
>
> +static int dualsense_set_central_bdaddr(int fd, const bdaddr_t *bdaddr)
> +{
> +       uint8_t buf[27];
> +       int ret;
> +
> +       buf[0] = 0x0A;
> +       bacpy((bdaddr_t*) (buf + 1), bdaddr);
> +       /* TODO: we could put the key here but
> +          there is no way to force a re-loading
> +          of link keys to the kernel from here. */

Not quite following, what key are you talking about? I thought the
link keys are still generated over Bluetooth, or are you talking about
passkeys here?

> +       memset(buf + 7, 0, 16);
> +
> +       ret = ioctl(fd, HIDIOCSFEATURE(sizeof(buf)), buf);
> +       if (ret < 0)
> +               error("sixaxis: failed to write DualSense central address (%s)",
> +                     strerror(errno));
> +
> +       return ret;
> +}
> +
>  static int set_central_bdaddr(int fd, const bdaddr_t *bdaddr,
>                                         CablePairingType type)
>  {
> @@ -237,6 +305,32 @@ static int set_central_bdaddr(int fd, const bdaddr_t *bdaddr,
>                 return sixaxis_set_central_bdaddr(fd, bdaddr);
>         else if (type == CABLE_PAIRING_DS4)
>                 return ds4_set_central_bdaddr(fd, bdaddr);
> +       else if (type == CABLE_PAIRING_DUALSENSE)
> +               return dualsense_set_central_bdaddr(fd, bdaddr);
> +       return -1;
> +}
> +
> +static int dualsense_set_bluetooth_state(int fd, bool state)
> +{
> +       uint8_t buf[48];
> +       int ret;
> +
> +       buf[0] = 0x08;
> +       buf[1] = state?1:2;
> +
> +       ret = ioctl(fd, HIDIOCSFEATURE(sizeof(buf)), buf);
> +       if (ret < 0)
> +               error("sixaxis: failed to set DualSense Bluetooth state (%s)",
> +                     strerror(errno));
> +
> +       return ret;
> +}
> +
> +static int set_bluetooth_state(int fd, CablePairingType type,
> +                                       bool state)
> +{
> +       if (type == CABLE_PAIRING_DUALSENSE)
> +               return dualsense_set_bluetooth_state(fd, state);
>         return -1;
>  }
>
> @@ -297,12 +391,13 @@ static void agent_auth_cb(DBusError *derr, void *user_data)
>         remove_device = false;
>         btd_device_set_temporary(closure->device, false);
>
> -       if (closure->type == CABLE_PAIRING_SIXAXIS) {
> +       if (closure->type == CABLE_PAIRING_SIXAXIS)
>                 btd_device_set_record(closure->device, HID_UUID,
>                                                  SIXAXIS_HID_SDP_RECORD);
>
> +       if (closure->type == CABLE_PAIRING_SIXAXIS ||
> +                               closure->type == CABLE_PAIRING_DUALSENSE) {
>                 device_set_cable_pairing(closure->device, true);
> -
>                 server_set_cable_pairing(adapter_bdaddr, true);
>         }
>
> @@ -312,6 +407,11 @@ static void agent_auth_cb(DBusError *derr, void *user_data)
>         DBG("remote %s old_central %s new_central %s",
>                                 device_addr, central_addr, adapter_addr);
>
> +       if (closure->type == CABLE_PAIRING_DUALSENSE) {
> +               DBG("Enabling Bluetooth connection on the device");
> +               set_bluetooth_state(closure->fd, closure->type, true);
> +       }
> +
>  out:
>         g_hash_table_steal(pending_auths, closure->sysfs_path);
>
> @@ -432,7 +532,8 @@ static void device_added(struct udev_device *udevice)
>
>         cp = get_pairing_type_for_device(udevice, &bus, &sysfs_path);
>         if (!cp || (cp->type != CABLE_PAIRING_SIXAXIS &&
> -                               cp->type != CABLE_PAIRING_DS4)) {
> +                               cp->type != CABLE_PAIRING_DS4 &&
> +                               cp->type != CABLE_PAIRING_DUALSENSE)) {
>                 g_free(sysfs_path);
>                 return;
>         }
> --
> 2.49.0
>
>


-- 
Luiz Augusto von Dentz

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH BlueZ 2/2] plugins/sixaxis: Implement cable pairing for DualSense
  2025-06-03 14:40   ` Luiz Augusto von Dentz
@ 2025-06-03 14:55     ` Egor Vorontsov
  2025-06-03 15:38       ` Luiz Augusto von Dentz
  0 siblings, 1 reply; 16+ messages in thread
From: Egor Vorontsov @ 2025-06-03 14:55 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth

On Tue, 2025-06-03 at 10:40 -0400, Luiz Augusto von Dentz wrote:
> > +       /* TODO: we could put the key here but
> > +          there is no way to force a re-loading
> > +          of link keys to the kernel from here. */
> 
> Not quite following, what key are you talking about? I thought the
> link keys are still generated over Bluetooth, or are you talking about
> passkeys here?

Hi Luiz, thank you for the quick response!

If you look a little bit upper, in the `ds4_set_central_bdaddr', you'll
see the exact same comment. As I pointed out, I decided to just
duplicate the code for now, as a proper general implementation might
require some further refactoring of somewhat unrelated code.

From my understanding of the original author's thoughts combined with
the experimentation I've done, it is about the possibility to directly
provide a generated link key, completely skipping the usual BT bonding
process (that, I positively tested with my script by writing directly
to BlueZ's device `/info' file), instead of writing all zeros and
relying on (I assume?) Just Works repairing on the following connect.

My knowledge in terms of Kernel Bluetooth subsystem doesn't go so far
to actually tackle the problem; it might require implementing a key
reloading ABI in the kernel. On the other hand, there's `btmgmt keys'
command which, I assume, does pretty much that, but I didn't have any
success using it in my testing -- only a full restart of `bluetoothd'
did the thing.

I'm up to further investigation of this nitpick, as I'd love to see a
seamless pairing process just like it was intended, but I'd need some
assistance in locating the appropriate showstoppers mentioned in that
comment. That said, I don't see this as a stopper for the patch itself.

-- 
Egor Vorontsov <sdoregor@sdore.me>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH BlueZ 2/2] plugins/sixaxis: Implement cable pairing for DualSense
  2025-06-03 14:55     ` Egor Vorontsov
@ 2025-06-03 15:38       ` Luiz Augusto von Dentz
  2025-06-03 18:35         ` Egor Vorontsov
  0 siblings, 1 reply; 16+ messages in thread
From: Luiz Augusto von Dentz @ 2025-06-03 15:38 UTC (permalink / raw)
  To: sdoregor; +Cc: linux-bluetooth

Hi Egor,

On Tue, Jun 3, 2025 at 10:55 AM Egor Vorontsov <sdoregor@sdore.me> wrote:
>
> On Tue, 2025-06-03 at 10:40 -0400, Luiz Augusto von Dentz wrote:
> > > +       /* TODO: we could put the key here but
> > > +          there is no way to force a re-loading
> > > +          of link keys to the kernel from here. */
> >
> > Not quite following, what key are you talking about? I thought the
> > link keys are still generated over Bluetooth, or are you talking about
> > passkeys here?
>
> Hi Luiz, thank you for the quick response!
>
> If you look a little bit upper, in the `ds4_set_central_bdaddr', you'll
> see the exact same comment. As I pointed out, I decided to just
> duplicate the code for now, as a proper general implementation might
> require some further refactoring of somewhat unrelated code.
>
> From my understanding of the original author's thoughts combined with
> the experimentation I've done, it is about the possibility to directly
> provide a generated link key, completely skipping the usual BT bonding
> process (that, I positively tested with my script by writing directly
> to BlueZ's device `/info' file), instead of writing all zeros and
> relying on (I assume?) Just Works repairing on the following connect.

Well except if there is some sort of OOB to generate the link key I
don't that is possible, note that we don't mark the device as paired
so the process of doing CablePairing is just creating a device, then
by the time it first connects it will then do the regular pairing.
Perhaps it is possible to write the link keys directly via cable but
then we need the OOB data, etc, to generate the keys which in my
opinion it just extra work that doesn't really add anything if just
works, or autopair, is used.

> My knowledge in terms of Kernel Bluetooth subsystem doesn't go so far
> to actually tackle the problem; it might require implementing a key
> reloading ABI in the kernel. On the other hand, there's `btmgmt keys'
> command which, I assume, does pretty much that, but I didn't have any
> success using it in my testing -- only a full restart of `bluetoothd'
> did the thing.
>
> I'm up to further investigation of this nitpick, as I'd love to see a
> seamless pairing process just like it was intended, but I'd need some
> assistance in locating the appropriate showstoppers mentioned in that
> comment. That said, I don't see this as a stopper for the patch itself.

Is it not seamless right now? Doesn't it use 'just works'/autopair?


-- 
Luiz Augusto von Dentz

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH BlueZ 2/2] plugins/sixaxis: Implement cable pairing for DualSense
  2025-06-03 15:38       ` Luiz Augusto von Dentz
@ 2025-06-03 18:35         ` Egor Vorontsov
  2025-06-04 12:41           ` Luiz Augusto von Dentz
  2025-08-21 13:12           ` Bastien Nocera
  0 siblings, 2 replies; 16+ messages in thread
From: Egor Vorontsov @ 2025-06-03 18:35 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth

On Tue, 2025-06-03 at 11:38 -0400, Luiz Augusto von Dentz wrote:
> Perhaps it is possible to write the link keys directly via cable but
> then we need the OOB data, etc, to generate the keys which in my
> opinion it just extra work that doesn't really add anything if just
> works, or autopair, is used.

In my experimental PoC I just generated a random 128-bit string and
used it as the link key for both sides (placed into `LinkKey=' in
BlueZ's `/info' and sent to DualSense over USB), which showed to be
working perfectly.

> Is it not seamless right now? Doesn't it use 'just works'/autopair?

It is kind of seamless, but you still have to accept the pairing
manually (e.g. be discoverable and with an active agent). In terms of
security I'd say this behavior is indeed preferable (otherwise one
could spoof the VID:PID and zero-click bond with the host), but it
still requires two separate confirmations.

If we could generate a static key, place it to both devices BUT at the
same time mark the device as unconfirmed/untrusted/etc. locally, so
that it is still going to trigger one and only one interactive pairing
confirmation, that'd be the intended design at least in my view.

Another possible way would be to automatically accept the first, dummy
pairing request that doesn't bear a link key yet -- so no security risk
there, but still more seamless experience for the user.

-- 
Egor Vorontsov <sdoregor@sdore.me>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH BlueZ 2/2] plugins/sixaxis: Implement cable pairing for DualSense
  2025-06-03 18:35         ` Egor Vorontsov
@ 2025-06-04 12:41           ` Luiz Augusto von Dentz
  2025-06-04 22:50             ` Egor Vorontsov
  2025-08-21 13:12           ` Bastien Nocera
  1 sibling, 1 reply; 16+ messages in thread
From: Luiz Augusto von Dentz @ 2025-06-04 12:41 UTC (permalink / raw)
  To: sdoregor; +Cc: linux-bluetooth

Hi Egor,

On Tue, Jun 3, 2025 at 2:35 PM Egor Vorontsov <sdoregor@sdore.me> wrote:
>
> On Tue, 2025-06-03 at 11:38 -0400, Luiz Augusto von Dentz wrote:
> > Perhaps it is possible to write the link keys directly via cable but
> > then we need the OOB data, etc, to generate the keys which in my
> > opinion it just extra work that doesn't really add anything if just
> > works, or autopair, is used.
>
> In my experimental PoC I just generated a random 128-bit string and
> used it as the link key for both sides (placed into `LinkKey=' in
> BlueZ's `/info' and sent to DualSense over USB), which showed to be
> working perfectly.

Hmm, not so sure this is secure though, I mean it could be a rogue USB
device pretending to be a controller so it would automatically be
considered paired if we just self generate the keys without asking for
user confirmation.

> > Is it not seamless right now? Doesn't it use 'just works'/autopair?
>
> It is kind of seamless, but you still have to accept the pairing
> manually (e.g. be discoverable and with an active agent). In terms of
> security I'd say this behavior is indeed preferable (otherwise one
> could spoof the VID:PID and zero-click bond with the host), but it
> still requires two separate confirmations.

Yeah, the zero-click bond might be a security concern though, so I
think having the user do a confirmation for each step is sort of
assuring he knows (or at least pretend) what is going on.

> If we could generate a static key, place it to both devices BUT at the
> same time mark the device as unconfirmed/untrusted/etc. locally, so
> that it is still going to trigger one and only one interactive pairing
> confirmation, that'd be the intended design at least in my view.

When would we generate the confirmation though? I sort of trust more
the Bluetooth process to generate and exchange keys.

> Another possible way would be to automatically accept the first, dummy
> pairing request that doesn't bear a link key yet -- so no security risk
> there, but still more seamless experience for the user.
>
> --
> Egor Vorontsov <sdoregor@sdore.me>



-- 
Luiz Augusto von Dentz

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH BlueZ 2/2] plugins/sixaxis: Implement cable pairing for DualSense
  2025-06-04 12:41           ` Luiz Augusto von Dentz
@ 2025-06-04 22:50             ` Egor Vorontsov
  2025-08-10 20:46               ` Egor Vorontsov
  2025-08-21 13:12               ` Bastien Nocera
  0 siblings, 2 replies; 16+ messages in thread
From: Egor Vorontsov @ 2025-06-04 22:50 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth

On Wed, 2025-06-04 at 08:41 -0400, Luiz Augusto von Dentz wrote:
> Hmm, not so sure this is secure though, I mean it could be a rogue USB
> device pretending to be a controller so it would automatically be
> considered paired if we just self generate the keys without asking for
> user confirmation.

We can generate whatever we want, unless BlueZ will treat the key as
bonded no question asked. Read on to see what I mean.

> Yeah, the zero-click bond might be a security concern though, so I
> think having the user do a confirmation for each step is sort of
> assuring he knows (or at least pretend) what is going on.

I strongly believe you only should confirm once. Especially since the
first one doesn't actually pair or trust anything, instead it just
creates the device record for it to be able to initiate a bonding
connection to us without discoverable being on (as far as I understand
it).

The painful re-re-pairing process is so strongly tied with Bluetooth in
our minds, so I really don't want to further increase its awkwardness.

> When would we generate the confirmation though? I sort of trust more
> the Bluetooth process to generate and exchange keys.

That's exactly what I'd love to hear from someone, honestly :)

I see a possible solution where we trigger agent on the first connect,
even though the link key is already established. It might be a special
flag for the device, or even just another value in the `LinkKey.Type'
field -- meaning, "key was generated by us, should reconfirm pairing".

-- 
Egor Vorontsov <sdoregor@sdore.me>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH BlueZ 2/2] plugins/sixaxis: Implement cable pairing for DualSense
  2025-06-04 22:50             ` Egor Vorontsov
@ 2025-08-10 20:46               ` Egor Vorontsov
  2025-08-21 13:12               ` Bastien Nocera
  1 sibling, 0 replies; 16+ messages in thread
From: Egor Vorontsov @ 2025-08-10 20:46 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth

A kind reminder — let's work on getting this merged hopefully!

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH BlueZ 0/2] Cable pairing support for DualSense
  2025-06-03  9:56 [PATCH BlueZ 0/2] Cable pairing support for DualSense Egor Vorontsov
  2025-06-03  9:56 ` [PATCH BlueZ 1/2] profiles/input: Add cable pairing constants " Egor Vorontsov
  2025-06-03  9:56 ` [PATCH BlueZ 2/2] plugins/sixaxis: Implement cable pairing " Egor Vorontsov
@ 2025-08-21 13:00 ` Bastien Nocera
  2 siblings, 0 replies; 16+ messages in thread
From: Bastien Nocera @ 2025-08-21 13:00 UTC (permalink / raw)
  To: Egor Vorontsov, linux-bluetooth

On Tue, 2025-06-03 at 12:56 +0300, Egor Vorontsov wrote:
> I have figured out the DualSense pairing to be pretty similar to that
> of DualShock 4. Successfully tested with a DualSense, from CLI and
> via GNOME Control Center.
> 
> As a side discussion, don't we also have to add the DS4 constant
> at L398 (that's with this patch) for it to be supported as well?
> An article at Gentoo Wiki [1] suggests that DS4 pairing cannot
> currently be done the cable way. I don't currently have a way to
> verify this myself, though.
> 
> [1]: https://wiki.gentoo.org/wiki/Sony_DualShock#DualShock_4

My guess is that the DS4 cable-pairing support stopped working when the
kernel migrated from hid-sony to hid-playstation (and devices changed
names...).

I sent patches which fix that in my local testing.

> 
> Egor Vorontsov (2):
>   profiles/input: Add cable pairing constants for DualSense
>   plugins/sixaxis: Implement cable pairing for DualSense
> 
>  plugins/sixaxis.c        | 107
> +++++++++++++++++++++++++++++++++++++--
>  profiles/input/server.c  |   3 +-
>  profiles/input/sixaxis.h |  25 +++++++++
>  3 files changed, 131 insertions(+), 4 deletions(-)

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH BlueZ 1/2] profiles/input: Add cable pairing constants for DualSense
  2025-06-03  9:56 ` [PATCH BlueZ 1/2] profiles/input: Add cable pairing constants " Egor Vorontsov
  2025-06-03 11:32   ` Cable pairing support " bluez.test.bot
@ 2025-08-21 13:11   ` Bastien Nocera
  1 sibling, 0 replies; 16+ messages in thread
From: Bastien Nocera @ 2025-08-21 13:11 UTC (permalink / raw)
  To: Egor Vorontsov, linux-bluetooth


On Tue, 2025-06-03 at 12:56 +0300, Egor Vorontsov wrote:
> Sony DualSense & DualSense Edge controllers support cable pairing
> the same way as previous Sixaxis controller generations do.
> 
> This patch prepares their input profile for its implementation.
> ---
>  profiles/input/server.c  |  3 ++-
>  profiles/input/sixaxis.h | 25 +++++++++++++++++++++++++
>  2 files changed, 27 insertions(+), 1 deletion(-)
> 
> diff --git a/profiles/input/server.c b/profiles/input/server.c
> index c8be445c7..68105d48c 100644
> --- a/profiles/input/server.c
> +++ b/profiles/input/server.c
> @@ -122,7 +122,8 @@ static bool dev_is_sixaxis(const bdaddr_t *src,
> const bdaddr_t *dst)
>  
>  	cp = get_pairing(vid, pid, NULL);
>  	if (cp && (cp->type == CABLE_PAIRING_SIXAXIS ||
> -					cp->type ==
> CABLE_PAIRING_DS4))
> +					cp->type ==
> CABLE_PAIRING_DS4 ||
> +					cp->type ==
> CABLE_PAIRING_DUALSENSE))
>  		return true;
>  
>  	return false;
> diff --git a/profiles/input/sixaxis.h b/profiles/input/sixaxis.h
> index ab8831995..ac7e75223 100644
> --- a/profiles/input/sixaxis.h
> +++ b/profiles/input/sixaxis.h
> @@ -17,6 +17,7 @@ typedef enum {
>  	CABLE_PAIRING_UNSUPPORTED = 0,
>  	CABLE_PAIRING_SIXAXIS,
>  	CABLE_PAIRING_DS4,
> +	CABLE_PAIRING_DUALSENSE,
>  } CablePairingType;
>  
>  struct cable_pairing {
> @@ -72,6 +73,30 @@ get_pairing(uint16_t vid, uint16_t pid, const char
> *name)
>  			.version = 0x0001,
>  			.type = CABLE_PAIRING_DS4,
>  		},
> +		{
> +			.name = "Sony Interactive Entertainment
> Wireless Controller",
> +			.source = 0x0002,
> +			.vid = 0x054c,
> +			.pid = 0x0ce6,
> +			.version = 0x0001,
> +			.type = CABLE_PAIRING_DUALSENSE,
> +		},
> +		{
> +			.name = "Sony Interactive Entertainment
> DualSense Wireless Controller",
> +			.source = 0x0002,
> +			.vid = 0x054c,
> +			.pid = 0x0ce6,
> +			.version = 0x0001,
> +			.type = CABLE_PAIRING_DUALSENSE,
> +		},
> +		{
> +			.name = "Sony Interactive Entertainment
> DualSense Edge Wireless Controller",

Need to remove the "Sony Interactive Entertainment" prefix from those.

> +			.source = 0x0002,
> +			.vid = 0x054c,
> +			.pid = 0x0df2,
> +			.version = 0x0001,
> +			.type = CABLE_PAIRING_DUALSENSE,
> +		},
>  	};
>  	guint i;
>  

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH BlueZ 2/2] plugins/sixaxis: Implement cable pairing for DualSense
  2025-06-03 18:35         ` Egor Vorontsov
  2025-06-04 12:41           ` Luiz Augusto von Dentz
@ 2025-08-21 13:12           ` Bastien Nocera
  1 sibling, 0 replies; 16+ messages in thread
From: Bastien Nocera @ 2025-08-21 13:12 UTC (permalink / raw)
  To: sdoregor, Luiz Augusto von Dentz; +Cc: linux-bluetooth

On Tue, 2025-06-03 at 21:35 +0300, Egor Vorontsov wrote:
> On Tue, 2025-06-03 at 11:38 -0400, Luiz Augusto von Dentz wrote:
> > Perhaps it is possible to write the link keys directly via cable
> > but
> > then we need the OOB data, etc, to generate the keys which in my
> > opinion it just extra work that doesn't really add anything if just
> > works, or autopair, is used.
> 
> In my experimental PoC I just generated a random 128-bit string and
> used it as the link key for both sides (placed into `LinkKey=' in
> BlueZ's `/info' and sent to DualSense over USB), which showed to be
> working perfectly.
> 
> > Is it not seamless right now? Doesn't it use 'just works'/autopair?
> 
> It is kind of seamless, but you still have to accept the pairing
> manually (e.g. be discoverable and with an active agent). In terms of
> security I'd say this behavior is indeed preferable (otherwise one
> could spoof the VID:PID and zero-click bond with the host), but it
> still requires two separate confirmations.
> 
> If we could generate a static key, place it to both devices BUT at the
> same time mark the device as unconfirmed/untrusted/etc. locally, so
> that it is still going to trigger one and only one interactive pairing
> confirmation, that'd be the intended design at least in my view.
> 
> Another possible way would be to automatically accept the first, dummy
> pairing request that doesn't bear a link key yet -- so no security risk
> there, but still more seamless experience for the user.

The way it's supposed to work right now, is that you get an
authorisation request when you plug the device in and the Bluetooth
panel is open. This is what it does with PS3 and PS4 controllers (after
my recent bug fixes for PS4 controllers).

Then, when you unplug the controller and click on the PS/Power button,
it's supposed to connect without any more confirmations or the need to
have the Bluetooth panel open. This is how it works with PS3
controllers which don't pair.

PS4 controllers expect to pair, so they need to be authorised again.
Unfortunately, Sony won't share any cable pairing information with
kernel drivers writers, so we can't easily reimplement this.

So a "pairing" dialogue after the "authorisation" dialogue is how it
works. Removing the first "authorisation" dialogue is out of the
question, that's what makes it possible to plug the controller for
charging without pairing it.

See the patchset that starts with:
adapter: Add btd_request_authorization_cable_configured()
that I sent in 2017 and implemented that cable pairing authorisation.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH BlueZ 2/2] plugins/sixaxis: Implement cable pairing for DualSense
  2025-06-03  9:56 ` [PATCH BlueZ 2/2] plugins/sixaxis: Implement cable pairing " Egor Vorontsov
  2025-06-03 14:40   ` Luiz Augusto von Dentz
@ 2025-08-21 13:12   ` Bastien Nocera
  1 sibling, 0 replies; 16+ messages in thread
From: Bastien Nocera @ 2025-08-21 13:12 UTC (permalink / raw)
  To: Egor Vorontsov, linux-bluetooth

On Tue, 2025-06-03 at 12:56 +0300, Egor Vorontsov wrote:
> The code is very similar to that for DS4, but I found it's better
> to separate the matters instead of generalizing it via constants.

I don't think there was a need to mention it that way, the code is
already setup in such a way that it has separate code paths for each
supported type of hardware. Maybe:
"The protocol used by the DualSense cable pairing is similar to that
used by the DualShock4 controllers, but different enough that using
separate code paths is more legible."

> Also added a request to enable Bluetooth on the controller to initiate
> pairing without the need to disconnect it and power on again wirelessly,
> basically emulating what PS itself does. Only for DualSense family now,
> but can be expanded to DS4 too (I don't have one at hand to test this).

The fact that you wrote "also" in this commit message is a good
indicator that this should probably have been a separate commit.

> ---
>  plugins/sixaxis.c | 107
> ++++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 104 insertions(+), 3 deletions(-)
> 
> diff --git a/plugins/sixaxis.c b/plugins/sixaxis.c
> index 1fab8ae59..a583c8b82 100644
> --- a/plugins/sixaxis.c
> +++ b/plugins/sixaxis.c
> @@ -131,12 +131,36 @@ static int ds4_get_device_bdaddr(int fd,
> bdaddr_t *bdaddr)
>  	return 0;
>  }
>  
> +static int dualsense_get_device_bdaddr(int fd, bdaddr_t *bdaddr)
> +{
> +	uint8_t buf[20];
> +	int ret;
> +
> +	memset(buf, 0, sizeof(buf));
> +
> +	buf[0] = 0x09;
> +
> +	ret = ioctl(fd, HIDIOCGFEATURE(sizeof(buf)), buf);
> +	if (ret < 0) {
> +		error("sixaxis: failed to read DualSense device
> address (%s)",
> +		      strerror(errno));
> +		return ret;
> +	}
> +
> +	/* address is little-endian on DualSense */
> +	bacpy(bdaddr, (bdaddr_t*) (buf + 1));
> +
> +	return 0;
> +}
> +
>  static int get_device_bdaddr(int fd, bdaddr_t *bdaddr,
> CablePairingType type)
>  {
>  	if (type == CABLE_PAIRING_SIXAXIS)
>  		return sixaxis_get_device_bdaddr(fd, bdaddr);
>  	else if (type == CABLE_PAIRING_DS4)
>  		return ds4_get_device_bdaddr(fd, bdaddr);
> +	else if (type == CABLE_PAIRING_DUALSENSE)
> +		return dualsense_get_device_bdaddr(fd, bdaddr);
>  	return -1;
>  }
>  
> @@ -183,12 +207,36 @@ static int ds4_get_central_bdaddr(int fd,
> bdaddr_t *bdaddr)
>  	return 0;
>  }
>  
> +static int dualsense_get_central_bdaddr(int fd, bdaddr_t *bdaddr)
> +{
> +	uint8_t buf[20];
> +	int ret;
> +
> +	memset(buf, 0, sizeof(buf));
> +
> +	buf[0] = 0x09;
> +
> +	ret = ioctl(fd, HIDIOCGFEATURE(sizeof(buf)), buf);
> +	if (ret < 0) {
> +		error("sixaxis: failed to read DualSense central
> address (%s)",
> +		      strerror(errno));
> +		return ret;
> +	}
> +
> +	/* address is little-endian on DualSense */
> +	bacpy(bdaddr, (bdaddr_t*) (buf + 10));
> +
> +	return 0;
> +}
> +
>  static int get_central_bdaddr(int fd, bdaddr_t *bdaddr,
> CablePairingType type)
>  {
>  	if (type == CABLE_PAIRING_SIXAXIS)
>  		return sixaxis_get_central_bdaddr(fd, bdaddr);
>  	else if (type == CABLE_PAIRING_DS4)
>  		return ds4_get_central_bdaddr(fd, bdaddr);
> +	else if (type == CABLE_PAIRING_DUALSENSE)
> +		return dualsense_get_central_bdaddr(fd, bdaddr);
>  	return -1;
>  }
>  
> @@ -230,6 +278,26 @@ static int ds4_set_central_bdaddr(int fd, const
> bdaddr_t *bdaddr)
>  	return ret;
>  }
>  
> +static int dualsense_set_central_bdaddr(int fd, const bdaddr_t
> *bdaddr)
> +{
> +	uint8_t buf[27];
> +	int ret;
> +
> +	buf[0] = 0x0A;
> +	bacpy((bdaddr_t*) (buf + 1), bdaddr);
> +	/* TODO: we could put the key here but
> +	   there is no way to force a re-loading
> +	   of link keys to the kernel from here. */
> +	memset(buf + 7, 0, 16);
> +
> +	ret = ioctl(fd, HIDIOCSFEATURE(sizeof(buf)), buf);
> +	if (ret < 0)
> +		error("sixaxis: failed to write DualSense central
> address (%s)",
> +		      strerror(errno));
> +
> +	return ret;
> +}
> +
>  static int set_central_bdaddr(int fd, const bdaddr_t *bdaddr,
>  					CablePairingType type)
>  {
> @@ -237,6 +305,32 @@ static int set_central_bdaddr(int fd, const
> bdaddr_t *bdaddr,
>  		return sixaxis_set_central_bdaddr(fd, bdaddr);
>  	else if (type == CABLE_PAIRING_DS4)
>  		return ds4_set_central_bdaddr(fd, bdaddr);
> +	else if (type == CABLE_PAIRING_DUALSENSE)
> +		return dualsense_set_central_bdaddr(fd, bdaddr);
> +	return -1;
> +}
> +
> +static int dualsense_set_bluetooth_state(int fd, bool state)
> +{
> +	uint8_t buf[48];
> +	int ret;
> +
> +	buf[0] = 0x08;
> +	buf[1] = state?1:2;

buf[1] = state ? 0x1 : 0x2;

> +
> +	ret = ioctl(fd, HIDIOCSFEATURE(sizeof(buf)), buf);
> +	if (ret < 0)
> +		error("sixaxis: failed to set DualSense Bluetooth
> state (%s)",
> +		      strerror(errno));
> +
> +	return ret;
> +}
> +
> +static int set_bluetooth_state(int fd, CablePairingType type,
> +					bool state)
> +{
> +	if (type == CABLE_PAIRING_DUALSENSE)
> +		return dualsense_set_bluetooth_state(fd, state);
>  	return -1;
>  }
>  
> @@ -297,12 +391,13 @@ static void agent_auth_cb(DBusError *derr, void
> *user_data)
>  	remove_device = false;
>  	btd_device_set_temporary(closure->device, false);
>  
> -	if (closure->type == CABLE_PAIRING_SIXAXIS) {
> +	if (closure->type == CABLE_PAIRING_SIXAXIS)

It's a multi-line conditional, we still want the braces.

>  		btd_device_set_record(closure->device, HID_UUID,
>  						
> SIXAXIS_HID_SDP_RECORD);
>  
> +	if (closure->type == CABLE_PAIRING_SIXAXIS ||
> +				closure->type ==
> CABLE_PAIRING_DUALSENSE) {
>  		device_set_cable_pairing(closure->device, true);
> -

No white space changes please.

>  		server_set_cable_pairing(adapter_bdaddr, true);
>  	}

device_set_cable_pairing() and server_set_cable_pairing() are supposed
to be called for DS4 as well. I've fixed that in another patchset,
which you'll probably need to rebase on top of.

>  
> @@ -312,6 +407,11 @@ static void agent_auth_cb(DBusError *derr, void
> *user_data)
>  	DBG("remote %s old_central %s new_central %s",
>  				device_addr, central_addr,
> adapter_addr);
>  
> +	if (closure->type == CABLE_PAIRING_DUALSENSE) {
> +		DBG("Enabling Bluetooth connection on the device");
> +		set_bluetooth_state(closure->fd, closure->type,
> true);
> +	}
> +
>  out:
>  	g_hash_table_steal(pending_auths, closure->sysfs_path);
>  
> @@ -432,7 +532,8 @@ static void device_added(struct udev_device
> *udevice)
>  
>  	cp = get_pairing_type_for_device(udevice, &bus,
> &sysfs_path);
>  	if (!cp || (cp->type != CABLE_PAIRING_SIXAXIS &&
> -				cp->type != CABLE_PAIRING_DS4)) {
> +				cp->type != CABLE_PAIRING_DS4 &&
> +				cp->type !=
> CABLE_PAIRING_DUALSENSE)) {
>  		g_free(sysfs_path);
>  		return;
>  	}

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH BlueZ 2/2] plugins/sixaxis: Implement cable pairing for DualSense
  2025-06-04 22:50             ` Egor Vorontsov
  2025-08-10 20:46               ` Egor Vorontsov
@ 2025-08-21 13:12               ` Bastien Nocera
  1 sibling, 0 replies; 16+ messages in thread
From: Bastien Nocera @ 2025-08-21 13:12 UTC (permalink / raw)
  To: sdoregor, Luiz Augusto von Dentz; +Cc: linux-bluetooth

On Thu, 2025-06-05 at 01:50 +0300, Egor Vorontsov wrote:
> On Wed, 2025-06-04 at 08:41 -0400, Luiz Augusto von Dentz wrote:
> > Hmm, not so sure this is secure though, I mean it could be a rogue
> > USB
> > device pretending to be a controller so it would automatically be
> > considered paired if we just self generate the keys without asking
> > for
> > user confirmation.
> 
> We can generate whatever we want, unless BlueZ will treat the key as
> bonded no question asked. Read on to see what I mean.
> 
> > Yeah, the zero-click bond might be a security concern though, so I
> > think having the user do a confirmation for each step is sort of
> > assuring he knows (or at least pretend) what is going on.
> 
> I strongly believe you only should confirm once. Especially since the
> first one doesn't actually pair or trust anything, instead it just
> creates the device record for it to be able to initiate a bonding
> connection to us without discoverable being on (as far as I
> understand
> it).

It also modifies the controller's storage to tell it to connect to our
computer when clicking the PS button.

> 
> The painful re-re-pairing process is so strongly tied with Bluetooth
> in
> our minds, so I really don't want to further increase its
> awkwardness.
> 
> > When would we generate the confirmation though? I sort of trust
> > more
> > the Bluetooth process to generate and exchange keys.
> 
> That's exactly what I'd love to hear from someone, honestly :)
> 
> I see a possible solution where we trigger agent on the first
> connect,
> even though the link key is already established. It might be a
> special
> flag for the device, or even just another value in the `LinkKey.Type'
> field -- meaning, "key was generated by us, should reconfirm
> pairing".

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2025-08-21 13:13 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-03  9:56 [PATCH BlueZ 0/2] Cable pairing support for DualSense Egor Vorontsov
2025-06-03  9:56 ` [PATCH BlueZ 1/2] profiles/input: Add cable pairing constants " Egor Vorontsov
2025-06-03 11:32   ` Cable pairing support " bluez.test.bot
2025-08-21 13:11   ` [PATCH BlueZ 1/2] profiles/input: Add cable pairing constants " Bastien Nocera
2025-06-03  9:56 ` [PATCH BlueZ 2/2] plugins/sixaxis: Implement cable pairing " Egor Vorontsov
2025-06-03 14:40   ` Luiz Augusto von Dentz
2025-06-03 14:55     ` Egor Vorontsov
2025-06-03 15:38       ` Luiz Augusto von Dentz
2025-06-03 18:35         ` Egor Vorontsov
2025-06-04 12:41           ` Luiz Augusto von Dentz
2025-06-04 22:50             ` Egor Vorontsov
2025-08-10 20:46               ` Egor Vorontsov
2025-08-21 13:12               ` Bastien Nocera
2025-08-21 13:12           ` Bastien Nocera
2025-08-21 13:12   ` Bastien Nocera
2025-08-21 13:00 ` [PATCH BlueZ 0/2] Cable pairing support " Bastien Nocera

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox