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

Windows: Bluetooth and WriteFile API issues #513

Open
DJm00n opened this issue Feb 26, 2023 · 5 comments
Open

Windows: Bluetooth and WriteFile API issues #513

DJm00n opened this issue Feb 26, 2023 · 5 comments
Labels
Windows Related to Windows backend

Comments

@DJm00n
Copy link
Contributor

DJm00n commented Feb 26, 2023

Looks like Windows Bluetooth drivers have issues with sending output reports with WriteFile.
Need to investigate this and try to use HidD_SetOutputReport as a fallback.

https://stackoverflow.com/questions/29480144/hidapi-sending-packet-smaller-than-caps-outputreportbytelength
https://social.msdn.microsoft.com/Forums/ie/en-US/834d2cf2-672d-424b-a126-dbc69f3f75a2/hiddsetoutputreportwritefile-bluetooth-low-energy-windows-81

Related libsdl-org/SDL#7224

@DJm00n
Copy link
Contributor Author

DJm00n commented Feb 26, 2023

The GATT Read Characteristic Value or Read Long Characteristic Value subprocedures are used to read a Report characteristic containing Output Report data. This procedure maps to a Get_Report (Output) request in USB HID [2].

The GATT Write Characteristic Value sub-procedure is used to write to a Report characteristic containing Output Report data. This procedure maps to a Set_Report (Output) request in USB HID [2]. The GATT Write Without Response sub-procedure is
also used to write to a Report characteristic containing Output Report data, and this procedure maps to Data Output in USB HID [2].

https://www.bluetooth.com/specifications/specs/human-interface-device-service-1-0/

@DJm00n
Copy link
Contributor Author

DJm00n commented Feb 26, 2023

HidD_SetOutputReport becomes IOCTL_HID_SET_OUTPUT_REPORT
WriteFile becomes IOCTL_HID_WRITE_REPORT

https://stackoverflow.com/questions/63115984/what-is-the-difference-between-read-report-get-input-report-write-report

Output items make Output reports accessible via the Control pipe with a Set_Report (Output) command.
Output type reports can optionally be sent via an Interrupt Out pipe.

The Control pipe is used for: ... Transmitting data when polled by the HID class driver (using the Get_Report
request).

The Interrupt Out pipe is optional. If a device declares an Interrupt Out endpoint then Output reports are transmitted by the host to the device through the Interrupt Out endpoint. If no Interrupt Out endpoint is declared then Output reports are transmitted to a device through the Control endpoint, using Set_Report(Output) requests.

https://www.usb.org/document-library/device-class-definition-hid-111

@Youw
Copy link
Member

Youw commented Feb 26, 2023

The later only proves that we cannot unconditionally replace WriteFile with SetOutputReport, I guess.

As for bug "WriteFile() doesn't work correctly" I think we could have a per-device, WinAPI-specific option to use HidD_SetOutputReport as hid_write implementation.

Or do you think we can predict for which devices WriteFile is going to fail? Is it known to be specific to BLE or smth?

@mcuee mcuee added the Windows Related to Windows backend label Feb 27, 2023
@DJm00n
Copy link
Contributor Author

DJm00n commented Feb 27, 2023

As far as I understand, in BLE case API works like this:
WriteFile -> IOCTL_HID_WRITE_REPORT -> Data Output -> GATT Write Without Response -> ATT_OP_WRITE_CMD -> 0x52
HidD_SetOutputReport -> IOCTL_HID_SET_OUTPUT_REPORT -> Set_Report (Output) -> GATT Write Characteristic Value -> ATT_OP_WRITE_REQ -> 0x12

According to the HIDS spec Read/Write/Write Without Response are mandatory for Report: Output Report Type characteristic.

image

But seems some devices are not declaring Write Without Response and in result WriteFile call is failing (for example Stadia Controller with new "Bluetooth mode" firmware is known to have such issues).

I'll try to debug this to find out more.

@Youw
Copy link
Member

Youw commented Feb 27, 2023

But seems some devices are not declaring Write Without Response

Would be great to figure out if it is possible to check its support over WinAPI before trying to use WriteFile (e.g. if it is a part of some descriptor, or just device fails to respond on a specific command).

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

No branches or pull requests

3 participants