Ignore:
Timestamp:
May 5, 2011, 5:36:53 AM (14 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/tools/runonphone/serenum_unix.cpp

    r769 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
     
    4747#include <QDir>
    4848
    49 QList<SerialPortId> enumerateSerialPorts()
     49#include <usb.h>
     50
     51class InterfaceInfo
    5052{
     53public:
     54    InterfaceInfo(const QString &mf, const QString &pr, int mfid, int prid);
     55    QString manufacturer;
     56    QString product;
     57    int manufacturerid;
     58    int productid;
     59};
     60
     61InterfaceInfo::InterfaceInfo(const QString &mf, const QString &pr, int mfid, int prid) :
     62    manufacturer(mf),
     63    product(pr),
     64    manufacturerid(mfid),
     65    productid(prid)
     66{
     67    if(mf.isEmpty())
     68        manufacturer = QString("[%1]").arg(mfid, 4, 16, QChar('0'));
     69    if(pr.isEmpty())
     70        product = QString("[%1]").arg(prid, 4, 16, QChar('0'));
     71}
     72
     73QList<SerialPortId> enumerateSerialPorts(int loglevel)
     74{
     75    QList<QString> eligibleInterfaces;
     76    QList<InterfaceInfo> eligibleInterfacesInfo;
    5177    QList<SerialPortId> list;
     78
     79    usb_init();
     80    usb_find_busses();
     81    usb_find_devices();
     82
     83    for (struct usb_bus *bus = usb_get_busses(); bus; bus = bus->next) {
     84        for (struct usb_device *device = bus->devices; device; device = device->next) {
     85            for (int n = 0; n < device->descriptor.bNumConfigurations && device->config; ++n) {
     86                struct usb_config_descriptor &usbConfig =device->config[n];
     87                QList<int> usableInterfaces;
     88                for (int m = 0; m < usbConfig.bNumInterfaces; ++m) {
     89                    for (int o = 0; o < usbConfig.interface[m].num_altsetting; ++o) {
     90                        struct usb_interface_descriptor &descriptor = usbConfig.interface[m].altsetting[o];
     91                        if (descriptor.bInterfaceClass != 2 // "Communication"
     92                                || descriptor.bInterfaceSubClass != 2 // Abstract (modem)
     93                                || descriptor.bInterfaceProtocol != 255) // Vendor Specific
     94                            continue;
     95
     96                        unsigned char *buf = descriptor.extra;
     97                        unsigned int size = descriptor.extralen;
     98                        while (size >= 2 * sizeof(u_int8_t)) {
     99                            // for Communication devices there is a slave interface for the actual
     100                            // data transmission.
     101                            // the extra info stores that as a index for the interface
     102                            if (buf[0] >= 5 && buf[1] == 36 && buf[2] == 6) { // CDC Union
     103                                for (int i = 4; i < buf[0]; i++)
     104                                    usableInterfaces.append((int) buf[i]);
     105                            }
     106                            size -= buf[0];
     107                            buf += buf[0];
     108                        }
     109                    }
     110                }
     111               
     112                if (usableInterfaces.isEmpty())
     113                    continue;
     114               
     115                QString manufacturerString;
     116                QString productString;
     117               
     118                usb_dev_handle *devh = usb_open(device);
     119                if (devh) {
     120                    QByteArray buf;
     121                    buf.resize(256);
     122                    int err = usb_get_string_simple(devh, device->descriptor.iManufacturer, buf.data(), buf.size());
     123                    if (err < 0) {
     124                        if (loglevel > 1)
     125                            qDebug() << "      can't read manufacturer name, error:" << err;
     126                    } else {
     127                        manufacturerString = QString::fromAscii(buf);
     128                        if (loglevel > 1)
     129                            qDebug() << "      manufacturer:" << manufacturerString;
     130                    }
     131
     132                    buf.resize(256);
     133                    err = usb_get_string_simple(devh, device->descriptor.iProduct, buf.data(), buf.size());
     134                    if (err < 0) {
     135                        if (loglevel > 1)
     136                            qDebug() << "      can't read product name, error:" << err;
     137                    } else {
     138                        productString = QString::fromAscii(buf);
     139                        if (loglevel > 1)
     140                            qDebug() << "      product:" << productString;
     141                    }
     142                    usb_close(devh);
     143                } else if (loglevel > 0) {
     144                    qDebug() << "      can't open usb device";
     145                }
     146
     147                // second loop to find the actual data interface.
     148                foreach (int i, usableInterfaces) {
     149                    for (int m = 0; m < usbConfig.bNumInterfaces; ++m) {
     150                        for (int o = 0; o < usbConfig.interface[m].num_altsetting; ++o) {
     151                            struct usb_interface_descriptor &descriptor = usbConfig.interface[m].altsetting[o];
     152                            if (descriptor.bInterfaceNumber != i)
     153                                continue;
     154                            if (descriptor.bInterfaceClass == 10) { // "CDC Data"
     155                                if (loglevel > 1) {
     156                                    qDebug() << "      found the data port"
     157                                             << "bus:" << bus->dirname
     158                                             << "device" << device->filename
     159                                             << "interface" << descriptor.bInterfaceNumber;
     160                                }
     161#ifdef Q_OS_MAC
     162                                eligibleInterfaces << QString("^cu\\.usbmodem.*%1$")
     163                                                      .arg(QString("%1").arg(descriptor.bInterfaceNumber, 1, 16).toUpper());
     164#else
     165                                // ### manufacturer and product strings are only readable as root :(
     166                                if (!manufacturerString.isEmpty() && !productString.isEmpty()) {
     167                                    eligibleInterfaces << QString("usb-%1_%2-if%3")
     168                                                          .arg(manufacturerString.replace(QChar(' '), QChar('_')))
     169                                                          .arg(productString.replace(QChar(' '), QChar('_')))
     170                                                          .arg(i, 2, 16, QChar('0'));
     171                                } else {
     172                                    eligibleInterfaces << QString("if%1").arg(i, 2, 16, QChar('0')); // fix!
     173                                }
     174#endif
     175                                eligibleInterfacesInfo << InterfaceInfo(manufacturerString, productString, device->descriptor.idVendor, device->descriptor.idProduct);
     176                            }
     177                        }
     178                    }
     179                }
     180            }
     181        }
     182    }
     183   
     184    if (loglevel > 1)
     185        qDebug() << "      searching for interfaces:" << eligibleInterfaces;
     186
     187#ifdef Q_OS_MAC
     188    QDir dir("/dev/");
     189    bool allowAny = false;
     190#else
    52191    QDir dir("/dev/serial/by-id/");
    53     QFileInfoList ports(dir.entryInfoList());
    54     foreach (const QFileInfo &info, ports) {
     192    bool allowAny = eligibleInterfaces.isEmpty();
     193#endif
     194    foreach (const QFileInfo &info, dir.entryInfoList(QDir::System)) {
    55195        if (!info.isDir()) {
     196            bool usable = allowAny;
     197            QString friendlyName = info.fileName();
     198            foreach (const QString &iface, eligibleInterfaces) {
     199                if (info.fileName().contains(QRegExp(iface))) {
     200                    if (loglevel > 1)
     201                        qDebug() << "      found device file:" << info.fileName() << endl;
     202#ifdef Q_OS_MAC
     203                    friendlyName = eligibleInterfacesInfo[eligibleInterfaces.indexOf(iface)].product;
     204#endif
     205                    usable = true;
     206                    break;
     207                }
     208            }
     209            if (!usable)
     210                continue;
     211
    56212            SerialPortId id;
    57             id.friendlyName = info.fileName();
     213            id.friendlyName = friendlyName;
    58214            id.portName = info.canonicalFilePath();
    59215            list << id;
    60216        }
    61217    }
     218
     219    if (list.isEmpty() && !eligibleInterfacesInfo.isEmpty() && loglevel > 0) {
     220        qDebug() << "Possible USB devices found, but without serial drivers:";
     221        foreach(const InterfaceInfo &iface, eligibleInterfacesInfo) {
     222            qDebug() << "    Manufacturer:"
     223                     << iface.manufacturer
     224                     << "Product:"
     225                     << iface.product
     226#ifdef Q_OS_LINUX
     227                     << endl
     228                     << "    Load generic driver using:"
     229                     << QString("sudo modprobe usbserial vendor=0x%1 product=0x%2")
     230                        .arg(iface.manufacturerid, 4, 16, QChar('0'))
     231                        .arg(iface.productid, 4, 16, QChar('0'));
     232#else
     233                     ;
     234#endif
     235        }
     236    }
    62237    return list;
    63238}
Note: See TracChangeset for help on using the changeset viewer.