From cc6e853fba02ca64d4e0eb27e4f07bb534003320 Mon Sep 17 00:00:00 2001
From: Kishi <41839133+Kishi85@users.noreply.github.com>
Date: Sun, 17 Aug 2025 00:17:04 +0200
Subject: [PATCH] feat(input/linux): allow ds5 gamepads to have a fixed device
mac based on controller index (#4158)
---
docs/configuration.md | 24 +++++++++++++++++
src/config.cpp | 1 +
src/config.h | 1 +
.../linux/input/inputtino_gamepad.cpp | 15 ++++++++---
.../common/assets/web/configs/tabs/Inputs.vue | 26 +++++++++++++++++++
.../assets/web/public/assets/locale/en.json | 3 +++
6 files changed, 66 insertions(+), 4 deletions(-)
diff --git a/docs/configuration.md b/docs/configuration.md
index a1ae900c3..70e2a97be 100644
--- a/docs/configuration.md
+++ b/docs/configuration.md
@@ -416,6 +416,30 @@ editing the `conf` file in a text editor. Use the examples as reference.
+### ds5_inputtino_randomize_mac
+
+
+
+ | Description |
+
+ Randomize the MAC-Address for the generated virtual controller.
+ @hint{Only applies on linux for gamepads created as PS5-style controllers}
+ |
+
+
+ | Default |
+ @code{}
+ enabled
+ @endcode |
+
+
+ | Example |
+ @code{}
+ ds5_inputtino_randomize_mac = enabled
+ @endcode |
+
+
+
### back_button_timeout
diff --git a/src/config.cpp b/src/config.cpp
index 24ef2a084..5268af669 100644
--- a/src/config.cpp
+++ b/src/config.cpp
@@ -1216,6 +1216,7 @@ namespace config {
bool_f(vars, "ds4_back_as_touchpad_click", input.ds4_back_as_touchpad_click);
bool_f(vars, "motion_as_ds4", input.motion_as_ds4);
bool_f(vars, "touchpad_as_ds4", input.touchpad_as_ds4);
+ bool_f(vars, "ds5_inputtino_randomize_mac", input.ds5_inputtino_randomize_mac);
bool_f(vars, "mouse", input.mouse);
bool_f(vars, "keyboard", input.keyboard);
diff --git a/src/config.h b/src/config.h
index 287efaf5a..cda1f7c69 100644
--- a/src/config.h
+++ b/src/config.h
@@ -193,6 +193,7 @@ namespace config {
bool ds4_back_as_touchpad_click;
bool motion_as_ds4;
bool touchpad_as_ds4;
+ bool ds5_inputtino_randomize_mac;
bool keyboard;
bool mouse;
diff --git a/src/platform/linux/input/inputtino_gamepad.cpp b/src/platform/linux/input/inputtino_gamepad.cpp
index 438146317..7e782b59b 100644
--- a/src/platform/linux/input/inputtino_gamepad.cpp
+++ b/src/platform/linux/input/inputtino_gamepad.cpp
@@ -42,8 +42,15 @@ namespace platf::gamepad {
.version = 0x8111});
}
- auto create_ds5() {
- return inputtino::PS5Joypad::create({.name = "Sunshine PS5 (virtual) pad", .vendor_id = 0x054C, .product_id = 0x0CE6, .version = 0x8111});
+ auto create_ds5(int globalIndex) {
+ std::string device_mac = ""; // Inputtino checks empty() to generate a random MAC
+
+ if (!config::input.ds5_inputtino_randomize_mac && globalIndex >= 0 && globalIndex <= 255) {
+ // Generate private virtual device MAC based on gamepad globalIndex between 0 (00) and 255 (ff)
+ device_mac = std::format("02:00:00:00:00:{:02x}", globalIndex);
+ }
+
+ return inputtino::PS5Joypad::create({.name = "Sunshine PS5 (virtual) pad", .vendor_id = 0x054C, .product_id = 0x0CE6, .version = 0x8111, .device_phys = device_mac, .device_uniq = device_mac});
}
int alloc(input_raw_t *raw, const gamepad_id_t &id, const gamepad_arrival_t &metadata, feedback_queue_t feedback_queue) {
@@ -138,7 +145,7 @@ namespace platf::gamepad {
}
case DualSenseWired:
{
- auto ds5 = create_ds5();
+ auto ds5 = create_ds5(id.globalIndex);
if (ds5) {
(*ds5).set_on_rumble(on_rumble_fn);
(*ds5).set_on_led([feedback_queue, idx = id.clientRelativeIndex, gamepad](int r, int g, int b) {
@@ -267,7 +274,7 @@ namespace platf::gamepad {
return gps;
}
- auto ds5 = create_ds5();
+ auto ds5 = create_ds5(-1); // Index -1 will result in a random MAC virtual device, which is fine for probing
auto switchPro = create_switch();
auto xOne = create_xbox_one();
diff --git a/src_assets/common/assets/web/configs/tabs/Inputs.vue b/src_assets/common/assets/web/configs/tabs/Inputs.vue
index 2e7a081f8..d639c5e12 100644
--- a/src_assets/common/assets/web/configs/tabs/Inputs.vue
+++ b/src_assets/common/assets/web/configs/tabs/Inputs.vue
@@ -89,6 +89,32 @@ const config = ref(props.config)
+
+
+
diff --git a/src_assets/common/assets/web/public/assets/locale/en.json b/src_assets/common/assets/web/public/assets/locale/en.json
index 160c13868..ab3907c1d 100644
--- a/src_assets/common/assets/web/public/assets/locale/en.json
+++ b/src_assets/common/assets/web/public/assets/locale/en.json
@@ -195,6 +195,8 @@
"dd_wa_hdr_toggle_delay": "High-contrast workaround for HDR",
"ds4_back_as_touchpad_click": "Map Back/Select to Touchpad Click",
"ds4_back_as_touchpad_click_desc": "When forcing DS4 emulation, map Back/Select to Touchpad Click",
+ "ds5_inputtino_randomize_mac": "Randomize virtual controller MAC",
+ "ds5_inputtino_randomize_mac_desc": "Upon controller registration use a random MAC instead of one based on the controllers internal index to avoid mixing configuration settings of different controllers when the are swapped on client-side.",
"encoder": "Force a Specific Encoder",
"encoder_desc": "Force a specific encoder, otherwise Sunshine will select the best available option. Note: If you specify a hardware encoder on Windows, it must match the GPU where the display is connected.",
"encoder_software": "Software",
@@ -213,6 +215,7 @@
"gamepad_ds4": "DS4 (PS4)",
"gamepad_ds4_manual": "DS4 selection options",
"gamepad_ds5": "DS5 (PS5)",
+ "gamepad_ds5_manual": "DS5 selection options",
"gamepad_switch": "Nintendo Pro (Switch)",
"gamepad_manual": "Manual DS4 options",
"gamepad_x360": "X360 (Xbox 360)",