Exemplo n.º 1
0
int
main(void)
{
    CFMutableDictionaryRef match;
    IONotificationPortRef  notifyPort;
    CFRunLoopSourceRef     notificationRunLoopSource;
    io_iterator_t          notificationIn, notificationOut;
   
    // Create a matching dictionary for all IOMedia objects.
    if (!(match = IOServiceMatching("IOMedia"))) {
        fprintf(stderr, "*** failed to create matching dictionary.\n");
        exit(1);
    }
   
    // Create a notification object for receiving I/O Kit notifications.
    notifyPort = IONotificationPortCreate(kIOMasterPortDefault);
   
    // Get a CFRunLoopSource that we will use to listen for notifications.
    notificationRunLoopSource = IONotificationPortGetRunLoopSource(notifyPort);
   
    // Add the CFRunLoopSource to the default mode of our current run loop.
    CFRunLoopAddSource(CFRunLoopGetCurrent(), notificationRunLoopSource,
                       kCFRunLoopDefaultMode);
   
    // One reference of the matching dictionary will be consumed when we install
    // a notification request. Since we need to install two such requests (one
    // for ejectable media coming in and another for it going out), we need
    // to increment the reference count on our matching dictionary.
    CFRetain(match);
   
    // Install notification request for matching objects coming in.
    // Note that this will also look up already existing objects.
    IOServiceAddMatchingNotification(
        notifyPort,             // notification port reference
        kIOMatchedNotification, // notification type
        match,                  // matching dictionary
        matchingCallback,       // this is called when notification fires
        NULL,                   // reference constant
        &notificationIn);       // iterator handle
   
    // Install notification request for matching objects going out.
    IOServiceAddMatchingNotification(
        notifyPort,
        kIOTerminatedNotification,
        match,
        matchingCallback,
        NULL,
        &notificationOut);
   
    // Invoke callbacks explicitly to empty the iterators/arm the notifications.
    matchingCallback(0, notificationIn);
    matchingCallback(0, notificationOut);
   
    CFRunLoopRun(); // run
   
    exit(0);
}
Exemplo n.º 2
0
int usbmain(){
    int vendor = V_CORSAIR;
    int products[] = { P_K65, P_K70, P_K70_NRGB, P_K95, P_K95_NRGB/*, P_M65*/ };
    // Tell IOService which type of devices we want (IOHIDDevices matching the supported vendor/products)
    CFMutableDictionaryRef match = IOServiceMatching(kIOHIDDeviceKey);
    CFNumberRef cfvendor = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &vendor);
    CFDictionarySetValue(match, CFSTR(kIOHIDVendorIDKey), cfvendor);
    CFRelease(cfvendor);
    CFMutableArrayRef cfproducts = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
    for(uint i = 0; i < sizeof(products) / sizeof(int); i++){
        int product = products[i];
        CFNumberRef cfproduct = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &product);
        CFArrayAppendValue(cfproducts, cfproduct);
        CFRelease(cfproduct);
    }
    CFDictionarySetValue(match, CFSTR(kIOHIDProductIDArrayKey), cfproducts);
    CFRelease(cfproducts);

    notify = IONotificationPortCreate(kIOMasterPortDefault);
    CFRunLoopAddSource(mainloop = CFRunLoopGetCurrent(), IONotificationPortGetRunLoopSource(notify), kCFRunLoopDefaultMode);
    io_iterator_t iterator;
    IOReturn res = IOServiceAddMatchingNotification(notify, kIOMatchedNotification, match, iterate_devices, 0, &iterator);
    if(res != kIOReturnSuccess){
        ckb_fatal("Failed to list devices: %x\n", res);
        return -1;
    }
    // Iterate existing devices
    iterate_devices(0, iterator);
    // Enter loop to scan/connect new devices
    CFRunLoopRun();
    return 0;
}
Exemplo n.º 3
0
int AoEProperties::configure_matching(void)
{
//	debugVerbose("AoEProperties::configure_matching\n");
	
	// Obtain ports for notifications (this will be used for all service matching notifications)
	kern_return_t kresult;
	mach_port_t MasterPort;
	kresult = IOMasterPort(MACH_PORT_NULL, &MasterPort);
	if ( kresult )
	{
		debugError("Could not get masterport. Error=%d\n", kresult);
		return false;
	}
	
	ms_NotificationPort = IONotificationPortCreate(MasterPort);
	
	ms_IOKitNotificationRunLoopSource = IONotificationPortGetRunLoopSource(ms_NotificationPort);
	CFRunLoopAddSource(CFRunLoopGetCurrent(), ms_IOKitNotificationRunLoopSource, kCFRunLoopDefaultMode);
	
	// SetUp Notification for matching to our device
	CFMutableDictionaryRef MatchingDict = IOServiceMatching(AOE_KEXT_NAME_Q);

	IOServiceAddMatchingNotification(ms_NotificationPort,
									 kIOMatchedNotification,
									 MatchingDict,
									 AoEProperties::matched_callback,
									 this,
									 &ms_MatchIt);
	
	// Call the callback immediately to check if our iterator already contains our device (ie. the device is already loaded)
	matched_callback(this, ms_MatchIt);
	
	return m_fMatched ? 0 : -1;
}
Exemplo n.º 4
0
TorcUSBPrivOSX::TorcUSBPrivOSX(TorcUSB *Parent)
  : QObject(Parent),
    m_usbRef(NULL),
    m_usbNotifyPort(NULL),
    m_iterator(0),
    m_notificationsLock(new QMutex())
{
    if (!gAdminRunLoop)
    {
        LOG(VB_GENERAL, LOG_ERR, "OS X callback run loop not present - aborting");
        return;
    }

    CFMutableDictionaryRef match = IOServiceMatching(kIOUSBDeviceClassName);

    m_usbNotifyPort = IONotificationPortCreate(kIOMasterPortDefault);
    m_usbRef = IONotificationPortGetRunLoopSource(m_usbNotifyPort);
    CFRunLoopAddSource(gAdminRunLoop, m_usbRef, kCFRunLoopCommonModes);

    IOReturn ok = IOServiceAddMatchingNotification(m_usbNotifyPort, kIOFirstMatchNotification, match,
                                                   (IOServiceMatchingCallback)DeviceAddedCallback,
                                                   this, &m_iterator);
    if (kIOReturnSuccess == ok)
        DeviceAddedCallback(this, m_iterator);
    else
        LOG(VB_GENERAL, LOG_ERR, "Failed to register for attachment notifications");
}
Exemplo n.º 5
0
static Boolean RegisterServiceMatchedCallback() {
	io_iterator_t	iter = 0;
	CFDictionaryRef	matchDictionary = NULL;
	Boolean			success = TRUE;
	
	write_log(LOG_NOTICE, "Creating matching dictionary for class '"
			   kDriverClassName "'.");
			   
	matchDictionary = IOServiceMatching(kDriverClassName);
	if(matchDictionary == NULL) {
		write_log(LOG_ERR, "Couldn't create matching dictionary for class '"
			   kDriverClassName "'!");
		success = FALSE;
		goto EXIT;
	}
	
	write_log(LOG_NOTICE, "Registering service matched notification.");
	
	if(IOServiceAddMatchingNotification(ioKitNotificationPort,
										kIOMatchedNotification,	matchDictionary,
										ServiceMatchedCallbackFunction, NULL, 
										&iter) != kIOReturnSuccess) {
		write_log(LOG_ERR, "Couldn't register service matched notification!");
		success = FALSE;
		goto EXIT;
	}
	
	ServiceMatchedCallbackFunction(NULL, iter);
	
EXIT:
	return success;
}
Exemplo n.º 6
0
static void *media_poll_func(void *)
{
	media_poll_loop = CFRunLoopGetCurrent();

	mach_port_t masterPort;
	kern_return_t kernResult = IOMasterPort(bootstrap_port, &masterPort);
	if (kernResult != KERN_SUCCESS) {
		fprintf(stderr, "IOMasterPort() returned %d\n", kernResult);
		return NULL;
	}

	CFMutableDictionaryRef matchingDictionary = IOServiceMatching(kIOCDMediaClass);
	if (matchingDictionary == NULL) {
		fprintf(stderr, "IOServiceMatching() returned a NULL dictionary\n");
		return NULL;
	}
	matchingDictionary = (CFMutableDictionaryRef)CFRetain(matchingDictionary);

	IONotificationPortRef notificationPort = IONotificationPortCreate(kIOMasterPortDefault);
	CFRunLoopAddSource(media_poll_loop,
					   IONotificationPortGetRunLoopSource(notificationPort),
					   kCFRunLoopDefaultMode);

	io_iterator_t mediaArrivedIterator;
	kernResult = IOServiceAddMatchingNotification(notificationPort,
												  kIOMatchedNotification,
												  matchingDictionary,
												  (IOServiceMatchingCallback)media_arrived,
												  (void *)MEDIA_CD, &mediaArrivedIterator);
	if (kernResult != KERN_SUCCESS)
		fprintf(stderr, "IOServiceAddMatchingNotification() returned %d\n", kernResult);
	media_arrived(MEDIA_CD, mediaArrivedIterator);

	io_iterator_t mediaRemovedIterator;
	kernResult = IOServiceAddMatchingNotification(notificationPort,
												  kIOTerminatedNotification,
												  matchingDictionary,
												  (IOServiceMatchingCallback)media_removed,
												  (void *)MEDIA_CD, &mediaRemovedIterator);
	if (kernResult != KERN_SUCCESS)
		fprintf(stderr, "IOServiceAddMatchingNotification() returned %d\n", kernResult);
	media_removed(MEDIA_CD, mediaRemovedIterator);

	CFRunLoopRun();
	return NULL;
}
Exemplo n.º 7
0
static int
InitUSB()
{
    CFMutableDictionaryRef  matchingDict;
    CFRunLoopSourceRef      runLoopSource;
    SInt32                  vendor, if_subclass, if_protocol;
    unsigned                i;

    //* To set up asynchronous notifications, create a notification port and
    //* add its run loop event source to the program's run loop
    notificationPort = IONotificationPortCreate(kIOMasterPortDefault);
    runLoopSource = IONotificationPortGetRunLoopSource(notificationPort);
    CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopDefaultMode);

    memset(notificationIterators, 0, sizeof(notificationIterators));

    //* loop through all supported vendors
    for (i = 0; i < vendorIdCount; i++) {
        //* Create our matching dictionary to find the Android device's
        //* adb interface
        //* IOServiceAddMatchingNotification consumes the reference, so we do
        //* not need to release this
        matchingDict = IOServiceMatching(kIOUSBInterfaceClassName);

        if (!matchingDict) {
            DBG("ERR: Couldn't create USB matching dictionary.\n");
            return -1;
        }

        //* Match based on vendor id, interface subclass and protocol
        vendor = vendorIds[i];
        if_subclass = ADB_SUBCLASS;
        if_protocol = ADB_PROTOCOL;
        CFDictionarySetValue(matchingDict, CFSTR(kUSBVendorID),
                             CFNumberCreate(kCFAllocatorDefault,
                                            kCFNumberSInt32Type, &vendor));
        CFDictionarySetValue(matchingDict, CFSTR(kUSBInterfaceSubClass),
                             CFNumberCreate(kCFAllocatorDefault,
                                            kCFNumberSInt32Type, &if_subclass));
        CFDictionarySetValue(matchingDict, CFSTR(kUSBInterfaceProtocol),
                             CFNumberCreate(kCFAllocatorDefault,
                                            kCFNumberSInt32Type, &if_protocol));
        IOServiceAddMatchingNotification(
                notificationPort,
                kIOFirstMatchNotification,
                matchingDict,
                AndroidInterfaceAdded,
                NULL,
                &notificationIterators[i]);

        //* Iterate over set of matching interfaces to access already-present
        //* devices and to arm the notification
        AndroidInterfaceAdded(NULL, notificationIterators[i]);
    }

    return 0;
}
Exemplo n.º 8
0
static void HPEstablishPCCardNotification(void)
{
	io_iterator_t deviceAddedIterator;
	io_iterator_t deviceRemovedIterator;
	CFMutableDictionaryRef matchingDictionary;
	IONotificationPortRef notificationPort;
	IOReturn kret;

	notificationPort = IONotificationPortCreate(kIOMasterPortDefault);
	CFRunLoopAddSource(CFRunLoopGetCurrent(),
		IONotificationPortGetRunLoopSource(notificationPort),
		kCFRunLoopDefaultMode);

	matchingDictionary = IOServiceMatching("IOPCCard16Device");
	if (!matchingDictionary)
	{
		Log1(PCSC_LOG_ERROR, "IOServiceMatching() failed");
	}
	matchingDictionary =
		(CFMutableDictionaryRef) CFRetain(matchingDictionary);

	kret = IOServiceAddMatchingNotification(notificationPort,
		kIOMatchedNotification,
		matchingDictionary, HPDeviceAppeared, NULL, &deviceAddedIterator);
	if (kret)
	{
		Log2(PCSC_LOG_ERROR,
			"IOServiceAddMatchingNotification()-1 failed with code %d", kret);
	}
	HPDeviceAppeared(NULL, deviceAddedIterator);

	kret = IOServiceAddMatchingNotification(notificationPort,
		kIOTerminatedNotification,
		matchingDictionary,
		HPDeviceDisappeared, NULL, &deviceRemovedIterator);
	if (kret)
	{
		Log2(PCSC_LOG_ERROR,
			"IOServiceAddMatchingNotification()-2 failed with code %d", kret);
	}
	HPDeviceDisappeared(NULL, deviceRemovedIterator);
}
Exemplo n.º 9
0
void InitUPSNotifications()
{
    CFMutableDictionaryRef 	matchingDict;
    CFMutableDictionaryRef	propertyDict;
    kern_return_t		kr;

    // Create a notification port and add its run loop event source to our run loop
    // This is how async notifications get set up.
    //
    gNotifyPort = IONotificationPortCreate(kIOMasterPortDefault);
    CFRunLoopAddSource(	CFRunLoopGetCurrent(), 
                        IONotificationPortGetRunLoopSource(gNotifyPort), 
                        kCFRunLoopDefaultMode);

    // Create the IOKit notifications that we need
    //
    matchingDict = IOServiceMatching(kIOServiceClass); 
    
    if (!matchingDict)
	return;    
        
    propertyDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 
                    0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);

    if (!propertyDict)
    {
        CFRelease(matchingDict);
	return;
    }
        
    // We are only interested in devices that have kIOUPSDeviceKey property set
    CFDictionarySetValue(propertyDict, CFSTR(kIOUPSDeviceKey), kCFBooleanTrue);
    
    CFDictionarySetValue(matchingDict, CFSTR(kIOPropertyMatchKey), propertyDict);
    
    CFRelease(propertyDict);


    // Now set up a notification to be called when a device is first matched by I/O Kit.
    // Note that this will not catch any devices that were already plugged in so we take
    // care of those later.
    kr = IOServiceAddMatchingNotification(gNotifyPort,			// notifyPort
                                          kIOFirstMatchNotification,	// notificationType
                                          matchingDict,			// matching
                                          UPSDeviceAdded,		// callback
                                          NULL,				// refCon
                                          &gAddedIter			// notification
                                          );

    if ( kr != kIOReturnSuccess )
        return;
        
    UPSDeviceAdded( NULL, gAddedIter );
}
Exemplo n.º 10
0
bool HIDDevice::setupDevicePluggedInNotification()
{
    
    // Setup notification when devices are plugged in.
    RepluggedNotificationPort = IONotificationPortCreate(kIOMasterPortDefault);
    
    CFRunLoopSourceRef notificationRunLoopSource =
        IONotificationPortGetRunLoopSource(RepluggedNotificationPort);
    
    CFRunLoopAddSource(HIDManager->getRunLoop(),
                       notificationRunLoopSource,
                       kCFRunLoopDefaultMode);
    
    CFMutableDictionaryRef matchingDict = IOServiceMatching(kIOUSBDeviceClassName);
    
    // Have to specify vendorId and productId. Doesn't seem to accept additional
    // things like serial number.
    SInt32 vendorId = DevDesc.VendorId;
    CFNumberRef numberRef = CFNumberCreate(kCFAllocatorDefault,
                                           kCFNumberSInt32Type,
                                           &vendorId);
    CFDictionarySetValue(matchingDict, CFSTR(kUSBVendorID), numberRef);
    CFRelease(numberRef);
    
    SInt32 deviceProductId = DevDesc.ProductId;
    numberRef = CFNumberCreate(kCFAllocatorDefault,
                               kCFNumberSInt32Type,
                               &deviceProductId);
    CFDictionarySetValue(matchingDict, CFSTR(kUSBProductID), numberRef);
    CFRelease(numberRef);
    
    kern_return_t result =
            IOServiceAddMatchingNotification(RepluggedNotificationPort,
                                             kIOMatchedNotification,
                                             matchingDict,
                                             staticDeviceAddedCallback,
                                             this,
                                             &RepluggedNotification);
    
    if (result != KERN_SUCCESS)
    {
        CFRelease(RepluggedNotificationPort);
        RepluggedNotificationPort = 0;
        return false;
    }
    
    // Iterate through to arm.
    while (IOIteratorNext(RepluggedNotification))
    {
	}
    
    return true;
}
Exemplo n.º 11
0
void InputHandler_MacOSX_HID::AddDevices( int usagePage, int usage, InputDevice &id )
{
	io_iterator_t iter;
	CFDictionaryRef dict = GetMatchingDictionary( usagePage, usage );
	kern_return_t ret = IOServiceAddMatchingNotification( m_NotifyPort, kIOFirstMatchNotification, dict,
						InputHandler_MacOSX_HID::DeviceAdded, this, &iter );
	io_object_t device;

	if( ret != KERN_SUCCESS )
		return;

	m_vIters.push_back( iter );

	// Iterate over the devices and add them
	while( (device = IOIteratorNext(iter)) )
	{
		LOG->Trace( "\tFound device %d", id );
		HIDDevice *dev = MakeDevice( id );
		int num;

		if( !dev )
		{
			LOG->Trace( "\t\tInvalid id, deleting device" );
			IOObjectRelease( device );
			continue;
		}

		if( !dev->Open(device) || (num = dev->AssignIDs(id)) == -1 )
		{
			LOG->Trace( "\tFailed top open or assign id, deleting device" );
			delete dev;
			IOObjectRelease( device );
			continue;
		}
		io_iterator_t i;

		enum_add( id, num );
		m_vDevices.push_back( dev );

		ret = IOServiceAddInterestNotification(
			m_NotifyPort, device, kIOGeneralInterest,
			InputHandler_MacOSX_HID::DeviceChanged,
			this, &i
		);

		if( ret == KERN_SUCCESS )
			m_vIters.push_back( i );
		else
			LOG->Trace( "\t\tFailed to add device changed notification, deleting device" );
		IOObjectRelease( device );
	}
}
Exemplo n.º 12
0
void IOKitEventPublisher::restart() {
  static std::vector<const std::string*> device_classes = {
      &kIOUSBDeviceClassName_,
      &kIOPCIDeviceClassName_,
      &kIOPlatformExpertDeviceClassName_,
      &kIOACPIPlatformDeviceClassName_,
      &kIOPlatformDeviceClassname_,
  };

  if (run_loop_ == nullptr) {
    return;
  }

  // Remove any existing stream.
  stop();

  {
    WriteLock lock(mutex_);
    port_ = IONotificationPortCreate(kIOMasterPortDefault);
    // Get a run loop source from the created IOKit notification port.
    auto run_loop_source = IONotificationPortGetRunLoopSource(port_);
    CFRunLoopAddSource(run_loop_, run_loop_source, kCFRunLoopDefaultMode);
  }

  publisher_started_ = false;
  for (const auto& class_name : device_classes) {
    // Service matching is USB for now, must find a way to get more!
    // Can provide a "IOPCIDevice" here too.
    auto matches = IOServiceMatching(class_name->c_str());

    // Register attach/detaches (could use kIOPublishNotification).
    // Notification types are defined in IOKitKeys.
    IOReturn result = kIOReturnSuccess + 1;
    {
      WriteLock lock(mutex_);
      result = IOServiceAddMatchingNotification(
          port_,
          kIOFirstMatchNotification,
          matches,
          (IOServiceMatchingCallback)deviceAttach,
          this,
          &iterator_);
    }
    if (result == kIOReturnSuccess) {
      deviceAttach(this, iterator_);
    }
  }
  publisher_started_ = true;
}
Exemplo n.º 13
0
void InitDetection() {
	kern_return_t kr;

	// Set up the matching criteria for the devices we're interested in. The matching criteria needs to follow
	// the same rules as kernel drivers: mainly it needs to follow the USB Common Class Specification, pp. 6-7.
	// See also Technical Q&A QA1076 "Tips on USB driver matching on Mac OS X"
	// <http://developer.apple.com/qa/qa2001/qa1076.html>.
	// One exception is that you can use the matching dictionary "as is", i.e. without adding any matching
	// criteria to it and it will match every IOUSBDevice in the system. IOServiceAddMatchingNotification will
	// consume this dictionary reference, so there is no need to release it later on.

	// Interested in instances of class
	// IOUSBDevice and its subclasses
	matchingDict = IOServiceMatching(kIOUSBDeviceClassName);

	if (matchingDict == NULL) {
		fprintf(stderr, "IOServiceMatching returned NULL.\n");
	}

	// Create a notification port and add its run loop event source to our run loop
	// This is how async notifications get set up.

	gNotifyPort = IONotificationPortCreate(kIOMasterPortDefault);

	// Now set up a notification to be called when a device is first matched by I/O Kit.
	kr = IOServiceAddMatchingNotification(
			gNotifyPort, // notifyPort
			kIOFirstMatchNotification, // notificationType
			matchingDict, // matching
			DeviceAdded, // callback
			NULL, // refCon
			&gAddedIter // notification
		);

	if (KERN_SUCCESS != kr) {
		printf("IOServiceAddMatchingNotification returned 0x%08x.\n", kr);
	}

	// Iterate once to get already-present devices and arm the notification
	DeviceAdded(NULL, gAddedIter);
	initialDeviceImport = false;
}
Exemplo n.º 14
0
static int
InitUSB()
{
    CFMutableDictionaryRef  matchingDict;
    CFRunLoopSourceRef      runLoopSource;

    //* To set up asynchronous notifications, create a notification port and
    //* add its run loop event source to the program's run loop
    notificationPort = IONotificationPortCreate(kIOMasterPortDefault);
    runLoopSource = IONotificationPortGetRunLoopSource(notificationPort);
    CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopDefaultMode);

    //* Create our matching dictionary to find the Android device's
    //* adb interface
    //* IOServiceAddMatchingNotification consumes the reference, so we do
    //* not need to release this
    matchingDict = IOServiceMatching(kIOUSBInterfaceClassName);

    if (!matchingDict) {
        DBG("ERR: Couldn't create USB matching dictionary.\n");
        return -1;
    }

    //* We have to get notifications for all potential candidates and test them
    //* at connection time because the matching rules don't allow for a
    //* USB interface class of 0xff for class+subclass+protocol matches
    //* See https://developer.apple.com/library/mac/qa/qa1076/_index.html
    IOServiceAddMatchingNotification(
            notificationPort,
            kIOFirstMatchNotification,
            matchingDict,
            AndroidInterfaceAdded,
            NULL,
            &notificationIterator);

    //* Iterate over set of matching interfaces to access already-present
    //* devices and to arm the notification
    AndroidInterfaceAdded(NULL, notificationIterator);

    return 0;
}
Exemplo n.º 15
0
CFStringRef copy_wifi_mac_address() {
    CFStringRef wifimac = NULL;
    IONotificationPortRef notify_port = 0;
    io_iterator_t iterator = 0;
    
    wifimac = lookup_mac_address("sdio");
    if (wifimac != NULL)
        return wifimac;

    wifimac = lookup_mac_address("wlan");
    if (wifimac != NULL)
        return wifimac;
    
    notify_port = IONotificationPortCreate(kIOMasterPortDefault);
    
    CFRunLoopSourceRef  runLoopSource = IONotificationPortGetRunLoopSource(notify_port);
    
    CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopDefaultMode);

    if (!IOServiceAddMatchingNotification( notify_port,
          kIOMatchedNotification,
          IOServiceMatching("IONetworkController"),
          (IOServiceMatchingCallback) search_wifi_mac_callback,
          &wifimac,
          &iterator
          ))
    {
        search_wifi_mac_callback((void**)&wifimac, iterator);
        while( wifimac == NULL)
        {
            if( CFRunLoopRunInMode(kCFRunLoopDefaultMode,0, TRUE) != kCFRunLoopRunHandledSource)
            {
                printf("giving up on wifi mac address\n");
                break;
            }
        }
    }
    IONotificationPortDestroy(notify_port);
    return wifimac;
}
Exemplo n.º 16
0
void find_device () {
    CFMutableDictionaryRef matchingDict;
    CFNumberRef refUsage;
    CFNumberRef refUsagePageKey;
    SInt32 usage = 1;        /* mouse */
    SInt32 usagePageKey = 2; /* mouse */
    mach_port_t	masterPort;
    kern_return_t kr;

    kr = IOMasterPort (bootstrap_port, &masterPort);
    if (kr || !masterPort) {
        return;
    }

    gNotifyPort = IONotificationPortCreate (masterPort);
    CFRunLoopAddSource (CFRunLoopGetCurrent (), IONotificationPortGetRunLoopSource (gNotifyPort), kCFRunLoopDefaultMode);

    matchingDict = IOServiceMatching ("IOHIDDevice");

    if (!matchingDict) {
        return;
    }

    refUsage = CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &usage);
    refUsagePageKey = CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &usagePageKey);

    CFDictionarySetValue (matchingDict, CFSTR (kIOHIDPrimaryUsageKey), refUsagePageKey);
    CFDictionarySetValue (matchingDict, CFSTR (kIOHIDPrimaryUsagePageKey), refUsage);

    CFRelease (refUsage);
    CFRelease (refUsagePageKey);

    kr = IOServiceAddMatchingNotification (gNotifyPort, kIOFirstMatchNotification, matchingDict, init_device, NULL, &gAddedIter);

    if (kr != kIOReturnSuccess) {
        return;
    }

    init_device (NULL, gAddedIter);
}
Exemplo n.º 17
0
//================================================================================================
//	main
//================================================================================================
//
int main (int argc, const char *argv[])
{
    mach_port_t 		masterPort;
    CFMutableDictionaryRef 	matchingDict;
    CFRunLoopSourceRef		runLoopSource;
    CFNumberRef			numberRef;
    CFStringRef         stringRef;
    kern_return_t		kr;
    long			usbVendor = kMyVendorID;
    sig_t			oldHandler;

    // pick up command line arguments
    //
    if (argc > 1)
        usbVendor = atoi(argv[1]);

    // Set up a signal handler so we can clean up when we're interrupted from the command line
    // Otherwise we stay in our run loop forever.
    //
    oldHandler = signal(SIGINT, SignalHandler);
    if (oldHandler == SIG_ERR)
        printf("Could not establish new signal handler");

    // first create a master_port for my task
    //
    kr = IOMasterPort(MACH_PORT_NULL, &masterPort);
    if (kr || !masterPort)
    {
        printf("ERR: Couldn't create a master IOKit Port(%08x)\n", kr);
        return -1;
    }

    printf("Looking for devices matching vendor ID=%ld\n", usbVendor);

    // Set up the matching criteria for the devices we're interested in.  The matching criteria needs to follow
    // the same rules as kernel drivers:  mainly it needs to follow the USB Common Class Specification, pp. 6-7.
    // See also http://developer.apple.com/qa/qa2001/qa1076.html
    // One exception is that you can use the matching dictionary "as is", i.e. without adding any matching criteria
    // to it and it will match every IOUSBDevice in the system.  IOServiceAddMatchingNotification will consume this
    // dictionary reference, so there is no need to release it later on.
    //
    matchingDict = IOServiceMatching(kIOUSBDeviceClassName);	// Interested in instances of class
    // IOUSBDevice and its subclasses
    if (!matchingDict)
    {
        printf("Can't create a USB matching dictionary\n");
        mach_port_deallocate(mach_task_self(), masterPort);
        return -1;
    }

    // We are interested in all USB Devices (as opposed to USB interfaces).  The Common Class Specification
    // tells us that we need to specify the idVendor, idProduct, and bcdDevice fields, or, if we're not interested
    // in particular bcdDevices, just the idVendor and idProduct.  Note that if we were trying to match an IOUSBInterface,
    // we would need to set more values in the matching dictionary (e.g. idVendor, idProduct, bInterfaceNumber and
    // bConfigurationValue.
    //

    // Create a CFNumber for the idVendor and set the value in the dictionary
    //
    numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &usbVendor);
    CFDictionarySetValue(
        matchingDict,
        CFSTR(kUSBVendorID),
        numberRef);
    CFRelease(numberRef);
    numberRef = 0;

    // Create a CFString for the wildcard product ID and set the value in the dictionary
    //
    stringRef = CFSTR("*");
    CFDictionarySetValue(
        matchingDict,
        CFSTR(kUSBProductID),
        stringRef);
    CFRelease(stringRef);
    stringRef = 0;

    // Create a notification port and add its run loop event source to our run loop
    // This is how async notifications get set up.
    //
    gNotifyPort = IONotificationPortCreate(masterPort);
    runLoopSource = IONotificationPortGetRunLoopSource(gNotifyPort);

    gRunLoop = CFRunLoopGetCurrent();
    CFRunLoopAddSource(gRunLoop, runLoopSource, kCFRunLoopDefaultMode);

    // Now set up a notification to be called when a device is first matched by I/O Kit.
    // Note that this will not catch any devices that were already plugged in so we take
    // care of those later.
    //
    kr = IOServiceAddMatchingNotification(gNotifyPort,			// notifyPort
                                          kIOFirstMatchNotification,	// notificationType
                                          matchingDict,			// matching
                                          DeviceAdded,			// callback
                                          NULL,				// refCon
                                          &gAddedIter			// notification
                                         );

    // Iterate once to get already-present devices and arm the notification
    //
    DeviceAdded(NULL, gAddedIter);

    // Now done with the master_port
    mach_port_deallocate(mach_task_self(), masterPort);
    masterPort = 0;

    // Start the run loop. Now we'll receive notifications.
    //
    printf("Starting run loop.\n");
    CFRunLoopRun();

    // We should never get here
    //
    printf("Unexpectedly back from CFRunLoopRun()!\n");

    return 0;
}
Exemplo n.º 18
0
void HPMPrivate::run()
{
    mach_port_t masterPort = 0;
    IONotificationPortRef notifyPort = 0;
    io_iterator_t rawAddedIter = 0;
    io_iterator_t rawRemovedIter = 0;

    // Create an IOMasterPort for accessing IOKit
    kern_return_t kr = IOMasterPort(MACH_PORT_NULL, &masterPort);
    if (kr || !masterPort)
    {
        qWarning() << Q_FUNC_INFO << "Unable to create a master I/O Kit port" << (void*) kr;
        return;
    }

    // Create a new dictionary for matching device classes
    CFMutableDictionaryRef matchingDict = IOServiceMatching(kIOUSBDeviceClassName);
    if (!matchingDict)
    {
        qWarning() << Q_FUNC_INFO << "Unable to create a USB matching dictionary";
        mach_port_deallocate(mach_task_self(), masterPort);
        return;
    }

    // Take an extra reference because IOServiceAddMatchingNotification consumes one
    matchingDict = (CFMutableDictionaryRef) CFRetain(matchingDict);

    // Store the thread's run loop context
    loop = CFRunLoopGetCurrent();
    // New notification port
    notifyPort = IONotificationPortCreate(masterPort);

    CFRunLoopSourceRef runLoopSource = IONotificationPortGetRunLoopSource(notifyPort);
    CFRunLoopAddSource(loop, runLoopSource, kCFRunLoopDefaultMode);

    // Listen to device add notifications
    kr = IOServiceAddMatchingNotification(notifyPort,
                                          kIOFirstMatchNotification,
                                          matchingDict,
                                          onHPMPrivateRawDeviceAdded,
                                          (void*) this,
                                          &rawAddedIter);
    if (kr != kIOReturnSuccess)
        qFatal("Unable to add notification for device additions");

    // Iterate over set of matching devices to access already-present devices
    // and to arm the notification.
    onHPMPrivateRawDeviceAdded(this, rawAddedIter);

    // Listen to device removal notifications
    kr = IOServiceAddMatchingNotification(notifyPort,
                                          kIOTerminatedNotification,
                                          matchingDict,
                                          onHPMPrivateRawDeviceRemoved,
                                          (void*) this,
                                          &rawRemovedIter);
    if (kr != kIOReturnSuccess)
        qFatal("Unable to add notification for device termination");

    // Iterate over set of matching devices to release each one and to
    // arm the notification.
    onHPMPrivateRawDeviceRemoved(this, rawRemovedIter);

    // No longer needed
    mach_port_deallocate(mach_task_self(), masterPort);
    masterPort = 0;

    // Start the run loop inside this thread. The thread "stops" here.
    CFRunLoopRun();

    // Destroy the notification port when the thread exits
    IONotificationPortDestroy(notifyPort);
    notifyPort = 0;
}
Exemplo n.º 19
0
io_connect_t ks_connect_to_service(const char *className)
{
	kern_return_t kernResult;
    io_connect_t connect = IO_OBJECT_NULL;
	io_iterator_t iterator = IO_OBJECT_NULL;
    IONotificationPortRef notifyport = NULL;
	CFDictionaryRef	classToMatch;

	if ((classToMatch = IOServiceMatching(className)) == NULL) {
		asl_log(NULL, NULL, ASL_LEVEL_ERR,
            "IOServiceMatching failed for '%s'", className);
		return connect;
	}

    /* consumed by IOServiceGetMatchingServices, we need it if that fails. */
    CFRetain(classToMatch);
    kernResult = IOServiceGetMatchingServices(kIOMasterPortDefault,
        classToMatch, &iterator);

    if (kernResult == KERN_SUCCESS) {
        CFRelease(classToMatch);
    } else {
        asl_log(NULL, NULL, ASL_LEVEL_WARNING,
            "IOServiceGetMatchingServices() failed %d", kernResult);

        notifyport = IONotificationPortCreate(kIOMasterPortDefault);
        if (!notifyport) {
            asl_log(NULL, NULL, ASL_LEVEL_ERR,
                "IONotificationPortCreate() failed");
            return connect;
        }

        kernResult = IOServiceAddMatchingNotification(notifyport,
            kIOFirstMatchNotification, classToMatch,
            ks_service_matching_callback, &connect, &iterator);
        if (kernResult) {
            asl_log(NULL, NULL, ASL_LEVEL_ERR,
                "IOServiceAddMatchingNotification() failed: %d", kernResult);
            return connect;
        }
    }

    /* Check whether it was already there before we registered for the
       notification. */
    ks_service_matching_callback(&connect, iterator);

    if (notifyport) {
        /* We'll get set up to wait for it to appear */
        if (connect == IO_OBJECT_NULL) {
            asl_log(NULL, NULL, ASL_LEVEL_ERR,
                "Waiting for %s to show up.", className);
            CFStringRef mode = CFSTR("WaitForCryptoService");
            CFRunLoopAddSource(CFRunLoopGetCurrent(),
                IONotificationPortGetRunLoopSource(notifyport), mode);
            CFRunLoopRunInMode(mode, 30.0, true);
            if (connect == MACH_PORT_NULL)
                asl_log(NULL, NULL, ASL_LEVEL_ERR, "Cannot find %s", className);
        }
        IONotificationPortDestroy(notifyport);
    }

    IOObjectRelease(iterator);

    if (connect != IO_OBJECT_NULL) {
        secdebug("iokit", "obtained connection for '%s'", className);
    }
    return connect;
}
Exemplo n.º 20
0
int main(int argc, const char *argv[])
{
    time_t current_time = time(NULL);
    char* c_time_string = ctime(&current_time);
    size_t l = strlen(c_time_string);
    if (l > 0)
        c_time_string[l-1] = 0;
    DEBUG_LOG("%s: VoodooPS2Daemon 1.7.12 starting...\n", c_time_string);

    // first check for trackpad driver
	g_ioservice = IOServiceGetMatchingService(0, IOServiceMatching("ApplePS2SynapticsTouchPad"));
	if (!g_ioservice)
	{
        // otherwise, talk to mouse driver
        g_ioservice = IOServiceGetMatchingService(0, IOServiceMatching("ApplePS2Mouse"));
        if (!g_ioservice)
        {
            DEBUG_LOG("No ApplePS2SynapticsTouchPad or ApplePS2Mouse found\n");
            return -1;
        }
	}
    
    // Set up a signal handler so we can clean up when we're interrupted from the command line
    // or otherwise asked to terminate.
    if (SIG_ERR == signal(SIGINT, SignalHandler1))
        DEBUG_LOG("Could not establish new SIGINT handler\n");
    if (SIG_ERR == signal(SIGTERM, SignalHandler1))
        DEBUG_LOG("Could not establish new SIGTERM handler\n");
    
    // First create a master_port for my task
    mach_port_t masterPort;
    kern_return_t kr = IOMasterPort(MACH_PORT_NULL, &masterPort);
    if (kr || !masterPort)
    {
        DEBUG_LOG("ERR: Couldn't create a master IOKit Port(%08x)\n", kr);
        return -1;
    }
    
    // Create dictionary to match all USB devices
    CFMutableDictionaryRef matchingDict = IOServiceMatching(kIOUSBDeviceClassName);
    if (!matchingDict)
    {
        DEBUG_LOG("Can't create a USB matching dictionary\n");
        mach_port_deallocate(mach_task_self(), masterPort);
        return -1;
    }
    
    // Create a notification port and add its run loop event source to our run loop
    // This is how async notifications get set up.
    g_NotifyPort = IONotificationPortCreate(masterPort);
    CFRunLoopSourceRef runLoopSource = IONotificationPortGetRunLoopSource(g_NotifyPort);
    CFRunLoopRef runLoop = CFRunLoopGetCurrent();
    CFRunLoopAddSource(runLoop, runLoopSource, kCFRunLoopDefaultMode);
    
    // Now set up a notification to be called when a device is first matched by I/O Kit.
    // Note that this will not catch any devices that were already plugged in so we take
    // care of those later.
    kr = IOServiceAddMatchingNotification(g_NotifyPort, kIOFirstMatchNotification, matchingDict, DeviceAdded, NULL, &g_AddedIter);
    
    // Iterate once to get already-present devices and arm the notification
    DeviceAdded(NULL, g_AddedIter);
    
    // Now done with the master_port
    mach_port_deallocate(mach_task_self(), masterPort);
    masterPort = 0;
    
    // Start the run loop. Now we'll receive notifications.
    CFRunLoopRun();
    
    // We should never get here
    DEBUG_LOG("Unexpectedly back from CFRunLoopRun()!\n");
    
    return 0;
}
Exemplo n.º 21
0
/* Function to scan the system for joysticks.
 * Joystick 0 should be the system default joystick.
 * This function should return the number of available joysticks, or -1
 * on an unrecoverable fatal error.
 */
int
SDL_SYS_JoystickInit(void)
{
    IOReturn result = kIOReturnSuccess;
    mach_port_t masterPort = 0;
    io_iterator_t hidObjectIterator = 0;
    CFMutableDictionaryRef hidMatchDictionary = NULL;
    io_object_t ioHIDDeviceObject = 0;
	io_iterator_t portIterator = 0;

    if (gpDeviceList) {
        SDL_SetError("Joystick: Device list already inited.");
        return -1;
    }

    result = IOMasterPort(bootstrap_port, &masterPort);
    if (kIOReturnSuccess != result) {
        SDL_SetError("Joystick: IOMasterPort error with bootstrap_port.");
        return -1;
    }

    /* Set up a matching dictionary to search I/O Registry by class name for all HID class devices. */
    hidMatchDictionary = IOServiceMatching(kIOHIDDeviceKey);
    if (hidMatchDictionary) {
        /* Add key for device type (joystick, in this case) to refine the matching dictionary. */

        /* NOTE: we now perform this filtering later
           UInt32 usagePage = kHIDPage_GenericDesktop;
           UInt32 usage = kHIDUsage_GD_Joystick;
           CFNumberRef refUsage = NULL, refUsagePage = NULL;

           refUsage = CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &usage);
           CFDictionarySetValue (hidMatchDictionary, CFSTR (kIOHIDPrimaryUsageKey), refUsage);
           refUsagePage = CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &usagePage);
           CFDictionarySetValue (hidMatchDictionary, CFSTR (kIOHIDPrimaryUsagePageKey), refUsagePage);
         */
    } else {
        SDL_SetError
            ("Joystick: Failed to get HID CFMutableDictionaryRef via IOServiceMatching.");
        return -1;
    }

    /*/ Now search I/O Registry for matching devices. */
    result =
        IOServiceGetMatchingServices(masterPort, hidMatchDictionary,
                                     &hidObjectIterator);
    /* Check for errors */
    if (kIOReturnSuccess != result) {
        SDL_SetError("Joystick: Couldn't create a HID object iterator.");
        return -1;
    }
    if (!hidObjectIterator) {   /* there are no joysticks */
        gpDeviceList = NULL;
        return 0;
    }
    /* IOServiceGetMatchingServices consumes a reference to the dictionary, so we don't need to release the dictionary ref. */

    /* build flat linked list of devices from device iterator */

    gpDeviceList = NULL;

    while ((ioHIDDeviceObject = IOIteratorNext(hidObjectIterator))) {
		AddDeviceHelper( ioHIDDeviceObject );
    }
    result = IOObjectRelease(hidObjectIterator);        /* release the iterator */
	
	/* now connect notification for new devices */
	notificationPort = IONotificationPortCreate(masterPort);
	hidMatchDictionary = IOServiceMatching(kIOHIDDeviceKey);

	CFRunLoopAddSource(CFRunLoopGetCurrent(), 
					   IONotificationPortGetRunLoopSource(notificationPort), 
					   kCFRunLoopDefaultMode);
	
	// Register for notifications when a serial port is added to the system
	result = IOServiceAddMatchingNotification(notificationPort,
															kIOFirstMatchNotification,
															hidMatchDictionary,
															JoystickDeviceWasAddedCallback,
															NULL,           
															&portIterator);
	while (IOIteratorNext(portIterator)) {}; // Run out the iterator or notifications won't start (you can also use it to iterate the available devices).

    return SDL_SYS_NumJoysticks();
}
Exemplo n.º 22
0
int main (int argc, const char *argv[])
{
    mach_port_t 		masterPort;
    CFMutableDictionaryRef 	matchingDict;
    CFRunLoopSourceRef		runLoopSource;
    kern_return_t		kr;
    SInt32			usbVendor = kOurVendorID;
    SInt32			usbProduct = kOurProductID;
    sig_t			oldHandler;
    
    // pick up command line arguments
    if (argc > 1)
        usbVendor = atoi(argv[1]);
    if (argc > 2)
        usbProduct = atoi(argv[2]);

    // Set up a signal handler so we can clean up when we're interrupted from the command line
    // Otherwise we stay in our run loop forever.
    oldHandler = signal(SIGINT, SignalHandler);
    if (oldHandler == SIG_ERR)
        printf("Could not establish new signal handler");
        
    // first create a master_port for my task
    kr = IOMasterPort(MACH_PORT_NULL, &masterPort);
    if (kr || !masterPort)
    {
        printf("ERR: Couldn't create a master IOKit Port(%08x)\n", kr);
        return -1;
    }

    printf("Looking for devices matching vendor ID=%ld and product ID=%ld\n", usbVendor, usbProduct);

    // Set up the matching criteria for the devices we're interested in
    matchingDict = IOServiceMatching(kIOUSBDeviceClassName);	// Interested in instances of class IOUSBDevice and its subclasses
    if (!matchingDict)
    {
        printf("Can't create a USB matching dictionary\n");
        mach_port_deallocate(mach_task_self(), masterPort);
        return -1;
    }
    
    // Add our vendor and product IDs to the matching criteria
    CFDictionarySetValue( 
            matchingDict, 
            CFSTR(kUSBVendorID), 
            CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &usbVendor)); 
    CFDictionarySetValue( 
            matchingDict, 
            CFSTR(kUSBProductID), 
            CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &usbProduct)); 

    // Create a notification port and add its run loop event source to our run loop
    // This is how async notifications get set up.
    gNotifyPort = IONotificationPortCreate(masterPort);
    runLoopSource = IONotificationPortGetRunLoopSource(gNotifyPort);
    
    CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopDefaultMode);
    
    // Retain additional references because we use this same dictionary with four calls to 
    // IOServiceAddMatchingNotification, each of which consumes one reference.
    matchingDict = (CFMutableDictionaryRef) CFRetain( matchingDict ); 
    matchingDict = (CFMutableDictionaryRef) CFRetain( matchingDict ); 
    matchingDict = (CFMutableDictionaryRef) CFRetain( matchingDict ); 
    
    // Now set up two notifications, one to be called when a raw device is first matched by I/O Kit, and the other to be
    // called when the device is terminated.
    kr = IOServiceAddMatchingNotification(  gNotifyPort,
                                            kIOFirstMatchNotification,
                                            matchingDict,
                                            RawDeviceAdded,
                                            NULL,
                                            &gRawAddedIter );
                                            
    RawDeviceAdded(NULL, gRawAddedIter);	// Iterate once to get already-present devices and
                                                // arm the notification

    kr = IOServiceAddMatchingNotification(  gNotifyPort,
                                            kIOTerminatedNotification,
                                            matchingDict,
                                            RawDeviceRemoved,
                                            NULL,
                                            &gRawRemovedIter );
                                            
    RawDeviceRemoved(NULL, gRawRemovedIter);	// Iterate once to arm the notification
    
    // Change the USB product ID in our matching dictionary to the one the device will have once the
    // bulktest firmware has been downloaded.
    usbProduct = kOurProductIDBulkTest;
    
    CFDictionarySetValue( 
            matchingDict, 
            CFSTR(kUSBProductID), 
            CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &usbProduct)); 

    // Now set up two more notifications, one to be called when a bulk test device is first matched by I/O Kit, and the other to be
    // called when the device is terminated.
    kr = IOServiceAddMatchingNotification(  gNotifyPort,
                                            kIOFirstMatchNotification,
                                            matchingDict,
                                            BulkTestDeviceAdded,
                                            NULL,
                                            &gBulkTestAddedIter );
                                            
    BulkTestDeviceAdded(NULL, gBulkTestAddedIter);	// Iterate once to get already-present devices and
                                                        // arm the notification

    kr = IOServiceAddMatchingNotification(  gNotifyPort,
                                            kIOTerminatedNotification,
                                            matchingDict,
                                            BulkTestDeviceRemoved,
                                            NULL,
                                            &gBulkTestRemovedIter );
                                            
    BulkTestDeviceRemoved(NULL, gBulkTestRemovedIter); 	// Iterate once to arm the notification

    // Now done with the master_port
    mach_port_deallocate(mach_task_self(), masterPort);
    masterPort = 0;

    // Start the run loop. Now we'll receive notifications.
    CFRunLoopRun();
        
    // We should never get here
    return 0;
}
Exemplo n.º 23
0
//================================================================================================
//  main
//================================================================================================
int main(int argc, const char *argv[])
{
    CFMutableDictionaryRef  matchingDict;
    CFRunLoopSourceRef      runLoopSource;
    CFNumberRef             numberRef;
    kern_return_t           kr;
    long                    usbVendor = kMyVendorID;
    long                    usbProduct = kMyProductID;
    sig_t                   oldHandler;
    
    // pick up command line arguments
    if (argc > 1) {
        usbVendor = atoi(argv[1]);
    }
    if (argc > 2) {
        usbProduct = atoi(argv[2]);
    }
    
    // Set up a signal handler so we can clean up when we're interrupted from the command line
    // Otherwise we stay in our run loop forever.
    oldHandler = signal(SIGINT, SignalHandler);
    if (oldHandler == SIG_ERR) {
        fprintf(stderr, "Could not establish new signal handler.");
    }
    
    fprintf(stderr, "Looking for devices matching vendor ID=%ld and product ID=%ld.\n", usbVendor, usbProduct);
    
    // Set up the matching criteria for the devices we're interested in. The matching criteria needs to follow
    // the same rules as kernel drivers: mainly it needs to follow the USB Common Class Specification, pp. 6-7.
    // See also Technical Q&A QA1076 "Tips on USB driver matching on Mac OS X" 
    // <http://developer.apple.com/qa/qa2001/qa1076.html>.
    // One exception is that you can use the matching dictionary "as is", i.e. without adding any matching 
    // criteria to it and it will match every IOUSBDevice in the system. IOServiceAddMatchingNotification will 
    // consume this dictionary reference, so there is no need to release it later on.
    
    matchingDict = IOServiceMatching(kIOUSBDeviceClassName);    // Interested in instances of class
    // IOUSBDevice and its subclasses
    if (matchingDict == NULL) {
        fprintf(stderr, "IOServiceMatching returned NULL.\n");
        return -1;
    }
    
    // We are interested in all USB devices (as opposed to USB interfaces).  The Common Class Specification
    // tells us that we need to specify the idVendor, idProduct, and bcdDevice fields, or, if we're not interested
    // in particular bcdDevices, just the idVendor and idProduct.  Note that if we were trying to match an 
    // IOUSBInterface, we would need to set more values in the matching dictionary (e.g. idVendor, idProduct, 
    // bInterfaceNumber and bConfigurationValue.
    
    // Create a CFNumber for the idVendor and set the value in the dictionary
    numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &usbVendor);
    CFDictionarySetValue(matchingDict, 
                         CFSTR(kUSBVendorID), 
                         numberRef);
    CFRelease(numberRef);
    
    // Create a CFNumber for the idProduct and set the value in the dictionary
    numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &usbProduct);
    CFDictionarySetValue(matchingDict, 
                         CFSTR(kUSBProductID), 
                         numberRef);
    CFRelease(numberRef);
    numberRef = NULL;
    
    // Create a notification port and add its run loop event source to our run loop
    // This is how async notifications get set up.
    
    gNotifyPort = IONotificationPortCreate(kIOMasterPortDefault);
    runLoopSource = IONotificationPortGetRunLoopSource(gNotifyPort);
    
    gRunLoop = CFRunLoopGetCurrent();
    CFRunLoopAddSource(gRunLoop, runLoopSource, kCFRunLoopDefaultMode);
    
    // Now set up a notification to be called when a device is first matched by I/O Kit.
    kr = IOServiceAddMatchingNotification(gNotifyPort,                  // notifyPort
                                          kIOFirstMatchNotification,    // notificationType
                                          matchingDict,                 // matching
                                          DeviceAdded,                  // callback
                                          NULL,                         // refCon
                                          &gAddedIter                   // notification
                                          );        
    
    // Iterate once to get already-present devices and arm the notification    
    DeviceAdded(NULL, gAddedIter);  
    
    // Start the run loop. Now we'll receive notifications.
    fprintf(stderr, "Starting run loop.\n\n");
    CFRunLoopRun();
    
    // We should never get here
    fprintf(stderr, "Unexpectedly back from CFRunLoopRun()!\n");
    return 0;
}
/*
  Create matching dictionaries for the devices we want to get notifications for,
  and add them to the current run loop.  Invoke the callbacks that will be responding
  to these notifications once to arm them, and discover any devices that
  are currently connected at the time notifications are setup.
*/
void QextSerialEnumerator::setUpNotificationOSX( )
{
    kern_return_t kernResult;
    mach_port_t masterPort;
    CFRunLoopSourceRef notificationRunLoopSource;
    CFMutableDictionaryRef classesToMatch;
    CFMutableDictionaryRef cdcClassesToMatch;
    io_iterator_t portIterator;

    kernResult = IOMasterPort(MACH_PORT_NULL, &masterPort);
    if (KERN_SUCCESS != kernResult) {
        qDebug() << "IOMasterPort returned:" << kernResult;
        return;
    }

    classesToMatch = IOServiceMatching(kIOSerialBSDServiceValue);
    if (classesToMatch == NULL)
        qDebug("IOServiceMatching returned a NULL dictionary.");
    else
        CFDictionarySetValue(classesToMatch, CFSTR(kIOSerialBSDTypeKey), CFSTR(kIOSerialBSDAllTypes));

    if( !(cdcClassesToMatch = IOServiceNameMatching("AppleUSBCDC") ) ) {
        qWarning("couldn't create cdc matching dict");
        return;
    }

    // Retain an additional reference since each call to IOServiceAddMatchingNotification consumes one.
    classesToMatch = (CFMutableDictionaryRef) CFRetain(classesToMatch);
    cdcClassesToMatch = (CFMutableDictionaryRef) CFRetain(cdcClassesToMatch);

    notificationPortRef = IONotificationPortCreate(masterPort);
    if(notificationPortRef == NULL) {
        qDebug("IONotificationPortCreate return a NULL IONotificationPortRef.");
        return;
    }

    notificationRunLoopSource = IONotificationPortGetRunLoopSource(notificationPortRef);
    if (notificationRunLoopSource == NULL) {
        qDebug("IONotificationPortGetRunLoopSource returned NULL CFRunLoopSourceRef.");
        return;
    }

    CFRunLoopAddSource(CFRunLoopGetCurrent(), notificationRunLoopSource, kCFRunLoopDefaultMode);

    kernResult = IOServiceAddMatchingNotification(notificationPortRef, kIOMatchedNotification, classesToMatch,
                                                  deviceDiscoveredCallbackOSX, this, &portIterator);
    if (kernResult != KERN_SUCCESS) {
        qDebug() << "IOServiceAddMatchingNotification return:" << kernResult;
        return;
    }

    // arm the callback, and grab any devices that are already connected
    deviceDiscoveredCallbackOSX( this, portIterator );

    kernResult = IOServiceAddMatchingNotification(notificationPortRef, kIOMatchedNotification, cdcClassesToMatch,
                                                  deviceDiscoveredCallbackOSX, this, &portIterator);
    if (kernResult != KERN_SUCCESS) {
        qDebug() << "IOServiceAddMatchingNotification return:" << kernResult;
        return;
    }

    // arm the callback, and grab any devices that are already connected
    deviceDiscoveredCallbackOSX( this, portIterator );

    kernResult = IOServiceAddMatchingNotification(notificationPortRef, kIOTerminatedNotification, classesToMatch,
                                                  deviceTerminatedCallbackOSX, this, &portIterator);
    if (kernResult != KERN_SUCCESS) {
        qDebug() << "IOServiceAddMatchingNotification return:" << kernResult;
        return;
    }

    // arm the callback, and clear any devices that are terminated
    deviceTerminatedCallbackOSX( this, portIterator );

    kernResult = IOServiceAddMatchingNotification(notificationPortRef, kIOTerminatedNotification, cdcClassesToMatch,
                                                  deviceTerminatedCallbackOSX, this, &portIterator);
    if (kernResult != KERN_SUCCESS) {
        qDebug() << "IOServiceAddMatchingNotification return:" << kernResult;
        return;
    }

    // arm the callback, and clear any devices that are terminated
    deviceTerminatedCallbackOSX( this, portIterator );
}
Exemplo n.º 25
0
int main (int argc, const char *argv[])
{
    mach_port_t                 masterPort;
    CFMutableDictionaryRef      matchingDict;
    CFRunLoopSourceRef          runLoopSource;
    kern_return_t               kr;
    SInt32                      usbVendor = kOurVendorID;
    SInt32                      usbProduct = kOurProductID;
    
    kr = IOMasterPort(MACH_PORT_NULL, &masterPort);

    if (kr || !masterPort)
    {
        printf("ERR: Couldn't create a master I/O Kit port(%08x)\n", kr);
        return -1;
    }

    // Setup matching dictionary for class IOUSBDevice and its subclasses

    matchingDict = IOServiceMatching(kIOUSBDeviceClassName);

    if (!matchingDict)
    {

        printf("couldn't craete a usb matching dictionary :(\n");

        mach_port_deallocate(mach_task_self(), masterPort);

        return -1;
    }

    // add vendor and product Ids to dict

    CFDictionarySetValue(matchingDict, CFSTR(kUSBVendorName),
                            CFNumberCreate(kCFAllocatorDefault,
                                        kCFNumberSInt32Type, &usbVendor));

    CFDictionarySetValue(matchingDict, CFSTR(kUSBProductName),
                            CFNumberCreate(kCFAllocatorDefault,
                                        kCFNumberSInt32Type, &usbProduct));

    gNotifyPort = IONotificationPortCreate(masterPort);
    runLoopSource = IONotificationPortGetRunLoopSource(gNotifyPort);
    CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource,
                    kCFRunLoopDefaultMode);

    //Now set up two notifications: one to be called when a raw device
    //is first matched by the I/O Kit and another to be called when the
    //device is terminated
    //Notification of first match:
    kr = IOServiceAddMatchingNotification(gNotifyPort,
                    kIOFirstMatchNotification, matchingDict,
                    RawDeviceAdded, NULL, &gRawAddedIter);
    //Iterate over set of matching devices to access already-present devices
    //and to arm the notification
    RawDeviceAdded(NULL, gRawAddedIter);


/* 
    //Notification of termination:
    kr = IOServiceAddMatchingNotification(gNotifyPort,
                    kIOTerminatedNotification, matchingDict,
                    RawDeviceRemoved, NULL, &gRawRemovedIter);
    //Iterate over set of matching devices to release each one and to
    //arm the notification
    RawDeviceRemoved(NULL, gRawRemovedIter);
*/
    mach_port_deallocate(mach_task_self(), masterPort);
    masterPort = 0;

    CFRunLoopRun();

    return 0;
}