Чтобы получить дескрипторы конфигурации, вы можете использовать код, подобный следующему:
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 описывает, как это сделать.В основном вы:
Выполните передачу управления с помощью bmRequestType = Device | Standard | In
, bRequest = USB_GET_DESCRIPTOR_REQUEST
, wValue = (USB_DEVICE_DESCRIPTOR_TYPE << 8)
, wIndex = 0
, wLength = 2
.Это не удастся, потому что дескриптор длиннее 2, но он возвращает заголовок дескриптора, который включает его длину.
Повторите этот запрос, но с правильной длиной.
Для дескрипторов конфигурации выполните третий запрос длиной 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
.Теперь это работает.: -)