/*************************************************************************** * Copyright (C) 2001 by Matthias Hoelzer-Kluepfel * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "usbdevices.h" #include #include #include #include QList USBDevice::_devices; static KDeviceDatabase kdevicedb; static float getSpeed(int number) { switch (number) { case LIBUSB_SPEED_LOW: { return 1.5; } case LIBUSB_SPEED_FULL: { return 12.0; } case LIBUSB_SPEED_HIGH: { return 480.0; } case LIBUSB_SPEED_SUPER: { return 5000.0; } #if !defined(Q_OS_FREEBSD) && !defined(Q_OS_DRAGONFLY) case LIBUSB_SPEED_SUPER_PLUS: { return 10000.0; } #endif case LIBUSB_SPEED_UNKNOWN: { return 0.0; } } kWarning() << "Unknown libusb speed" << number; return 0.0; } static QString getVersion(uint16_t number) { uint8_t *numberarray = reinterpret_cast(&number); return QString::fromLatin1("%1.%2").arg(QString::number(numberarray[1], 16)).arg(QString::number(numberarray[0], 16)); } USBDevice::USBDevice() : _bus(0), _level(0), _parent(0), _port(0), _device(0), _channels(0), _speed(0.0), _class(0), _sub(0), _prot(0), _maxPacketSize(0), _vendorID(0), _prodID(0) { _devices.append(this); } USBDevice::~USBDevice() { } USBDevice* USBDevice::find(int bus, int device) { foreach(USBDevice* usbDevice, _devices) { if (usbDevice->bus() == bus && usbDevice->device() == device) { return usbDevice; } } return NULL; } QString USBDevice::product() { QString pname = kdevicedb.lookupUSBDevice( QByteArray::number(_vendorID, 16), QByteArray::number(_prodID, 16) ); if (!pname.isEmpty()) { return pname; } return i18n("Unknown"); } QString USBDevice::dump() { QString r; const QByteArray class16 = QByteArray::number(_class, 16); const QByteArray sub16 = QByteArray::number(_sub, 16); const QByteArray vendorid16 = QByteArray::number(_vendorID, 16); r = "

" + product() + "


"; if (!_serial.isEmpty()) { r += i18n("Serial #: ") + _serial + "
"; } r += "
"; QString c = QString("").arg(_class); QString cname = kdevicedb.lookupUSBClass(class16); if (!cname.isEmpty()) { c += ""; } r += i18n("%1", c); QString sc = QString("").arg(_sub); QString scname = kdevicedb.lookupUSBSubClass(class16, sub16); if (!scname.isEmpty()) { sc += ""; } r += i18n("%1", sc); QString pr = QString("").arg(_prot); QString prname = kdevicedb.lookupUSBProtocol(class16, sub16, QByteArray::number(_prot, 16)); if (!prname.isEmpty()) { pr += ""; } r += i18n("%1", pr); r += i18n("", _ver); r += ""; QString v = QString::number(_vendorID, 16); QString name = kdevicedb.lookupUSBVendor(vendorid16); if (!name.isEmpty()) { v += ""; } r += i18n("", v); QString p = QString::number(_prodID, 16); QString pname = kdevicedb.lookupUSBDevice(vendorid16, QByteArray::number(_prodID, 16)); if (!pname.isEmpty()) { p += ""; } r += i18n("", p); r += i18n("", _rev); r += ""; r += i18n("", _speed); r += i18n("", _channels); r += i18n("", _maxPacketSize); r += ""; r += "
%1(" + i18n(cname.toLatin1()) +")
Class
%1(" + i18n(scname.toLatin1()) +")
Subclass
%1(" + prname +")
Protocol
USB Version%1
(" + name +")
Vendor ID0x%1
(" + pname +")
Product ID0x%1
Revision%1
Speed%1 Mbit/s
Channels%1
Max. Packet Size%1
"; return r; } void USBDevice::init() { _devices.clear(); struct libusb_context *libusbctx = nullptr; int libusbstatus = libusb_init(&libusbctx); if (libusbstatus != LIBUSB_SUCCESS) { kWarning() << libusb_error_name(libusbstatus); return; } struct libusb_device **libusbdevices = nullptr; const size_t libusbdevicessize = libusb_get_device_list(libusbctx, &libusbdevices); // qDebug() << Q_FUNC_INFO << libusbdevicessize; for (size_t i = 0; i < libusbdevicessize; i++) { USBDevice* device = new USBDevice(); struct libusb_device_descriptor libusbdevice; ::memset(&libusbdevice, 0, sizeof(struct libusb_device_descriptor)); libusbstatus = libusb_get_device_descriptor(libusbdevices[i], &libusbdevice); if (libusbstatus != LIBUSB_SUCCESS) { kWarning() << libusb_error_name(libusbstatus); _devices.clear(); break; } // qDebug() << Q_FUNC_INFO << libusbdevice.idVendor << libusbdevice.idProduct; device->_bus = libusb_get_bus_number(libusbdevices[i]); device->_port = libusb_get_port_number(libusbdevices[i]); device->_speed = getSpeed(libusb_get_device_speed(libusbdevices[i])); // the maximum is supposed to be 7 uint8_t portnumbersbuffer[10]; ::memset(portnumbersbuffer, 0, sizeof(portnumbersbuffer) * sizeof(uint8_t)); device->_channels = libusb_get_port_numbers(libusbdevices[i], portnumbersbuffer, sizeof(portnumbersbuffer)); device->_class = libusbdevice.bDeviceClass; device->_sub = libusbdevice.bDeviceSubClass; device->_prot = libusbdevice.bDeviceProtocol; device->_maxPacketSize = libusbdevice.bMaxPacketSize0; device->_vendorID = libusbdevice.idVendor; device->_prodID = libusbdevice.idProduct; if (libusbdevice.iSerialNumber > 0) { device->_serial = QString::number(libusbdevice.iSerialNumber); } device->_ver = getVersion(libusbdevice.bcdUSB); device->_rev = getVersion(libusbdevice.bcdDevice); device->_device = device->_port; device->_level = 0; #if !defined(Q_OS_FREEBSD) && !defined(Q_OS_DRAGONFLY) struct libusb_device *libusbparent = libusb_get_parent(libusbdevices[i]); if (libusbparent) { device->_parent = libusb_get_port_number(libusbparent); device->_level = 1; struct libusb_device *libusbparentparent = libusb_get_parent(libusbparent); if (libusbparentparent) { // device->_parent = libusb_get_port_number(libusbparentparent); device->_level = 2; } } #endif } libusb_free_device_list(libusbdevices, 1); libusb_exit(libusbctx); }