Какао: обнаружение USB-устройств по идентификатору производителя

Я пишу инструмент Foundation для Mac и пытаюсь определить, когда устройства Apple подключены и отключены через USB. Я нашел некоторую помощь в этот пост вместе с USBPrivateDataSample - но, похоже, будет работать, только если я предоставлю и идентификатор поставщика, и идентификатор продукта. Я хотел бы удалить идентификатор продукта и обнаружить все события USB на устройствах Apple (идентификатор производителя 1452). Любая помощь здесь?

Вот мой код, который не обнаруживает никаких устройств:

 #include <CoreFoundation/CoreFoundation.h>

#include <IOKit/IOKitLib.h>
#include <IOKit/IOMessage.h>
#include <IOKit/IOCFPlugIn.h>
#include <IOKit/usb/IOUSBLib.h>

#define kMyVendorID 1452

int list_devices(void);

int list_devices(void){
    CFMutableDictionaryRef matchingDict;
    io_iterator_t iter;
    kern_return_t kr;
    io_service_t device;
    CFNumberRef numberRef;
    long usbVendor = kMyVendorID;

    /* set up a matching dictionary for the class */
    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);
    numberRef = NULL;    


    /* Now we have a dictionary, get an iterator.*/
    kr = IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, &iter);
    if (kr != KERN_SUCCESS)
        return -1;

    /* iterate */
    while ((device = IOIteratorNext(iter)))
    {
        io_name_t       deviceName;
        CFStringRef     deviceNameAsCFString;   

        /* do something with device, eg. check properties */
        /* ... */
        /* And free the reference taken before continuing to the next item */

        // Get the USB device's name.
        kr = IORegistryEntryGetName(device, deviceName);
        if (KERN_SUCCESS != kr) {
            deviceName[0] = '\0';
        }

        deviceNameAsCFString = CFStringCreateWithCString(kCFAllocatorDefault, deviceName, 
                                                         kCFStringEncodingASCII);

        // Dump our data to stderr just to see what it looks like.
        fprintf(stderr, "deviceName: ");
        CFShow(deviceNameAsCFString);

        IOObjectRelease(device);
    }

    /* Done, release the iterator */
    IOObjectRelease(iter);

    return 1;
}

int main(int argc, char* argv[])
{
    while(1){
        list_devices();
        sleep(1);
    }
    return 0;
}

Примечание: если я добавлю идентификатор продукта к соответствующему документу и подключу такое устройство, оно не обнаружит проблем с устройством (без изменения идентификатора поставщика). Но я не могу найти его только по идентификатору поставщика.

7 голосов | спросил skandocious 1 J0000006Europe/Moscow 2012, 06:07:11

2 ответа


0

Чтобы получить список всех продуктов, принадлежащих конкретному поставщику, вы можете использовать подстановочные знаки в поле идентификатора продукта. Пример условия соответствия указан ниже:

            long vid = 1452; //Apple vendor ID
        CFNumberRef refVendorId = CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &vid);
        CFDictionarySetValue (matchingDict, CFSTR ("idVendor"), refVendorId);
        CFRelease(refVendorId);
        //all product by same vendor
        CFDictionarySetValue (matchingDict, CFSTR ("idProduct"), CFSTR("*"));
ответил Raviprakash 9 Mayam13 2013, 10:42:46
0

Создание фильтра словаря только с записью VID должно соответствовать всем идентификаторам PID этого поставщика. Я бы порекомендовал регистрироваться для обратных вызовов при вставке устройства вместо опроса в вашем собственном коде. Позвольте ОС обрабатывать обнаружение и уведомлять ваше приложение асинхронно.

Этот код работает для меня:

#import "IOKit/hid/IOHIDManager.h"
#include <IOKit/usb/IOUSBLib.h>

@implementation MyApp

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {

    IOHIDManagerRef HIDManager = IOHIDManagerCreate(kCFAllocatorDefault,
                                                    kIOHIDOptionsTypeNone);
    CFMutableDictionaryRef matchDict = CFDictionaryCreateMutable(
                                                    kCFAllocatorDefault,
                                                    2,
                                                    &kCFTypeDictionaryKeyCallBacks,
                                                    &kCFTypeDictionaryValueCallBacks);
    int vid = 0x1234; // ToDo: Place your VID here
    CFNumberRef vid_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &vid);
    CFDictionarySetValue(matchDict, CFSTR(kUSBVendorID), vid_num);
    CFRelease(vid_num);

    IOHIDManagerSetDeviceMatching(HIDManager, matchDict);
    // Here we use the same callback for insertion & removal.
    // Use separate handlers if desired.
    IOHIDManagerRegisterDeviceMatchingCallback(HIDManager, Handle_UsbDetectionCallback, (__bridge void*)self);
    IOHIDManagerRegisterDeviceRemovalCallback(HIDManager, Handle_UsbDetectionCallback, (__bridge void*)self);
    IOHIDManagerScheduleWithRunLoop(HIDManager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
    IOHIDManagerOpen(HIDManager, kIOHIDOptionsTypeNone);
}

// New USB device specified in the matching dictionary has been added (callback function)
static void Handle_UsbDetectionCallback(void *inContext, IOReturn inResult, void *inSender, IOHIDDeviceRef inIOHIDDeviceRef) {
    //ToDo: Code for dealing with the USB device
}

@end
ответил pmont 18 J000000Friday14 2014, 23:46:02

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132