Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SDL2 fails to open Steam Controller (GET_ATTRIBUTES_VALUES failed for controller) #12166

Closed
shoeffner opened this issue Feb 3, 2025 · 1 comment

Comments

@shoeffner
Copy link

I am trying to get the input-overlay plugin for OBS to work with the Steam Controller.

Unfortunately, it seems SDL2 fails to reset the controller as I get the error message:

GET_ATTRIBUTES_VALUES failed for controller 0x1a3c1029960

I found this particular error message only once in the SDL codebase -- in SDL_hidapi_steam.c here:

static bool ResetSteamController(SDL_hid_device *dev, bool bSuppressErrorSpew, uint32_t *punUpdateRateUS)
{
// Firmware quirk: Set Feature and Get Feature requests always require a 65-byte buffer.
unsigned char buf[65];
unsigned int i;
int res = -1;
int nSettings = 0;
int nAttributesLength;
FeatureReportMsg *msg;
uint32_t unUpdateRateUS = 9000; // Good default rate
DPRINTF("ResetSteamController hid=%p\n", dev);
buf[0] = 0;
buf[1] = ID_GET_ATTRIBUTES_VALUES;
res = SetFeatureReport(dev, buf, 2);
if (res < 0) {
if (!bSuppressErrorSpew) {
printf("GET_ATTRIBUTES_VALUES failed for controller %p\n", dev);
}
return false;
}

So the controller seems to be detected correctly as a Steam Controller, but something fails when communicating with it.
I also tried out the gamepadtest.exe from univrsal/input-overlay#297, which has the same issue:

INFO: GET_ATTRIBUTES_VALUES failed for controller 2ba68d00
INFO: Couldn't open controller: Couldn't reset controller
INFO: Game Controller 0: Steam Controller, \\?\hid#vid_28de&pid_1142&mi_04#8&e7b56b&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030} (guid 03002854de2800004211000001006800, VID 0x28de, PID 0x1142, player index = 1)
INFO: GET_ATTRIBUTES_VALUES failed for controller 2ba69a88
INFO: Couldn't open controller: Couldn't reset controller
INFO: Game Controller 1: Steam Controller, \\?\hid#vid_28de&pid_1142&mi_02#8&b2bfc12&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030} (guid 03002854de2800004211000001006800, VID 0x28de, PID 0x1142, player index = 3)
INFO: There are 2 game controller(s) attached (2 joystick(s))
INFO: Game controller device 0 removed.
INFO: Game controller device 2 removed.
INFO: Game controller device 1 added.
INFO: GET_ATTRIBUTES_VALUES failed for controller 2ba69650
INFO: Couldn't open controller: Couldn't reset controller
INFO: Game controller device 1 removed.
INFO: Game controller device 3 added.
INFO: GET_ATTRIBUTES_VALUES failed for controller 2ba69998
INFO: Couldn't open controller: Couldn't reset controller
INFO: Game controller device 3 removed.

I don't know why it detects four devices 0--3, I only have one controller attached (I use the wireless dongle).

The input-overlay plugin uses SDL2 (2.30.4) and comes with a small client tool to read out the controls.

info: Initializing SDL2 for gamepad input (compile-time: 2.30.4, run-time:  2.30.4)

It is also able to load a gamecontrollerdb.txt from its working directory.
While I don't know if that works correctly, I at least tried to place the gamecontrollerdb.txt from mdqinc/SDL_GameControllerDB there.
Then I checked its entries and my Steam\config\config.vdf files and found out that one line from my vdf was missing (the last below), so I used my own gamecontrollerdb.txt containing only my three lines:

03000000de280000ff11000000000000,Steam Virtual Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
03000000de280000ff11000001000000,Steam Virtual Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
03000000de280000ff11000000007701,Steam Virtual Gamepad,a:b0,b:b1,x:b2,y:b3,back:b6,start:b7,leftstick:b8,rightstick:b9,leftshoulder:b4,rightshoulder:b5,dpup:b10,dpdown:b12,dpleft:b13,dpright:b11,leftx:a1,lefty:a0~,rightx:a3,righty:a2~,lefttrigger:a4,righttrigger:a5

But I didn't really expect the mapping to make a difference here.

I also checked my Steam Controller settings and if running Steam makes a difference (it does not).
These are my settings in Steam:

Setting Value(s) tried
Game rumble off
Steam haptics on
Use Nintendo Button Layout off
Universal Face Button Glyphs off
Guide button focuses Steam on
Enable Steam Input for Xbox controllers on / off
PlayStation Controller Support Enabled in Games w/o Support
Enable Steam Input for Switch Pro controllers off
Enable Steam Input for generic controllers off
Turn off controllers when exiting Big Picture Mode off
Enable Guide Button Chords for controllers on
Idle Gamepad Shutdown Timeout 15 Minutes
Xbox Extended Feature Support Driver Installed / Uninstalled

The device manager lists it as an HID-compliant vendor-defined device, its driver is steamxbox.sys 1.0.0.16 -- although the device property Driver version states 10.0.26100.1882.
(This is with the Xbox Extended Feature Support Driver; I have not checked the driver before, but if it could be useful I'll do that.)
I recently updated Windows and the driver was installed then as well, as it claims its first install date was 2025-01-10.
(Though I never tried the plugin or SDL with the controller before, so I am not sure this is related; I guess not.)

Do you have any ideas why it's not working?
I am happy to help with any further debugging and fixing, though I might need a few hints where to start as I am not too familiar with SDL and gamepads :)

@shoeffner
Copy link
Author

I was able to compile the testgamecontroller.c and found out that the call to HidD_SetFeature in hid.c:908 returns 0:

int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *dev, const unsigned char *data, size_t length)
{
BOOL res = HidD_SetFeature(dev->device_handle, (PVOID)data, (ULONG)length);
if (!res) {
register_error(dev, "HidD_SetFeature");
return -1;
}
return (int)length;
}

data is [3, 192, 131, 0, 0, ... remainder 0], length is 20.
The error code from GetLastError() (as retrieved in register_error and documented in HidD_SetFeature function (hidsdi.h)) is 87.

I tried out the testcontroller of SDL3 and it works perfectly!

So I tried to find out the difference and as it turns out, my device is not connected via bluetooth, thus in SDL3 it jumps into the non-BLE case (which missing in SDL2):

} else {
for (int nRetries = 0; nRetries < RADIO_WORKAROUND_SLEEP_ATTEMPTS; nRetries++) {
nRet = SDL_hid_send_feature_report(dev->dev, uBuffer, 65);
if (nRet >= 0) {
break;
}
SDL_DelayNS(RADIO_WORKAROUND_SLEEP_DURATION_US * 1000);
}
}

I copied that code to the SDL2 branch, set the bBle to false, and replaced SDL_DelayNS with SDL_Delay and it looks like SetFeatureReport works then but the program fails to call GetFeatureReport (due to the same issue, basically).

So the main issue is that the packet is too small, as is even pointed out in a comment:

// Firmware quirk: Set Feature and Get Feature requests always require a 65-byte buffer.

But that quirk is not passed to the subsequent calls -- as we can see, the else-case in SDL3 does it and passes the full 65 byte.

For SetFeature, it seems to be enough to pass the full 65 bytes, but for the GetFeature, the result also changes as the skip byte is not needed and I couldn't get it easily to work with WriteSegmentToSteamControllerPacketAssembler.

With the wired controller, it also didn't work, so I installed the firmware update as outlined here https://help.steampowered.com/en/faqs/view/1796-5FC3-88B3-C85F#switch and used my Bluetooth dongle.

This seems to work! So I think unless someone wants to backport the non-bluetooth functionality to SDL2, this issue can safely be closed and I'll leave the comment here for others who look into this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant