IOUSBInterfaceOpen не работает, но я могу заставить его работать, отключив камеру. Что происходит?

Я пытаюсь написать драйвер USB камеры Pentax для MacO без особого опыта. Мне удалось установить связь с камерой, используя пример кода в разделе «Работа с интерфейсами USB-устройств», но только если я использую асинхронные уведомления и если я извлекаю и повторно подключаю камеру. Кажется, работает, если во время отладки код захватывает камеру до ее установки. Я хочу сделать это без уведомлений и CFRunloop, поэтому сейчас пытаюсь использовать IOServiceGetMatchingServices (). Я могу получить устройство, настроить, выполнить DeviceRequest и даже создать интерфейс устройства, получить его класс, но USBInterfaceOpen не работает. Я думаю, мне нужно настроить канал к одной из конечных точек, чтобы DeviceRequest работал не только для получения статуса, но я не могу обойтись без открытия интерфейса. Благодарность

РЕДАКТИРОВАТЬ:

Мне кажется, что единственный интерфейс - это IOUSBHostInterface @ 0, и он предназначен для доступа к запоминающим устройствам, верно? Итак, я предполагаю, что попытка отправить команды с помощью DeviceRequest - в интерфейс управления, который, как я полагаю, - это единственный вариант, но он не работает с кодом ошибки e000404f. Я считаю, что могу правильно сформулировать команду, поскольку я вижу байты в Wireshark, но весь пакет не такой, как то, что я вижу на USB-устройстве ПК. Может, у меня все еще нет нужных командных байтов?

+-o K-5 II@14200000  <class IORegistryEntry:IOService:IOUSBNub:IOUSBDevice, id 0x100002645, registered, matched, active, busy 0 (2976 ms), retai$
  | {
  |   "sessionID" = 116428207269670
  |   "USBSpeed" = 3
  |   "IOServiceLegacyMatchingRegistryID" = 4294977095
  |   "idProduct" = 328
  |   "bDeviceClass" = 0
  |   "IOPowerManagement" = {"PowerOverrideOn"=Yes,"CapabilityFlags"=32768,"MaxPowerState"=2,"DevicePowerState"=2,"ChildrenPowerState"=2,"Driver$
  |   "bcdDevice" = 263
  |   "USB Product Name" = "K-5 II"
  |   "AppleUSBAlternateServiceRegistryID" = 4294977095
  |   "locationID" = 337641472
  |   "kUSBSerialNumberString" = "4585468"
  |   "bDeviceSubClass" = 0
  |   "kUSBCurrentConfiguration" = 1
  |   "IOCFPlugInTypes" = {"9dc7b780-9ec0-11d4-a54f-000a27052861"="IOUSBFamily.kext/Contents/PlugIns/IOUSBLib.bundle"}
  |   "bDeviceProtocol" = 0
  |   "USBPortType" = 0
  |   "USB Vendor Name" = "PENTAX"
  |   "idVendor" = 9723
  |   "USB Serial Number" = "4585468"
  |   "IOGeneralInterest" = "IOCommand is not serializable"
  |   "kUSBVendorString" = "PENTAX"
  |   "IOClassNameOverride" = "IOUSBDevice"
  | }
  | 
  +-o AppleUSBHostLegacyClient  <class IORegistryEntry:IOService:AppleUSBHostLegacyClient, id 0x100002648, !registered, !matched, active, busy 0$
  |   {
  |     "IOPowerManagement" = {"DevicePowerState"=0,"CurrentPowerState"=1,"CapabilityFlags"=65536,"MaxPowerState"=2,"DriverPowerState"=1}
  |   }
  |   
  +-o AppleUSBHostCompositeDevice  <class IORegistryEntry:IOService:AppleUSBHostCompositeDevice, id 0x100002650, !registered, !matched, active, $
  |   {
  |     "IOProbeScore" = 50000
  |     "CFBundleIdentifier" = "com.apple.driver.usb.AppleUSBHostCompositeDevice"
  |     "IOProviderClass" = "IOUSBHostDevice"
  |     "IOClass" = "AppleUSBHostCompositeDevice"
  |     "bDeviceSubClass" = 0
  |     "IOMatchCategory" = "IODefaultMatchCategory"
  |     "kUSBPreferredConfiguration" = 1
  |     "bDeviceClass" = 0
  |   }
  |   
  +-o IOUSBHostInterface@0  <class IORegistryEntry:IOService:IOUSBNub:IOUSBInterface, id 0x100002652, registered, matched, active, busy 0 (1112 $
    | {
    |   "USBPortType" = 0
    |   "IOCFPlugInTypes" = {"2d9786c6-9ef3-11d4-ad51-000a27052861"="IOUSBFamily.kext/Contents/PlugIns/IOUSBLib.bundle"}
    |   "bcdDevice" = 263
    |   "USBSpeed" = 3
    |   "idProduct" = 328
    |   "bConfigurationValue" = 1
    |   "bInterfaceSubClass" = 6
    |   "locationID" = 337641472
    |   "IOGeneralInterest" = "IOCommand is not serializable"
    |   "IOServiceLegacyMatchingRegistryID" = 4294977107
    |   "IOClassNameOverride" = "IOUSBInterface"
    |   "AppleUSBAlternateServiceRegistryID" = 4294977107
    |   "idVendor" = 9723
    |   "bInterfaceProtocol" = 80
    |   "bAlternateSetting" = 0
    |   "bInterfaceNumber" = 0
    |   "bInterfaceClass" = 8
    | }
    | 
    +-o IOUSBMassStorageInterfaceNub  <class IORegistryEntry:IOService:IOUSBMassStorageInterfaceNub, id 0x100002654, registered, matched, active$
      | {
      |   "IOClass" = "IOUSBMassStorageInterfaceNub"
      |   "idProduct" = 328
      |   "bInterfaceProtocol" = 80
      |   "USB Device Info" = {"bcdDevice"=263,"idProduct"=328,"kUSBVendorString"="PENTAX","bConfigurationValue"=1,"kUSBSerialNumberString"="458$
      |   "bcdDevice" = 263
      |   "IOProviderClass" = "IOUSBHostInterface"
      |   "Physical Interconnect Location" = "External"
      |   "USB Product Name" = "K-5 II"
      |   "IOPowerManagement" = {"DevicePowerState"=1,"CurrentPowerState"=1,"CapabilityFlags"=32768,"MaxPowerState"=1,"DriverPowerState"=1}
      |   "IOProbeScore" = 50000
      |   "locationID" = 337641472
      |   "kUSBSerialNumberString" = "4585468"
      |   "bInterfaceSubClass" = 6
      |   "bInterfaceClass" = 8
      |   "Physical Interconnect" = "USB"
      |   "bConfigurationValue" = 1
      |   "IOMatchCategory" = "IODefaultMatchCategory"
      |   "CFBundleIdentifier" = "com.apple.iokit.IOUSBMassStorageDriver"
      |   "bInterfaceNumber" = 0
      |   "idVendor" = 9723
      |   "USB Mass Storage Trace ID" = 2736782607644622848
      |   "kUSBVendorString" = "PENTAX"
      | }
      | 
      +-o IOUSBMassStorageDriverNub  <class IORegistryEntry:IOService:IOUSBMassStorageDriverNub, id 0x100002656, registered, matched, active, bu$
        | {
        |   "IOClass" = "IOUSBMassStorageDriverNub"
        |   "CFBundleIdentifier" = "com.apple.iokit.IOUSBMassStorageDriver"
        |   "IOProviderClass" = "IOUSBMassStorageInterfaceNub"
        |   "USB Mass Storage Trace ID" = 2736782607644622848
        |   "IOPowerManagement" = {"ChildrenPowerState"=1,"DevicePowerState"=1,"CurrentPowerState"=1,"CapabilityFlags"=32768,"MaxPowerState"=1,"$
        |   "idProduct" = 328
        |   "IOProbeScore" = 0
        |   "bConfigurationValue" = 1
        |   "bInterfaceSubClass" = 6
        |   "IOMatchCategory" = "IODefaultMatchCategory"
        |   "kUSBVendorString" = "PENTAX"
        |   "USB Product Name" = "K-5 II"
        |   "USB Device Info" = {"bcdDevice"=263,"idProduct"=328,"kUSBVendorString"="PENTAX","bConfigurationValue"=1,"kUSBSerialNumberString"="4$
        |   "Physical Interconnect" = "USB"
        |   "idVendor" = 9723
        |   "bInterfaceProtocol" = 80
        |   "Physical Interconnect Location" = "External"
        |   "bInterfaceNumber" = 0
        |   "bInterfaceClass" = 8
        | }
        | 
        +-o IOUSBMassStorageDriver  <class IORegistryEntry:IOService:IOSCSIProtocolInterface:IOSCSIProtocolServices:IOUSBMassStorageDriver, id 0$
          | {
          |   "IOClass" = "IOUSBMassStorageDriver"
          |   "CFBundleIdentifier" = "com.apple.iokit.IOUSBMassStorageDriver"
          |   "IOProviderClass" = "IOUSBMassStorageDriverNub"
          |   "Write Time Out Duration" = 30000
          |   "USB Mass Storage Trace ID" = 2736782607644622848
          |   "IOPowerManagement" = {"ChildrenPowerState"=1,"DevicePowerState"=1,"CurrentPowerState"=1,"CapabilityFlags"=32768,"MaxPowerState"=1$
          |   "Read Time Out Duration" = 30000
          |   "IOProbeScore" = 0
          |   "IOUnit" = 16
          |   "IOMatchCategory" = "IODefaultMatchCategory"
          |   "Retry Count" = 20
          |   "Protocol Characteristics" = {"Physical Interconnect"="USB","Read Time Out Duration"=30000,"Physical Interconnect Location"="Exter$
          |   "bInterfaceProtocol" = 80
          |   "Physical Interconnect Location" = "External"
          |   "No INQUIRY VPD Pages" = Yes
          | }
          | 
          +-o IOSCSILogicalUnitNub@0  <class IORegistryEntry:IOService:IOSCSIProtocolInterface:IOSCSIProtocolServices:IOSCSIPeripheralDeviceNub:$
            | {
            |   "TPGS Information" = 0
            |   "Peripheral Device Type" = 0
            |   "Vendor Identification" = "PENTAX"
            |   "SCSI Logical Unit Number" = 0
            |   "IOMatchCategory" = "SCSITaskUserClientIniter"
            |   "Product Identification" = "DSC_K-5_II"
            |   "Protocol Characteristics" = {"Physical Interconnect"="USB","Read Time Out Duration"=30000,"SCSI Logical Unit Number"=0,"Physica$
            |   "IOUnitLUN" = 0
            |   "Product Revision Level" = "1.07"
            | }
            | 
            +-o IOSCSIPeripheralDeviceType00  <class IORegistryEntry:IOService:IOSCSIProtocolInterface:IOSCSIPrimaryCommandsDevice:IOSCSIBlockCo$
              | {
              |   "IOClass" = "IOSCSIPeripheralDeviceType00"
              |   "CFBundleIdentifier" = "com.apple.iokit.IOSCSIBlockCommandsDevice"
              |   "IOProviderClass" = "IOSCSIPeripheralDeviceNub"
              |   "IOMaximumBlockCountRead" = 256
              |   "IOPowerManagement" = {"CapabilityFlags"=49216,"MaxPowerState"=4,"ActivityTickles"=58,"IdleTimerPeriod"=200000,"DevicePowerSta$
              |   "IOMaximumBlockCountWrite" = 256
              |   "IOProbeScore" = 5000
              |   "Peripheral Device Type" = 0
              |   "IOMatchCategory" = "IODefaultMatchCategory"
              |   "IOMaximumByteCountWrite" = 131072
              |   "WriteCacheState" = No
              |   "IOMaximumByteCountRead" = 131072
              | }
              | 
              +-o IOBlockStorageServices  <class IORegistryEntry:IOService:IOBlockStorageDevice:IOBlockStorageServices, id 0x100002660, register$
                | {
                |   "IOMinimumSegmentAlignmentByteCount" = 4
                |   "device-type" = "Generic"
                |   "Device Characteristics" = {"Vendor Name"="PENTAX","Product Name"="DSC_K-5_II","Product Revision Level"="1.07"}
                |   "Protocol Characteristics" = {"Physical Interconnect"="USB","Read Time Out Duration"=30000,"SCSI Logical Unit Number"=0,"Phy$
                | }
                | 
                +-o IOBlockStorageDriver  <class IORegistryEntry:IOService:IOStorage:IOBlockStorageDriver, id 0x100002661, registered, matched, $
                  | {
                  |   "IOPropertyMatch" = {"device-type"="Generic"}
                  |   "IOProbeScore" = 0
                  |   "IOProviderClass" = "IOBlockStorageDevice"
                  |   "IOClass" = "IOBlockStorageDriver"
                  |   "CFBundleIdentifier" = "com.apple.iokit.IOStorageFamily"
                  |   "Statistics" = {"Operations (Write)"=6,"Latency Time (Write)"=0,"Bytes (Read)"=2269184,"Errors (Write)"=0,"Total Time (Rea$
                  |   "IOMatchCategory" = "IODefaultMatchCategory"
                  |   "IOGeneralInterest" = "IOCommand is not serializable"
                  | }
                  | 
                  +-o PENTAX DSC_K-5_II Media  <class IORegistryEntry:IOService:IOStorage:IOMedia, id 0x100002664, registered, matched, active, $
                    | {
                    |   "Removable" = Yes
                    |   "Content" = "FDisk_partition_scheme"
                    |   "Whole" = Yes
                    |   "Leaf" = No
                    |   "BSD Name" = "disk2"
                    |   "Ejectable" = Yes
                    |   "Preferred Block Size" = 512
                    |   "IOMediaIcon" = {"IOBundleResourceFile"="Removable.icns","CFBundleIdentifier"="com.apple.iokit.IOStorageFamily"}
                    |   "BSD Minor" = 8
                    |   "IOGeneralInterest" = "IOCommand is not serializable"
                    |   "Writable" = Yes
                    |   "BSD Major" = 1
                    |   "Size" = 16147022336
                    |   "IOBusyInterest" = "IOCommand is not serializable"
                    |   "Open" = Yes
                    |   "Content Hint" = ""
                    |   "BSD Unit" = 2
                    | }
                    | 
                    +-o IOMediaBSDClient  <class IORegistryEntry:IOService:IOMediaBSDClient, id 0x100002665, registered, matched, active, busy 0$
                    |   {
                    |     "IOClass" = "IOMediaBSDClient"
                    |     "IOMatchCategory" = "IOMediaBSDClient"
                    |     "IOProbeScore" = 30000
                    |     "IOProviderClass" = "IOMedia"
                    |     "IOResourceMatch" = "IOBSD"
                    |     "CFBundleIdentifier" = "com.apple.iokit.IOStorageFamily"
                    |   }
                    |   
                    +-o IOFDiskPartitionScheme  <class IORegistryEntry:IOService:IOStorage:IOPartitionScheme:IOFDiskPartitionScheme, id 0x100002$
                      | {
                      |   "IOPropertyMatch" = {"Whole"=Yes}
                      |   "IOProbeScore" = 3000
                      |   "IOMatchCategory" = "IOStorage"
                      |   "IOClass" = "IOFDiskPartitionScheme"
                      |   "IOProviderClass" = "IOMedia"
                      |   "CFBundleIdentifier" = "com.apple.iokit.IOStorageFamily"
                      |   "Content Mask" = "FDisk_partition_scheme"
                      |   "Content Table" = {"0xA9"="NetBSD","0x82"="Linux_Swap","0x01"="DOS_FAT_12","0xA7"="Apple_Rhapsody_UFS","0x0B"="DOS_FAT$
                      | }
                      | 
                      +-o Untitled 1@1  <class IORegistryEntry:IOService:IOStorage:IOMedia, id 0x10000266b, registered, matched, active, busy 0 $
                        | {
                        |   "Removable" = Yes
                        |   "Content" = "DOS_FAT_32"
                        |   "Whole" = No
                        |   "Leaf" = Yes
                        |   "BSD Name" = "disk2s1"
                        |   "Ejectable" = Yes
                        |   "Preferred Block Size" = 512
                        |   "Base" = 4194304
                        |   "BSD Minor" = 9
                        |   "IOGeneralInterest" = "IOCommand is not serializable"
                        |   "Writable" = Yes
                        |   "Partition ID" = 1
                        |   "BSD Major" = 1
                        |   "Size" = 16142827520
                        |   "IOBusyInterest" = "IOCommand is not serializable"
                        |   "Open" = Yes
                        |   "Content Hint" = "DOS_FAT_32"
                        |   "BSD Unit" = 2
                        | }
                        | 
                        +-o IOMediaBSDClient  <class IORegistryEntry:IOService:IOMediaBSDClient, id 0x10000266c, registered, matched, active, bu$
                            {
                              "IOClass" = "IOMediaBSDClient"
                              "IOMatchCategory" = "IOMediaBSDClient"
                              "IOProbeScore" = 30000
                              "IOProviderClass" = "IOMedia"
                              "IOResourceMatch" = "IOBSD"
                              "CFBundleIdentifier" = "com.apple.iokit.IOStorageFamily"
                            }


person codesurfer    schedule 27.02.2019    source источник


Ответы (2)


Во-первых, какой код ошибки вернул? Я предполагаю kIOReturnExclusiveAccess, но было бы хорошо знать наверняка.

Во-вторых, сообщает ли устройство как составное устройство? В этом случае вы должны пытаться открыть не USB устройство, а USB интерфейс, который вас интересует.

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

person pmdj    schedule 27.02.2019
comment
Да, вы правы, когда я включаю камеру, она монтируется, я запускаю код и пытаюсь сделать: kr = (* interface) - ›USBInterfaceOpen (interface); код ошибки: 0x2c5 #define kIOReturnExclusiveAccess iokit_common_err (0x2c5) // монопольный доступ и // устройство уже открыто. Если я извлекаю камеру и запускаю код, я получаю ту же ошибку. Итак, если я пропущу: kr = (* dev) - ›USBDeviceOpen (dev); часть кода для обоих вышеуказанных условий, я получаю ту же ошибку. - person codesurfer; 28.02.2019
comment
Я считаю, что это «составной», как вы говорите, потому что он монтируется как запоминающее устройство, но я почти уверен, что мне нужно открыть другой интерфейс, чтобы получить доступ к конечной точке управления устройства, например, для срабатывания затвора. Но вот где у меня проблема, не могу открыть интерфейс. Глядя на ioregistry, я вижу, что есть только интерфейс 0, который, похоже, используется для доступа к запоминающим устройствам. Затем, я думаю, есть контрольная точка более высокого уровня, которую я мог запрашивать, но пытался отправить команды, и они тоже терпят неудачу. При извлечении камеры реестр не очищается. - person codesurfer; 28.02.2019
comment
Используя Wireshark на компьютере, я вижу, что при попытке DeviceRequest отправляется еще 8–16 байтов. Я предполагаю, что это потому, что команда проходит через интерфейс с конечной точкой, которую я не смог открыть. - person codesurfer; 28.02.2019
comment
Я вижу, что IORegistryExplorer сообщает, что к устройству подключен драйвер запоминающего устройства. Как мне это удалить, если при извлечении этого не происходит? - person codesurfer; 28.02.2019
comment
В linux есть файл правил, запрещающий монтировать камеру как диск. Мне нужно это делать? Как? - person codesurfer; 28.02.2019
comment
Не могли бы вы запустить ioreg -lirc IOUSBHostDevice и обновить свой вопрос целым поддеревом устройства, к которому вы пытаетесь получить доступ? Я сомневаюсь, что вам следует отправлять команды камеры на интерфейс запоминающего устройства. Если интерфейс управления камерой не отображается, возможно, речь идет о включении альтернативной конфигурации на композитном устройстве? - person pmdj; 28.02.2019
comment
Спасибо @pmdj. Я сделаю это. - person codesurfer; 01.03.2019

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

Я видел массовую команду на ПК, используя Wireshark во время разговора с камерой с помощью PK_Tether. (Еще один интересный факт заключается в том, что pk_tether не мог получить доступ к массовому хранилищу, если у меня не была SD-карта в слоте для карты камеры.)

Итак, теперь мне нужно узнать, как запускать массовые команды, поэтому я задам этот вопрос в новой беседе.

person codesurfer    schedule 03.03.2019