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) | |
download | qtserialport-959775c41683033adbd99faab7e3d70e0009c143.tar.gz |
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 2d770e8..5007389 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 f365ace..48cacbd 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 28c1211..8f15b1a 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 401973f..90b22ce 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 8320fc5..7635caa 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 c69a4a3..2c2564e 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 1f12e69..4731941 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 cae00e9..3f851b5 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 a8bb6d3..9ef113b 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 85d40cc..448f3ed 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 df7ea43..c73aa00 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()); } |