int yyyUSBGetInterfaces(yInterfaceSt **ifaces,int *nbifaceDetect,char *errmsg) { int nbifaceAlloc; int deviceIndex; CFIndex deviceCount; IOHIDDeviceRef *dev_refs; // get all device detected by the OSX dev_refs = getDevRef(&yContext->hid, &deviceCount); if(dev_refs == NULL) { return 0; } // allocate buffer for detected interfaces *nbifaceDetect = 0; nbifaceAlloc = 8; *ifaces =yMalloc(nbifaceAlloc * sizeof(yInterfaceSt)); memset(*ifaces, 0 ,nbifaceAlloc * sizeof(yInterfaceSt)); for(deviceIndex=0 ; deviceIndex < deviceCount ;deviceIndex++){ u16 vendorid; u16 deviceid; IOHIDDeviceRef dev = dev_refs[deviceIndex]; yInterfaceSt *iface; vendorid = get_int_property(dev,CFSTR(kIOHIDVendorIDKey)); deviceid = get_int_property(dev,CFSTR(kIOHIDProductIDKey)); //ensure the buffer of detected interface is big enought if(*nbifaceDetect == nbifaceAlloc){ yInterfaceSt *tmp; tmp = (yInterfaceSt*) yMalloc(nbifaceAlloc*2 * sizeof(yInterfaceSt)); memset(tmp,0,nbifaceAlloc*2 * sizeof(yInterfaceSt)); yMemcpy(tmp,*ifaces, nbifaceAlloc * sizeof(yInterfaceSt) ); yFree(*ifaces); *ifaces = tmp; nbifaceAlloc *=2; } iface = *ifaces + *nbifaceDetect; //iface->devref = dev; iface->vendorid = vendorid; iface->deviceid = deviceid; get_txt_property(dev,iface->serial,YOCTO_SERIAL_LEN*2, CFSTR(kIOHIDSerialNumberKey)); HALENUMLOG("work on interface %d (%x:%x:%s)\n",deviceIndex,vendorid,deviceid,iface->serial); (*nbifaceDetect)++; } yFree(dev_refs); return YAPI_SUCCESS; }
static void get_txt_property(IOHIDDeviceRef device,char *buffer,u32 maxlen, CFStringRef key) { CFTypeRef ref; size_t len; ref = IOHIDDeviceGetProperty(device, key); if (ref) { if (CFGetTypeID(ref) == CFStringGetTypeID()) { const char *str; CFStringEncoding encodingMethod; encodingMethod = CFStringGetSystemEncoding(); // 1st try for English system str = CFStringGetCStringPtr(ref, encodingMethod); //str = NULL; if ( str == NULL ) { // 2nd try encodingMethod = kCFStringEncodingUTF8; str = CFStringGetCStringPtr(ref, encodingMethod); } if( str == NULL ) { //3rd try CFIndex cflength = CFStringGetLength(ref)*2+2; char *tmp_str = yMalloc( (u32)cflength); if (!CFStringGetCString(ref, tmp_str, cflength, kCFStringEncodingUTF8 )) { yFree( tmp_str ); *buffer=0; return; } if(cflength>maxlen-1){ cflength=maxlen-1; } memcpy(buffer,tmp_str,cflength); buffer[cflength]=0; yFree( tmp_str ); return; } len=strlen(str); if(len>maxlen-1){ len=maxlen-1; } memcpy(buffer,str,len); buffer[len]=0; return; } } *buffer=0; }
static IOHIDDeviceRef* getDevRef(OSX_HID_REF *hid, CFIndex *deviceCount) { CFSetRef deviceCFSetRef; IOHIDDeviceRef *dev_refs=NULL; *deviceCount = 0; yEnterCriticalSection(&hid->hidMCS); deviceCFSetRef = IOHIDManagerCopyDevices(hid->manager); yLeaveCriticalSection(&hid->hidMCS); if (deviceCFSetRef!= NULL) { // how many devices in the set? *deviceCount = CFSetGetCount( deviceCFSetRef ); dev_refs = yMalloc( sizeof(IOHIDDeviceRef) * (u32)*deviceCount ); // now extract the device ref's from the set CFSetGetValues( deviceCFSetRef, (const void **) dev_refs ); } return dev_refs; }
int yUSBGetInterfaces(yInterfaceSt **ifaces,int *nbifaceDetect,char *errmsg) { int nbifaceAlloc; int deviceIndex; CFSetRef deviceCFSetRef; CFIndex deviceCount; IOHIDDeviceRef *dev_refs; // allocate buffer for detected interfaces *nbifaceDetect = 0; nbifaceAlloc = 8; *ifaces =yMalloc(nbifaceAlloc * sizeof(yInterfaceSt)); memset(*ifaces, 0 ,nbifaceAlloc * sizeof(yInterfaceSt)); yEnterCriticalSection(&yContext->hidMCS); deviceCFSetRef = IOHIDManagerCopyDevices( yContext->hidM ); yLeaveCriticalSection(&yContext->hidMCS); if(deviceCFSetRef== NULL){ //no device found return 0; } // how many devices in the set? deviceCount = CFSetGetCount( deviceCFSetRef ); HALLOG("%ld usb interfaces detected\n",deviceCount); dev_refs = yMalloc( sizeof(IOHIDDeviceRef) * (u32)deviceCount ); // now extract the device ref's from the set CFSetGetValues( deviceCFSetRef, (const void **) dev_refs ); for(deviceIndex=0 ; deviceIndex < deviceCount ;deviceIndex++){ u16 vendorid; u16 deviceid; IOHIDDeviceRef dev = dev_refs[deviceIndex]; yInterfaceSt *iface; vendorid = get_int_property(dev,CFSTR(kIOHIDVendorIDKey)); deviceid = get_int_property(dev,CFSTR(kIOHIDProductIDKey)); //ensure the buffer of detected interface is big enought if(*nbifaceDetect == nbifaceAlloc){ yInterfaceSt *tmp; tmp = (yInterfaceSt*) yMalloc(nbifaceAlloc*2 * sizeof(yInterfaceSt)); memset(tmp,0,nbifaceAlloc*2 * sizeof(yInterfaceSt)); yMemcpy(tmp,*ifaces, nbifaceAlloc * sizeof(yInterfaceSt) ); yFree(*ifaces); *ifaces = tmp; nbifaceAlloc *=2; } iface = *ifaces + *nbifaceDetect; iface->devref = dev; iface->vendorid = vendorid; iface->deviceid = deviceid; get_txt_property(dev,iface->serial,YOCTO_SERIAL_LEN*2, CFSTR(kIOHIDSerialNumberKey)); HALLOG("work on interface %d (%x:%x:%s)\n",deviceIndex,vendorid,deviceid,iface->serial); (*nbifaceDetect)++; } CFRelease(deviceCFSetRef); yFree(dev_refs); return YAPI_SUCCESS; }
int yyyUSBGetInterfaces(yInterfaceSt **ifaces,int *nbifaceDetect,char *errmsg) { libusb_device **list; ssize_t nbdev; int returnval=YAPI_SUCCESS; int i,j; int nbifaceAlloc; yInterfaceSt *iface; nbdev=libusb_get_device_list(yContext->libusb,&list); if(nbdev<0) return yLinSetErr("Unable to get device list",nbdev,errmsg); HALLOG("%d devices found\n",nbdev); // allocate buffer for detected interfaces *nbifaceDetect = 0; nbifaceAlloc = nbdev*2; *ifaces = (yInterfaceSt*) yMalloc(nbifaceAlloc * sizeof(yInterfaceSt)); memset(*ifaces,0,nbifaceAlloc * sizeof(yInterfaceSt)); for(i=0; i < nbdev; i++){ int res; struct libusb_device_descriptor desc; struct libusb_config_descriptor *config; libusb_device_handle *hdl; libusb_device *dev=list[i]; if((res=libusb_get_device_descriptor(dev,&desc))!=0){ returnval = yLinSetErr("Unable to get device descriptor",res,errmsg); goto exit; } if(desc.idVendor!=YOCTO_VENDORID ){ continue; } HALLOG("open device %x:%x\n",desc.idVendor,desc.idProduct); if(getDevConfig(dev,&config)<0) continue; for(j=0 ; j < config->bNumInterfaces; j++){ //ensure the buffer of detected interface is big enough if(*nbifaceDetect == nbifaceAlloc){ yInterfaceSt *tmp; u32 newsize = nbifaceAlloc*2 * sizeof(yInterfaceSt); tmp = (yInterfaceSt*) yMalloc(newsize); memset(tmp,0,newsize); yMemcpy(tmp,*ifaces, nbifaceAlloc * sizeof(yInterfaceSt) ); yFree(*ifaces); *ifaces = tmp; nbifaceAlloc *=2; } iface = *ifaces + *nbifaceDetect; iface->vendorid = (u16)desc.idVendor; iface->deviceid = (u16)desc.idProduct; iface->ifaceno = (u16)j; iface->devref = libusb_ref_device(dev); res = libusb_open(dev,&hdl); if(res==LIBUSB_ERROR_ACCESS){ returnval =YERRMSG(YAPI_IO_ERROR,"the user has insufficient permissions to access USB devices"); goto exit; } if(res!=0){ HALLOG("unable to access device %x:%x\n",desc.idVendor,desc.idProduct); continue; } HALLOG("try to get serial for %x:%x:%x (%p)\n",desc.idVendor,desc.idProduct,desc.iSerialNumber,dev); res = getUsbStringASCII(hdl, dev, desc.iSerialNumber, iface->serial, YOCTO_SERIAL_LEN); if(res<0){ HALLOG("unable to get serial for device %x:%x\n",desc.idVendor,desc.idProduct); } libusb_close(hdl); (*nbifaceDetect)++; HALLOG("----Running Dev %x:%x:%d:%s ---\n",iface->vendorid,iface->deviceid,iface->ifaceno,iface->serial); } libusb_free_config_descriptor(config); } exit: libusb_free_device_list(list,1); return returnval; }
// on success data point to a null terminated string of max length-1 characters static int getUsbStringASCII(libusb_device_handle *hdl, libusb_device *dev, u8 desc_index, char *data, u32 length) { u8 buffer[512]; u32 l,len; int res,i; stringCacheSt *c = stringCache; stringCacheSt *f = NULL; u64 now = yapiGetTickCount(); yEnterCriticalSection(&yContext->string_cache_cs); for (i = 0; i < STRING_CACHE_SIZE; i++, c++) { if (c->expiration > now) { if(c->dev == dev && c->desc_index == desc_index) { if (c->len > 0 && c->string) { len = c->len; if (c->len >= length) len = length-1; memcpy(data, c->string, len); data[len] = 0; HALLOG("return string from cache (%p:%d->%s)\n",dev,desc_index,c->string); yLeaveCriticalSection(&yContext->string_cache_cs); return c->len; } else { f = c; break; } } } else { if (c->string) { yFree(c->string); c->string =NULL; } if (f == NULL) { f = c; } } } res=libusb_control_transfer(hdl, LIBUSB_ENDPOINT_IN, LIBUSB_REQUEST_GET_DESCRIPTOR, (LIBUSB_DT_STRING << 8) | desc_index, 0, buffer, 512, 10000); if(res<0) return res; len=(buffer[0]-2)/2; if (len >= length) { len = length - 1; } for (l = 0; l < len; l++){ data[l] = (char) buffer[2+(l*2)]; } data[len] = 0; if (f != NULL) { f->dev = dev; f->desc_index = desc_index; f->string = yMalloc(len+1); memcpy(f->string, data, len+1); f->len = len; f->expiration = yapiGetTickCount() + STRING_CACHE_EXPIRATION; HALLOG("add string to cache (%p:%d->%s)\n",dev,desc_index,f->string); } yLeaveCriticalSection(&yContext->string_cache_cs); return len; }