diff options
author | Shane Kearns <shane.kearns@accenture.com> | 2010-07-09 10:16:35 (GMT) |
---|---|---|
committer | Shane Kearns <shane.kearns@accenture.com> | 2010-07-09 12:37:09 (GMT) |
commit | 767aa8d648bf81a3303da66a4fef98657ea5ece3 (patch) | |
tree | 79a7899be5e77ac75b43f89fcd9905009be9c6f0 /tools | |
parent | c950283638f05176f80b1fc6711a5340184e25e3 (diff) | |
download | Qt-767aa8d648bf81a3303da66a4fef98657ea5ece3.zip Qt-767aa8d648bf81a3303da66a4fef98657ea5ece3.tar.gz Qt-767aa8d648bf81a3303da66a4fef98657ea5ece3.tar.bz2 |
Fix USB serial port detection of the Nokia N95 on linux
The interface numbers in /dev/serial/by-id are hex rather than decimal.
Also added code to read the manufacturer name and product name from string descriptors
in order to get a better match. Unfortunately, root privilege is needed or the API
returns an error.
In this case, we still use the weak matching on interface number only.
Task-Number: QTBUG-11794
Reviewed-By: Thomas Zander
Diffstat (limited to 'tools')
-rw-r--r-- | tools/runonphone/main.cpp | 2 | ||||
-rw-r--r-- | tools/runonphone/serenum.h | 2 | ||||
-rw-r--r-- | tools/runonphone/serenum_unix.cpp | 62 | ||||
-rw-r--r-- | tools/runonphone/serenum_win.cpp | 2 |
4 files changed, 59 insertions, 9 deletions
diff --git a/tools/runonphone/main.cpp b/tools/runonphone/main.cpp index dc83044..7767e4b 100644 --- a/tools/runonphone/main.cpp +++ b/tools/runonphone/main.cpp @@ -155,7 +155,7 @@ int main(int argc, char *argv[]) if (serialPortName.isEmpty()) { if (loglevel > 0) outstream << "Detecting serial ports" << endl; - foreach (const SerialPortId &id, enumerateSerialPorts()) { + foreach (const SerialPortId &id, enumerateSerialPorts(loglevel)) { if (loglevel > 0) outstream << "Port Name: " << id.portName << ", " << "Friendly Name:" << id.friendlyName << endl; diff --git a/tools/runonphone/serenum.h b/tools/runonphone/serenum.h index b794b97..a65c8cb 100644 --- a/tools/runonphone/serenum.h +++ b/tools/runonphone/serenum.h @@ -51,6 +51,6 @@ struct SerialPortId QString friendlyName; }; -QList<SerialPortId> enumerateSerialPorts(); +QList<SerialPortId> enumerateSerialPorts(int loglevel); #endif // WIN32SERENUM_H diff --git a/tools/runonphone/serenum_unix.cpp b/tools/runonphone/serenum_unix.cpp index b6f0293..4c90d7a 100644 --- a/tools/runonphone/serenum_unix.cpp +++ b/tools/runonphone/serenum_unix.cpp @@ -48,7 +48,7 @@ #include <usb.h> -QList<SerialPortId> enumerateSerialPorts() +QList<SerialPortId> enumerateSerialPorts(int loglevel) { QList<QString> eligableInterfaces; QList<SerialPortId> list; @@ -85,6 +85,41 @@ QList<SerialPortId> enumerateSerialPorts() } } } + + if (usableInterfaces.isEmpty()) + continue; + + QString manufacturerString; + QString productString; + + usb_dev_handle *devh = usb_open(device); + if (devh) { + QByteArray buf; + buf.resize(256); + int err = usb_get_string_simple(devh, device->descriptor.iManufacturer, buf.data(), buf.size()); + if (err < 0) { + if (loglevel > 1) + qDebug() << " can't read manufacturer name, error:" << err; + } else { + manufacturerString = QString::fromAscii(buf); + if (loglevel > 1) + qDebug() << " manufacturer:" << manufacturerString; + } + + buf.resize(256); + err = usb_get_string_simple(devh, device->descriptor.iProduct, buf.data(), buf.size()); + if (err < 0) { + if (loglevel > 1) + qDebug() << " can't read product name, error:" << err; + } else { + productString = QString::fromAscii(buf); + if (loglevel > 1) + qDebug() << " product:" << productString; + } + usb_close(devh); + } else if (loglevel > 0) { + qDebug() << " can't open usb device"; + } // second loop to find the actual data interface. foreach (int i, usableInterfaces) { @@ -94,11 +129,21 @@ QList<SerialPortId> enumerateSerialPorts() if (descriptor.bInterfaceNumber != i) continue; if (descriptor.bInterfaceClass == 10) { // "CDC Data" - // qDebug() << " found the data port" - // << "bus:" << bus->dirname - // << "device" << device->filename - // << "interface" << descriptor.bInterfaceNumber; - eligableInterfaces << QString("if%1").arg(QString::number(i), 2, QChar('0')); // fix! + if (loglevel > 1) { + qDebug() << " found the data port" + << "bus:" << bus->dirname + << "device" << device->filename + << "interface" << descriptor.bInterfaceNumber; + } + // ### manufacturer and product strings are only readable as root :( + if (!manufacturerString.isEmpty() && !productString.isEmpty()) { + eligableInterfaces << QString("usb-%1_%2-if%3") + .arg(manufacturerString.replace(QChar(' '), QChar('_'))) + .arg(productString.replace(QChar(' '), QChar('_'))) + .arg(i, 2, 16, QChar('0')); + } else { + eligableInterfaces << QString("if%1").arg(i, 2, 16, QChar('0')); // fix! + } } } } @@ -106,6 +151,9 @@ QList<SerialPortId> enumerateSerialPorts() } } } + + if (loglevel > 1) + qDebug() << " searching for interfaces:" << eligableInterfaces; QDir dir("/dev/serial/by-id/"); foreach (const QFileInfo &info, dir.entryInfoList()) { @@ -113,6 +161,8 @@ QList<SerialPortId> enumerateSerialPorts() bool usable = eligableInterfaces.isEmpty(); foreach (const QString &iface, eligableInterfaces) { if (info.fileName().contains(iface)) { + if (loglevel > 1) + qDebug() << " found device file:" << info.fileName() << endl; usable = true; break; } diff --git a/tools/runonphone/serenum_win.cpp b/tools/runonphone/serenum_win.cpp index 572161c..070cac2 100644 --- a/tools/runonphone/serenum_win.cpp +++ b/tools/runonphone/serenum_win.cpp @@ -53,7 +53,7 @@ //{4d36e978-e325-11ce-bfc1-08002be10318} //DEFINE_GUID(GUID_DEVCLASS_PORTS, 0x4D36E978, 0xE325, 0x11CE, 0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18 ); -QList<SerialPortId> enumerateSerialPorts() +QList<SerialPortId> enumerateSerialPorts(int) { DWORD index=0; SP_DEVINFO_DATA info; |