예제 #1
1
static void *read_thread(void *param)
{
	hid_device *dev = param;
	
	/* Move the device's run loop to this thread. */
	IOHIDDeviceScheduleWithRunLoop(dev->device_handle, CFRunLoopGetCurrent(), dev->run_loop_mode);

	/* Create the RunLoopSource which is used to signal the
	   event loop to stop when hid_close() is called. */
	CFRunLoopSourceContext ctx;
	memset(&ctx, 0, sizeof(ctx));
	ctx.version = 0;
	ctx.info = dev;
	ctx.perform = &perform_signal_callback;
	dev->source = CFRunLoopSourceCreate(kCFAllocatorDefault, 0/*order*/, &ctx);
	CFRunLoopAddSource(CFRunLoopGetCurrent(), dev->source, dev->run_loop_mode);
	
	/* Store off the Run Loop so it can be stopped from hid_close()
	   and on device disconnection. */
	dev->run_loop = CFRunLoopGetCurrent();

	/* Notify the main thread that the read thread is up and running. */
	pthread_barrier_wait(&dev->barrier);

	/* Run the Event Loop. CFRunLoopRunInMode() will dispatch HID input
	   reports into the hid_report_callback(). */
	SInt32 code;
	while (!dev->shutdown_thread && !dev->disconnected) {
		code = CFRunLoopRunInMode(dev->run_loop_mode, 1000/*sec*/, FALSE);
		/* Return if the device has been disconnected */
		if (code == kCFRunLoopRunFinished) {
			dev->disconnected = 1;
			break;
		}


		/* Break if The Run Loop returns Finished or Stopped. */
		if (code != kCFRunLoopRunTimedOut &&
		    code != kCFRunLoopRunHandledSource) {
			/* There was some kind of error. Setting
			   shutdown seems to make sense, but
			   there may be something else more appropriate */
			dev->shutdown_thread = 1;
			break;
		}
	}

	/* Now that the read thread is stopping, Wake any threads which are
	   waiting on data (in hid_read_timeout()). Do this under a mutex to
	   make sure that a thread which is about to go to sleep waiting on
	   the condition acutally will go to sleep before the condition is
	   signaled. */
	pthread_mutex_lock(&dev->mutex);
	pthread_cond_broadcast(&dev->condition);
	pthread_mutex_unlock(&dev->mutex);

	/* Close the OS handle to the device, but only if it's not
	   been unplugged. If it's been unplugged, then calling
	   IOHIDDeviceClose() will crash. */
	if (!dev->disconnected) {
		IOHIDDeviceClose(dev->device_handle, kIOHIDOptionsTypeNone);
	}
	
	/* Wait here until hid_close() is called and makes it past
	   the call to CFRunLoopWakeUp(). This thread still needs to
	   be valid when that function is called on the other thread. */
	pthread_barrier_wait(&dev->shutdown_barrier);

	return NULL;
}
예제 #2
0
static void hid_close(hid_t *hid)
{
    if (!hid || !hid->open || !hid->ref) return;
    IOHIDDeviceUnscheduleFromRunLoop(hid->ref, CFRunLoopGetCurrent( ), kCFRunLoopDefaultMode);
    IOHIDDeviceClose(hid->ref, kIOHIDOptionsTypeNone);
    hid->ref = NULL;
}
예제 #3
0
void TeensyControls_usb_close(void)
{
	teensy_t *t;
	int wait=0;

	for (t = TeensyControls_first_teensy; t; t = t->next) {
		if (t->online) {
			printf("close USB device\n");
			IOHIDDeviceRegisterInputReportCallback(t->usb.dev,
				t->usb.inbuf, 64, NULL, NULL);
			// TODO: how to terminate input thread?
			// TODO: how to terminate output thread?
			pthread_cond_signal(&t->output_event);
			IOHIDDeviceClose(t->usb.dev, 0);
			t->online = 0;
		}
	}
	if (hmgr) {
		printf("closing hid manager\n");
		IOHIDManagerRegisterDeviceMatchingCallback(hmgr, NULL, NULL);
		IOHIDManagerRegisterDeviceRemovalCallback(hmgr, NULL, NULL);
		IOHIDManagerClose(hmgr, 0);
		hmgr = NULL;
	}
	while (++wait < 20 && num_thread_alive() > 0) {
		usleep(10000);
		printf("wait #%d for thread exit\n", wait);
	}
}
예제 #4
0
void yyyPacketShutdown(yInterfaceSt  *iface)
{
    int i;

    // remove iface from setuped ifaces
    for (i=0; i< SETUPED_IFACE_CACHE_SIZE ; i++) {
        if(yContext->setupedIfaceCache[i]==iface){
            yContext->setupedIfaceCache[i] = NULL;
            break;
        }
    }
    YASSERT(i<SETUPED_IFACE_CACHE_SIZE);
    if(iface->devref!=NULL){
        IOHIDDeviceRegisterInputReportCallback(iface->devref,              // IOHIDDeviceRef for the HID device
                                               (u8*) &iface->tmprxpkt,   // pointer to the report data (uint8_t's)
                                               USB_PKT_SIZE,              // number of bytes in the report (CFIndex)
                                               NULL,   // the callback routine
                                               iface);                      // context passed to callback
        IOHIDDeviceClose(iface->devref, kIOHIDOptionsTypeNone);
        iface->devref=NULL;
    }
    yPktQueueFree(&iface->rxQueue);
	yPktQueueFree(&iface->txQueue);
    iface->flags.yyySetupDone = 0;
    CFRelease(iface->run_loop_mode);
    if (yContext->osx_flags & YCTX_OSX_MULTIPLES_HID) {
        stopHIDManager(&iface->hid);
    }
}
예제 #5
0
파일: hidapi-osx.c 프로젝트: psumbera/wview
void HID_API_EXPORT hid_close(hid_device *dev)
{
    if (!dev)
        return;

    /* Close the OS handle to the device. */
    IOHIDDeviceClose(dev->device_handle, kIOHIDOptionsTypeNone);

    /* Delete any input reports still left over. */
    struct input_report *rpt = dev->input_reports;
    while (rpt)
    {
        struct input_report *next = rpt->next;
        free(rpt->data);
        free(rpt);
        rpt = next;
    }

    /* Free the string and the report buffer. */
    CFRelease(dev->run_loop_mode);
    free(dev->input_report_buf);
    pthread_mutex_destroy(&dev->mutex);

    free(dev);
}
예제 #6
0
void joy_hidlib_close_device(joy_hid_device_t *device)
{
    /* close old device */
    if(device->internal_device != NULL) {
        IOHIDDeviceClose(device->internal_device, 0);
    }
}
예제 #7
0
void HIDDevice::closeDevice(bool wasUnplugged)
{
    OVR_ASSERT(Device != NULL);
    
    if (!wasUnplugged)
    {
        // Clear the registered callbacks.
        IOHIDDeviceRegisterInputReportCallback(Device,
                                               ReadBuffer,
                                               InputReportBufferLength,
                                               NULL,
                                               this);
        
        IOHIDDeviceRegisterRemovalCallback(Device, NULL, this);
        
        IOHIDDeviceUnscheduleFromRunLoop(Device,
                                         HIDManager->getRunLoop(),
                                         kCFRunLoopDefaultMode);
        IOHIDDeviceClose(Device, kIOHIDOptionsTypeNone);
    }
    
	CFRelease(Device);
    Device = NULL;
        
    LogText("OVR::OSX::HIDDevice - HID Device Closed '%s'\n", DevDesc.Path.ToCStr());
}
 void osxPointingDeviceManager::RemoveDevice(void *sender, IOReturn, void *, IOHIDDeviceRef devRef)
 {
   osxPointingDeviceManager *self = (osxPointingDeviceManager *)sender;
   if (self->unregisterDevice(devRef))
   {
     IOHIDDeviceClose(devRef, kIOHIDOptionsTypeNone);
   }
 }
예제 #9
0
파일: usb_mac.c 프로젝트: julianliaw/ckb
void closehandle(usbdevice* kb){
    kb->handle = 0;
    for(int i = 0; i < 4; i++){
        if(kb->handles[i]){
            IOHIDDeviceClose(kb->handles[i], kIOHIDOptionsTypeNone);
            kb->handles[i] = 0;
        }
    }
}
예제 #10
0
int _ykusb_close_device(void *dev)
{
	_ykusb_IOReturn = IOHIDDeviceClose( dev, 0L );
	CFRelease(dev);

	if ( _ykusb_IOReturn == kIOReturnSuccess )
		return 1;

	yk_errno = YK_EUSBERR;
	return 0;
}
예제 #11
0
bool GPUSB_Close() {
    if (!pGPUSB) return false;
    IOReturn ioReturnValue = IOHIDDeviceClose(pGPUSB, kIOHIDOptionsTypeSeizeDevice);
    if(ioReturnValue != kIOReturnSuccess)
    {
        wxMessageBox ("GPUSB_Close: error while closing the device",_("Error"));
    }
    
    CFRelease(pGPUSB);
    return ioReturnValue == kIOReturnSuccess;
}
예제 #12
0
static void close_usb_device(IOHIDDeviceRef dev)
{
	struct usb_list_struct *p;

	do_run_loop();
	for (p = usb_list; p; p = p->next) {
		if (p->ref == dev) {
			IOHIDDeviceClose(dev, kIOHIDOptionsTypeNone);
			return;
		}
	}
}
예제 #13
0
파일: hid.c 프로젝트: keepitcool/3m2tuio
void HID_API_EXPORT hid_close(hid_device *dev)
{
	if (!dev)
		return;
	
	/* Close the OS handle to the device, but only if it's not
	   been unplugged. If it's been unplugged, then calling
	   IOHIDDeviceClose() will crash. */
	if (!dev->disconnected) {
		IOHIDDeviceClose(dev->device_handle, kIOHIDOptionsTypeNone);
	}

	free_hid_device(dev);
}
예제 #14
0
static void hid_device_removed(void* context, IOReturn result, void* sender)
{
   struct apple_pad_connection* connection = (struct apple_pad_connection*)context;

   if (connection && connection->slot < MAX_PLAYERS)
   {
      g_current_input_data.pad_buttons[connection->slot] = 0;
      memset(g_current_input_data.pad_axis[connection->slot], 0, sizeof(g_current_input_data.pad_axis));
      
      apple_joypad_disconnect(connection->slot);
      free(connection);
   }

   IOHIDDeviceClose(sender, kIOHIDOptionsTypeNone);
}
예제 #15
0
파일: hid.c 프로젝트: jingoro2112/dna
void HID_API_EXPORT hid_close(hid_device *dev)
{
	if ( !dev )
	{
		return;
	}

	/* Disconnect the report callback before close. */
	if (!dev->disconnected) {
		IOHIDDeviceRegisterInputReportCallback(
			dev->device_handle, dev->input_report_buf, dev->max_input_report_len,
			NULL, dev);
		IOHIDManagerRegisterDeviceRemovalCallback(hid_mgr, NULL, dev);
		IOHIDDeviceUnscheduleFromRunLoop(dev->device_handle, dev->run_loop, dev->run_loop_mode);
		IOHIDDeviceScheduleWithRunLoop(dev->device_handle, CFRunLoopGetMain(), kCFRunLoopDefaultMode);
	}
	
	/* Cause read_thread() to stop. */
	dev->shutdown_thread = 1;
	
	/* Wake up the run thread's event loop so that the thread can exit. */
	CFRunLoopSourceSignal(dev->source);
	CFRunLoopWakeUp(dev->run_loop);
	
	/* Notify the read thread that it can shut down now. */
	pthread_barrier_wait(&dev->shutdown_barrier);

	/* Wait for read_thread() to end. */
	pthread_join(dev->thread, NULL);

	/* Close the OS handle to the device, but only if it's not
	   been unplugged. If it's been unplugged, then calling
	   IOHIDDeviceClose() will crash. */
	if (!dev->disconnected) {
		IOHIDDeviceClose(dev->device_handle, kIOHIDOptionsTypeNone);
	}
	
	/* Clear out the queue of received reports. */
	pthread_mutex_lock(&dev->mutex);
	while (dev->input_reports) {
		return_data(dev, NULL, 0);
	}
	pthread_mutex_unlock(&dev->mutex);

	free_hid_device(dev);
}
예제 #16
0
void yyyPacketShutdown(yInterfaceSt  *iface)
{
    
    yEnterCriticalSection(&iface->yyyCS);
    if(iface->devref!=NULL){
        IOHIDDeviceRegisterInputReportCallback( iface->devref,              // IOHIDDeviceRef for the HID device
                                            (u8*) &iface->tmprxpkt,   // pointer to the report data (uint8_t's)
                                            USB_PKT_SIZE,              // number of bytes in the report (CFIndex)
                                            NULL,   // the callback routine
                                            iface);                      // context passed to callback
        IOHIDDeviceClose(iface->devref, kIOHIDOptionsTypeNone);
        iface->devref=NULL;
    }
    yLeaveCriticalSection(&iface->yyyCS);
    yDeleteCriticalSection(&iface->yyyCS);
    yyyFreePktQueue(iface);

}
예제 #17
0
//! Close the HID device
void pjrc_rawhid::close(int)
{
    // Make sure any pending locks are done
    QMutexLocker lock(m_writeMutex);

    if (device_open) {
        device_open = false;
        CFRunLoopStop(the_correct_runloop);

        if (!unplugged) {
            IOHIDDeviceUnscheduleFromRunLoop(dev, the_correct_runloop, kCFRunLoopDefaultMode);
            IOHIDDeviceRegisterInputReportCallback(dev, buffer, sizeof(buffer), NULL, NULL);
            IOHIDDeviceClose(dev, kIOHIDOptionsTypeNone);
        }

        IOHIDManagerRegisterDeviceRemovalCallback(hid_manager, NULL, NULL);
        IOHIDManagerClose(hid_manager, 0);

        dev = NULL;
        hid_manager = NULL;
    }
}
예제 #18
0
 ~Connection()
 {
     delete hidpad;        
     if (device)
         IOHIDDeviceClose(device, kIOHIDOptionsTypeNone);
 }    
예제 #19
0
bool HIDDeviceManager::Enumerate(HIDEnumerateVisitor* enumVisitor)
{
    if (!initializeManager())
    {
        return false;
    }
    

	CFSetRef deviceSet = IOHIDManagerCopyDevices(HIDManager);
    if (!deviceSet)
        return false;
    
	CFIndex deviceCount = CFSetGetCount(deviceSet);
    
    // Allocate a block of memory and read the set into it.
    IOHIDDeviceRef* devices = (IOHIDDeviceRef*) OVR_ALLOC(sizeof(IOHIDDeviceRef) * deviceCount);
    CFSetGetValues(deviceSet, (const void **) devices);
    

    // Iterate over devices.
    for (CFIndex deviceIndex = 0; deviceIndex < deviceCount; deviceIndex++)
    {
        IOHIDDeviceRef hidDev = devices[deviceIndex];
        
        if (!hidDev)
        {
            continue;
        }
        
        HIDDeviceDesc devDesc;
                
        if (getPath(hidDev, &(devDesc.Path)) &&
            initVendorProductVersion(hidDev, &devDesc) &&
            enumVisitor->MatchVendorProduct(devDesc.VendorId, devDesc.ProductId) &&
            initUsage(hidDev, &devDesc))
        {
            initStrings(hidDev, &devDesc);
            initSerialNumber(hidDev, &devDesc);

            // Look for the device to check if it is already opened.
            Ptr<DeviceCreateDesc> existingDevice = DevManager->FindHIDDevice(devDesc, true);
            // if device exists and it is opened then most likely the CreateHIDFile
            // will fail; therefore, we just set Enumerated to 'true' and continue.
            if (existingDevice && existingDevice->pDevice)
            {
                existingDevice->Enumerated = true;
                continue;
            }

            // open the device temporarily for startup communication
            if (IOHIDDeviceOpen(hidDev, kIOHIDOptionsTypeSeizeDevice) == kIOReturnSuccess)
            {
                // Construct minimal device that the visitor callback can get feature reports from.
                OSX::HIDDevice device(this, hidDev);

                enumVisitor->Visit(device, devDesc);

                IOHIDDeviceClose(hidDev, kIOHIDOptionsTypeSeizeDevice);
            }
        }
    }
    
    OVR_FREE(devices);
    CFRelease(deviceSet);
    
    return true;
}
예제 #20
0
bool HIDDevice::openDevice()
{
    
    // Have to iterate through devices again to generate paths.
	CFSetRef deviceSet = IOHIDManagerCopyDevices(HIDManager->HIDManager);
	CFIndex deviceCount = CFSetGetCount(deviceSet);
    
    // Allocate a block of memory and read the set into it.
    IOHIDDeviceRef* devices = (IOHIDDeviceRef*) OVR_ALLOC(sizeof(IOHIDDeviceRef) * deviceCount);
    CFSetGetValues(deviceSet, (const void **) devices);
    
    
    // Iterate over devices.
    IOHIDDeviceRef device = NULL;

    for (CFIndex deviceIndex = 0; deviceIndex < deviceCount; deviceIndex++)
    {
        IOHIDDeviceRef tmpDevice = devices[deviceIndex];
        
        if (!tmpDevice)
        {
            continue;
        }
        
        String path;
        if (!HIDManager->getPath(tmpDevice, &path))
        {
            continue;
        }
        
        if (path == DevDesc.Path)
        {
            device = tmpDevice;
            break;
        }
    }
    
    
    OVR_FREE(devices);
    
    if (!device)
    {
        CFRelease(deviceSet);
        return false;
    }
    
    // Attempt to open device.
    if (IOHIDDeviceOpen(device, kIOHIDOptionsTypeSeizeDevice)
        != kIOReturnSuccess)
    {
        CFRelease(deviceSet);
        return false;
    }

    // Retain the device before we release the set.
    CFRetain(device);
    CFRelease(deviceSet);
    
    
    Device = device;

    
    if (!initInfo())
    {
        IOHIDDeviceClose(Device, kIOHIDOptionsTypeSeizeDevice);
        CFRelease(Device);
        Device = NULL;
        return false;
    }
    
    
    // Setup the Run Loop and callbacks.
    IOHIDDeviceScheduleWithRunLoop(Device,
                                   HIDManager->getRunLoop(),
                                   kCFRunLoopDefaultMode);
    
    IOHIDDeviceRegisterInputReportCallback(Device,
                                           ReadBuffer,
                                           ReadBufferSize,
                                           staticHIDReportCallback,
                                           this);

    IOHIDDeviceRegisterRemovalCallback(Device,
                                       staticDeviceRemovedCallback,
                                       this);
    
    return true;
}