Как получить дескриптор устройства и дескриптор конфигурации USB-устройства на Mac?

#xcode #macos #usb #iokit

#xcode #macos #usb #iokit

Вопрос:

Я минимально знаком с xcode и I / Okit framework. Я видел дескриптор устройства и дескриптор конфигурации USB-устройства в USB prober.введите описание изображения здесь

Я написал программу xcode, используя фреймворк I / O kit, который выдает имя usb-устройства в качестве выходных данных, когда мы вводим идентификатор продукта и идентификатор поставщика этого устройства в качестве входных данных.

 /*Take the vendor and product id from console*/

printf("nEnter the vendor id : ");
scanf("%lx",amp;usbVendor);

printf("nEnter the product id :");
scanf("%lx",amp;usbProduct);


/* Set up a matching dictionary for the class */
matchingDict = IOServiceMatching(kIOUSBDeviceClassName);
if (matchingDict == NULL)
{
    return -1; // fail
}
// Create a CFNumber for the idVendor and set the value in the dictionary
numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, amp;usbVendor);
CFDictionarySetValue(matchingDict, 
                     CFSTR(kUSBVendorID), 
                     numberRef);
CFRelease(numberRef);

// Create a CFNumber for the idProduct and set the value in the dictionary
numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, amp;usbProduct);
CFDictionarySetValue(matchingDict, 
                     CFSTR(kUSBProductID), 
                     numberRef);
CFRelease(numberRef);
numberRef = NULL;

/*Get an iterator.*/
kr = IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, amp;iter);
if (kr != KERN_SUCCESS)
{
    return -1;// fail
}

/* iterate */
while ((device = IOIteratorNext(iter)))
{
    /*Display the device names */

    io_name_t       deviceName;
    kr = IORegistryEntryGetName(device, deviceName);
    if (KERN_SUCCESS != kr) {
        deviceName[0] = '';
    }


    printf("ndeviceName:%s",deviceName);

    /*Free the reference taken before continuing to the next item */
    IOObjectRelease(device);
}

/*Release the iterator */
IOObjectRelease(iter);
return 0;
  

}

Мне нужно изменить это, чтобы при указании идентификатора поставщика и продукта usb-устройства я получал дескриптор устройства и дескриптор конфигурации (как показано в USB prober) в качестве выходных данных.

Здесь я только что привел пример, код может измениться, но на выходе должен быть дескриптор (по крайней мере, дескриптор устройства).

Заранее спасибо…

Комментарии:

1. Есть ли какая-либо встроенная функция для получения дескриптора устройства, дескриптора конфигурации, дескриптора интерфейса?

2. В usb.h есть USBDeviceDescriptor. Я попытался вызвать указатель этого типа, чтобы получить все параметры, но мне это не удалось. Любая помощь?

3. Я также пробовал использовать функции, доступные с помощью IOUSBDeviceInterface. Но он не предоставляет функций для извлечения всех параметров

4. Затем я попытался использовать IORegistryEntryCreateCFProperty, но и здесь не удалось получить все параметры. Есть идеи по этому поводу, пожалуйста, ответьте

5. Для получения указателя на дескриптор конфигурации мы можем использовать GetConfigurationDescriptor() в интерфейсе IOUSBDeviceInterface. developer.apple.com/library/mac/#documentation/Darwin/Reference /.

Ответ №1:

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

Всю информацию, представленную в USBProber, вы могли бы получить рано или поздно, проанализировав исходный код.

Вот ссылка для загрузки исходного кода IOUSBFamily с USBProber внутри него. http://opensource.apple.com/tarballs/IOUSBFamily /

Комментарии:

1. я устал от USBprober. Я не мог правильно понять его поток, так как я искал простую программу. Я попробовал функции, предоставляемые классами под USB на Mac.

2. Я написал пример, чтобы получить всю информацию, отображаемую в пробнике USB-> USB-зонд, то, что вы хотите получить, находится внутри него.<br/> Ниже приведен основной шаг для создания демонстрации.<br/> 1. Импортируйте исходные файлы из проекта USB Prober. Не забывайте USBVendor.txt , который используется для расшифровки поставщика.<br/>2. Импортируйте необходимую структуру, просто следуйте проекту USB Prober.<br />3. Добавьте интерфейс для вывода журнала в BusProbeController. Вы можете выполнить поиск «IvanDebug», чтобы найти интерфейс.<br />4. Напишите файл main.m для использования BusProbeController. <br/>

3. Дайте мне знать, как отправить вам демо-версию, если это необходимо. 0_-

4. Пожалуйста, отправьте демо на мой mail:mdileep1989@gmail.com . Это будет очень полезно.

Ответ №2:

Чтобы получить дескрипторы конфигурации, вы можете использовать следующий код:

 IOUSBDeviceInterface650** dev = ...;
IOUSBConfigurationDescriptor* configDesc = nullptr;

// Get the configuration descriptor for the first configuration (configuration 0).
kern_return_t kr = (*dev)->GetConfigurationDescriptorPtr(dev, 0, amp;configDesc);
if (kr != kIOReturnSuccess)
    return an_error;

// Now use configDesc->...
  

К сожалению, похоже, что нет функции для получения дескриптора устройства. Есть функции, чтобы получить некоторые из них:

 kr = (*dev)->GetDeviceClass(dev, amp;desc.bDeviceClass);
kr = (*dev)->GetDeviceSubClass(dev, amp;desc.bDeviceSubClass);
kr = (*dev)->GetDeviceProtocol(dev, amp;desc.bDeviceProtocol);
kr = (*dev)->GetDeviceVendor(dev, amp;desc.idVendor);
kr = (*dev)->GetDeviceProduct(dev, amp;desc.idProduct);
kr = (*dev)->GetDeviceReleaseNumber(dev, amp;desc.bcdDevice);
kr = (*dev)->GetNumberOfConfigurations(dev, amp;desc.bNumConfigurations);
  

Но я не вижу способа получить iManufacturer , iProduct , iSerial , bMaxPacketSize0 , или bcdUSB .

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

Спецификация USB 2.0 описывает, как это сделать. В основном вы:

  1. Выполните передачу элемента управления с bmRequestType = Device | Standard | In помощью , bRequest = USB_GET_DESCRIPTOR_REQUEST , wValue = (USB_DEVICE_DESCRIPTOR_TYPE << 8) , wIndex = 0 , wLength = 2 . Это приведет к сбою, потому что дескриптор длиннее 2, но он возвращает вам заголовок дескриптора, который включает его длину.

  2. Повторите этот запрос, но с правильной длиной.

  3. Для дескрипторов конфигурации выполните третий запрос с длиной wTotalLength .

Вы можете сделать это с одним меньшим запросом, поскольку вы заранее знаете размер дескрипторов, но мне нравится делать это так, потому что тогда вы можете обернуть это в очень общий getDescriptor() метод.

Теоретически вы можете сделать это так просто:

 IOUSBDeviceDescriptor devDesc;

IOUSBDevRequest request;
request.bmRequestType = USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice);
request.bRequest = kUSBRqGetDescriptor;
request.wValue = kUSBDeviceDesc << 8;
request.wIndex = 0;
request.wLength = sizeof(devDesc); // 18
request.pData = amp;devDesc;
request.wLenDone = 0;

kern_return_t kr = (*dev)->DeviceRequest(dev, amp;request);
  

Но по какой-то причине это выдает kIOUSBPipeStalled ошибку. Не уверен, почему.

Редактировать: я забыл << 8 . Теперь это работает. 🙂

Ответ №3:

Заголовок IOKit/usb/USBSpec.h содержит документированный список ключей свойств, соответствующих значениям внутри разных дескрипторов. Вы можете использовать их с IORegistryEntrySearchCFProperty (или аналогичными функциями) для получения значений дескриптора. Таким образом, вам не нужен запрос устройства от an IOUSBDeviceInterface , что выгодно, потому что:

  • в документации (комментариях) говорится, что для всех запросов устройств требуется открытое USB-устройство, и у вас может не быть разрешения на это для всех устройств (возможно, документация неверна, по крайней мере, для запросов дескрипторов, но у меня нет гарантии этого, и, похоже, лучше следовать ей в любом случае)
  • запросы устройств могут блокироваться на неопределенное время
  • строки производителя, продукта и серийного номера (на которые ссылается дескриптор устройства, но технически не являются его частью) не извлекаются в этом запросе

Ответ №4:

Для получения дескриптора устройства и дескриптора конфигурации мы можем использовать функции в классе IOUSBDeviceInterface

Ссылка: http://developer.apple.com/library/mac/#documentation/Darwin/Reference/IOKit/IOUSBLib_h/Classes/IOUSBDeviceInterface/index.html#//apple_ref/doc/com/intfm/IOUSBDeviceInterface/

Для получения дескриптора интерфейса и дескриптора конечной точки мы можем использовать функции в классе IOUSBInterfaceInterface

Ссылка: http://developer.apple.com/library/mac/#documentation/Darwin/Reference/IOKit/IOUSBLib_h/Classes/IOUSBInterfaceInterface/