tools/runonphone/serenum_unix.cpp
changeset 30 5dc02b23752f
parent 19 fcece45ef507
child 33 3e2da88830cd
equal deleted inserted replaced
29:b72c6db6890b 30:5dc02b23752f
    44 #include <QString>
    44 #include <QString>
    45 #include <QDebug>
    45 #include <QDebug>
    46 #include <QFileInfo>
    46 #include <QFileInfo>
    47 #include <QDir>
    47 #include <QDir>
    48 
    48 
       
    49 #include <usb.h>
       
    50 
    49 QList<SerialPortId> enumerateSerialPorts()
    51 QList<SerialPortId> enumerateSerialPorts()
    50 {
    52 {
       
    53     QList<QString> eligableInterfaces;
    51     QList<SerialPortId> list;
    54     QList<SerialPortId> list;
       
    55 
       
    56     usb_init();
       
    57     usb_find_busses();
       
    58     usb_find_devices();
       
    59 
       
    60     for (struct usb_bus *bus = usb_get_busses(); bus; bus = bus->next) {
       
    61         for (struct usb_device *device = bus->devices; device; device = device->next) {
       
    62             for (int n = 0; n < device->descriptor.bNumConfigurations; ++n) {
       
    63                 struct usb_config_descriptor &usbConfig =device->config[n];
       
    64                 QList<int> usableInterfaces;
       
    65                 for (int m = 0; m < usbConfig.bNumInterfaces; ++m) {
       
    66                     for (int o = 0; o < usbConfig.interface[m].num_altsetting; ++o) {
       
    67                         struct usb_interface_descriptor &descriptor = usbConfig.interface[m].altsetting[o];
       
    68                         if (descriptor.bInterfaceClass != 2 // "Communication"
       
    69                                 || descriptor.bInterfaceSubClass != 2 // Abstract (modem)
       
    70                                 || descriptor.bInterfaceProtocol != 255) // Vendor Specific
       
    71                             continue;
       
    72 
       
    73                         unsigned char *buf = descriptor.extra;
       
    74                         unsigned int size = descriptor.extralen;
       
    75                         while (size >= 2 * sizeof(u_int8_t)) {
       
    76                             // for Communication devices there is a slave interface for the actual
       
    77                             // data transmission.
       
    78                             // the extra info stores that as a index for the interface
       
    79                             if (buf[0] >= 5 && buf[1] == 36 && buf[2] == 6) { // CDC Union
       
    80                                 for (int i = 4; i < buf[0]; i++)
       
    81                                     usableInterfaces.append((int) buf[i]);
       
    82                             }
       
    83                             size -= buf[0];
       
    84                             buf += buf[0];
       
    85                         }
       
    86                     }
       
    87                 }
       
    88 
       
    89                 // second loop to find the actual data interface.
       
    90                 foreach (int i, usableInterfaces) {
       
    91                     for (int m = 0; m < usbConfig.bNumInterfaces; ++m) {
       
    92                         for (int o = 0; o < usbConfig.interface[m].num_altsetting; ++o) {
       
    93                             struct usb_interface_descriptor &descriptor = usbConfig.interface[m].altsetting[o];
       
    94                             if (descriptor.bInterfaceNumber != i)
       
    95                                 continue;
       
    96                             if (descriptor.bInterfaceClass == 10) { // "CDC Data"
       
    97                                 // qDebug() << "      found the data port"
       
    98                                 //     << "bus:" << bus->dirname
       
    99                                 //     << "device" << device->filename
       
   100                                 //     << "interface" << descriptor.bInterfaceNumber;
       
   101                                 eligableInterfaces << QString("if%1").arg(QString::number(i), 2, QChar('0')); // fix!
       
   102                             }
       
   103                         }
       
   104                     }
       
   105                 }
       
   106             }
       
   107         }
       
   108     }
       
   109 
    52     QDir dir("/dev/serial/by-id/");
   110     QDir dir("/dev/serial/by-id/");
    53     QFileInfoList ports(dir.entryInfoList());
   111     foreach (const QFileInfo &info, dir.entryInfoList()) {
    54     foreach (const QFileInfo &info, ports) {
       
    55         if (!info.isDir()) {
   112         if (!info.isDir()) {
       
   113             bool usable = eligableInterfaces.isEmpty();
       
   114             foreach (const QString &iface, eligableInterfaces) {
       
   115                 if (info.fileName().contains(iface)) {
       
   116                     usable = true;
       
   117                     break;
       
   118                 }
       
   119             }
       
   120             if (!usable)
       
   121                 continue;
       
   122 
    56             SerialPortId id;
   123             SerialPortId id;
    57             id.friendlyName = info.fileName();
   124             id.friendlyName = info.fileName();
    58             id.portName = info.canonicalFilePath();
   125             id.portName = info.canonicalFilePath();
    59             list << id;
   126             list << id;
    60         }
   127         }