diff options
Diffstat (limited to 'src/serialport/qserialportinfo_unix.cpp')
-rw-r--r-- | src/serialport/qserialportinfo_unix.cpp | 170 |
1 files changed, 94 insertions, 76 deletions
diff --git a/src/serialport/qserialportinfo_unix.cpp b/src/serialport/qserialportinfo_unix.cpp index 4fc6650..b4caf88 100644 --- a/src/serialport/qserialportinfo_unix.cpp +++ b/src/serialport/qserialportinfo_unix.cpp @@ -218,6 +218,22 @@ QList<QSerialPortInfo> availablePortsBySysfs() struct ScopedPointerUdevDeleter { + static inline void cleanup(struct ::udev *pointer) + { + ::udev_unref(pointer); + } +}; + +struct ScopedPointerUdevEnumeratorDeleter +{ + static inline void cleanup(struct ::udev_enumerate *pointer) + { + ::udev_enumerate_unref(pointer); + } +}; + +struct ScopedPointerUdevDeviceDeleter +{ static inline void cleanup(struct ::udev_device *pointer) { ::udev_device_unref(pointer); @@ -234,6 +250,45 @@ QString getUdevPropertyValue(struct ::udev_device *dev, const char *name) return QString::fromLatin1(::udev_device_get_property_value(dev, name)); } +static +bool checkUdevForSerial8250Driver(struct ::udev_device *dev) +{ + const QString driverName = QString::fromLatin1(::udev_device_get_driver(dev)); + return (driverName == QStringLiteral("serial8250")); +} + +static +QString getUdevModelName(struct ::udev_device *dev) +{ + return getUdevPropertyValue(dev, "ID_MODEL") + .replace(QLatin1Char('_'), QLatin1Char(' ')); +} + +static +QString getUdevVendorName(struct ::udev_device *dev) +{ + return getUdevPropertyValue(dev, "ID_VENDOR") + .replace(QLatin1Char('_'), QLatin1Char(' ')); +} + +static +quint16 getUdevModelIdentifier(struct ::udev_device *dev, bool &hasIdentifier) +{ + return getUdevPropertyValue(dev, "ID_MODEL_ID").toInt(&hasIdentifier, 16); +} + +static +quint16 getUdevVendorIdentifier(struct ::udev_device *dev, bool &hasIdentifier) +{ + return getUdevPropertyValue(dev, "ID_VENDOR_ID").toInt(&hasIdentifier, 16); +} + +static +QString getUdevSerialNumber(struct ::udev_device *dev) +{ + return getUdevPropertyValue(dev,"ID_SERIAL_SHORT"); +} + QList<QSerialPortInfo> availablePortsByUdev() { #ifndef LINK_LIBUDEV @@ -241,99 +296,62 @@ QList<QSerialPortInfo> availablePortsByUdev() if (!symbolsResolved) return QList<QSerialPortInfo>(); #endif - QList<QSerialPortInfo> serialPortInfoList; - static const QString rfcommDeviceName(QStringLiteral("rfcomm")); - struct ::udev *udev = ::udev_new(); - if (udev) { - - struct ::udev_enumerate *enumerate = - ::udev_enumerate_new(udev); - - if (enumerate) { - - ::udev_enumerate_add_match_subsystem(enumerate, "tty"); - ::udev_enumerate_scan_devices(enumerate); - - struct ::udev_list_entry *devices = - ::udev_enumerate_get_list_entry(enumerate); - - struct ::udev_list_entry *dev_list_entry; - udev_list_entry_foreach(dev_list_entry, devices) { - - QScopedPointer<struct ::udev_device, ScopedPointerUdevDeleter> dev(::udev_device_new_from_syspath(udev, - ::udev_list_entry_get_name(dev_list_entry))); - - if (dev) { - - QSerialPortInfo serialPortInfo; + QScopedPointer<struct ::udev, ScopedPointerUdevDeleter> udev(::udev_new()); - serialPortInfo.d_ptr->device = QString::fromLatin1(::udev_device_get_devnode(dev.data())); - serialPortInfo.d_ptr->portName = QString::fromLatin1(::udev_device_get_sysname(dev.data())); - - struct ::udev_device *parentdev = ::udev_device_get_parent(dev.data()); - - if (parentdev) { - - QString subsys = QString::fromLatin1(::udev_device_get_subsystem(parentdev)); - - if (subsys == QStringLiteral("usb-serial") - || subsys == QStringLiteral("usb")) { - serialPortInfo.d_ptr->description = - getUdevPropertyValue(dev.data(), "ID_MODEL").replace(QLatin1Char('_'), QLatin1Char(' ')); + if (!udev) + return QList<QSerialPortInfo>(); - serialPortInfo.d_ptr->manufacturer = - getUdevPropertyValue(dev.data(), "ID_VENDOR").replace(QLatin1Char('_'), QLatin1Char(' ')); + QScopedPointer<udev_enumerate, ScopedPointerUdevEnumeratorDeleter> + enumerate(::udev_enumerate_new(udev.data())); - serialPortInfo.d_ptr->serialNumber = getUdevPropertyValue(dev.data(),"ID_SERIAL_SHORT"); + if (!enumerate) + return QList<QSerialPortInfo>(); - serialPortInfo.d_ptr->vendorIdentifier = - getUdevPropertyValue(dev.data(), "ID_VENDOR_ID").toInt(&serialPortInfo.d_ptr->hasVendorIdentifier, 16); + ::udev_enumerate_add_match_subsystem(enumerate.data(), "tty"); + ::udev_enumerate_scan_devices(enumerate.data()); - serialPortInfo.d_ptr->productIdentifier = - getUdevPropertyValue(dev.data(), "ID_MODEL_ID").toInt(&serialPortInfo.d_ptr->hasProductIdentifier, 16); + udev_list_entry *devices = ::udev_enumerate_get_list_entry(enumerate.data()); - } else if (subsys == QStringLiteral("pnp")) { - // TODO: Obtain more information - } else if (subsys == QStringLiteral("platform")) { - continue; - } else if (subsys == QStringLiteral("pci")) { - serialPortInfo.d_ptr->description = - getUdevPropertyValue(dev.data(), "ID_MODEL"); + QList<QSerialPortInfo> serialPortInfoList; + udev_list_entry *dev_list_entry; + udev_list_entry_foreach(dev_list_entry, devices) { - serialPortInfo.d_ptr->manufacturer = - getUdevPropertyValue(dev.data(), "ID_VENDOR"); + QScopedPointer<udev_device, ScopedPointerUdevDeviceDeleter> + dev(::udev_device_new_from_syspath( + udev.data(), ::udev_list_entry_get_name(dev_list_entry))); - serialPortInfo.d_ptr->vendorIdentifier = - getUdevPropertyValue(dev.data(), "ID_VENDOR_ID").toInt(&serialPortInfo.d_ptr->hasVendorIdentifier, 16); + if (!dev) + return serialPortInfoList; - serialPortInfo.d_ptr->productIdentifier = - getUdevPropertyValue(dev.data(), "ID_MODEL_ID").toInt(&serialPortInfo.d_ptr->hasProductIdentifier, 16); - } else { - // FIXME: Obtain more information - } - } else { - if (serialPortInfo.d_ptr->portName.startsWith(rfcommDeviceName)) { - bool ok; - int portNumber = serialPortInfo.d_ptr->portName.mid(rfcommDeviceName.length()).toInt(&ok); + QSerialPortInfo serialPortInfo; - if (!ok || (portNumber < 0) || (portNumber > 255)) - continue; - } else { - continue; - } - } + serialPortInfo.d_ptr->device = QString::fromLatin1(::udev_device_get_devnode(dev.data())); + serialPortInfo.d_ptr->portName = QString::fromLatin1(::udev_device_get_sysname(dev.data())); - serialPortInfoList.append(serialPortInfo); - } + udev_device *parentdev = ::udev_device_get_parent(dev.data()); + if (parentdev) { + if (checkUdevForSerial8250Driver(parentdev)) + continue; + serialPortInfo.d_ptr->description = getUdevModelName(dev.data()); + serialPortInfo.d_ptr->manufacturer = getUdevVendorName(dev.data()); + serialPortInfo.d_ptr->serialNumber = getUdevSerialNumber(dev.data()); + serialPortInfo.d_ptr->vendorIdentifier = getUdevModelIdentifier(dev.data(), serialPortInfo.d_ptr->hasVendorIdentifier); + serialPortInfo.d_ptr->productIdentifier = getUdevVendorIdentifier(dev.data(), serialPortInfo.d_ptr->hasProductIdentifier); + } else { + if (serialPortInfo.d_ptr->portName.startsWith(rfcommDeviceName)) { + bool ok; + int portNumber = serialPortInfo.d_ptr->portName.mid(rfcommDeviceName.length()).toInt(&ok); + if (!ok || (portNumber < 0) || (portNumber > 255)) + continue; + } else { + continue; } - - ::udev_enumerate_unref(enumerate); } - ::udev_unref(udev); + serialPortInfoList.append(serialPortInfo); } return serialPortInfoList; |