Mac IOKit USB обнаружение сигнала - PullRequest
1 голос
/ 17 марта 2011
 matchingDict = IOServiceMatching(kIOUSBDeviceClassName); 

 numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &vendorId);  
 CFDictionarySetValue(matchingDict, CFSTR(kUSBVendorID), numberRef);  
 CFRelease(numberRef);  

 numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &deviceProductId);  
 CFDictionarySetValue(matchingDict, CFSTR(kUSBProductID), numberRef);  
 CFRelease(numberRef);  
 numberRef = NULL;  

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

Для обработки уведомлений при добавлении USB-устройства на Mac ПК все в порядке, но могу ли я получить сигнал, пока пользователь нажимает кнопку на USB-устройстве?

Спасибо ВСЕМ!

1 Ответ

8 голосов
/ 21 марта 2011

Если пользователь нажимает кнопку на устройстве, это не создает уведомление устройства. Если это не устройство, для которого у Apple есть драйвер (в этом случае вы можете получить событие ввода, например, NSEvent), вам придется получить интерфейс устройства и общаться с этим устройством через его интерфейс. Например. Устройства USB имеют интерфейсы, каждый интерфейс имеет конечные точки, а соединения с этими конечными точками обозначены как конвейеры. Существуют исходящие и входящие конвейеры, и вы можете отправлять или читать данные из этих конвейеров. Существуют различные типы конвейеров, конвейеры с объемной передачей, изохронные и прерывистые. Кроме того, каждое устройство имеет канал управления, единственный канал, который вы можете использовать в двух направлениях.

Apple поставляет инструмент под названием USB Prober с XCode, посмотрите на него на своих USB-устройствах. Например. Дисплей Apple Cinema Display, также подключенный через USB, сообщает следующее:

Full Speed device @ 3 (0xFD520000): .............................................   Composite device: "Apple Cinema HD Display"
    Port Information:   0x0019
           Captive
           External Device
           Connected
           Enabled
    Device Descriptor   
        Descriptor Version Number:   0x0110
        Device Class:   0   (Composite)
        Device Subclass:   0
        Device Protocol:   0
        Device MaxPacketSize:   8
        Device VendorID/ProductID:   0x05AC/0x9223   (Apple Inc.)
        Device Version Number:   0x0114
        Number of Configurations:   1
        Manufacturer String:   1 "Apple Computer, Inc."
        Product String:   2 "Apple Cinema HD Display"
        Serial Number String:   0 (none)
    Configuration Descriptor   
        Length (and contents):   34
            Raw Descriptor (hex)    0000: 09 02 22 00 01 01 00 E0  01 09 04 00 00 01 03 00  
            Raw Descriptor (hex)    0010: 00 00 09 21 11 01 00 01  22 37 00 07 05 81 03 08  
            Raw Descriptor (hex)    0020: 00 10 
        Number of Interfaces:   1
        Configuration Value:   1
        Attributes:   0xE0 (self-powered, remote wakeup)
        MaxPower:   2 ma
        Interface #0 - HID   
            Alternate Setting   0
            Number of Endpoints   1
            Interface Class:   3   (HID)
            Interface Subclass;   0
            Interface Protocol:   0
            HID Descriptor   
                Descriptor Version Number:   0x0111
                Country Code:   0
                Descriptor Count:   1
                Descriptor 1   
                    Type:   0x22  (Report Descriptor)
                    Length (and contents):   55
                        Raw Descriptor (hex)    0000: 05 80 09 01 A1 01 15 00  26 FF 00 75 08 85 02 96  
                        Raw Descriptor (hex)    0010: 01 01 09 02 B2 02 01 05  82 95 02 85 10 09 10 B1  
                        Raw Descriptor (hex)    0020: 02 25 04 85 D6 09 D6 B1  02 25 07 85 E7 B1 02 26  
                        Raw Descriptor (hex)    0030: FF 00 85 E4 81 02 C0 
                    Parsed Report Descriptor:   
                          Usage Page    (Monitor) 
                          Usage 1 (0x1)    
                              Collection (Application)    
                                Logical Minimum.........    (0)  
                                Logical Maximum.........    (255)  
                                Report Size.............    (8)  
                                ReportID................    (2)  
                                Report Count............    (257)  
                                Usage 2 (0x2)    
                                Feature.................   (Data, Variable, Absolute, No Wrap, Linear, Preferred State, No Null Position, Nonvolatile, Buffered bytes) 
                                Usage Page    (VESA Virtual Controls) 
                                Report Count............    (2)  
                                ReportID................    (16)  
                                Usage 16 (0x10)    
                                Feature.................   (Data, Variable, Absolute, No Wrap, Linear, Preferred State, No Null Position, Nonvolatile, Bitfield) 
                                Logical Maximum.........    (4)  
                                ReportID................    (214)  
                                Usage 214 (0xd6)    
                                Feature.................   (Data, Variable, Absolute, No Wrap, Linear, Preferred State, No Null Position, Nonvolatile, Bitfield) 
                                Logical Maximum.........    (7)  
                                ReportID................    (231)  
                                Feature.................   (Data, Variable, Absolute, No Wrap, Linear, Preferred State, No Null Position, Nonvolatile, Bitfield) 
                                Logical Maximum.........    (255)  
                                ReportID................    (228)  
                                Input...................   (Data, Variable, Absolute, No Wrap, Linear, Preferred State, No Null Position, Bitfield) 
                              End Collection     
            Endpoint 0x81 - Interrupt Input   
                Address:   0x81  (IN)
                Attributes:   0x03  (Interrupt no synchronization data endpoint)
                Max Packet Size:   8
                Polling Interval:   16 ms

Это устройство имеет один интерфейс, интерфейс # 0, и на этом интерфейсе существует одна конечная точка (0x81), которая подключена через конвейер прерываний, который может передавать пакеты размером до 8 байтов каждые 16 мс. Если вы теперь хотите установить связь с этим конвейером, вам нужно получить интерфейс USB-драйвера устройства, и этот интерфейс предлагает функции для взаимодействия с рассматриваемым конвейером, синхронно или асинхронно, все это очень похоже на сетевой код.

Если вы сейчас спросите себя, для чего этот конвейер в первую очередь полезен для монитора, это как монитор передает кнопки в систему. Дисплеи Apple Cinema имеют 3 кнопки: «+» и «-» для яркости и кнопку питания. Функциональность кнопки питания настраивается в системных настройках, например, если захочу, он может отправить весь Mac спать. Всякий раз, когда я нажимаю одну из этих кнопок, событие прерывания создается и отправляется через этот канал USB в систему (фактически система должна опрашивать такое событие каждые 16 мс, но система делает это за вас - ваш код может притвориться событие было выдвинуто монитором).

Посмотрите на IOUSBDeviceInterface197 и обратите внимание, что он наследует IOUSBDeviceInterface187, который наследует IOUSBDeviceInterface182, который снова наследует IOUSBDeviceInterface. Это означает, что если вы получите версию интерфейса 197, все методы интерфейсов, от которых он наследуется, будут доступны и для этого интерфейса (их просто нет в списке на странице). Apple должна использовать интерфейс с версиями в названии, чтобы оставаться совместимым со старым кодом. Со временем Apple расширила интерфейсы USB (например, с новыми выпусками OS X) и, чтобы быть уверенным, что старый код все еще работает, они всегда добавляли новые интерфейсы, в противном случае они сломали бы существующий код.

Здесь вы получите список всех этих интерфейсов. Да, документация ужасна. Вы должны учиться, пытаясь и / или и пример кода. Обратите внимание, что существуют DeviceInterfaces и InterfaceInterfaces; это не одно и то же. DeviceInterface - это интерфейс драйвера к самому устройству, каждое устройство может иметь несколько «USB-интерфейсов» (это термин стандарта USB), а интерфейс к такому «usb-интерфейсу» называется «InterfaceInterface». Простые устройства, как показано выше на мониторе, имеют только один интерфейс.

Вы думаете, что это чертовски сложно?Что ж, большинство разработчиков с других платформ говорят, что, как только они выяснят, как все это работает, Mac OS станет самой простой из всех платформ, если вам нужен прямой доступ к USB-каналам.Однако это становится еще хуже: каждый интерфейс может иметь несколько конфигураций, и вы можете установить конфигурацию на интерфейсе, которая может изменить конвейеры (например, в одной конфигурации труба является объемной, а в другой та же самая труба теперь изохронной).труба).Вы можете увидеть все это в приложении USB Prober (оно показывает альтернативную конфигурацию).И, пожалуйста, обратите внимание, что USB-устройство может иметь совершенно другой набор интерфейсов, конвейеров и конфигураций для разных скоростей (например, один для USB 1.2, он же низкий + полная скорость, и один для USB 2, он же высокоскоростной).

Apple пытается объяснить большинство основ USB, которые вы должны знать, прежде чем начать писать код на этой странице .И если вы нажмете «Работа с интерфейсами USB-устройств», у Apple даже будет множество примеров кода для вас, как получить DeviceInterface, который вы можете использовать для получения InterfaceInterfaces.

Я надеюсь, что смогу дать вам несколько указателейи некоторые интересные ссылки для чтения.Это не совсем ответ на ваш вопрос, но это хорошее начало.Конечно, вы могли бы также написать драйвер ядра (расширение ядра), чтобы добавить поддержку вашего устройства в систему, чтобы при нажатии кнопки генерировалось событие, которое может обрабатывать любое программное обеспечение без использования IOKit вообще ... но я как-тосомневаюсь, что ты хочешь пойти туда.

...