summaryrefslogtreecommitdiff
path: root/src/serialport/qserialportinfo_unix.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/serialport/qserialportinfo_unix.cpp')
-rw-r--r--src/serialport/qserialportinfo_unix.cpp170
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;