diff options
Diffstat (limited to 'libvoltronic/voltronic_dev_usb_hidapi.c')
-rw-r--r-- | libvoltronic/voltronic_dev_usb_hidapi.c | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/libvoltronic/voltronic_dev_usb_hidapi.c b/libvoltronic/voltronic_dev_usb_hidapi.c new file mode 100644 index 0000000..05d9a83 --- /dev/null +++ b/libvoltronic/voltronic_dev_usb_hidapi.c @@ -0,0 +1,106 @@ +/** + * Copyright (C) 2019 Johan van der Vyver + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <string.h> +#include <stdlib.h> +#include "voltronic_dev_impl.h" +#include "voltronic_dev_usb.h" +#include "hidapi.h" + +#define HID_REPORT_SIZE 8 + +#define VOLTRONIC_DEV_USB(_impl_ptr_) \ + ((hid_device*) (_impl_ptr_)) + +#define GET_REPORT_SIZE(_val_) \ + (((_val_) > HID_REPORT_SIZE) ? HID_REPORT_SIZE : (_val_)) + +static inline void voltronic_usb_init_hidapi(void); + +voltronic_dev_t voltronic_usb_create( + const unsigned int vendor_id, + const unsigned int product_id) { + + voltronic_usb_init_hidapi(); + + SET_LAST_ERROR(0); + hid_device* dev = hid_open( + (unsigned short) vendor_id, + (unsigned short) product_id, + (const wchar_t*) 0); + + if (dev != 0) { + SET_LAST_ERROR(0); + return voltronic_dev_internal_create((void*) dev); + } + + return 0; +} + +inline int voltronic_dev_impl_read( + void* impl_ptr, + char* buffer, + const size_t buffer_size, + const unsigned int timeout_milliseconds) { + + SET_LAST_ERROR(0); + return hid_read_timeout( + VOLTRONIC_DEV_USB(impl_ptr), + (unsigned char*) buffer, + GET_REPORT_SIZE(buffer_size), + (int) timeout_milliseconds); +} + +inline int voltronic_dev_impl_write( + void* impl_ptr, + const char* buffer, + const size_t buffer_size, + unsigned int timeout_milliseconds) { + + ++timeout_milliseconds; // stop unused warnings + const int write_size = GET_REPORT_SIZE(buffer_size); + unsigned char write_buffer[HID_REPORT_SIZE + 1] = { 0 }; + COPY_MEMORY(&write_buffer[1], buffer, write_size); + + SET_LAST_ERROR(0); + const int bytes_written = hid_write( + VOLTRONIC_DEV_USB(impl_ptr), + (const unsigned char*) write_buffer, + (size_t) (HID_REPORT_SIZE + 1)); + + return GET_REPORT_SIZE(bytes_written); +} + +inline int voltronic_dev_impl_close(void* impl_ptr) { + hid_close(VOLTRONIC_DEV_USB(impl_ptr)); + return 1; +} + +static inline void voltronic_usb_exit_hidapi(void) { + hid_exit(); +} + +static inline void voltronic_usb_init_hidapi(void) { + static int hidapi_init_complete = 0; + + if (hidapi_init_complete == 0) { + if (hid_init() == 0) { + atexit(voltronic_usb_exit_hidapi); + hidapi_init_complete = 1; + } + } +} |