Как получить дескриптор устройства и дескриптор конфигурации USB-устройства в Mac? - PullRequest
3 голосов
/ 30 сентября 2011

У меня минимальное воздействие xcode и I / Okit framework. Я видел дескриптор устройства и дескриптор конфигурации USB-устройства в USB Prober. enter image description here

Я написал программу xcode, использующую инфраструктуру набора I / O, которая выдает имя устройства 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-пробере).

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

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

Ответы [ 3 ]

5 голосов
/ 19 октября 2011

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

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

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

1 голос
/ 26 мая 2017

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

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.Теперь это работает.: -)

0 голосов
/ 13 октября 2011

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

...