00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <stdio.h>
00010 #include "blink1/hiddata.h"
00011
00012
00013 #if defined(WIN32)
00014
00015
00016 #include <windows.h>
00017 #include <setupapi.h>
00018 #include "hidsdi.h"
00019 #include <ddk/hidpi.h>
00020
00021 #ifdef DEBUG
00022 #define DEBUG_PRINT(arg) printf arg
00023 #else
00024 #define DEBUG_PRINT(arg)
00025 #endif
00026
00027
00028
00029 static void convertUniToAscii(char *buffer)
00030 {
00031 unsigned short *uni = (void *)buffer;
00032 char *ascii = buffer;
00033
00034 while(*uni != 0){
00035 if(*uni >= 256){
00036 *ascii++ = '?';
00037 }else{
00038 *ascii++ = *uni++;
00039 }
00040 }
00041 *ascii++ = 0;
00042 }
00043
00044 int usbhidOpenDevice(usbDevice_t **device, int vendor, char *vendorName, int product, char *productName, int usesReportIDs)
00045 {
00046 GUID hidGuid;
00047 HDEVINFO deviceInfoList;
00048 SP_DEVICE_INTERFACE_DATA deviceInfo;
00049 SP_DEVICE_INTERFACE_DETAIL_DATA *deviceDetails = NULL;
00050 DWORD size;
00051 int i, openFlag = 0;
00052 int errorCode = USBOPEN_ERR_NOTFOUND;
00053 HANDLE handle = INVALID_HANDLE_VALUE;
00054 HIDD_ATTRIBUTES deviceAttributes;
00055
00056 HidD_GetHidGuid(&hidGuid);
00057 deviceInfoList = SetupDiGetClassDevs(&hidGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
00058 deviceInfo.cbSize = sizeof(deviceInfo);
00059 for(i=0;;i++){
00060 if(handle != INVALID_HANDLE_VALUE){
00061 CloseHandle(handle);
00062 handle = INVALID_HANDLE_VALUE;
00063 }
00064 if(!SetupDiEnumDeviceInterfaces(deviceInfoList, 0, &hidGuid, i, &deviceInfo))
00065 break;
00066
00067 SetupDiGetDeviceInterfaceDetail(deviceInfoList, &deviceInfo, NULL, 0, &size, NULL);
00068 if(deviceDetails != NULL)
00069 free(deviceDetails);
00070 deviceDetails = malloc(size);
00071 deviceDetails->cbSize = sizeof(*deviceDetails);
00072
00073 SetupDiGetDeviceInterfaceDetail(deviceInfoList, &deviceInfo, deviceDetails, size, &size, NULL);
00074 DEBUG_PRINT(("checking HID path \"%s\"\n", deviceDetails->DevicePath));
00075 #if 0
00076
00077
00078
00079
00080 handle = CreateFile(deviceDetails->DevicePath, ACCESS_TYPE_NONE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, openFlag, NULL);
00081 #endif
00082
00083 handle = CreateFile(deviceDetails->DevicePath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, openFlag, NULL);
00084 if(handle == INVALID_HANDLE_VALUE){
00085 DEBUG_PRINT(("opening failed: %d\n", (int)GetLastError()));
00086
00087 continue;
00088 }
00089 deviceAttributes.Size = sizeof(deviceAttributes);
00090 HidD_GetAttributes(handle, &deviceAttributes);
00091 DEBUG_PRINT(("device attributes: vid=%d pid=%d\n", deviceAttributes.VendorID, deviceAttributes.ProductID));
00092 if(deviceAttributes.VendorID != vendor || deviceAttributes.ProductID != product)
00093 continue;
00094 errorCode = USBOPEN_ERR_NOTFOUND;
00095 if(vendorName != NULL && productName != NULL){
00096 char buffer[512];
00097 if(!HidD_GetManufacturerString(handle, buffer, sizeof(buffer))){
00098 DEBUG_PRINT(("error obtaining vendor name\n"));
00099 errorCode = USBOPEN_ERR_IO;
00100 continue;
00101 }
00102 convertUniToAscii(buffer);
00103 DEBUG_PRINT(("vendorName = \"%s\"\n", buffer));
00104 if(strcmp(vendorName, buffer) != 0)
00105 continue;
00106 if(!HidD_GetProductString(handle, buffer, sizeof(buffer))){
00107 DEBUG_PRINT(("error obtaining product name\n"));
00108 errorCode = USBOPEN_ERR_IO;
00109 continue;
00110 }
00111 convertUniToAscii(buffer);
00112 DEBUG_PRINT(("productName = \"%s\"\n", buffer));
00113 if(strcmp(productName, buffer) != 0)
00114 continue;
00115 }
00116 break;
00117 }
00118 SetupDiDestroyDeviceInfoList(deviceInfoList);
00119 if(deviceDetails != NULL)
00120 free(deviceDetails);
00121 if(handle != INVALID_HANDLE_VALUE){
00122 *device = (usbDevice_t *)handle;
00123 errorCode = 0;
00124 }
00125 return errorCode;
00126 }
00127
00128
00129
00130 void usbhidCloseDevice(usbDevice_t *device)
00131 {
00132 CloseHandle((HANDLE)device);
00133 }
00134
00135
00136
00137 int usbhidSetReport(usbDevice_t *device, char *buffer, int len)
00138 {
00139 BOOLEAN rval;
00140
00141 rval = HidD_SetFeature((HANDLE)device, buffer, len);
00142 return rval == 0 ? USBOPEN_ERR_IO : 0;
00143 }
00144
00145
00146
00147 int usbhidGetReport(usbDevice_t *device, int reportNumber, char *buffer, int *len)
00148 {
00149 BOOLEAN rval = 0;
00150
00151 buffer[0] = reportNumber;
00152 rval = HidD_GetFeature((HANDLE)device, buffer, *len);
00153 return rval == 0 ? USBOPEN_ERR_IO : 0;
00154 }
00155
00156
00157
00158
00159 #else
00160
00161
00162 #include <string.h>
00163 #include <usb.h>
00164
00165 #define usbDevice usb_dev_handle
00166
00167
00168
00169 #define USBRQ_HID_GET_REPORT 0x01
00170 #define USBRQ_HID_SET_REPORT 0x09
00171
00172 #define USB_HID_REPORT_TYPE_FEATURE 3
00173
00174
00175 static int usesReportIDs;
00176
00177
00178
00179 static int usbhidGetStringAscii(usb_dev_handle *dev, int index, char *buf, int buflen)
00180 {
00181 char buffer[256];
00182 int rval, i;
00183
00184 if((rval = usb_get_string_simple(dev, index, buf, buflen)) >= 0)
00185 return rval;
00186 if((rval = usb_control_msg(dev, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR, (USB_DT_STRING << 8) + index, 0x0409, buffer, sizeof(buffer), 5000)) < 0)
00187 return rval;
00188 if(buffer[1] != USB_DT_STRING){
00189 *buf = 0;
00190 return 0;
00191 }
00192 if((unsigned char)buffer[0] < rval)
00193 rval = (unsigned char)buffer[0];
00194 rval /= 2;
00195
00196 for(i=1;i<rval;i++){
00197 if(i > buflen)
00198 break;
00199 buf[i-1] = buffer[2 * i];
00200 if(buffer[2 * i + 1] != 0)
00201 buf[i-1] = '?';
00202 }
00203 buf[i-1] = 0;
00204 return i-1;
00205 }
00206
00207 int usbhidOpenDevice(usbDevice_t **device, int vendor, char *vendorName, int product, char *productName, int _usesReportIDs)
00208 {
00209 char drivername[2];
00210 int detachrc;
00211 struct usb_bus *bus;
00212 struct usb_device *dev;
00213 usb_dev_handle *handle = NULL;
00214 int errorCode = USBOPEN_ERR_NOTFOUND;
00215 static int didUsbInit = 0;
00216
00217 if(!didUsbInit){
00218 usb_init();
00219 didUsbInit = 1;
00220 }
00221 usb_find_busses();
00222 usb_find_devices();
00223 for(bus=usb_get_busses(); bus; bus=bus->next){
00224 for(dev=bus->devices; dev; dev=dev->next){
00225 if(dev->descriptor.idVendor == vendor && dev->descriptor.idProduct == product){
00226 char string[256];
00227 int len;
00228 handle = usb_open(dev);
00229 if(!handle){
00230 errorCode = USBOPEN_ERR_ACCESS;
00231 fprintf(stderr, "Warning: cannot open USB device: %s\n", usb_strerror());
00232 continue;
00233 }
00234
00235
00236
00237
00238 usb_get_driver_np(handle, 0, drivername, sizeof(drivername));
00239
00240 if(strlen(drivername) > 0){
00241
00242 detachrc = usb_detach_kernel_driver_np(handle, 0);
00243 if (detachrc != 0) {
00244 errorCode = USBOPEN_ERR_IO;
00245 fprintf(stderr, "Warning: cannot detach kernel driver from interface 0: %s\n", usb_strerror());
00246 continue;
00247 }
00248 }
00249
00250 if(vendorName == NULL && productName == NULL){
00251 break;
00252 }
00253
00254 len = usbhidGetStringAscii(handle, dev->descriptor.iManufacturer, string, sizeof(string));
00255 if(len < 0){
00256 errorCode = USBOPEN_ERR_IO;
00257 fprintf(stderr, "Warning: cannot query manufacturer for device: %s\n", usb_strerror());
00258 }else{
00259 errorCode = USBOPEN_ERR_NOTFOUND;
00260
00261 if(strcmp(string, vendorName) == 0){
00262 len = usbhidGetStringAscii(handle, dev->descriptor.iProduct, string, sizeof(string));
00263 if(len < 0){
00264 errorCode = USBOPEN_ERR_IO;
00265 fprintf(stderr, "Warning: cannot query product for device: %s\n", usb_strerror());
00266 }else{
00267 errorCode = USBOPEN_ERR_NOTFOUND;
00268
00269 if(strcmp(string, productName) == 0)
00270 break;
00271 }
00272 }
00273 }
00274 usb_close(handle);
00275 handle = NULL;
00276 }
00277 }
00278 if(handle)
00279 break;
00280 }
00281 if(handle != NULL){
00282 errorCode = 0;
00283 *device = (void *)handle;
00284 usesReportIDs = _usesReportIDs;
00285 }
00286 return errorCode;
00287 }
00288
00289
00290
00291 void usbhidCloseDevice(usbDevice_t *device)
00292 {
00293 if(device != NULL)
00294 usb_close((void *)device);
00295 }
00296
00297
00298
00299 int usbhidSetReport(usbDevice_t *device, char *buffer, int len)
00300 {
00301 int bytesSent, reportId = buffer[0];
00302 int claimrc, releaserc;
00303
00304 if(!usesReportIDs){
00305 buffer++;
00306 len--;
00307 }
00308
00309 claimrc = usb_claim_interface((void *)device, 0);
00310 if(claimrc != 0){
00311 fprintf(stderr, "Error claiming interface 0 before sending a control message: %s\n", usb_strerror());
00312 return USBOPEN_ERR_IO;
00313 }
00314
00315
00316
00317
00318
00319 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 | (reportId & 0xff), 0, buffer, len, 5000);
00320 if(bytesSent != len){
00321 if(bytesSent < 0)
00322 {
00323 fprintf(stderr, "Error sending message: %s\n", usb_strerror());
00324 }
00325
00326 usb_release_interface((void *)device, 0);
00327 return USBOPEN_ERR_IO;
00328 }
00329
00330 releaserc = usb_release_interface((void *)device, 0);
00331 if(releaserc != 0){
00332 fprintf(stderr, "Error releasing interface 0 after sending a control message: %s\n", usb_strerror());
00333 return USBOPEN_ERR_IO;
00334 }
00335
00336 return 0;
00337 }
00338
00339
00340
00341 int usbhidGetReport(usbDevice_t *device, int reportNumber, char *buffer, int *len)
00342 {
00343 int bytesReceived, maxLen = *len;
00344 int claimrc, releaserc;
00345
00346 if(!usesReportIDs){
00347 buffer++;
00348 maxLen--;
00349 }
00350
00351 claimrc = usb_claim_interface((void *)device, 0);
00352 if(claimrc != 0){
00353 fprintf(stderr, "Error claiming interface 0 before sending a control message: %s\n", usb_strerror());
00354 return USBOPEN_ERR_IO;
00355 }
00356
00357
00358
00359
00360 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);
00361 if(bytesReceived < 0){
00362 fprintf(stderr, "Error sending message: %s\n", usb_strerror());
00363 usb_release_interface((void *)device, 0);
00364 return USBOPEN_ERR_IO;
00365 }
00366 *len = bytesReceived;
00367 if(!usesReportIDs){
00368 buffer[-1] = reportNumber;
00369 (*len)++;
00370 }
00371
00372 releaserc = usb_release_interface((void *)device, 0);
00373 if(releaserc != 0){
00374 fprintf(stderr, "Error releasing interface 0 after sending a control message: %s\n", usb_strerror());
00375 return USBOPEN_ERR_IO;
00376 }
00377
00378 return 0;
00379 }
00380
00381
00382 #endif
00383