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 } |