Проблема с получением серийного номера USB-устройства в Mac OS X

Я работаю с libusb 0.1 и Qt в Mac OS X v10.10 (Yosemite). Моя цель — получить серийные номера всех подключенных USB-ключей (usbclass = 8).

Обычно первое чтение происходит нормально, и я не могу понять почему, но иногда из последующих чтений устройство уже не определяется. Иногда я получаю код ошибки -60 в функции usb_get_string_simple(handle, device->descriptor.iSerialNumber). Как я могу решить эту проблему?

Я пробовал USB-накопители с файловыми системами FAT, FAT32 и NTFS, но у всех была одна и та же проблема.

В том же проекте я использую libusb для чтения/записи с принтерами, подключенными к Mac, а также для чтения серийных номеров. Нет проблем с этим типом устройств. Так странно.

В файле .pro:

INCLUDEPATH +=   /Users/sborfedor/Desktop/root/current/includes
DEPENDPATH  +=   /Users/sborfedor/Desktop/root/current/includes
LIBS        += -L/Users/sborfedor/Desktop/root/current/bin_osx/libs/ -lusb-legacy
DESTDIR     =    /Users/sborfedor/Desktop/root/current/bin_osx

Это мой код:

void MainWindow::run() {
    struct usb_bus* bus = NULL;
    struct usb_device* device = NULL;
    const int MASSSTORAGE_CLASS = 8;
    usb_init();
    usb_set_debug(3);
    usb_find_busses();
    usb_find_devices();
    int ret;
    for ( bus = usb_get_busses(); bus; bus = bus->next ) {
        for ( device = bus->devices; device; device = device->next )  {
            if (device->descriptor.bDeviceClass != MASSSTORAGE_CLASS && device->descriptor.bDeviceClass != 0) {
                continue;
            }
            for ( int cid = 0; cid < device->descriptor.bNumConfigurations; ++cid ) {
                struct usb_config_descriptor* config = &( device->config[cid] );
                if (config == NULL)
                    continue;
                for ( int iid = 0; iid < config->bNumInterfaces; ++iid ) {
                    struct usb_interface* interface = &( config->interface[iid] );
                    if (interface == NULL)
                        continue;
                    usb_dev_handle* handle = usb_open( device );
                    if (handle == NULL)
                        continue;
                    for ( int sid = 0; sid < interface->num_altsetting; sid++ ) {
                        struct usb_interface_descriptor* settings = &( interface->altsetting[sid] );
                        if (settings == NULL)
                            continue;
                        int usbClass = device->descriptor.bDeviceClass;
                        if (usbClass == 0) {
                            usbClass = settings->bInterfaceClass;
                        }
                        if (usbClass != MASSSTORAGE_CLASS)
                            continue;
                        char device_serial_number[255];
                        ret = usb_get_string_simple( handle, device->descriptor.iSerialNumber, device_serial_number, sizeof(device_serial_number) );
                        if (ret > 0 ) {
                            qDebug() << "SERIAL_NUMBER="<<QString(device_serial_number);
                        } else {
                            qDebug() << "*** usb_get_string_simple( handle, device->descriptor.iSerialNumber, device_serial_number, USBX_DEVICE_SERIAL_NUMBER_MAX_SIZE ) RET="<<ret;
                        }
                    }
                    usb_close( handle );
                }
            }
        }
    }
}

person sborfedor    schedule 21.10.2015    source источник
comment
Как вы установили libusb?   -  person Mark Setchell    schedule 21.10.2015
comment
В том же проекте я использую libusb для чтения/записи с принтерами, подключенными к Mac, а также для чтения серийных номеров. Нет проблем с этим типом устройств. Так странно. Я думаю, что libusb установлен правильно.   -  person sborfedor    schedule 21.10.2015
comment
Но как вы его установили?   -  person Mark Setchell    schedule 21.10.2015
comment
я обновил свой вопрос   -  person sborfedor    schedule 21.10.2015


Ответы (1)


Я не очень хорошо знаком с libusb, но OSX уже считывает серийные номера и сохраняет их в соответствующем свойстве на блоках устройств IOKit. Значит, нет необходимости посылать запросы к оборудованию, что может сбить с толку активный драйвер? (Предположительно, Libusb создает экземпляр драйвера пользовательского клиента на устройстве)

Disk Arbitration Framework — это хороший способ перечисления дисков в системе и запроса их свойств — это немного проще, чем напрямую использовать IOKit.

person pmdj    schedule 20.11.2015