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

Option to use HidD_SetOutputReport for writing output (DS4) #378

Open
Pecacheu opened this issue Feb 3, 2018 · 4 comments
Open

Option to use HidD_SetOutputReport for writing output (DS4) #378

Pecacheu opened this issue Feb 3, 2018 · 4 comments

Comments

@Pecacheu
Copy link

Pecacheu commented Feb 3, 2018

Moved from node-hid/node-hid#245.

Context: DS4Windows sends data packet and Dualshock 4 responds. Node-hid (hidapi) sends exact same type of message with exact same data, and nothing happens.

Looking at the DS4Windows source code, specifically the source code of the native wrapper, it has to be down to the difference between WriteOutputReportViaControl and WriteOutputReportViaInterrupt.

In DS4Device.cs, WriteOutputReportViaControl is called when using bluetooth, which calls the function in HidDevice.cs. WriteOutputReportViaControl uses the HidD_SetOutputReport function, while WriteOutputReportViaInterrupt writes to the device using a filestream.

Meanwhile, hidapi (hence node-hid) uses only the filestream (aka WriteOutputReportViaInterrupt) approach for hid_write. I tried changing this to HidD_SetOutputReport in hidapi\windows\hid.c and recompiling using node-gyp. The file compiled successfully with no errors, however the program crashes silently when attempting to call .write. The program must be crashing during the call to HidD_SetOutputReport, as I tried intentionally crashing the program on the next line in hid.c, and the program still crashes silently.

int HID_API_EXPORT HID_API_CALL hid_write(hid_device *dev, const unsigned char *data, size_t length) {
	if(TRUE) { //WriteOutputReportViaControl
		BOOL res = HidD_SetOutputReport(dev->device_handle, (PVOID)data, length);
		if(!res) { register_error(dev, "HidD_SetOutputReport"); return -1; }
		return length;
	} else { //WriteOutputReportViaInterrupt
		/* ... Normal node-hid function ... */

Somewhere near top of file:

typedef BOOLEAN (__stdcall *HidD_SetOutputReport_)(HANDLE handle, PVOID data, ULONG length);
static HidD_SetOutputReport_ HidD_SetOutputReport;

Additionally, I recompiled DS4Windows to use WriteOutputReportViaInterrupt over bluetooth, and the application behaved normally except LED/rumble settings had no effect. So that's definitely why it's not working with hidapi. (I propose an additional boolean argument to hid_write or a second function.)

@Pecacheu
Copy link
Author

Can I get an answer on this? I need to use the DS4 for an app I'm making.

@Pecacheu
Copy link
Author

Update:

So after endlessly searching the hidapi fork tree for hours, I found this one: https://github.com/jarveson/hidapi
It successfully implements what I was trying to do with hid.c in the code above!

I've created a fork of node-hid here: https://github.com/Pecacheu/node-hid that accepts an optional boolean argument to hid.write which can be set to true to use hid_write_control instead.

With this change, now the DS4 can work via bluetooth!
https://github.com/Pecacheu/dualshock

@mirh
Copy link

mirh commented Sep 12, 2022

That fork was used for RPCS3/rpcs3#2733.
You can now find an updated version at https://github.com/RPCS3/hidapi

@Youw
Copy link

Youw commented Sep 12, 2022

Please see #468

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

3 participants