summaryrefslogtreecommitdiffstats
path: root/tools/runonphone
diff options
context:
space:
mode:
authorShane Kearns <shane.kearns@accenture.com>2010-07-09 10:16:35 (GMT)
committerShane Kearns <shane.kearns@accenture.com>2010-07-09 12:37:09 (GMT)
commit767aa8d648bf81a3303da66a4fef98657ea5ece3 (patch)
tree79a7899be5e77ac75b43f89fcd9905009be9c6f0 /tools/runonphone
parentc950283638f05176f80b1fc6711a5340184e25e3 (diff)
downloadQt-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/runonphone')
-rw-r--r--tools/runonphone/main.cpp2
-rw-r--r--tools/runonphone/serenum.h2
-rw-r--r--tools/runonphone/serenum_unix.cpp62
-rw-r--r--tools/runonphone/serenum_win.cpp2
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;