Skip to content

hurryman2212/vds

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

vDS (virtual DualSense)

Linux virtual USB-to-Bluetooth bridge for DualSense and DualSense Edge Wireless Controllers, focused on USB-only features such as 4-channel audio-based haptic feedback. Detailed DualSense output and haptics packet handling is based on DS5Dongle and protocol capture research.

Warning

This project is still in development. Performance has not been tuned, and race conditions may still exist. Many components currently run in userspace, so continuous context switching can add significant overhead.

Application
  -> Userspace audio server (e.g. PipeWire)
  -(ALSA PCM)-> Linux ALSA stack [snd-usb-audio.ko]
  -(USB isochronous OUT URBs)-> **Linux USB stack [vds_hcd.ko]**
  **-(/dev/vdsX)-> vdsd (implements raw Bluetooth HID handling)**
  **-(AF_BLUETOOTH L2CAP socket)->** Linux Bluetooth stack
  -(Bluetooth HID Control/Interrupt)-> DualSense (Edge) controller

This project includes a custom virtual USB HCD primarily because Linux's dummy_hcd module does not support isochronous transfers, which are required for the USB audio path used by DualSense haptics. The custom HCD currently also hosts the /dev/vdsX bridge and virtual port lifecycle, but that architecture may be revisited if dummy_hcd gains suitable isochronous transfer support. The current architecture should therefore be treated as temporary. Future work will move more of the bridge from userspace into the kernel to reduce context-switching overhead.

Currently, the virtual USB HID endpoints are fixed to a 1000 Hz polling rate. This affects host-side HID report scheduling, input/output latency, USB/HCD wakeups, and CPU/context-switch load.

Initial Bluetooth Pairing

Important

Current limitation: run bluetoothd with the input plugin disabled (--noplugin=input). vDS needs direct ownership of the Bluetooth HID Control and Interrupt L2CAP channels. If the normal BlueZ input plugin is active, it can claim the controller first and expose it as a regular Bluetooth gamepad instead of letting vDS bridge it as a virtual USB controller.

Pair each physical controller once before registering it with vdsctl. Start bluetoothctl, put the controller in Bluetooth pairing mode (hold Create and PS until the light bar blinks rapidly), then use the MAC address printed by scan on:

agent NoInputNoOutput
default-agent
pairable on
scan on
pair XX:XX:XX:XX:XX:XX
trust XX:XX:XX:XX:XX:XX
scan off
quit

When re-pairing a controller that BlueZ already knows, run remove XX:XX:XX:XX:XX:XX before scan on.

Module Install

Build the kernel module locally:

make -C module

Install or remove it through DKMS:

sudo make -C module install
sudo make -C module uninstall

Load the module:

sudo modprobe vds_hcd

To expose more than one virtual controller:

sudo modprobe vds_hcd max_port=2

Userspace Install

Build the daemon and CLI:

cmake . -B build
make -C build

Install or remove the userspace tools:

sudo make -C build install
sudo make -C build uninstall

The installed tools are:

vdsd
vdsctl

Binding Physical Controllers

Load two virtual controller ports:

sudo modprobe vds_hcd max_port=2

Start the daemon:

sudo vdsd

Bind two paired/trusted Bluetooth DualSense or DualSense Edge controllers:

sudo vdsctl attach aa:bb:cc:dd:ee:01 --identity ds5 --limit-dev /dev/vds0
sudo vdsctl attach aa:bb:cc:dd:ee:02 --identity dse --limit-dev /dev/vds1

Important

Configure the virtual controller audio device as 48 kHz 4-channel S16_LE PCM. The exact setup differs by audio stack, such as PipeWire, PulseAudio, ALSA, or JACK.

List persistent bindings:

sudo vdsctl list

Toggle packet-level daemon tracing:

sudo vdsctl trace on
sudo vdsctl trace off

Detach each binding:

sudo vdsctl detach aa:bb:cc:dd:ee:XX

Testing

Check that the virtual USB controller enumerated:

lsusb -d 054c:

Check input devices and force-feedback support with standard tools:

evtest
fftest /dev/input/eventX

Check the virtual USB audio endpoint with standard ALSA tools:

aplay -l
speaker-test -D hw:<card-number>,<device-number> -c 4 -r 48000 -F S16_LE -t sine

Inspect daemon logs:

sudo tail -f /var/log/vdsd.log

About

Linux Virtual USB-to-Bluetooth bridge for DualSense and DualSense Edge Wireless Controllers

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages