From 5e5aa71cfebaaaaa98c6b31512e0926986f2ed6a Mon Sep 17 00:00:00 2001 From: MarcelineVPQ Date: Sun, 7 Jun 2026 00:39:46 -0600 Subject: [PATCH] fix(usb): use the controller MAC as the USB serial, matching the 0x09 report MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The serial was the Pico flash unique id (board_usb_get_serial), while the 0x09 pairing-info feature report returns the controller's BT MAC. The host saw two identities for one controller (flash-id over USB, MAC over 0x09), and Wine/Steam device-matching choked — "recognized but no controller" in-game. Set STRID_SERIAL to the controller MAC (live bt_get_addr, falling back to the current slot's stored addr, then the flash id if never paired) so the dongle presents one consistent identity like a real DualSense. Steam now recognises the dongle as a native DualSense. Co-Authored-By: Claude Opus 4.8 --- src/usb_descriptors.cpp | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/src/usb_descriptors.cpp b/src/usb_descriptors.cpp index 4c5b701..b3207cb 100644 --- a/src/usb_descriptors.cpp +++ b/src/usb_descriptors.cpp @@ -26,6 +26,8 @@ #include "bsp/board_api.h" #include "tusb.h" #include "config.h" +#include "bt.h" +#include "slots.h" #ifndef ENABLE_SERIAL #define ENABLE_SERIAL 0 @@ -858,9 +860,35 @@ uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { chr_count = 1; break; - case STRID_SERIAL: - chr_count = board_usb_get_serial(_desc_str + 1, 32); + case STRID_SERIAL: { + // Present like a REAL DualSense: USB serial == controller MAC, the + // same value the 0x09 pairing-info feature report returns. Before + // this the serial was the Pico flash unique id, so the host saw two + // identities for one controller (flash-id over USB, MAC over 0x09) + // and Wine/Steam device-matching choked. Prefer the live connected + // MAC; fall back to the current slot's stored MAC (known at boot, + // before BT connects); finally fall back to the flash id if never + // paired so the descriptor is always valid. + uint8_t mac[6] = {0}; + bool have = false; + bt_get_addr(mac); + for (int i = 0; i < 6; ++i) if (mac[i]) { have = true; break; } + if (!have) { + slot_get_addr(get_config().current_slot, mac); + for (int i = 0; i < 6; ++i) if (mac[i]) { have = true; break; } + } + if (have) { + static const char hexd[] = "0123456789ABCDEF"; + for (int i = 0; i < 6; ++i) { + _desc_str[1 + i * 2] = hexd[(mac[i] >> 4) & 0x0F]; + _desc_str[1 + i * 2 + 1] = hexd[mac[i] & 0x0F]; + } + chr_count = 12; + } else { + chr_count = board_usb_get_serial(_desc_str + 1, 32); + } break; + } default: // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors.