diff options
author | Laszlo Papp <lpapp@kde.org> | 2013-07-27 16:57:08 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-03-02 21:05:07 +0100 |
commit | 959775c41683033adbd99faab7e3d70e0009c143 (patch) | |
tree | 4d6586946d44617271dbbc56840d45196e855dec | |
parent | 5a2314414fc89c6ef44521f6d13899045b6da7af (diff) |
Add API for querying the serial number
Thanks go to Massimo Callegari for the initial patch and the request to remind
us again. Thanks also go to Denis and Sergey for working on the windows serial
number parser.
Task-number: QTBUG-31981
Change-Id: I60d882280f481eb99d275e0a9c81da50292b1c61
Reviewed-by: Massimo Callegari <massimocallegari@yahoo.it>
Reviewed-by: Sergey Belyashov <Sergey.Belyashov@gmail.com>
-rw-r--r-- | examples/serialport/cenumerator/main.cpp | 3 | ||||
-rw-r--r-- | examples/serialport/enumerator/main.cpp | 1 | ||||
-rw-r--r-- | examples/serialport/terminal/settingsdialog.ui | 11 | ||||
-rw-r--r-- | src/serialport/qserialportinfo.cpp | 20 | ||||
-rw-r--r-- | src/serialport/qserialportinfo.h | 1 | ||||
-rw-r--r-- | src/serialport/qserialportinfo_mac.cpp | 26 | ||||
-rw-r--r-- | src/serialport/qserialportinfo_p.h | 1 | ||||
-rw-r--r-- | src/serialport/qserialportinfo_symbian.cpp | 2 | ||||
-rw-r--r-- | src/serialport/qserialportinfo_unix.cpp | 3 | ||||
-rw-r--r-- | src/serialport/qserialportinfo_win.cpp | 24 | ||||
-rw-r--r-- | tests/manual/qserialportinfo/tst_qserialportinfo.cpp | 2 |
11 files changed, 89 insertions, 5 deletions
diff --git a/examples/serialport/cenumerator/main.cpp b/examples/serialport/cenumerator/main.cpp index 2d770e81..5007389d 100644 --- a/examples/serialport/cenumerator/main.cpp +++ b/examples/serialport/cenumerator/main.cpp @@ -56,15 +56,18 @@ int main(int argc, char *argv[]) const QString blankString = QObject::tr("N/A"); QString description; QString manufacturer; + QString serialNumber; foreach (const QSerialPortInfo &serialPortInfo, serialPortInfoList) { description = serialPortInfo.description(); manufacturer = serialPortInfo.manufacturer(); + serialNumber = serialPortInfo.serialNumber(); out << endl << QObject::tr("Port: ") << serialPortInfo.portName() << endl << QObject::tr("Location: ") << serialPortInfo.systemLocation() << endl << QObject::tr("Description: ") << (!description.isEmpty() ? description : blankString) << endl << QObject::tr("Manufacturer: ") << (!manufacturer.isEmpty() ? manufacturer : blankString) << endl + << QObject::tr("Serial number: ") << (!serialNumber.isEmpty() ? serialNumber : blankString) << endl << QObject::tr("Vendor Identifier: ") << (serialPortInfo.hasVendorIdentifier() ? QByteArray::number(serialPortInfo.vendorIdentifier(), 16) : blankString) << endl << QObject::tr("Product Identifier: ") << (serialPortInfo.hasProductIdentifier() ? QByteArray::number(serialPortInfo.productIdentifier(), 16) : blankString) << endl << QObject::tr("Busy: ") << (serialPortInfo.isBusy() ? QObject::tr("Yes") : QObject::tr("No")) << endl; diff --git a/examples/serialport/enumerator/main.cpp b/examples/serialport/enumerator/main.cpp index f365ace9..48cacbda 100644 --- a/examples/serialport/enumerator/main.cpp +++ b/examples/serialport/enumerator/main.cpp @@ -61,6 +61,7 @@ int main(int argc, char *argv[]) + QObject::tr("Location: ") + info.systemLocation() + "\n" + QObject::tr("Description: ") + info.description() + "\n" + QObject::tr("Manufacturer: ") + info.manufacturer() + "\n" + + QObject::tr("Serial number: ") + info.serialNumber() + "\n" + QObject::tr("Vendor Identifier: ") + (info.hasVendorIdentifier() ? QString::number(info.vendorIdentifier(), 16) : QString()) + "\n" + QObject::tr("Product Identifier: ") + (info.hasProductIdentifier() ? QString::number(info.productIdentifier(), 16) : QString()) + "\n" + QObject::tr("Busy: ") + (info.isBusy() ? QObject::tr("Yes") : QObject::tr("No")) + "\n"; diff --git a/examples/serialport/terminal/settingsdialog.ui b/examples/serialport/terminal/settingsdialog.ui index 28c1211a..8f15b1a5 100644 --- a/examples/serialport/terminal/settingsdialog.ui +++ b/examples/serialport/terminal/settingsdialog.ui @@ -97,20 +97,27 @@ </widget> </item> <item row="3" column="0"> + <widget class="QLabel" name="serialNumberLabel"> + <property name="text"> + <string>Serial number:</string> + </property> + </widget> + </item> + <item row="4" column="0"> <widget class="QLabel" name="locationLabel"> <property name="text"> <string>Location:</string> </property> </widget> </item> - <item row="4" column="0"> + <item row="5" column="0"> <widget class="QLabel" name="vidLabel"> <property name="text"> <string>Vendor ID:</string> </property> </widget> </item> - <item row="5" column="0"> + <item row="6" column="0"> <widget class="QLabel" name="pidLabel"> <property name="text"> <string>Product ID:</string> diff --git a/src/serialport/qserialportinfo.cpp b/src/serialport/qserialportinfo.cpp index 401973fb..90b22cec 100644 --- a/src/serialport/qserialportinfo.cpp +++ b/src/serialport/qserialportinfo.cpp @@ -170,7 +170,7 @@ QString QSerialPortInfo::systemLocation() const Returns the description string of the serial port, if available; otherwise returns an empty string. - \sa manufacturer() + \sa manufacturer(), serialNumber() */ QString QSerialPortInfo::description() const { @@ -182,7 +182,7 @@ QString QSerialPortInfo::description() const Returns the manufacturer string of the serial port, if available; otherwise returns an empty string. - \sa description() + \sa description(), serialNumber() */ QString QSerialPortInfo::manufacturer() const { @@ -191,6 +191,22 @@ QString QSerialPortInfo::manufacturer() const } /*! + \since 5.3 + + Returns the serial number string of the serial port, + if available; otherwise returns an empty string. + + \note The serial number may include letters. + + \sa description(), manufacturer() +*/ +QString QSerialPortInfo::serialNumber() const +{ + Q_D(const QSerialPortInfo); + return !d ? QString() : d->serialNumber; +} + +/*! Returns the 16-bit vendor number for the serial port, if available; otherwise returns zero. diff --git a/src/serialport/qserialportinfo.h b/src/serialport/qserialportinfo.h index 8320fc5a..7635caa6 100644 --- a/src/serialport/qserialportinfo.h +++ b/src/serialport/qserialportinfo.h @@ -71,6 +71,7 @@ public: QString systemLocation() const; QString description() const; QString manufacturer() const; + QString serialNumber() const; quint16 vendorIdentifier() const; quint16 productIdentifier() const; diff --git a/src/serialport/qserialportinfo_mac.cpp b/src/serialport/qserialportinfo_mac.cpp index c69a4a30..2c2564e9 100644 --- a/src/serialport/qserialportinfo_mac.cpp +++ b/src/serialport/qserialportinfo_mac.cpp @@ -63,7 +63,7 @@ QList<QSerialPortInfo> QSerialPortInfo::availablePorts() { QList<QSerialPortInfo> serialPortInfoList; - static const int propertyCount = 6; + static const int propertyCount = 7; ::CFMutableDictionaryRef matching = ::IOServiceMatching(kIOSerialBSDServiceValue); @@ -90,6 +90,7 @@ QList<QSerialPortInfo> QSerialPortInfo::availablePorts() ::CFTypeRef portName = 0; ::CFTypeRef description = 0; ::CFTypeRef manufacturer = 0; + ::CFTypeRef serialNumber = 0; ::CFTypeRef vendorIdentifier = 0; ::CFTypeRef productIdentifier = 0; @@ -159,6 +160,19 @@ QList<QSerialPortInfo> QSerialPortInfo::availablePorts() } + if (!serialNumber) { + serialNumber = + ::IORegistryEntrySearchCFProperty(entry, + kIOServicePlane, + CFSTR(kUSBSerialNumberString), + kCFAllocatorDefault, + 0); + if (serialNumber) + ++matchingPropertiesCounter; + + } + + if (!vendorIdentifier) { vendorIdentifier = ::IORegistryEntrySearchCFProperty(entry, @@ -237,6 +251,16 @@ QList<QSerialPortInfo> QSerialPortInfo::availablePorts() ::CFRelease(manufacturer); } + if (serialNumber) { + if (::CFStringGetCString(CFStringRef(serialNumber), + buffer.data(), + buffer.size(), + kCFStringEncodingUTF8)) { + serialPortInfo.d_ptr->serialNumber = QString::fromUtf8(buffer); + } + ::CFRelease(serialNumber); + } + quint16 value = 0; if (vendorIdentifier) { diff --git a/src/serialport/qserialportinfo_p.h b/src/serialport/qserialportinfo_p.h index 1f12e69b..47319410 100644 --- a/src/serialport/qserialportinfo_p.h +++ b/src/serialport/qserialportinfo_p.h @@ -64,6 +64,7 @@ public: QString device; QString description; QString manufacturer; + QString serialNumber; quint16 vendorIdentifier; quint16 productIdentifier; diff --git a/src/serialport/qserialportinfo_symbian.cpp b/src/serialport/qserialportinfo_symbian.cpp index cae00e97..3f851b50 100644 --- a/src/serialport/qserialportinfo_symbian.cpp +++ b/src/serialport/qserialportinfo_symbian.cpp @@ -125,6 +125,7 @@ QList<QSerialPortInfo> QSerialPortInfo::availablePorts() serialPortInfo.d_ptr->description = QString::fromUtf16(nativeSerialInfo.iDescription.Ptr(), nativeSerialInfo.iDescription.Length()); serialPortInfo.d_ptr->manufacturer = QString(QObject::tr("Unknown.")); + serialPortInfo.d_ptr->serialNumber = QString(QObject::tr("Unknown.")); serialPortInfoList.append(serialPortInfo); } } @@ -146,6 +147,7 @@ QList<QSerialPortInfo> QSerialPortInfo::availablePorts() serialPortInfo.d_ptr->description = QString::fromUtf16(nativeSerialInfo.iDescription.Ptr(), nativeSerialInfo.iDescription.Length()); serialPortInfo.d_ptr->manufacturer = QString(QObject::tr("Unknown.")); + serialPortInfo.d_ptr->serialNumber = QString(QObject::tr("Unknown.")); serialPortInfoList.append(serialPortInfo); } } diff --git a/src/serialport/qserialportinfo_unix.cpp b/src/serialport/qserialportinfo_unix.cpp index a8bb6d3d..9ef113ba 100644 --- a/src/serialport/qserialportinfo_unix.cpp +++ b/src/serialport/qserialportinfo_unix.cpp @@ -251,6 +251,9 @@ QList<QSerialPortInfo> availablePortsByUdev() serialPortInfo.d_ptr->manufacturer = QString::fromLatin1(::udev_device_get_property_value(dev, "ID_VENDOR")).replace(QLatin1Char('_'), QLatin1Char(' ')); + serialPortInfo.d_ptr->serialNumber = QString( + QLatin1String(::udev_device_get_property_value(dev, "ID_SERIAL_SHORT"))); + serialPortInfo.d_ptr->vendorIdentifier = QString::fromLatin1(::udev_device_get_property_value(dev, "ID_VENDOR_ID")).toInt(&serialPortInfo.d_ptr->hasVendorIdentifier, 16); diff --git a/src/serialport/qserialportinfo_win.cpp b/src/serialport/qserialportinfo_win.cpp index 85d40cc3..448f3edc 100644 --- a/src/serialport/qserialportinfo_win.cpp +++ b/src/serialport/qserialportinfo_win.cpp @@ -195,6 +195,28 @@ private: const QString &m_serialPortName; }; +static QString deviceSerialNumber(const QString &instanceIdentifier) +{ + int firstbound = instanceIdentifier.lastIndexOf(QLatin1Char('\\')); + int lastbound = instanceIdentifier.indexOf(QLatin1Char('_'), firstbound); + if (instanceIdentifier.startsWith(QStringLiteral("USB\\"))) { + if (lastbound != instanceIdentifier.size() - 3) + lastbound = instanceIdentifier.size(); + int ampersand = instanceIdentifier.indexOf(QLatin1Char('&'), firstbound); + if (ampersand != -1 && ampersand < lastbound) + return QString(); + } else if (instanceIdentifier.startsWith(QStringLiteral("FTDIBUS\\"))) { + firstbound = instanceIdentifier.lastIndexOf(QLatin1Char('+')); + lastbound = instanceIdentifier.indexOf(QLatin1Char('\\'), firstbound); + if (lastbound == -1) + return QString(); + } else { + return QString(); + } + + return instanceIdentifier.mid(firstbound + 1, lastbound - firstbound - 1); +} + QList<QSerialPortInfo> QSerialPortInfo::availablePorts() { static const QString usbVendorIdentifierPrefix(QStringLiteral("VID_")); @@ -238,6 +260,8 @@ QList<QSerialPortInfo> QSerialPortInfo::availablePorts() s = deviceInstanceIdentifier(deviceInfoSet, &deviceInfoData).toUpper(); + serialPortInfo.d_ptr->serialNumber = deviceSerialNumber(s); + int index = s.indexOf(usbVendorIdentifierPrefix); if (index != -1) { serialPortInfo.d_ptr->vendorIdentifier = s.mid(index + usbVendorIdentifierPrefix.size(), vendorIdentifierSize) diff --git a/tests/manual/qserialportinfo/tst_qserialportinfo.cpp b/tests/manual/qserialportinfo/tst_qserialportinfo.cpp index df7ea432..c73aa00b 100644 --- a/tests/manual/qserialportinfo/tst_qserialportinfo.cpp +++ b/tests/manual/qserialportinfo/tst_qserialportinfo.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2012 Denis Shienkov <denis.shienkov@gmail.com> +** Copyright (C) 2013 Laszlo Papp <lpapp@kde.org> ** Contact: http://www.qt-project.org/legal ** ** This file is part of the QtSerialPort module of the Qt Toolkit. @@ -78,6 +79,7 @@ void tst_QSerialPortInfo::assignment() QCOMPARE(otherSerialPortInfo.systemLocation(), serialPortInfo.systemLocation()); QCOMPARE(otherSerialPortInfo.description(), serialPortInfo.description()); QCOMPARE(otherSerialPortInfo.manufacturer(), serialPortInfo.manufacturer()); + QCOMPARE(otherSerialPortInfo.serialNumber(), serialPortInfo.serialNumber()); QCOMPARE(otherSerialPortInfo.vendorIdentifier(), serialPortInfo.vendorIdentifier()); QCOMPARE(otherSerialPortInfo.productIdentifier(), serialPortInfo.productIdentifier()); } |