File indexing completed on 2024-05-19 16:31:59
0001 /* 0002 * SPDX-FileCopyrightText: 2001 Matthias Hoelzer-Kluepfel <mhk@caldera.de> 0003 * SPDX-License-Identifier: GPL-2.0-or-later 0004 */ 0005 0006 #include "usbdb.h" 0007 0008 #include <iostream> 0009 0010 #include <QDebug> 0011 #include <QFile> 0012 #include <QRegularExpression> 0013 #include <QRegularExpressionMatch> 0014 #include <QStandardPaths> 0015 #include <QTextStream> 0016 0017 USBDB::USBDB() 0018 { 0019 QString db = QStringLiteral("/usr/share/hwdata/usb.ids"); /* on Fedora and Arch*/ 0020 if (!QFile::exists(db)) { 0021 db = QStringLiteral("/usr/share/misc/usb.ids"); /* on Gentoo */ 0022 } 0023 if (db.isEmpty()) 0024 return; 0025 0026 QFile f(db); 0027 0028 if (f.open(QIODevice::ReadOnly)) { 0029 QTextStream ts(&f); 0030 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 0031 ts.setCodec("UTF-8"); 0032 #endif 0033 0034 QString line; 0035 int id = -1, subid = -1; 0036 const QRegularExpression vendor(QStringLiteral("^([0-9a-fA-F]{4})\\s+(.+)$")); 0037 const QRegularExpression product(QStringLiteral("^\t([0-9a-fA-F]{4})\\s+(.+)$")); 0038 const QRegularExpression cls(QStringLiteral("^C ([0-9a-fA-F]{2})\\s+(.+)$")); 0039 const QRegularExpression subclass(QStringLiteral("^\t([0-9a-fA-F]{2})\\s+(.+)$")); 0040 const QRegularExpression prot(QStringLiteral("^\t\t([0-9a-fA-F]{2})\\s+(.+)$")); 0041 while (ts.readLineInto(&line)) { 0042 if (!line.isEmpty() && line.startsWith(QLatin1String("#"))) 0043 continue; 0044 0045 // skip unhandled categories lines 0046 if (line.isEmpty() || line.startsWith(QLatin1String("AT ")) || line.startsWith(QLatin1String("HID ")) || line.startsWith(QLatin1String("R ")) 0047 || line.startsWith(QLatin1String("BIAS ")) || line.startsWith(QLatin1String("PHY ")) || line.startsWith(QLatin1String("HUT ")) 0048 || line.startsWith(QLatin1String("L ")) || line.startsWith(QLatin1String("HCC ")) || line.startsWith(QLatin1String("VT "))) { 0049 id = -1; 0050 subid = -1; 0051 continue; 0052 } 0053 0054 QRegularExpressionMatch match; 0055 if (line.startsWith('C') && (match = cls.match(line)).hasMatch()) { 0056 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 0057 id = match.capturedRef(1).toInt(0, 16); 0058 const QString name = match.capturedRef(2).trimmed().toString(); 0059 #else 0060 id = match.capturedView(1).toInt(0, 16); 0061 const QString name = match.capturedView(2).trimmed().toString(); 0062 #endif 0063 _classes.insert(QStringLiteral("%1").arg(id), name); 0064 } else if (id >= 0 && subid >= 0 && (match = prot.match(line)).hasMatch()) { 0065 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 0066 const int protid = match.capturedRef(1).toInt(0, 16); 0067 const QString name = match.capturedRef(2).trimmed().toString(); 0068 #else 0069 const int protid = match.capturedView(1).toInt(0, 16); 0070 const QString name = match.capturedView(2).trimmed().toString(); 0071 #endif 0072 _classes.insert(QStringLiteral("%1-%2-%3").arg(id).arg(subid).arg(protid), name); 0073 } else if (id >= 0 && (match = subclass.match(line)).hasMatch()) { 0074 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 0075 subid = match.capturedRef(1).toInt(0, 16); 0076 const QString name = match.capturedRef(2).trimmed().toString(); 0077 #else 0078 subid = match.capturedView(1).toInt(0, 16); 0079 const QString name = match.capturedView(2).trimmed().toString(); 0080 #endif 0081 _classes.insert(QStringLiteral("%1-%2").arg(id).arg(subid), name); 0082 } else if ((match = vendor.match(line)).hasMatch()) { 0083 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 0084 id = match.capturedRef(1).toInt(0, 16); 0085 #else 0086 id = match.capturedView(1).toInt(0, 16); 0087 #endif 0088 const QString name = match.captured(2); 0089 _ids.insert(QStringLiteral("%1").arg(id), name); 0090 } else if (id >= 0 && (match = product.match(line)).hasMatch()) { 0091 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 0092 subid = match.capturedRef(1).toInt(0, 16); 0093 const QString name = match.capturedRef(2).trimmed().toString(); 0094 #else 0095 subid = match.capturedView(1).toInt(0, 16); 0096 const QString name = match.capturedView(2).trimmed().toString(); 0097 #endif 0098 _ids.insert(QStringLiteral("%1-%2").arg(id).arg(subid), name); 0099 } else { 0100 id = -1; 0101 subid = -1; 0102 } 0103 } 0104 0105 f.close(); 0106 } 0107 } 0108 0109 QString USBDB::vendor(uint16_t id) const 0110 { 0111 QString s = _ids.value(QStringLiteral("%1").arg(id)); 0112 if (id != 0) { 0113 return s; 0114 } 0115 return QString(); 0116 } 0117 0118 QString USBDB::device(uint16_t vendor, uint16_t id) const 0119 { 0120 QString s = _ids.value(QStringLiteral("%1-%2").arg(vendor).arg(id)); 0121 if ((id != 0) && (vendor != 0)) 0122 return s; 0123 return QString(); 0124 } 0125 0126 QString USBDB::cls(uint8_t cls) const 0127 { 0128 return _classes.value(QStringLiteral("%1").arg(cls)); 0129 } 0130 0131 QString USBDB::subclass(uint8_t cls, uint8_t sub) const 0132 { 0133 return _classes.value(QStringLiteral("%1-%2").arg(cls).arg(sub)); 0134 } 0135 0136 QString USBDB::protocol(uint8_t cls, uint8_t sub, uint8_t prot) const 0137 { 0138 return _classes.value(QStringLiteral("%1-%2-%3").arg(cls).arg(sub).arg(prot)); 0139 }