PlayStation 5 DualSense controller pairing

I would like to connect a DualShock 4 (and PS5 controller later on) with FreeBSD and my integrated (USB) Bluetooth 2.1 or 4.0 chip.
With the DualShock 4 connected via USB, controllermap successfully detects both the controller and every single controller button / analog stick.
Now I used bluetooth_config scan to pair the controller. When asked for a pin, I simply left it at the default nopin.

Now there is an alias in /etc/bluetooth/hosts, an entry in hcsecd.conf with nokey and nopin and bthidd.conf lists the device with the bdaddr, some more info and the hid_descriptor{ ... }.

However, nothing really happens from here on out.
Every 10 seconds, the bluetooth lamp blinks and hccontrol read_connection_list reports:
Code:
Remote BD_ADDR    Handle Type Mode Role Encrypt Pending Queue State
DualShock4          3902  ACL    0 MAST    NONE       0     0 W4_CONN_COMPLETE
This lasts roughly 3 seconds, before the entry disappears and the cycle starts anew. The DualShock4 never lights up, putting it into connection mode changes nothing, just the blue connection light flashing on the controller. controllermap never detects a joystick.

What can I do to get a connection? Is my pairing maybe incomplete, because I set nopin and nokey? With Linux and DualShock 3 there appears to be the need to connect it via USB first to exchange pairing data. Maybe that's when the key is transfered? But this does not appear to be the case for DualShock 4.
 
Last edited:
I compared to Linux and here are the results:
Connection on Linux works automatically. The DualShock4 turns instantly blue and the controller inputs are read successfully.
I checked /var/lib/bluetooth for pairing information.
My Smartphone leaves behind a pairing key, the DualShock4 does not. The DualShock4's bluetooth info file shows no special information being left behind:
Code:
[General]
Name=Wireless Controller
Class=0x002508
SupportedTechnologies=BR/EDR;
Trusted=false
Blocked=false
WakeAllowed=true
Services=00001124-0000-1000-8000-00805f9b34fb;00001200-0000-1000-8000-00805f9b34fb;

[DeviceID]
Source=2
Vendor=1356
Product=2508
Version=256
For comparison the SmartPhone Info file:
Code:
[LinkKey]
Key=4A210DB2D0D1CC87459184DFB6A7F601
Type=5
PINLength=0

[General]
Name=OnePlus One
Class=0x5a020c
SupportedTechnologies=BR/EDR;
Trusted=true
Blocked=false
Services=00001105-0000-1000-8000-00805f9b34fb;0000110a-0000-1000-8000-00805f9b34fb;0000110c-0000-1000-8000-00805f9b34fb;0000110d-0000-1000-8000-00805f9b34fb;0000110e-0000-1000-8000-00805f9b34fb;00001112-0000-1000-8000-00805f9b34fb;00001115-0000-1000-8000-00805f9b34fb;00001116-0000-1000-8000-00805f9b34fb;0000111f-0000-1000-8000-00805f9b34fb;0000112f-0000-1000-8000-00805f9b34fb;00001132-0000-1000-8000-00805f9b34fb;00001200-0000-1000-8000-00805f9b34fb;00001800-0000-1000-8000-00805f9b34fb;00001801-0000-1000-8000-00805f9b34fb;

[DeviceID]
Source=1
Vendor=224
Product=4608
Version=5174
Thus I conclude, that both nopin and nokey properties in FreeBSD are indeed correct. So something about the handling of the Controller is wrong. I don't even know whether the pairing succesds or not, and I have no idea how to understand what hccontrol means by "W4_CONN_COMPLETE". skimming the kernel code, ng_hci_ulpi.c states "NG_HCI_CON_W4_CONN_COMPLETE means that upper layer already requested connection or we just accepted it. In any case all we need to do here is set appropriate notification bit and wait."
I guess FreeBSD is waiting for the DualShock4 to answer, but I'm way over my head here. I have no idea how to proceed or where to look for answers.
halp 🥺
 
According to the Handbook, Bluetooth version 1.1 and some models of v2 work. Some have claimed up to Bluetooth 3.0, or Bluetooth LE works, while the documentation is years behind, but this is difficult to validate or confirm. They say Bluetooth audio works no matter the version, this is documented.
 
According to the Handbook, Bluetooth version 1 and some manufacturers of 2.1 work. Some have said up to Bluetooth 3.0 or Bluetooth LE works, while the documentation is years behind, but this is difficult to validate or confirm. They say Bluetooth audio works no matter the version.
Ohh... So I misunderstood what FBSD supports.
There is just no support for Bluetooth v4, no need to try and investigate anything. I specifically replaced the USB daughterboard in my Thinkpads to Bluetooth v4 ones. I can downgrade to Bluetooth 2.1 again. Since the DualShock 4 is BlueTooth v2.1 and the PS5's Dual Sense controller propably supports BlueTooth 2.0 via backwards compatibility, because you can use a PS5 controller on a PS3 (A BlueTooth 2.0 only device), I should get everything to work by downgrading to the BlueTooth 2.1 daughter board.

That seems like a good theory to try :] Will test that tomorrow and report back.
 
After reading the section on the handbook, the supported versions were easy to miss. I actually missed it, and went and bought a higher version Bluetooth dongle.

Some Bluetooth peripherals have shown up, but not as a Bluetooth device. They didn't work.

In a thread, there was a claim of Bluetooth v4 working. Bluetooth LE may possibly include higher versions. These claims of higher versions working is difficult to validate.

There's the possibility that some Bluetooth code was temporarily in Stable or Current. It's also possible that there's some code in FreeBSD base that isn't complete or officially functional.
 
Progress!
After changing from the BCM920702MD BlueTooth 4.0 board to the BCM92046MD BlueTooth 2.1 EDR2 Board, pairing can be successfully completed.
The Bluetooth driver responds when the DualShock4 is turned on and opens a connection. After a successful pairing, the bluetooth lamp starts blinking non-stop and the controller shines light-blue all the time.
Code:
bthidd[892]: Accepted control connection from a0:ab:51:43:ba:27
bthidd[892]: Accepted interrupt connection from a0:ab:51:43:ba:27
hccontrol read_connection_list now reports constantly:
Code:
Remote BD_ADDR    Handle Type Mode Role Encrypt Pending Queue State
a0:ab:51:43:ba:27     11  ACL    0 MAST     P2P       0     0 OPEN
Setting everything up, this article really helped. "bluetooth_config scan" behaves a bid weird, throwing error after writing the hid descriptor even though it succeeds. Manully setting it up, no errors were encountered. Also, I do not understand when or how it is setup, but sometimes I got to a state, where the BlueTooth chip would scan every 10 seconds actively with the lamp blinking. This is not the case anymore. Now it simply remains neutral, until the DS4 requests a connection.
Now the DualShock4 constantly shines light-blue. The same light blue that blinks when it searches for a connection. However, it is not the DarkBlue I encountered in Linux, when it is working as a controller.
No joystick is detected by controllermap. How can I procced? Where can I look? I don't even know whether there was a device created in /dev/ or not...
 
Highly annoyingly I cannot get it to pair again to research further >.<
Nothing changed, but now the DS4 just blinks, the Bluetooth lamp blinks for a single time but nothing happens, no "Accepted control connection" in /var/messages
Doing manually
sudo hccontrol -n ubt0hci create_connection a0:ab:51:43:ba:27
results in
Status: ACL connection already exists [0xb]
And hccontrol read_connection_list lists the following for a single second:
Code:
Remote BD_ADDR    Handle Type Mode Role Encrypt Pending Queue State
a0:ab:51:43:ba:27     3848  ACL    0 MAST     P2P       0     0 W4_CONN_COMPLETE
Like with the non-working BlueTooth 4.0. So frustrating, I don't know how to coerce it into connecting again. Since these are the symptoms as with BlueTooth 4, maybe BlueTooth 4 did work after all?
 
There exists this user space driver for the DualShock4 on Linux: https://github.com/chrippa/ds4drv
Let's say, that through sheer power of will I actually get FreeBSD's bluetooth to stick to "Accepted control connection" again, like on that miracle of a day...
... where would that bluetooth device be created? Is there a corresponding /dev/.... entry?
 
I believe so, that a device will be created in /dev/. A module may also be created in /boot/modules/. Use dmesg to see terminal output of a new connection.

* edit, a Bluetooth driver, if there is one. As for the gamepad driver, FreeBSD may already have it. Iichid is base of FreeBSD 13.0.
 
I believe so, that a device will be created in /dev/. A module may also be created in /boot/modules/. Use dmesg to see terminal output of a new connection.

* edit, a Bluetooth driver, if there is one. As for the gamepad driver, FreeBSD may already have it. Iichid is base of FreeBSD 13.0.
A Bluetooth driver what for? What is it's purpose, for what device? To interface with the DualShock 4? To manage the BlueTooth Chip?

Also any idea how to solve
"sudo hccontrol -n ubt0hci create_connection a0:ab:51:43:ba:27" returning "Status: ACL connection already exists [0xb]"?
 
A Bluetooth driver simply for being of Bluetooth, if the version needed still doesn't work.
sysutils/btsixad, iichid(4) is in base of FreeBSD 13.0, and they say SDL takes care of gamepad/joystick drivers too. Try one of those. If it has both Bluetooth and a USB cable, test it over USB connection first.

Is there a command to list connected Bluetooth devices? There's dmesg, but there may be one more specific to Bluetooth. What about kldstat? I would say, ask on the mailing list (https://lists.freebsd.org/mailman/listinfo/freebsd-bluetooth) too, but it hardly has anything. It wouldn't hurt to try, perhaps there can be a response.
 
A Bluetooth driver simply for being of Bluetooth, if the version needed still doesn't work.
sysutils/btsixad, iichid(4) is in base of FreeBSD 13.0, and they say SDL takes care of gamepad/joystick drivers too. Try one of those. If it has both Bluetooth and a USB cable, test it over USB connection first.

Is there a command to list connected Bluetooth devices? There's dmesg, but there may be one more specific to Bluetooth. What about kldstat? I would say, ask on the mailing list (https://lists.freebsd.org/mailman/listinfo/freebsd-bluetooth) too, but it hardly has anything. It wouldn't hurt to try, perhaps there can be a response.
DualShock4 via USB works flawlessly and spawns /dev/uhid0, as described in the OP.
As for BlueTooth, I think this is once more progress...
...bthidd can interpret the HID descriptor and accept the DualShock4, as described in this post. However, this does not get us far no device is spawned in /dev.
Now on to btsixad - Many thanks for the reference! bthidd and btsixad listen on the same socket, so one thing or the other.
With bthidd gone, btsixad also detects the DS4, though not in name and disconnects:
Code:
btsixad 23379 - - connection from a0:ab:51:43:ba:27 on control channel
btsixad 23379 - - connection from a0:ab:51:43:ba:27 on interrupt channel
btsixad 23379 - - connection is from unknown device: vendor 0x054c (by 0x0002), product 0x09cc, release 0x0100
btsixad 23379 - - connection from a0:ab:51:43:ba:27 closed
The kernel module ng_l2cap_l2ca_receive also complains:
Code:
Jun 16 01:30:01 stripes kernel: ng_l2cap_l2ca_receive: ubt0l2cap - unexpected L2CAP data packet. Invalid channel state, cid=108, state=5
Jun 16 01:30:01 stripes syslogd: last message repeated 2 times
I presume the kernel complains, because btsixad killed the connection ungracefully, and not vice-versa (bluetooth kernel module creates an issue, that makes btsixad fail)

This is as far as I get. The btsixad package homepage mentions, that btsixad is aimed at the DualShock3. Maybe involve that package author to explain to us what would have to be done to revamp support for the PS4's DualShock 4 and the PS5's DualSense...
 
I got my hands on a DualShock 3 and tried out the BlueTooth capability via sysutils/btsixad. It works!
It is successfully being detected as a controller and all inputs are being proccessed.

As mentioned in the previous post this does not extended to the DualShock 4. I do wonder what could be done about btsixad to get support going... The btsixad codebase is only 1000 SLOC. So I'll try to go through it to get a grip on the proccess of all of this...
 
I got myself a PlayStation5 DualSense controller.
On Linux pairing via BlueTooth 2.1 works flawlessly and all buttons and axis work <3
The Situtation with FreeBSD is unfortunately the same as with the DualShock4 controller: Connecting via USB works, but with bluetooth: After exchanging Pairing and hid data, which works flawlessly, a connection cannot be establised.
hccontrol reports:
Code:
Remote BD_ADDR    Handle Type Mode Role Encrypt Pending Queue State
a0:ab:51:c4:af:bb     13  ACL    0 MAST    NONE       1     0 OPEN

Followed by
Remote BD_ADDR    Handle Type Mode Role Encrypt Pending Queue State
a0:ab:51:c4:af:bb   3884  ACL    0 MAST    NONE       0     0 W4_CONN_COMPLETE
And the connection terminates. btsixad does not pick up anything at all.
So I guess the only hope is adapting btsixad?
 
btsixad author here. So btsixad has three functions:

1. Pairing. The PS3 gamepad uses a non-standard pairing procedure: it sets the host's Bluetooth address in the gamepad over USB. PS4 and PS5 gamepads use standard Bluetooth pairing.

2. Talking to the gamepad over Bluetooth L2CAP on HID control and interrupt channels and querying metadata over SDP. I think this is pretty normal for Bluetooth HID devices because bthidd and bthidcontrol do something similar. The PS3 controller either has a broken HID descriptor or none at all (seems pretty normal too) and needs a special message to initialize it. Other than that I think bthidd would be able to do this part.

3. Fakes a local /dev/uhid device via cuse(3). All the game engines (SDL etc.) understand this. The input reports received over Bluetooth are remapped a bit according to my preferences before being reported there. For example the D-pad is presented as a hat switch rather than buttons 4-7. I think the proper way to do this nowadays is evdev, which is mentioned on bthidd(8).

Only the PS3 gamepad is supported and you can see that a lot of this is relevant to the PS3 gamepad only. The immediate disconnect when it detects a different device is intentional.

As for the PS4 and PS5 gamepads - they are more well-behaved Bluetooth HID devices, and it sounds like you almost have bthidd working with them. Maybe the HID descriptor is broken and doesn't match the actual reports (bthidd.conf can provide a custom one), maybe some HID control message to initialize it is missing. The standard Linux driver (drivers/hid/hid-sony.c) or the userspace driver you mentioned (ds4drv) might have hints about this.

Adapting btsixad should only be needed if you want extra functions like changing the LED color, changing the default button map, or to do any initialization automatically. Since pairing already works, this would only involve detecting the new gamepad's model and creating a new device-specific file similar to sixaxis.c to send any required initialization messages, and to either provide a hardcoded HID descriptor as is done for the PS3 gamepad or to query the real HID descriptor over SDP. Unfortunately I don't have time to try this.
 
Had E-Mail notifications off for such an important post >.<
aaz Many thanks for your input!
I think bthidd would be able to do this part [...] and it sounds like you almost have bthidd working with them.
That sounds very good!
Adapting btsixad should only be needed if you want extra functions like changing the LED color, changing the default button map, or to do any initialization automatically.
This is settled then, there is no need to dig through btsixad for the DualShock 4 and the DualSense. These extra functions are not support by Linux's kernel driver either and modern features like adaptive trigger and new haptic feedback probably won't ever be even with user space drivers. I care only about the basic stuff, like analog sticks and buttons. I really enjoy demoing my work by giving clients a modern controller with a certain elegance, no cables and a comfortable design.
Maybe the HID descriptor is broken and doesn't match the actual reports (bthidd.conf can provide a custom one), maybe some HID control message to initialize it is missing. The standard Linux driver (drivers/hid/hid-sony.c) or the userspace driver you mentioned (ds4drv) might have hints about this.
This sounds like a lead <3 The HID descriptor is successfully provided by bthidcontrol -a ${BDADDR} query, but you say something with how bthidd handles things is going wrong with the symptoms being, that the connection is dropped and no device is spawned in /dev/. This is a very nice direction to dig in.
 
Back
Top