Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
0
int yyySignalOutPkt(yInterfaceSt *iface, char *errmsg)
{
    int res =YAPI_SUCCESS;
    pktItem *pktitem;

    yPktQueuePopH2D(iface, &pktitem);
    while (pktitem!=NULL){
        if(iface->devref==NULL){
            yFree(pktitem);
            return YERR(YAPI_IO_ERROR);
        }
        res = IOHIDDeviceSetReport(iface->devref,
                                   kIOHIDReportTypeOutput,
                                   0, /* Report ID*/
                                   (u8*)&pktitem->pkt, sizeof(USB_Packet));
        yFree(pktitem);
        if (res != kIOReturnSuccess) {
            dbglog("IOHIDDeviceSetReport failed with 0x%x\n", res);
            return YERRMSG(YAPI_IO_ERROR,"IOHIDDeviceSetReport failed");;
        }
        yPktQueuePopH2D(iface, &pktitem);
    }
	return YAPI_SUCCESS;
}
Пример #4
0
int yyySignalOutPkt(yInterfaceSt *iface)
{
    pktItem *pktitem;
    yPktQueuePopH2D(iface, &pktitem);
    while (pktitem!=NULL){
        int transfered,res;
        res = libusb_interrupt_transfer(iface->hdl,
                                    iface->wrendp,
                                    (u8*)&pktitem->pkt,
                                    sizeof(USB_Packet),
                                    &transfered,
                                    5000/*5 sec*/);
        yFree(pktitem);
        if(res<0){
            return YAPI_IO_ERROR;
        }
        yPktQueuePopH2D(iface, &pktitem);
    }

    return YAPI_SUCCESS;
}
Пример #5
0
int yyyUSB_stop(yContextSt *ctx,char *errmsg)
{
    int i;
    stringCacheSt *c = stringCache;

    if(ctx->usb_thread_state == USB_THREAD_RUNNING){
        ctx->usb_thread_state = USB_THREAD_MUST_STOP;
        pthread_join(ctx->usb_thread,NULL);
    }
    YASSERT(ctx->usb_thread_state == USB_THREAD_STOPED);

    libusb_exit(ctx->libusb);
    yReleaseGlobalAccess(ctx);
    for (i = 0; i < STRING_CACHE_SIZE; i++, c++) {
        if(c->string) {
            yFree(c->string);
        }
    }
    yDeleteCriticalSection(&ctx->string_cache_cs);

    return YAPI_SUCCESS;
}
Пример #6
0
int yyySetup(yInterfaceSt *iface,char *errmsg)
{
    char str[32];
    int i;
    CFIndex deviceCount;
    IOHIDDeviceRef *dev_refs;


    if (yContext->osx_flags & YCTX_OSX_MULTIPLES_HID) {
        if (YISERR(setupHIDManager(yContext, &iface->hid,errmsg))) {
            return YAPI_IO_ERROR;
        }
        // get all device detected by the OSX
        dev_refs = getDevRef(&iface->hid, &deviceCount);
    } else {
        dev_refs = getDevRef(&yContext->hid, &deviceCount);
    }
    if(dev_refs == NULL) {
        return YERRMSG(YAPI_IO_ERROR,"Device disapear before yyySetup");
    }


    for(i=0 ; i < deviceCount ;i++){
        u16 vendorid;
        u16 deviceid;
        IOHIDDeviceRef dev = dev_refs[i];
        vendorid = get_int_property(dev,CFSTR(kIOHIDVendorIDKey));
        deviceid = get_int_property(dev,CFSTR(kIOHIDProductIDKey));
        if (iface->vendorid == vendorid && iface->deviceid == deviceid){
            char serial[YOCTO_SERIAL_LEN * 2];
            memset(serial, 0, YOCTO_SERIAL_LEN * 2);
            get_txt_property(dev,serial,YOCTO_SERIAL_LEN * 2, CFSTR(kIOHIDSerialNumberKey));
            if (YSTRCMP(serial, iface->serial) == 0){
                HALLOG("right Interface detected (%x:%x:%s)\n",vendorid,deviceid,iface->serial);
                iface->devref = dev;
                break;
            }
        }
    }
    yFree(dev_refs);
    if (i == deviceCount) {
        return YERRMSG(YAPI_IO_ERROR,"Unable to match device detected");
    }

    IOReturn ret = IOHIDDeviceOpen(iface->devref, kIOHIDOptionsTypeNone);
    if (ret != kIOReturnSuccess) {
        YSPRINTF(str,32,"Unable to open device (0x%x)",ret);
        return YERRMSG(YAPI_IO_ERROR,str);
    }

    yPktQueueInit(&iface->rxQueue);
	yPktQueueInit(&iface->txQueue);


    /* Create the Run Loop Mode for this device. printing the reference seems to work. */
    sprintf(str, "yocto_%p", iface->devref);
    iface->run_loop_mode = CFStringCreateWithCString(NULL, str, kCFStringEncodingASCII);
    /* Attach the device to a Run Loop */
    IOHIDDeviceScheduleWithRunLoop(iface->devref, yContext->usb_run_loop, iface->run_loop_mode);
    IOHIDDeviceRegisterInputReportCallback( iface->devref,              // IOHIDDeviceRef for the HID device
                                           (u8*) &iface->tmprxpkt,     // pointer to the report data
                                           USB_PKT_SIZE,               // number of bytes in the report (CFIndex)
                                           &Handle_IOHIDDeviceIOHIDReportCallback,   // the callback routine
                                           iface);                     // context passed to callback

    // save setuped iface pointer in context in order
    // to retreive it durring unplugcallback
    for (i=0; i< SETUPED_IFACE_CACHE_SIZE ; i++) {
        if(yContext->setupedIfaceCache[i]==NULL){
            yContext->setupedIfaceCache[i] = iface;
            break;
        }
    }
    if (i==SETUPED_IFACE_CACHE_SIZE) {
        return YERRMSG(YAPI_IO_ERROR,"Too many setuped USB interfaces");
    }
    iface->flags.yyySetupDone = 1;
    return 0;
}
Пример #7
0
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;
}
Пример #8
0
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;

}
Пример #9
0
// 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;
}