diff options
author | Christian Starkjohann <cs+github@obdev.at> | 2008-04-17 19:00:20 +0000 |
---|---|---|
committer | Christian Starkjohann <cs+github@obdev.at> | 2008-04-17 19:00:20 +0000 |
commit | 95ca3f5bd696b5450820929e1b1a444d02f0bd1e (patch) | |
tree | 70ac0161a0e4548acaf2f89d2ecb77132579ff7a /libs-host/hiddata.c | |
parent | 2f465daef9e6c5a6b7bda3074c050cd7e8515770 (diff) | |
download | v-usb-95ca3f5bd696b5450820929e1b1a444d02f0bd1e.tar.gz v-usb-95ca3f5bd696b5450820929e1b1a444d02f0bd1e.tar.bz2 v-usb-95ca3f5bd696b5450820929e1b1a444d02f0bd1e.zip |
- imported new files into project
Diffstat (limited to 'libs-host/hiddata.c')
-rw-r--r-- | libs-host/hiddata.c | 317 |
1 files changed, 317 insertions, 0 deletions
diff --git a/libs-host/hiddata.c b/libs-host/hiddata.c new file mode 100644 index 0000000..3e884e8 --- /dev/null +++ b/libs-host/hiddata.c @@ -0,0 +1,317 @@ +/* Name: hiddata.c + * Author: Christian Starkjohann + * Creation Date: 2008-04-11 + * Tabsize: 4 + * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH + * License: GNU GPL v2 (see License.txt) or proprietary (CommercialLicense.txt) + * This Revision: $Id$ + */ + +#include <stdio.h> +#include "hiddata.h" + +/* ######################################################################## */ +#if defined(WIN32) /* ##################################################### */ +/* ######################################################################## */ + +#include <windows.h> +#include <setupapi.h> +#include "hidsdi.h" +#include <ddk/hidpi.h> + +#ifdef DEBUG +#define DEBUG_PRINT(arg) printf arg +#else +#define DEBUG_PRINT(arg) +#endif + +/* ------------------------------------------------------------------------ */ + +static void convertUniToAscii(char *buffer) +{ +unsigned short *uni = (void *)buffer; +char *ascii = buffer; + + while(*uni != 0){ + if(*uni >= 256){ + *ascii++ = '?'; + }else{ + *ascii++ = *uni++; + } + } + *ascii++ = 0; +} + +int usbhidOpenDevice(usbDevice_t **device, int vendor, char *vendorName, int product, char *productName, int usesReportIDs) +{ +GUID hidGuid; /* GUID for HID driver */ +HDEVINFO deviceInfoList; +SP_DEVICE_INTERFACE_DATA deviceInfo; +SP_DEVICE_INTERFACE_DETAIL_DATA *deviceDetails = NULL; +DWORD size; +int i, openFlag = 0; /* may be FILE_FLAG_OVERLAPPED */ +int errorCode = USBOPEN_ERR_NOTFOUND; +HANDLE handle = INVALID_HANDLE_VALUE; +HIDD_ATTRIBUTES deviceAttributes; + + HidD_GetHidGuid(&hidGuid); + deviceInfoList = SetupDiGetClassDevs(&hidGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE); + deviceInfo.cbSize = sizeof(deviceInfo); + for(i=0;;i++){ + if(handle != INVALID_HANDLE_VALUE){ + CloseHandle(handle); + handle = INVALID_HANDLE_VALUE; + } + if(!SetupDiEnumDeviceInterfaces(deviceInfoList, 0, &hidGuid, i, &deviceInfo)) + break; /* no more entries */ + /* first do a dummy call just to determine the actual size required */ + SetupDiGetDeviceInterfaceDetail(deviceInfoList, &deviceInfo, NULL, 0, &size, NULL); + if(deviceDetails != NULL) + free(deviceDetails); + deviceDetails = malloc(size); + deviceDetails->cbSize = sizeof(*deviceDetails); + /* this call is for real: */ + SetupDiGetDeviceInterfaceDetail(deviceInfoList, &deviceInfo, deviceDetails, size, &size, NULL); + DEBUG_PRINT(("checking HID path \"%s\"\n", deviceDetails->DevicePath)); + /* attempt opening for R/W -- we don't care about devices which can't be accessed */ + handle = CreateFile(deviceDetails->DevicePath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, openFlag, NULL); + if(handle == INVALID_HANDLE_VALUE){ + DEBUG_PRINT(("opening failed: %d\n", (int)GetLastError())); + /* errorCode = USBOPEN_ERR_ACCESS; opening will always fail for mouse -- ignore */ + continue; + } + deviceAttributes.Size = sizeof(deviceAttributes); + HidD_GetAttributes(handle, &deviceAttributes); + DEBUG_PRINT(("device attributes: vid=%d pid=%d\n", deviceAttributes.VendorID, deviceAttributes.ProductID)); + if(deviceAttributes.VendorID != vendor || deviceAttributes.ProductID != product) + continue; /* ignore this device */ + errorCode = USBOPEN_ERR_NOTFOUND; + if(vendorName != NULL && productName != NULL){ + char buffer[512]; + if(!HidD_GetManufacturerString(handle, buffer, sizeof(buffer))){ + DEBUG_PRINT(("error obtaining vendor name\n")); + errorCode = USBOPEN_ERR_IO; + continue; + } + convertUniToAscii(buffer); + DEBUG_PRINT(("vendorName = \"%s\"\n", buffer)); + if(strcmp(vendorName, buffer) != 0) + continue; + if(!HidD_GetProductString(handle, buffer, sizeof(buffer))){ + DEBUG_PRINT(("error obtaining product name\n")); + errorCode = USBOPEN_ERR_IO; + continue; + } + convertUniToAscii(buffer); + DEBUG_PRINT(("productName = \"%s\"\n", buffer)); + if(strcmp(productName, buffer) != 0) + continue; + } + break; /* we have found the device we are looking for! */ + } + SetupDiDestroyDeviceInfoList(deviceInfoList); + if(deviceDetails != NULL) + free(deviceDetails); + if(handle != INVALID_HANDLE_VALUE){ + *device = (usbDevice_t *)handle; + errorCode = 0; + } + return errorCode; +} + +/* ------------------------------------------------------------------------ */ + +void usbhidCloseDevice(usbDevice_t *device) +{ + CloseHandle((HANDLE)device); +} + +/* ------------------------------------------------------------------------ */ + +int usbhidSetReport(usbDevice_t *device, char *buffer, int len) +{ +BOOLEAN rval; + + rval = HidD_SetFeature((HANDLE)device, buffer, len); + return rval == 0 ? USBOPEN_ERR_IO : 0; +} + +/* ------------------------------------------------------------------------ */ + +int usbhidGetReport(usbDevice_t *device, int reportNumber, char *buffer, int *len) +{ +BOOLEAN rval = 0; + + buffer[0] = reportNumber; + rval = HidD_GetFeature((HANDLE)device, buffer, *len); + return rval == 0 ? USBOPEN_ERR_IO : 0; +} + +/* ------------------------------------------------------------------------ */ + +/* ######################################################################## */ +#else /* defined WIN32 #################################################### */ +/* ######################################################################## */ + +#include <string.h> +#include <usb.h> + +#define usbDevice usb_dev_handle /* use libusb's device structure */ + +/* ------------------------------------------------------------------------- */ + +#define USBRQ_HID_GET_REPORT 0x01 +#define USBRQ_HID_SET_REPORT 0x09 + +#define USB_HID_REPORT_TYPE_FEATURE 3 + + +static int usesReportIDs; + +/* ------------------------------------------------------------------------- */ + +static int usbhidGetStringAscii(usb_dev_handle *dev, int index, char *buf, int buflen) +{ +char buffer[256]; +int rval, i; + + if((rval = usb_get_string_simple(dev, index, buf, buflen)) >= 0) /* use libusb version if it works */ + return rval; + if((rval = usb_control_msg(dev, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR, (USB_DT_STRING << 8) + index, 0x0409, buffer, sizeof(buffer), 5000)) < 0) + return rval; + if(buffer[1] != USB_DT_STRING){ + *buf = 0; + return 0; + } + if((unsigned char)buffer[0] < rval) + rval = (unsigned char)buffer[0]; + rval /= 2; + /* lossy conversion to ISO Latin1: */ + for(i=1;i<rval;i++){ + if(i > buflen) /* destination buffer overflow */ + break; + buf[i-1] = buffer[2 * i]; + if(buffer[2 * i + 1] != 0) /* outside of ISO Latin1 range */ + buf[i-1] = '?'; + } + buf[i-1] = 0; + return i-1; +} + +int usbhidOpenDevice(usbDevice_t **device, int vendor, char *vendorName, int product, char *productName, int _usesReportIDs) +{ +struct usb_bus *bus; +struct usb_device *dev; +usb_dev_handle *handle = NULL; +int errorCode = USBOPEN_ERR_NOTFOUND; +static int didUsbInit = 0; + + if(!didUsbInit){ + usb_init(); + didUsbInit = 1; + } + usb_find_busses(); + usb_find_devices(); + for(bus=usb_get_busses(); bus; bus=bus->next){ + for(dev=bus->devices; dev; dev=dev->next){ + if(dev->descriptor.idVendor == vendor && dev->descriptor.idProduct == product){ + char string[256]; + int len; + handle = usb_open(dev); /* we need to open the device in order to query strings */ + if(!handle){ + errorCode = USBOPEN_ERR_ACCESS; + fprintf(stderr, "Warning: cannot open USB device: %s\n", usb_strerror()); + continue; + } + if(vendorName == NULL && productName == NULL){ /* name does not matter */ + break; + } + /* now check whether the names match: */ + len = usbhidGetStringAscii(handle, dev->descriptor.iManufacturer, string, sizeof(string)); + if(len < 0){ + errorCode = USBOPEN_ERR_IO; + fprintf(stderr, "Warning: cannot query manufacturer for device: %s\n", usb_strerror()); + }else{ + errorCode = USBOPEN_ERR_NOTFOUND; + /* fprintf(stderr, "seen device from vendor ->%s<-\n", string); */ + if(strcmp(string, vendorName) == 0){ + len = usbhidGetStringAscii(handle, dev->descriptor.iProduct, string, sizeof(string)); + if(len < 0){ + errorCode = USBOPEN_ERR_IO; + fprintf(stderr, "Warning: cannot query product for device: %s\n", usb_strerror()); + }else{ + errorCode = USBOPEN_ERR_NOTFOUND; + /* fprintf(stderr, "seen product ->%s<-\n", string); */ + if(strcmp(string, productName) == 0) + break; + } + } + } + usb_close(handle); + handle = NULL; + } + } + if(handle) + break; + } + if(handle != NULL){ + errorCode = 0; + *device = (void *)handle; + usesReportIDs = _usesReportIDs; + } + return errorCode; +} + +/* ------------------------------------------------------------------------- */ + +void usbhidCloseDevice(usbDevice_t *device) +{ + if(device != NULL) + usb_close((void *)device); +} + +/* ------------------------------------------------------------------------- */ + +int usbhidSetReport(usbDevice_t *device, char *buffer, int len) +{ +int bytesSent; + + if(!usesReportIDs){ + buffer++; /* skip dummy report ID */ + len--; + } + bytesSent = usb_control_msg((void *)device, USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_ENDPOINT_OUT, USBRQ_HID_SET_REPORT, USB_HID_REPORT_TYPE_FEATURE << 8 | (buffer[0] & 0xff), 0, buffer, len, 5000); + if(bytesSent != len){ + if(bytesSent < 0) + fprintf(stderr, "Error sending message: %s\n", usb_strerror()); + return USBOPEN_ERR_IO; + } + return 0; +} + +/* ------------------------------------------------------------------------- */ + +int usbhidGetReport(usbDevice_t *device, int reportNumber, char *buffer, int *len) +{ +int bytesReceived, maxLen = *len; + + if(!usesReportIDs){ + buffer++; /* make room for dummy report ID */ + maxLen--; + } + bytesReceived = usb_control_msg((void *)device, USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_ENDPOINT_IN, USBRQ_HID_GET_REPORT, USB_HID_REPORT_TYPE_FEATURE << 8 | reportNumber, 0, buffer, maxLen, 5000); + if(bytesReceived < 0){ + fprintf(stderr, "Error sending message: %s\n", usb_strerror()); + return USBOPEN_ERR_IO; + } + *len = bytesReceived; + if(!usesReportIDs){ + buffer[-1] = reportNumber; /* add dummy report ID */ + *len++; + } + return 0; +} + +/* ######################################################################## */ +#endif /* defined WIN32 ################################################### */ +/* ######################################################################## */ |