Доступ к устройствам FireWire из приложений
Устройство взаимодействует через интерфейс, семья FireWire обеспечивает, плагины, предоставляющие функции, которые Ваше приложение может вызвать, чтобы связаться с или управлять устройством. В этой главе описываются, как найти устройство FireWire и заставить один или несколько интерфейсов устройства связываться с ним.
Устройство, соответствующее для устройств FireWire
Весь доступ пользовательского уровня устройства начинается с порта Маха для передачи с Набором I/O. Вы получаете порт Маха путем вызывания функции Набора I/O IOMasterPort
, как в следующем примере:
kern_return_t result; |
mach_port_t masterPort; |
result = IOMasterPort( MACH_PORT_NULL, &masterPort ); |
Для нахождения устройства Вы создаете соответствующий словарь, описывающий тип устройства или тип устройства, которым Вы интересуетесь. Функция Набора I/O IOServiceMatching
создает словарь, соответствующий на данном имени класса, как в этом примере:
CFMutableDictionaryRef matchingDictionary = IOServiceMatching |
( “IOFireWireDevice” ); |
В этом примере можно использовать matchingDictionary
для нахождения всех устройств в настоящее время представляемыми IOFireWireDevice возражают в Реестре I/O. Таблица 2-1 перечисляет имена классов FireWire, которые можно использовать для создания соответствующего словаря.
Имя класса | Определение |
---|---|
IOFireWireSBP2Target | Модуль в устройстве, которое является целью SBP-2 |
IOFireWireSBP2LUN | ЛУН в цели SBP-2 |
IOFireWireAVCUnit | Модуль AV/C в устройстве |
IOFireWireUnit | Модуль в устройстве |
IOFireWireDevice | Устройство на Шине FireWire |
IOFireWireLocalNode | Сам Macintosh |
Если Вы не должны выполнять более определенный поиск, словарь IOServiceMatching
создает будет достаточно для нахождения всех устройств определенного класса в настоящее время в Реестре I/O.
Если Вы хотите совершенствовать свой поиск, можно добавить свойства к словарю для описания уникального устройства. Как описано в Поддержке Устройства FireWire В ядре, семья IOFireWire помещает свойства, описывающие каждое устройство и модуль в объекты, представляющие их в Реестре I/O. Можно использовать любое из этих свойств для сужения поиска определенного устройства или модуля. Таблица 2-2 показывает свойства, доступные в каждом объекте.
Имя класса | Ключ Property | Определение | Ввести |
---|---|---|---|
IOFireWireDevice |
| Текущий узел ID |
|
| Идентификатор поставщика устройства |
| |
| В настоящее время читайте, содержание конфигурации ROM (может не содержать все содержание ROM), |
| |
| Имя поставщика устройства |
| |
| Сам IDs получен от устройства |
| |
| Текущая рабочая скорость устройства |
| |
| Глобально уникальный идентификатор устройства |
| |
IOFireWireUnit |
| Идентификатор поставщика устройства |
|
| Имя поставщика устройства |
| |
| Глобально уникальный идентификатор модуля |
| |
| Спецификация модуля ID для этого модуля |
| |
| Версия программного обеспечения Unit модуля |
| |
| Название продукта устройства |
| |
IOFireWireSBP2Target |
| Набор команд SBP2 |
|
| Версия набора команд SBP2 |
| |
| Спецификация модуля ID для провайдера модуля FireWire этой цели SBP-2 |
| |
| Спецификация набора команд SBP-2 ID |
| |
| Глобально уникальный идентификатор для этого устройства |
| |
| Идентификатор поставщика устройства |
| |
| Тип устройства SBP-2 |
| |
| Версия встроенного микропрограммного обеспечения SBP-2 |
| |
| Версия программного обеспечения Unit для этого модуля |
| |
IOFireWireSBP2LUN |
| Идентификатор поставщика устройства |
|
| Набор команд SBP-2 |
| |
| Спецификация набора команд SBP-2 ID |
| |
| Глобально уникальный идентификатор для этого устройства |
| |
| Тип устройства SBP-2 |
| |
| Версия встроенного микропрограммного обеспечения SBP-2 |
| |
| SBP-2 число ЛУНА |
| |
IOFireWireAVCUnit |
| Спецификация модуля ID для этого модуля |
|
| Тип модуля AV/C |
| |
| Идентификатор поставщика устройства |
| |
| Глобально уникальный идентификатор для этого устройства |
| |
| Версия программного обеспечения Unit для этого модуля |
| |
| Имя этого продукта |
|
Для использования этих свойств для соответствия запустите со словаря от IOServiceMatching
и используйте Базовые функции Основы для добавления пар ключ/значение свойства к нему. Перечисление 2-1 показывает словарь, соответствующий на объекте IOFireWireUnit с определенным Unit_Spec_ID
и Unit_SW_Version
значения:
Перечисление 2-1 соответствующий словарь для объекта IOFireWireUnit
CFMutableDictionaryRef matchingDictionary = |
IOServiceMatching(“IOFireWireUnit” ); |
UInt32 value; |
CFNumberRef cfValue; |
value = myFireWireUnitSpecID; |
cfValue = CFNumberCreate( kCFAllocatorDefault, kCFNumberSInt32Type, &value ); |
CFDictionaryAddValue( matchingDictionary, CFSTR( “Unit_Spec_ID” ), cfValue ); |
CFRelease( cfValue ); |
value = myFireWireUnitSwVersionID; |
cfValue = CFNumberCreate( kCFAllocatorDefault, kCFNumberSInt32Type, &value ); |
CFDictionaryAddValue( matchingDictionary, CFSTR( “Unit_SW_Version” ), |
cfValue); |
CFRelease( cfValue ); |
Нахождение устройств FireWire
После установки соответствующего словаря, описывающего тип устройства или тип устройства, который Вы ищете, Вы передаете его функции Набора I/O IOServiceGetMatchingServices
. Эта функция ищет Реестр I/O объекты, соответствующие свойства в данном словаре, и возвращает итератор, который можно использовать для доступа к каждому:
kern_return_t result; |
io_iterator_t iterator; |
result = IOServiceGetMatchingServices( masterPort, matchingDictionary, |
&iterator ); |
Затем, передайте итератор функции Набора I/O IOIteratorNext
, который возвращает ссылку на первый соответствующий объект. Каждый вызов к IOIteratorNext
возвращает следующий доступный объект:
io_object_t aDevice; |
while ( (aDevice = IOIteratorNext( iterator ) ) != 0 ) { |
//get a device interface for the device |
} |
Можно также использовать функции Набора I/O, чтобы получить замену в горячем режиме устройства и отключить уведомления. Чтобы сделать это, Вы сначала устанавливаете порт уведомлений и добавляете его источник события цикла выполнения к циклу выполнения Вашей программы. Затем вместо вызова IOServiceGetMatchingServices
, Вы отправляете соответствующий словарь, который Вы создали ранее к функции Набора I/O IOServiceAddMatchingNotification
получить итератор для объектов согласующего устройства и установить запрос уведомления на новое устройство возражают тому соответствию. Функция myServiceMatchingCallback
функция, которую Вы предоставляете для итерации по согласующим устройствам и доступу каждого. Перечисление 2-2 показывает, как установить уведомление.
Перечисление 2-2 , Настраивающее устройство, заменяет уведомление в горячем режиме
//global variables |
IONotificationPortRef gNotifyPort; |
CFRunLoopSourceRef gNotifySource; |
//local variables |
io_iterator_t iterator; |
kern_return_t result; |
mach_port_t masterPort; |
CFMutableDictionaryRef matchingDictionary; |
//The acquisition of the Mach port and the creation of the matching |
//dictionary are not shown here. |
gNotifyPort = IONotificationPortCreate( masterPort ); |
gNotifySource = IONotificationPortGetRunLoopSource( gNotifyPort ); |
CFRunLoopAddSource( CFRunLoopGetCurrent(), gNotifySource, |
kCFRunLoopDefaultMode ); |
result = IOServiceAddMatchingNotification( gNotifyPort, |
kIOMatchedNotification, matchingDictionary, |
myServiceMatchingCallback, NULL, &iterator ); |
//IOServiceAddMatchingNotification consumes a reference to the |
//matching dictionary so if you need to use the dictionary again |
//after this call, you must first call CFRetain on it. |
//Execute your callback function to iterate over the set of matching |
//devices already present and to arm the notification for future devices. |
myServiceMatchingCallback( NULL, iterator ); |
Получение интерфейсов устройства FireWire
После того, как Вы получили итератор и использовали его для получения ссылки на каждое согласующее устройство, необходимо получить интерфейс устройства для него. Независимо от которого устройства FireWire соединяют интерфейсом библиотекой, которой Вы хотите пользоваться, Вы сначала получаете сменный интерфейс типа IOCFPlugInInterface. Вы используете устройство io_object_t
ссылка Вы добрались от IOIteratorNext
и константа kIOFireWireLibTypeID
, как в этом примере:
IOCFPlugInInterface** cfPlugInInterface = 0; |
IOReturn result; |
SInt32 theScore; |
result = IOCreatePlugInInterfaceForService( aDevice, kIOFireWireLibTypeID, |
kIOCFPlugInInterfaceID, &cfPlugInInterface, &theScore ); |
Затем Вы используете IOCFPlugInInterface QueryInterface
функция для получения определенного устройства соединяет интерфейсом с Вами потребность. Вы передаете его идентификатор интерфейса основного устройства, который Вы хотите использовать, например, kIOFireWireDeviceInterfaceID
или kIOFireWireSBP2LibLUNInterfaceID
:
IOFireWireLibDeviceRef fwDeviceInterface = 0; |
(*cfPlugInInterface)->QueryInterface( cfPlugInInterface, CFUUIDGetUUIDBytes( |
kIOFireWireDeviceInterfaceID ), (void **) fwDeviceInterface ); |
Существует три версии IOFireWireDeviceInterface, который можно использовать. Каждая версия добавляет новые службы к функциональности предыдущей версии. Обязательно проверьте заголовочные файлы, чтобы удостовериться, что Вы выполняете версию OS X, соответствующего версии IOFireWireDeviceInterface, которую Вы хотите. При попытке получить более позднюю версию IOFireWireDeviceInterface, чем Ваша версия поддержек OS X, QueryInterface
функция перестанет работать. Можно, однако, получить более раннюю версию интерфейса, чем в настоящее время поддерживается версией OS X, который Вы выполняете.
Можно также получить экземпляры IOFireWireUnitInterface и IOFireWireNubInterface. Они синонимичны с IOFireWireDeviceInterface и относятся к тому же объекту. Их единственная функция должна предоставить Вам более описательное имя для IOFireWireDeviceInterface при открытии его на модуле или локальном узле.
Когда у Вас есть интерфейс основного устройства в библиотеке, Вы хотите использовать, Вы не должны использовать IOCreatePlugInForService
и QueryInterface
функции для получения дополнительных интерфейсов, которые обеспечивает библиотека. Каждая библиотека обеспечивает свои собственные функции для получения ее других интерфейсов.
Получение многократных интерфейсов устройства FireWire
Когда Вы открываете устройство или модуль с помощью одного из интерфейса устройства open
функции, у Вас есть монопольное соединение с объектом, представляющим то устройство или модуль в ядре. Поскольку open
функция открывает не только объект, Вы обращаетесь к нему, но также и объекты, предшествующие ему в штабеле, никакое другое приложение не может тогда открыть то устройство или модуль. Например, если Вы открываете модуль AV/C с IOFireWireAVCLibUnitInterface open
функция, Вы автоматически открытие IOFireWireUnit и объекты IOFireWireDevice, а также объект IOFireWireAVCUnit.
Таким образом, если Вы хотите использовать или IOFireWireSBP2Lib или IOFireWireAVCLib в сотрудничестве с IOFireWireLib, необходимо, в действительности, открыть устройство или объект модуля, который уже открыт. Для разрешения этого семья IOFireWire использует понятие ссылки сеанса для обращения к определенному соединению с объектом модуля или устройством.
Ссылка сеанса походит на ключ, позволяющий Вам переопределять эксклюзивность open
функция. Если Ваше приложение использовало интерфейс устройства open
функция для открытия SBP-2 или модуля AV/C можно использовать GetSessionRef
функция (доступный и в IOFireWireAVCLib и в IOFireWireSBP2Lib) для получения IOFireWireSessionRef
открыть объекты IOFireWireDevice или IOFireWireUnit. GetSessionRef
функция требует указателя на текущий интерфейс устройства, который Вы содержите поэтому, только Ваше приложение может успешно использовать его.
Вы передаете IOFireWireSessionRef
к функции IOFireWireDeviceInterface openWithSessionRef
, открытие устройства в ядре или объекта модуля. Можно тогда использовать интерфейсы и функции обеих библиотек для передачи с устройством или модулем. Перечисление 2-3 показывает, как использовать экземпляр IOFireWireAVCLibUnitInterface, чтобы открыть модуль AV/C и затем заставить ссылку сеанса открывать устройство для экземпляра IOFireWireDeviceInterface.
Перечисление 2-3 , Добирающееся и использующее ссылку сеанса
IOFireWireSessionRef session; |
result = (*avcInterface)->open( avcInterface ); |
session = (*avcInterface)->getSessionRef( avcInterface ); |
result = (*fwInterface)->openWithSessionRef( fwInterface, session ); |
Прежде чем можно будет использовать эти интерфейсы устройства, однако, необходимо сначала найти устройство, которым Вы интересуетесь. Устройство, соответствующее, является процессом использования функций Набора I/O для поиска Реестра I/O определенные устройства (или модули) или типы устройства. Этот раздел предоставляет общую информацию относительно этого процесса, поскольку это применяется к устройствам FireWire. Это предоставляет фрагменты кода для общих задач, таких как поиск Реестра I/O, уведомлений установки для новых устройств и получения интерфейсов основного устройства в каждой библиотеке интерфейса устройства FireWire. Кроме того, в Получении Многократных Интерфейсов Устройства FireWire, это описывает, как использовать IOFireWireDeviceInterface или в сочетании с IOFireWireSBP2LibLUNInterface или в сочетании с IOFireWireAVCLibUnitInterface.