Releases: kungaa/DS5-Linux-Bridge
Release list
v2.3.0-beta.1 — resilient WiFi, WPA3, and microphone refinements
v2.3 beta
This pre-release adds more resilient WiFi onboarding and recovery, reduces idle microphone traffic, and makes controller-session cleanup easier.
What's new
- Resilient WiFi recovery: ordinary network failures keep saved credentials and retry in the background while Bluetooth gameplay remains available. Three consecutive authentication failures clear rejected credentials and reopen onboarding.
- WPA3-only onboarding: the setup portal now offers an explicit WPA3-SAE choice for routers and phone hotspots that require it. WPA2 remains the default for WPA2 and transition networks.
- Controller-safe setup recovery: with all controllers powered off, three BOOTSEL press-release cycles within four seconds reopen the setup network for one boot without erasing the old credentials. A continuous 2 Hz onboard-LED blink identifies onboarding mode.
- Idle microphone transport: controller microphone upload stops while no host application has the USB microphone stream open and resumes automatically when an application opens it.
- Layered microphone mute: the physical Mute button and host sound-panel mute are independent, so clearing one cannot override the other. The orange LED follows the effective combined state.
- Power off all controllers: a config-page action powers down every connected pad without forgetting pairings, making it easy to return from multi-controller mode to single-controller audio and HD haptics.
This is a beta pre-release. Download the appropriate UF2 below, or enable Include pre-releases on the config page's Update tab before installing over WiFi. Settings, WiFi credentials, and controller pairings are preserved during updates.
v2.2.1 — stable OTA and multi-controller release
Stable 2.2 release
This promotes the community-tested v2.2.0 beta firmware to a stable release and adds a minor OTA HTTP-header parsing correction.
- One-click over-the-air updates for Pico 2 W and Waveshare RP2350B-Plus-W, with HTTPS download and SHA-256 verification before installation.
- Stable and pre-release update-channel selection from the on-device config page.
- Opt-in support for up to four simultaneous DualSense controllers; audio and HD haptics remain single-controller features.
- Board-specific Pico 2 W, Waveshare, and Pico W firmware assets.
- Correctly preserves the final HTTP header value when headers and body data arrive together during OTA requests.
Settings, WiFi credentials, and paired controllers are preserved when updating.
v2.2.0-beta.1 — over-the-air updates (beta)
Over-the-air firmware updates (beta)
The config page gains an Update tab: one click installs the latest release straight from GitHub — no PC needed after the first flash. Hardware-verified end-to-end on Pico 2 W: resolve → download → SHA-256 verify → install → reboot, ~1 minute total.
- Downloads over HTTPS (pinned CA roots) and verifies the release SHA-256 before touching the running firmware; any failure reboots back unchanged with a readable reason.
- Stable vs beta channel: an "include pre-releases" checkbox picks which release to install; the page also shows latest-available vs installed.
- Settings, WiFi credentials and paired controllers are kept across updates.
⚠️ Do not unplug during the final installing step (~10 s) — interrupting that step requires reflashing over USB (hold BOOTSEL while plugging in, copy the release.uf2).- Pico W (RP2040) is excluded — its 2 MB flash cannot hold the staged second image. Pico 2 W and Waveshare RP2350B-Plus-W are supported.
Release assets now carry their board in the name: pico2w (standard), picow, waveshare. The stable-named OTA assets (ds5-bridge-pico2w-ota.bin, ds5-bridge-waveshare-ota.bin + .sha256) are what the updater downloads.
Also includes everything from v2.1.0-beta.1 (opt-in multi-controller support).
v2.1.0-beta.1 — multiple controllers (beta)
⚠️ Beta / pre-release. This is a field-test build, not the latest stable
(that remains v2.0.0). Please try it and report anything that misbehaves.
Firmware.uf2files are attached below once the build finishes.
What's new
Opt-in support for multiple DualSense controllers at once (local co-op).
Up to 4 controllers, each appearing on the PC as its own gamepad with
per-player LEDs. Off by default — until you enable it on the config page
(Controller tab → Allow multiple controllers simultaneously), the adapter
behaves exactly like v2.0.0.
Behavior once enabled:
- The adapter briefly re-plugs itself each time a new player joins; a
player leaving never interrupts the others. - Audio and HD haptics are inherently single-controller features. A single
controller's wireless audio + HD-haptics stream already sits near the ceiling
of what one Bluetooth radio can sustain, so a second connection displaces it
entirely — this is a structural limit, not something a future tweak unlocks.
With 2+ controllers connected the adapter presents plain gamepads and no audio
device. Classic rumble and adaptive triggers work for everyone. - To get audio / HD haptics back after a co-op session: power all
controllers off, then reconnect one.
See Using multiple controllers
in the user guide.
Also in this build:
- Diagnostic log (Network tab): an opt-in, RAM-only firmware log readable at
/api/logfor copy-paste bug reports. Off by default; never touches flash. - Internal RAM reclaim + boot heap telemetry.
Please test
- Enabling the toggle, then connecting a 2nd/3rd/4th controller (join + leave).
- Confirm audio + HD haptics return after all-off → reconnect-one.
- With the toggle off, confirm behavior is unchanged from v2.0.0.
- Windows: no ghost controllers, clean re-detect on each join, wake-from-sleep.
- Linux: all connected pads bind and work in your games.
Report issues on the tracker with the /api/log output if you can.
Credits
The multi-controller support is a port of the excellent work by
@cchulo in
DS5-Linux-Bridge, adapted here to
preserve this fork's dynamic-descriptor / plain-DualSense USB face (a
MINIMAL → FULL → MULTI variant model, high-water gamepad exposure, and the
opt-in toggle). Many thanks for paving the way.
v2.0.0 — WiFi config, plain-DualSense USB, Wake-on-LAN
This is a major release. The configuration transport moved from a USB network device to onboard WiFi, and over USB the adapter now presents a plain DualSense by default. Wake-on-LAN, a redesigned web UI, and a large batch of Bluetooth pairing/reliability fixes land alongside it.
⚠️ Requires Decky Loader plugin v0.4.0 or newer. The plugin talks to the redesigned on-device web API; older plugin versions will not work with this firmware.
⚠️ Breaking change. The USB network config interface is gone and the on-flash config layout changed. Configuration now happens over WiFi at http://ds5.local/. Re-onboard the adapter to your network after flashing (see the User Guide).
Highlights
- 📶 WiFi is the config transport. Configure the adapter over your own WiFi at http://ds5.local/ — no USB network device, no WebHID (which never worked in Firefox). On first boot it opens its own setup network,
DS5-Setup-XXXX; join it and browse to http://10.55.55.105/ to pick your WiFi. - 🎮 Plain-DualSense USB face by default. Over USB the adapter presents only the controller — no keyboard, no network device — so anticheat sees a normal DualSense.
- 🖥️ Wake-on-LAN. Press the controller's PS button to wake a sleeping or fully-off PC over the network — including S4/S5, which USB wake can't reach. Now supports a second WOL target, and Wake fires all configured targets.
- ⌨️ USB wake keyboard is now a runtime web toggle — off unless you turn it on, instead of a compile-time build. Wake by USB and Wake-on-LAN are configured side by side.
- 🌐 Redesigned web UI — a single tabbed page for settings, Wake, Wake-on-LAN, and paired-controller management.
Bluetooth pairing & reliability
- Bonds persist on fresh units (#2). Fixed a first-boot failure where the BTstack link-key store never formatted, so freshly-flashed adapters reported zero bonds. Link keys are now stored flash-safely (core1 parked during the write) and the SSP key is stored by us so DualSense bonds survive.
- Race-free incoming-connection gate + inquiry re-arm. Reworked the classic-connection accept/reject path onto a proper connection filter, fixed inquiry re-arming mid-connect, and closed a pairing-window leak that left inquiry running with a bond present.
- Wake-wedge fix. Distinct
bcdDeviceper USB variant so Windows re-reads the descriptor across an S3 wake instead of reusing a stale cached one — fixes the controller-off → S3 → controller-on-to-wake path that left the gamepad and audio dead. - DS5 detection fix. A too-aggressive runt-frame guard was skipping the 1-byte HID handshake that identifies a non-Edge DualSense, so the watchdog killed every connection; restored.
Hardening & performance
- BT HID input-latency path optimized; hot-path glue relocated to RAM; RP2350 overclocked to 200 MHz; HID report emitted before the audio loop.
- Input hardening. Clamp
GET_REPORT, guard out-of-bounds reads on runt HID/L2CAP frames, stop logging link keys, and throttle thetud_hid_reporterror log so it can't flood UART. - AP-mode API allowlist so only onboarding endpoints are reachable before the adapter has joined a network.
- Config store reworked to a size-migrated, append-only 512-byte layout with retry-on-failure and a factory reset, moved off the last flash sector (which the bootrom erases on reflash).
Firmware
CI builds and attaches the UF2s for standard (Pico 2 W), verbose-diagnostics, Waveshare RP2350B-Plus-W, and Pico W automatically.
v1.2.3 — faster BT reconnect + rumble/macOS fixes
Changes
- Faster controller reconnect — interlaced page scan at an 11.25 ms interval (was BTstack's ~1.28 s default), so the dongle answers the controller's PS-button page far quicker. Reconnect is noticeably snappier and more reliable. (hardware-confirmed)
- Rumble while audio is streaming — rumble-bearing output reports are now sent immediately instead of waiting for the next audio frame when a headset/speaker is active, so rumble no longer lags or drops a frame during audio.
- macOS / iPadOS state control — accept the shorter SetStateData these hosts send (previously rejected), restoring LED/rumble control. (LED confirmed on iPadOS)
Each change was ported from upstream awalol/DS5Dongle (1d4dbad, 07ecbb3 / #182, c47b7ed) and verified against this fork's architecture.
Firmware
CI builds and attaches the UF2s for standard (Pico 2 W), verbose-diagnostics, and Waveshare RP2350B-Plus-W automatically.
v1.2.2 — fix USB enumeration on release builds
Fixes the broken USB enumeration that affected the downloaded v1.2.0 / v1.2.1 release UF2s.
What was wrong
The release builds were compiled against TinyUSB 0.20.0, which predates the usbd
control-transfer fixes the device's MS OS 2.0 descriptor handling relies on. The result
was the idle (no-controller) USB variant failing to enumerate on Windows — a
"USB Composite Device" with a yellow bang (Code 10). Local builds were unaffected
(they used a newer TinyUSB), so the issue only ever appeared in downloaded firmware.
The fix
CI now pins TinyUSB to the exact verified commit, so the released UF2 matches what is
tested locally. This release also carries the v1.2.1 descriptor change (per-variant
MS OS 2.0 set) and the cold-boot detection fix (#4).
Flashing
Use ds5-bridge-v1.2.2.uf2 for the standard Pico 2 W build.
If Windows still shows a stale bang from a previous flash, unplug, remove the device in
Device Manager, and replug.
Full changelog: v1.2.0...v1.2.2
v1.2.0 — pairing rework, config page in both USB modes, custom IP, descriptor cleanup
Highlights
This release reworks controller pairing, makes the config page reachable in both USB modes, adds a custom config-page address for multi-adapter setups, and cleans the gamepad HID descriptor up to genuine-hardware parity.
Pairing
- Bond-gated pairing. The adapter now only scans for a new controller when none is remembered — once a controller is paired it stops inquiring, so a nearby DualSense in pairing mode won't get grabbed. A remembered controller still reconnects on its own.
- Pair-on-demand from the web page. A Pair new controller button opens a 30-second pairing window (drops the active controller but keeps its bond), so adding a second controller is a deliberate action.
Config page
- Reachable in both USB modes. The CDC-NCM config page is now served whether or not a controller is connected, and the host keeps a single stable network adapter across connect/disconnect (no more duplicate / "!" device in Windows Device Manager).
- Custom config-page address. Besides the three vetted presets, you can now enter a custom private IP (
10.x,172.16–31.x,192.168.x). Invalid/unreachable entries fall back to the default automatically — you can't lock yourself out. Handy for running several adapters on one PC, each on its own address. - UI polish. Restructured README, new User Guide, bond-row layout fix, GitHub/Ko-fi footer.
HID descriptor cleanup — now matches real hardware
- Removed the orphaned WebHID command channel (vendor feature reports
0xF6–0xF9) and its deadENABLE_DIAGapparatus — the on-device web API fully replaces it. - Removed stray DualShock 4 feature reports
0x0B/0x0Cthat had been in the descriptor since upstream's first commit (they're DS4 reports, never present on a real DualSense, and never used by the firmware). - Net result: the gamepad report-ID set now matches a genuine DualSense / DualSense Edge exactly (verified against real-device descriptor dumps). Shipping input/audio/haptics behavior is unchanged.
⚠️ Upgrade note
This bumps the on-flash config version (4 → 5). On first boot after flashing, saved settings reset to defaults once. Your paired controllers (bonds) are not affected — they're stored separately. Just re-apply any non-default settings on the config page.
Companion plugin
The Decky Loader plugin talks to the same on-device API. Multi-adapter discovery (probe presets, then enumerate NCM interfaces for custom-IP adapters) is on its roadmap.
CI attaches the standard, debug, and Waveshare UF2s to this release shortly after publish.
v1.1.0 — live controller status
Minor release on top of v1.0.1.
New: live controller status
- The config page now shows a status card at the top: whether a controller
is connected, its model (DualSense / DualSense Edge), and a battery gauge
(percent + charging indicator), refreshed every few seconds. - Served from a read-only
GET /api/statusendpoint, so any client can poll
it — this is the intended foundation for a future Decky Loader plugin that
would surface the same status in the Steam Deck Quick Access Menu, in parallel
with the web page (no firmware changes needed for that).
(RSSI was evaluated and intentionally left out: over Bluetooth Classic the
controller's HCI RSSI is relative to the Golden Receive Power Range and reads ~0
in normal use, so it isn't a useful signal-strength number.)
No other changes from v1.0.1. See the
v1.0.0 notes
for the full feature list.
Which firmware to flash
| File | Board |
|---|---|
ds5-bridge-v1.1.0.uf2 |
Raspberry Pi Pico 2 W (RP2350) — standard |
ds5-bridge-waveshare-v1.1.0.uf2 |
Waveshare RP2350B-Plus-W (compiles; untested on hardware) |
ds5-bridge-debug-v1.1.0.uf2 |
Pico 2 W + verbose UART diagnostics |
v1.0.1 — mic inactivity-disconnect fix
Point release on top of v1.0.0.
Fix
- Don't auto-disconnect a controller whose mic is in active use. The
inactivity watchdog inspected the input report's stick/button bytes for the
idle pattern, but while the controller mic streams those reports carry Opus
mic frames instead — so the watchdog mis-measured activity and could
disconnect an actively-used headset. It is now skipped while the mic bit is
set. (Ported from upstream awalol/DS5Dongled7fb163.)
No other changes from v1.0.0. See the
v1.0.0 notes
for the full feature list and the firmware-selection table.
Which firmware to flash
| File | Board |
|---|---|
ds5-bridge-v1.0.1.uf2 |
Raspberry Pi Pico 2 W (RP2350) — standard |
ds5-bridge-waveshare-v1.0.1.uf2 |
Waveshare RP2350B-Plus-W (compiles; untested on hardware) |
ds5-bridge-debug-v1.0.1.uf2 |
Pico 2 W + verbose UART diagnostics |