Skip to content

Commit

Permalink
winapi: add hid_winapi_set_write_timeout (#700)
Browse files Browse the repository at this point in the history
Add API function to control hid_write timeout on WinAPI backend.

Resolves: #686
  • Loading branch information
Youw authored Oct 3, 2024
1 parent 5c4acf8 commit c15392a
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 1 deletion.
4 changes: 4 additions & 0 deletions hidtest/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,10 @@ int main(int argc, char* argv[])
return 1;
}

#if defined(_WIN32) && HID_API_VERSION >= HID_API_MAKE_VERSION(0, 15, 0)
hid_winapi_set_write_timeout(handle, 5000);
#endif

// Read the Manufacturer String
wstr[0] = 0x0000;
res = hid_get_manufacturer_string(handle, wstr, MAX_STR);
Expand Down
9 changes: 8 additions & 1 deletion windows/hid.c
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ struct hid_device_ {
OVERLAPPED ol;
OVERLAPPED write_ol;
struct hid_device_info* device_info;
DWORD write_timeout_ms;
};

static hid_device *new_hid_device()
Expand All @@ -219,6 +220,7 @@ static hid_device *new_hid_device()
memset(&dev->write_ol, 0, sizeof(dev->write_ol));
dev->write_ol.hEvent = CreateEvent(NULL, FALSE, FALSE /*initial state f=nonsignaled*/, NULL);
dev->device_info = NULL;
dev->write_timeout_ms = 1000;

return dev;
}
Expand Down Expand Up @@ -1052,6 +1054,11 @@ HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path)
return dev;
}

void HID_API_EXPORT_CALL hid_winapi_set_write_timeout(hid_device *dev, unsigned long timeout)
{
dev->write_timeout_ms = timeout;
}

int HID_API_EXPORT HID_API_CALL hid_write(hid_device *dev, const unsigned char *data, size_t length)
{
DWORD bytes_written = 0;
Expand Down Expand Up @@ -1103,7 +1110,7 @@ int HID_API_EXPORT HID_API_CALL hid_write(hid_device *dev, const unsigned char *
if (overlapped) {
/* Wait for the transaction to complete. This makes
hid_write() synchronous. */
res = WaitForSingleObject(dev->write_ol.hEvent, 1000);
res = WaitForSingleObject(dev->write_ol.hEvent, dev->write_timeout_ms);
if (res != WAIT_OBJECT_0) {
/* There was a Timeout. */
register_winapi_error(dev, L"hid_write/WaitForSingleObject");
Expand Down
20 changes: 20 additions & 0 deletions windows/hidapi_winapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,26 @@ extern "C" {
*/
int HID_API_EXPORT_CALL hid_winapi_descriptor_reconstruct_pp_data(void *hidp_preparsed_data, unsigned char *buf, size_t buf_size);

/**
* @brief Sets the timeout for hid_write operation.
*
* Since version 0.15.0, @ref HID_API_VERSION >= HID_API_MAKE_VERSION(0, 15, 0)
*
* The default timeout is 1sec for winapi backend.
*
* In case if 1sec is not enough, on in case of multi-platform development,
* the recommended value is 5sec, e.g. to match (unconfigurable) 5sec timeout
* set for hidraw (linux kernel) implementation.
*
* When the timeout is set to 0, hid_write function becomes non-blocking and would exit immediately.
* When the timeout is set to INFINITE ((DWORD)-1), the function will not exit,
* until the write operation is performed or an error occured.
* See dwMilliseconds parameter documentation of WaitForSingleObject function.
*
* @param timeout New timeout value in milliseconds.
*/
void HID_API_EXPORT_CALL hid_winapi_set_write_timeout(hid_device *dev, unsigned long timeout);

#ifdef __cplusplus
}
#endif
Expand Down

0 comments on commit c15392a

Please sign in to comment.