Проблемы с получением уведомлений от IOKit (CoreFoundation) для подключенных устройств

В настоящее время я разрабатываю приложение для 10.6.7, которое должно получать уведомления при подключении нового USB-устройства. Я обнаружил, что есть функция IOKit, которая обрабатывает такие вещи «IOServiceAddMatchingNotification». Поскольку возвращаемое значение этой конкретной функции равно 0, я думаю, что проблема, возможно, заключается в моем соответствующем словаре, который указан в этой функции. Я объявляю словарь таким образом:

CFMutableDictionaryRef matchingDict = IOServiceMatching(kIOUSBDeviceClassName);

Поскольку я не хочу получать уведомление для каждого устройства, я не знаю, правильный ли это способ создать этот конкретный словарь.

Мой полный код выглядит так:

ioKitNotificationPort = IONotificationPortCreate(kIOMasterPortDefault);
notificationRunLoopSource = IONotificationPortGetRunLoopSource(ioKitNotificationPort);

CFRunLoopAddSource(CFRunLoopGetCurrent(), notificationRunLoopSource, kCFRunLoopDefaultMode);

CFMutableDictionaryRef matchingDict = IOServiceMatching(kIOUSBDeviceClassName);


addMatchingNotificationResult = IOServiceAddMatchingNotification(ioKitNotificationPort,
                                                                 kIOPublishNotification,
                                                                 matchingDict,
                                                                 deviceAdded,
                                                                 NULL,

Кто-нибудь знает, почему это не сработает? (Примечание: функция обратного вызова является статической функцией void c, а все остальное заключено в класс Obj-C).

Спасибо

Xcode 4, 10.6.7


person Andi    schedule 10.04.2011    source источник
comment
Я еще не очень хорошо знаком с пользовательским пространством IOKit, но на стороне ядра сопоставление происходит сначала для наиболее конкретного совпадающего словаря, и только если это не удается, пробуются более общие сопоставления. Вы пытаетесь сделать это с устройствами, которые уже совместимы с существующими драйверами? Кроме того, возможно, это поможет: developer.apple.com/library/ mac/#qa/qa1076/_index.html   -  person pmdj    schedule 13.04.2011
comment
Я попробовал это с помощью USB-накопителя, который я использую пару раз. Finder находит эту флешку, поэтому я думаю, что мне не нужно писать запись в каталоге драйверов из OS X. Также мне нравится получать уведомления для флешек, которые никогда раньше не были подключены к моему Mac, поэтому должен быть способ справиться это... я до сих пор не могу найти этот путь...   -  person Andi    schedule 14.04.2011


Ответы (4)


Как ни странно, вы должны очистить итератор, возвращаемый IOServiceAddMatchingNotification, прежде чем уведомление будет активировано. Я не вижу этого в предоставленном коде, так что это может быть проблемой. Этот итератор на самом деле является тем, что вам нужно, чтобы уведомление продолжало работать.

io_iterator_t ioNotification;

addMatchingNotificationResult = IOServiceAddMatchingNotification(ioKitNotificationPort,
                                                                 kIOPublishNotification,
                                                                 matchingDict,
                                                                 deviceAdded,
                                                                 NULL,
                                                                 &ioNotification);

while ((service = IOIteratorNext(ioNotification)))
{
    NSLog(@"Hey, I found a service!");

    IOObjectRelease(service); // yes, you have to release this
}
person Mattie    schedule 09.08.2011

На мой взгляд, вы должны загрузить исходный код из IOUSBFamily на opensource.apple.com, а затем найти код для USB Prober, это приложение делает то же самое, что вы описали, прослушивая USB-устройство. вложение. (Кроме того, USB Prober также получает общий дескриптор устройства и конфигурации, возможно, это то, что вам нужно.)

person Ivan    schedule 13.07.2011

Вы добавили VID и PID устройства, которое хотите найти, в соответствующий словарь? Для имеющегося у вас словаря и VID= yourVid, PID= yourPid это будет:

CFDictionaryAddValue(matchingDict, usbVendorId, yourVid);  
CFDictionaryAddValue(matchingDict, usbProductId, yourPid);  

Другое дело — после того, как вызов IOServiceAddMatchingNotification увенчается успехом, вам нужно вызвать обработчик добавленного устройства с тем итератором, который был установлен в вызове. Это активирует уведомление и проверит существующие устройства.

person GTAE86    schedule 18.07.2012

Самый простой способ сделать то, что вы описываете, — это подключиться к DiskArbitration Framework. DA является относительно новым для OSX и позволяет пользовательским приложениям проверять устройства по мере их подключения. это то, что используется для открытия iTunes при подключении iPod, запуска iPhoto при подключении камеры и т. д. Если искомое USB-устройство является запоминающим устройством, то это сработает для вас. в противном случае вам нужно будет пройти соответствующий маршрут словаря...

person kent    schedule 07.07.2011