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

Имам минимално излагане на xcode и I/Okit framework. Видях дескриптор на устройство и дескриптор на конфигурация на USB устройство в USB сонда.въведете описание на изображението тук

Написах програма xcode, използвайки I/O kit framework, която дава името на 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
Има USBDeviceDescriptor в usb.h. Опитах се да извикам указател от този тип, за да получа всички параметри, но не успях. Някаква помощ?   -  person Dili    schedule 04.10.2011
comment
Опитах също с функции, налични от IOUSBDeviceInterface. Но не предоставя функции за извличане на всички параметри   -  person Dili    schedule 04.10.2011
comment
След това се опитах да използвам IORegistryEntryCreateCFProperty, но и тук не успях да получа всички параметри. Всяка идея за това, моля, отговорете   -  person Dili    schedule 04.10.2011
comment
За получаване на указател към конфигурационен декриптор можем да използваме 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, можете да получите рано или късно чрез анализиране на изходния код.

Ето връзка за изтегляне на изходния код на 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. Импортирайте необходимата рамка, просто следвайте проекта 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