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

hid_write works on windows 8 and 10, but fails on windows 7 #253

Closed
adriantirea opened this issue Jan 20, 2016 · 4 comments
Closed

hid_write works on windows 8 and 10, but fails on windows 7 #253

adriantirea opened this issue Jan 20, 2016 · 4 comments

Comments

@adriantirea
Copy link

I have the Clubsport Fanatec pedals v3 EU for car gaming. I use the hid api to read the state of pedals and all went excellent on windows 10 and 8. Thank you! I tested the same setup on more machines with windows 7, but none succeeded. The fail is in hid_write() at calling WriteFile(). Get last error is ERROR_INVALID_PARAMETER , 87 (0x57), "The parameter is incorrect.". This is the first call to hid after hid_open().

Do you have any idea on what may be wrong here?
I use hidapi 0.8.0-rc1. Following is my code.

bool Device::connect()
    handle = hid_open(vid, hid, NULL);
    if (!handle) {
        fanatec->logErrorError("unable to open device (%s, vid:%#06x hid:%#06x)", name, vid, hid);
        return false;
    }

    // Set the hid_read() function to be non-blocking.
    if (hid_set_nonblocking(handle, 1) != 0) {
        fanatec->logErrorError("unable to set nonblocking mode (%s, vid:%#06x hid:%#06x)", name, vid, hid);
        return false;
    }
    return true;
}
bool Device::readOutputs() {
    int res;
    unsigned char buf[256];
    // Request state (cmd 0x81). The first byte is the report number (0x1).
    buf[0] = 0x1;
    buf[1] = 0x81;
    res = hid_write(handle, buf, 17);       // !! Here res == 0, and ERROR_INVALID_PARAMETER
    if (res < 0) {
        logHidError();
        fanatec->logErrorError("Unable to write request state of device %s", name);
        return false;
    }
...
}
@signal11
Copy link
Owner

You need to send a message that's specific to your device. You're just sending data which was from my test device (0x1,0x81, 17 bytes). You need to figure out what the device wants to receive, and send that.

@adriantirea
Copy link
Author

Thanks for reply! I do not have specification for my device, so I figure out what is the message to sent to device.

In my opinion the problem is different because the same instance of device allows me to call hid_write from win8 and win10 but I can not make any hid_write from win7. Can you give me more hints on this issue?

I give here another example from my setup with hid_write(). This example again works on win10, but not on win7. The message to send I figure out by using Wireshark and USBPcap where I looked for the message sent from a test application from the manufacturer of device.

int Pedals::encodeData(unsigned char *buf) {
    // command
    buf[0] = 0x01;
    // package data
    buf[1] = 0xf8;
    buf[2] = 0x09;
    buf[3] = 0x01;
    buf[4] = 0x04;
    buf[5] = scaleToRaw(rumbleAccel, rumbleAccel.mifValue);
    buf[6] = scaleToRaw(rumbleBrake, rumbleBrake.mifValue);
    buf[7] = 0x00;
    return 8;
}

The upper buffer is used, and size is 8.
Also, if it helps, I see in debug that:

caps.InputReportByteLength  13
caps.OutputReportByteLength 8
bool Device::writeToHID(unsigned char *buf, int size) {
    int res = 0;
    int retries = 10;
    bool retry = true;
    while (res == 0 && retry) {
        res = hid_write(handle, buf, size);
        if (res == 0) {
            logThis(ERROR_WARNING, "waiting for device %s to response...", name);
            Sleep(1);
        }
        if (res < 0) {
            logThis(ERROR_WARNING, "Unable to write() to device %s", name);
            Sleep(1);
        }
        retries--;
    }
    if (res <= 0) {
        logHidError();
        fanatec->logErrorError("Unable to write() to device %s. Giving up.", name);
        return false;
    } else if (res != 8) {
        fanatec->logErrorError("Data written has unexpected size: %d. Device %s.", res, name);
        //printBuffer(buf, res);
        return false;
    }
}

@signal11
Copy link
Owner

signal11 commented Feb 1, 2016

Are you sure the report number is right? The device uses multiple reports?

@adriantirea
Copy link
Author

Thanks signal11. Indeed the report number was the problem. Setting it to 0x00 instead of 0x01 solved the problem.

Some comments from next links helped.

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

2 participants