kozec / sc-controller

User-mode driver and GTK3 based GUI for Steam Controller
GNU General Public License v2.0
1.53k stars 129 forks source link

HIDAPI feature reports on Windows over BT return zeroed buffer / BT Windows support #678

Open pattontim opened 2 years ago

pattontim commented 2 years ago

I wrote a driver using by_cable.c as a template and taking the feature reports from sc_by_bt.py. I initialize the controller by calling the setup functions in sequence and enumerate the available devices, opening the BT controller device...

\\?\hid#{00001812-0000-1000-8000-00805f9b34fb}_dev_vid&0228de_pid&1106_rev&0001_f6bb771b89cc&col03#a&26365d5a&0&0002#{4d1e55b2-f16f-11cf-88cb-001111000030} which appears to be the correct device. Then using HIDAPI as the subsystem I send a feature report requesting the serial from the controller using the report ID 0x03 and the feature report codes. The controller receives the feature report and fills the responding buffer with zeroes.

// 0xAE 0x15 0x01
uint8_t* response;
uint8_t data[64] = { PT_GET_SERIAL, PL_GET_SERIAL, 0x01 };
response = sc->dev->hid_request(sc->dev, sc->idx, data2, -64);

However the data is just zeroes. In fact even if I prepend 0xC0 and send that the response is still all zeroes. How can I successfully query the device?

Ryochan7 commented 2 years ago

Looking at the code, I am going to assume that the buffer length used in the sccd_input_hidapi_hid_request function is the culprit. Based on my experience, the buffer length used to read the feature report has to be exactly 65 bytes or the call will fail. It looks like scc creates a temporary array of 256 bytes and uses that buffer before it calls hid_get_feature_report. The final step of the function is to copy the data from the temporary array to the array you passed as the output buffer. Changing the hid_request call to use -65 for _length will likely not help with the problem.

https://github.com/kozec/sc-controller/blob/c/src/daemon/input_hidapi.c#L117

I could test the theory in my own project but I don't know if I would get around to it. I have a C# program that can interact with the Steam Controller in BLE mode. Ended up learning from VSCView about Windows requiring the read feature report buffer size needing to be exactly 65 bytes or the read will not work.

https://github.com/Ryochan7/SteamControllerTest/blob/master/SteamControllerTest/SteamControllerLibrary/SteamControllerBTDevice.cs

pattontim commented 2 years ago

The internal buffer was exactly the culprit, I saw the 65 byte requirement in another SC library but hadn't thought about changing the internal one.

I just tested it on Windows c branch and now my controller is out of lizard and is feeding data to input_interrupt_cb, I should be able to try to parse the data soon and clean up test and push the driver for the c code

pattontim commented 2 years ago

Reopening as I haven't pushed to the main c branch, in my windows-osd fork there is a driver for BT support on Windows implemented. I'm working on squaring off the last features like making sure the controller can reconnect and that my changes don't interfere with other controllers.

pattontim commented 1 year ago

The current blocker for this is turning the controller off and resetting. The controller seems to ignore requests to turn off...

//0xC0, 0x9F, 0x04, 0x6f, 0x66, 0x66, 0x21 }; uint8_t data[] = { PT_BT_PREFIX, PT_OFF, PL_OFF, 0x6f, 0x66, 0x66, 0x21 };

response

030000000000000000000...

The BLE command must differ signif from the dongle controller shutoff command or ignore it. Pursuing shutoff via dealocation