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

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

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

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

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

printf("\nEnter the product id :");
scanf("%lx",&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, &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, &usbProduct);
CFDictionarySetValue(matchingDict, 
                     CFSTR(kUSBProductID), 
                     numberRef);
CFRelease(numberRef);
numberRef = NULL;

/*Get an iterator.*/
kr = IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, &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] = '\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-пробере) в качестве вывода.

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

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


person Dili    schedule 30.09.2011    source источник
comment
Есть ли встроенная функция для получения дескриптора устройства, дескриптора конфигурации, дескриптора интерфейса?   -  person Dili    schedule 03.10.2011
comment
В usb.h есть дескриптор USBDeviceDescriptor. Я попытался вызвать указатель этого типа, чтобы получить все параметры, но мне это не удалось. Любая помощь?   -  person Dili    schedule 04.10.2011
comment
Я также пробовал использовать функции, доступные в IOUSBDeviceInterface. Но в нем нет функций для извлечения всех параметров.   -  person Dili    schedule 04.10.2011
comment
Затем я попытался использовать IORegistryEntryCreateCFProperty, но здесь тоже не удалось получить все параметры. Любые идеи об этом, пожалуйста, ответьте   -  person Dili    schedule 04.10.2011
comment
Для получения указателя на Decriptor конфигурации мы можем использовать GetConfigurationDescriptor () в IOUSBDeviceInterface. developer.apple.com/library/mac/#documentation/Darwin/Reference/.   -  person Dili    schedule 06.10.2011
comment
но все же я не смог найти ни одной функции, которая дает указатель на дескриптор устройства в качестве вывода. Любые идеи?   -  person Dili    schedule 06.10.2011


Ответы (4)


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

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

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

person Ivan    schedule 19.10.2011
comment
Устал USBprober. Я не мог правильно понять его поток, так как искал простую программу. Я попробовал функции, предоставляемые классами под USB в Mac. - person Dili; 20.10.2011
comment
У меня есть пример, чтобы получить всю информацию, отображаемую в USB Prober- ›USB Probe, то, что вы хотите получить, определенно находится внутри него. ‹Br/› Ниже приводится основной шаг для создания демоверсии. ‹Br/› 1. Импортируйте исходные файлы из проекта USB Prober. Не забывайте USBVendor.txt, который использовался для декодирования поставщика. ‹Br/› 2. Импортируйте необходимый Framework, просто следуйте проекту USB Prober ‹br/› 3. Добавьте интерфейс для вывода журнала в BusProbeController. Вы можете выполнить поиск по IvanDebug, чтобы найти интерфейс. ‹Br/› 4. Напишите файл main.m для использования BusProbeController. ‹Br/› - person Ivan; 22.10.2011
comment
Дайте мне знать, как отправить вам демо, если это необходимо. 0_- - person Ivan; 22.10.2011
comment
Пожалуйста, отправьте демо на мою почту: [email protected]. Это будет очень полезно. - person Dili; 24.10.2011

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

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

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

// Now use configDesc->...

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

kr = (*dev)->GetDeviceClass(dev, &desc.bDeviceClass);
kr = (*dev)->GetDeviceSubClass(dev, &desc.bDeviceSubClass);
kr = (*dev)->GetDeviceProtocol(dev, &desc.bDeviceProtocol);
kr = (*dev)->GetDeviceVendor(dev, &desc.idVendor);
kr = (*dev)->GetDeviceProduct(dev, &desc.idProduct);
kr = (*dev)->GetDeviceReleaseNumber(dev, &desc.bcdDevice);
kr = (*dev)->GetNumberOfConfigurations(dev, &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 = &devDesc;
request.wLenDone = 0;

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

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

Изменить: я забыл << 8. Теперь это работает. :-)

person Timmmm    schedule 26.05.2017

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

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

Для получения дескриптора устройства и декриптора конфигурации мы можем использовать функции в классе 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/.

person Dili    schedule 13.10.2011