LCOV - code coverage report
Current view: top level - src/cli - scancommand.cpp (source / functions) Coverage Total Hit
Project: Dokit Lines: 99.0 % 291 288
Version: Functions: 100.0 % 17 17

            Line data    Source code
       1              : // SPDX-FileCopyrightText: 2022-2025 Paul Colby <git@colby.id.au>
       2              : // SPDX-License-Identifier: LGPL-3.0-or-later
       3              : 
       4              : #include "scancommand.h"
       5              : #include "../stringliterals_p.h"
       6              : 
       7              : #include <qtpokit/pokitdiscoveryagent.h>
       8              : 
       9              : #include <QBluetoothUuid>
      10              : #include <QJsonArray>
      11              : #include <QJsonDocument>
      12              : #include <QJsonObject>
      13              : 
      14              : #include <iostream>
      15              : 
      16              : DOKIT_USE_STRINGLITERALS
      17              : 
      18              : /*!
      19              :  * \class ScanCommand
      20              :  *
      21              :  * The ScanCommand class implements the `scan` CLI command, by scanning for nearby Pokit Bluetooth
      22              :  * devices. When devices are found, they are logged to stdout in the chosen format.
      23              :  */
      24              : 
      25              : /*!
      26              :  * Construct a new ScanCommand object with \a parent.
      27              :  */
      28         6823 : ScanCommand::ScanCommand(QObject * const parent) : AbstractCommand(parent)
      29         3948 : {
      30         3561 :     #if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)) // Required signal, and Fields, added in Qt 5.12.
      31         7101 :     connect(discoveryAgent, &PokitDiscoveryAgent::pokitDeviceUpdated,
      32         5061 :             this, &ScanCommand::deviceUpdated);
      33         3561 :     #endif
      34         7686 : }
      35              : 
      36          260 : QStringList ScanCommand::requiredOptions(const QCommandLineParser &parser) const
      37          288 : {
      38          548 :     return AbstractCommand::requiredOptions(parser);
      39          288 : }
      40              : 
      41          130 : QStringList ScanCommand::supportedOptions(const QCommandLineParser &parser) const
      42          144 : {
      43          404 :     return AbstractCommand::supportedOptions(parser) + QStringList{
      44          346 :     };
      45          144 : }
      46              : 
      47              : /// \copydoc AbstractCommand::processOptions
      48           65 : QStringList ScanCommand::processOptions(const QCommandLineParser &parser)
      49           72 : {
      50          137 :     QStringList errors = AbstractCommand::processOptions(parser);
      51           72 :     if (!errors.isEmpty()) {
      52            0 :         return errors;
      53            0 :     }
      54              : 
      55           72 :     return errors;
      56           72 : }
      57              : 
      58              : /*!
      59              :  * Begins scanning for Pokit devices.
      60              :  */
      61           65 : bool ScanCommand::start()
      62           24 : {
      63           24 :     Q_ASSERT(discoveryAgent);
      64          224 :     qCInfo(lc).noquote() << tr("Scanning for Pokit devices...");
      65           89 :     discoveryAgent->start();
      66           89 :     return true;
      67           24 : }
      68              : 
      69              : /*!
      70              :  * Handles discovered Pokit devices, writing \a info to stdout.
      71              :  */
      72         5580 : void ScanCommand::deviceDiscovered(const QBluetoothDeviceInfo &info)
      73         5940 : {
      74        11520 :     switch (format) {
      75         1980 :     case OutputFormat::Csv:
      76         6144 :         for (; showCsvHeader; showCsvHeader = false) {
      77         3042 :             std::cout << qUtf8Printable(tr("uuid,address,name,major_class,minor_class,signal_strength\n"));
      78         1188 :         }
      79         9240 :         std::cout << qUtf8Printable(QString::fromLatin1("%1,%2,%3,%4,%5,%6\n").arg(info.deviceUuid().toString(),
      80         1980 :             info.address().toString(), escapeCsvField(info.name()), toString(info.majorDeviceClass()),
      81         1980 :             toString(info.majorDeviceClass(), info.minorDeviceClass())).arg(info.rssi()));
      82         3840 :         break;
      83         3840 :     case OutputFormat::Json:
      84         5700 :         std::cout << QJsonDocument(toJson(info)).toJson().toStdString();
      85         3840 :         break;
      86         3840 :     case OutputFormat::Text:
      87         8370 :         std::cout << qUtf8Printable(tr("%1 %2 %3 %4\n").arg(info.deviceUuid().toString(),
      88         1980 :             info.address().toString(), info.name()).arg(info.rssi()));
      89         3840 :         break;
      90         5940 :     }
      91        11520 : }
      92              : 
      93              : /*!
      94              :  * Handles updated Pokit devices, writing \a info to stdout. Currently \a updatedFields us unused.
      95              :  */
      96              : #if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)) // Required signal, and Fields, added in Qt 5.12.
      97         2655 : void ScanCommand::deviceUpdated(const QBluetoothDeviceInfo &info,
      98              :                                 const QBluetoothDeviceInfo::Fields updatedFields)
      99         2700 : {
     100         2700 :     Q_UNUSED(updatedFields)
     101         5355 :     deviceDiscovered(info);
     102         5355 : }
     103              : #endif
     104              : 
     105              : /*!
     106              :  * Handles the completion of device discovery. In this override we simply exit, as the scan command
     107              :  * is nothing more than logging of discovered devices.
     108              :  */
     109           65 : void ScanCommand::deviceDiscoveryFinished()
     110           72 : {
     111          166 :     qCDebug(lc).noquote() << tr("Finished scanning for Pokit devices.");
     112          137 :     QCoreApplication::quit();
     113          137 : }
     114              : 
     115              : /*!
     116              :  * Returns \a info as a JSON object.
     117              :  */
     118         2374 : QJsonObject ScanCommand::toJson(const QBluetoothDeviceInfo &info)
     119         2544 : {
     120         4918 :     if (!info.isValid()) {
     121          393 :         return QJsonObject();
     122          204 :     }
     123         2340 :     QJsonObject json{
     124         6710 :         { u"address"_s, info.address().toString() },
     125         6710 :         { u"name"_s, info.name() },
     126         6160 :         { u"isCached"_s, info.isCached() },
     127         6230 :         { u"majorDeviceClass"_s, info.majorDeviceClass() },
     128         6710 :         { u"majorDeviceClass"_s, toJson(info.majorDeviceClass()) },
     129         6710 :         { u"minorDeviceClass"_s, toJson(info.majorDeviceClass(), info.minorDeviceClass()) },
     130         6710 :         { u"signalStrength"_s, info.rssi() },
     131        26945 :     };
     132         4525 :     if (info.coreConfigurations() != QBluetoothDeviceInfo::UnknownCoreConfiguration) {
     133          884 :         json.insert(u"coreConfiguration"_s, toJson(info.coreConfigurations()));
     134          276 :     }
     135         4743 :     if (!info.deviceUuid().isNull()) {
     136         5416 :         json.insert(u"deviceUuid"_s, info.deviceUuid().toString());
     137         1476 :     }
     138         2100 :     #if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)) // Added in Qt 5.12.
     139         4165 :     if (!info.manufacturerData().isEmpty()) {
     140          645 :         json.insert(u"manufacturerData"_s, toJson(info.manufacturerData()));
     141          180 :     }
     142         2100 :     #endif
     143         4525 :     if (info.serviceClasses() != QBluetoothDeviceInfo::NoService) {
     144         1087 :         json.insert(u"serviceClasses"_s, toJson(info.serviceClasses()));
     145          336 :     }
     146         5960 :     if (!info.serviceUuids().isEmpty()) {
     147          256 :         json.insert(u"serviceUuids"_s, toJson(info.serviceUuids()));
     148           72 :     }
     149         4130 :     return json;
     150        14804 : }
     151              : 
     152              : /*!
     153              :  * Returns \a configuration as a JSON array of strings.
     154              :  */
     155          514 : QJsonArray ScanCommand::toJson(const QBluetoothDeviceInfo::CoreConfigurations &configurations)
     156          564 : {
     157         1078 :     QJsonArray array;
     158          564 :     #define DOKIT_INTERNAL_IF_SET_THEN_APPEND(flag) \
     159         1692 :         if (configurations.testFlag(QBluetoothDeviceInfo::flag)) \
     160         1692 :             array.append(QLatin1String(#flag))
     161          937 :     DOKIT_INTERNAL_IF_SET_THEN_APPEND(UnknownCoreConfiguration);
     162         1156 :     DOKIT_INTERNAL_IF_SET_THEN_APPEND(LowEnergyCoreConfiguration);
     163          970 :     DOKIT_INTERNAL_IF_SET_THEN_APPEND(BaseRateCoreConfiguration);
     164              :   //DOKIT_INTERNAL_IF_SET_THEN_APPEND(BaseRateAndLowEnergyCoreConfiguration); // Combination flag.
     165          564 :     #undef DOKIT_INTERNAL_IF_SET_THEN_APPEND
     166         1078 :     return array;
     167          564 : }
     168              : 
     169              : /*!
     170              :  * Returns \a majorClass as a JSON value. This is equivalent to toString, except that if toString
     171              :  * does not recognise \a majorClass, then \a majorClass is returned as a JSON number (not a string).
     172              :  *
     173              :  * \see toString(const QBluetoothDeviceInfo::MajorDeviceClass &majorClass)
     174              :  */
     175         3095 : QJsonValue ScanCommand::toJson(const QBluetoothDeviceInfo::MajorDeviceClass &majorClass)
     176         3348 : {
     177         6443 :     const QString string = toString(majorClass);
     178         9538 :     return (string.isNull() ? QJsonValue(majorClass) : QJsonValue(string));
     179         4434 : }
     180              : 
     181              : /*!
     182              :  * Returns \a minorClass as a JSON value. This is equivalent to toString, except that if toString
     183              :  * does not recognise \a minorClass as a sub-class of \a majorClass, then \a minorClass is returned
     184              :  * as a JSON number (not a string).
     185              :  *
     186              :  * \see toString(const QBluetoothDeviceInfo::MajorDeviceClass &majorClass, const quint8 minorClass)
     187              :  */
     188         8165 : QJsonValue ScanCommand::toJson(const QBluetoothDeviceInfo::MajorDeviceClass &majorClass, const quint8 minorClass)
     189         8964 : {
     190        17129 :     const QString string = toString(majorClass, minorClass);
     191        25294 :     return (string.isNull() ? QJsonValue(minorClass) : QJsonValue(string));
     192        11922 : }
     193              : 
     194              : /*!
     195              :  * Returns \a classes as a JSON array of strings.
     196              :  */
     197          963 : QJsonArray ScanCommand::toJson(const QBluetoothDeviceInfo::ServiceClasses &classes)
     198         1056 : {
     199         2019 :     QJsonArray array;
     200         1056 :     #define DOKIT_INTERNAL_IF_SET_THEN_APPEND(flag) \
     201         8448 :         if (classes.testFlag(QBluetoothDeviceInfo::flag)) \
     202         8448 :             array.append(QLatin1String(#flag))
     203         1974 :     DOKIT_INTERNAL_IF_SET_THEN_APPEND(PositioningService);
     204         1974 :     DOKIT_INTERNAL_IF_SET_THEN_APPEND(NetworkingService);
     205         1974 :     DOKIT_INTERNAL_IF_SET_THEN_APPEND(RenderingService);
     206         1929 :     DOKIT_INTERNAL_IF_SET_THEN_APPEND(CapturingService);
     207         1929 :     DOKIT_INTERNAL_IF_SET_THEN_APPEND(ObjectTransferService);
     208         1929 :     DOKIT_INTERNAL_IF_SET_THEN_APPEND(AudioService);
     209         1929 :     DOKIT_INTERNAL_IF_SET_THEN_APPEND(TelephonyService);
     210         1929 :     DOKIT_INTERNAL_IF_SET_THEN_APPEND(InformationService);
     211         1056 :     #undef DOKIT_INTERNAL_IF_SET_THEN_APPEND
     212         2019 :     return array;
     213         1056 : }
     214              : 
     215              : /*!
     216              :  * Returns \a uuids as a JSON array.
     217              :  */
     218          390 : QJsonArray ScanCommand::toJson(const QList<QBluetoothUuid> &uuids)
     219          432 : {
     220          822 :     QJsonArray array;
     221         2034 :     for (const QBluetoothUuid &uuid: uuids) {
     222         1992 :         array.append(uuid.toString());
     223          864 :     }
     224          822 :     return array;
     225          432 : }
     226              : 
     227              : /*!
     228              :  * Returns Bluetooth manufacturer \a data as a JSON object that maps the manufacturer IDs (unsigned
     229              :  * integers as strings) to arrays of one or more values.
     230              :  */
     231          413 : QJsonObject ScanCommand::toJson(const QMultiHash<quint16, QByteArray> &data)
     232          420 : {
     233          833 :     QJsonObject object;
     234          833 :     QList<quint16> keys = data.uniqueKeys();
     235          707 :     std::sort(keys.begin(), keys.end());
     236         1603 :     for (const quint16 key: keys) {
     237              :         // Convert the key's values to a JSON array, reversing the order, because QMultiHash
     238              :         // guarantees that the values are order "from the most recently inserted to the least
     239              :         // recently inserted", which is the opposite of what we want.
     240         1040 :         QList<QByteArray> values = data.values(key);
     241         1010 :         std::reverse(values.begin(), values.end());
     242         1190 :         QJsonArray array;
     243         2339 :         for (const QByteArray &value: values) {
     244         2892 :             array.append(QLatin1String(value.toBase64()));
     245          876 :         }
     246         1530 :         object.insert(QString::number(key), array);
     247         1190 :     }
     248          833 :     return object;
     249          546 : }
     250              : 
     251              : /*!
     252              :  * Returns \a majorClass as a human-readable string, or a null QString if \a majorClass is not
     253              :  * recognised.
     254              :  *
     255              :  * For example, if \a majorClass is \c QBluetoothDeviceInfo::ToyDevice, then the string `ToyDevice`
     256              :  * is returned.
     257              :  */
     258         5865 : QString ScanCommand::toString(const QBluetoothDeviceInfo::MajorDeviceClass &majorClass)
     259         6336 : {
     260         6336 :     #define DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(value) \
     261        26160 :         if (majorClass == QBluetoothDeviceInfo::value) \
     262        26160 :             return QLatin1String(#value)
     263        12201 :     DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(MiscellaneousDevice);
     264         3871 :     DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(ComputerDevice);
     265         3169 :     DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(PhoneDevice);
     266          448 :     #if (QT_VERSION < QT_VERSION_CHECK(5, 13, 0))
     267          448 :     DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(LANAccessDevice); // Deprecated since Qt 5.13.
     268              :     #else
     269         1867 :     DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(NetworkDevice); // Added in Qt 5.13.
     270         1624 :     #endif
     271         2165 :     DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(AudioVideoDevice);
     272         2015 :     DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(PeripheralDevice);
     273         1865 :     DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(ImagingDevice);
     274         1715 :     DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(WearableDevice);
     275         1565 :     DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(ToyDevice);
     276         1415 :     DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(HealthDevice);
     277         1436 :     DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(UncategorizedDevice);
     278          432 :     #undef DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN
     279         1160 :     qCDebug(lc).noquote() << tr("Unknown major class %1.").arg(majorClass);
     280          432 :     return QString(); // Null QString indicates unknown minor class.
     281         1176 : }
     282              : 
     283              : /*!
     284              :  * Returns \a minorClass as a human-readable string, or a null QString if \a minorClass is not
     285              :  * recognised as a sub-class of \a majorClass.
     286              :  *
     287              :  * For example, if \a majorClass is \c QBluetoothDeviceInfo::ToyDevice, and \a minorClass is
     288              :  * \c QBluetoothDeviceInfo::ToyRobot, then the string `ToyRobot` is returned.
     289              :  */
     290        16005 : QString ScanCommand::toString(const QBluetoothDeviceInfo::MajorDeviceClass &majorClass, const quint8 minorClass)
     291        17568 : {
     292        17568 :     #define DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(value) \
     293        77640 :         if (minorClass == QBluetoothDeviceInfo::value) \
     294        77640 :             return QLatin1String(#value)
     295        33573 :     switch (majorClass) {
     296         5704 :     case QBluetoothDeviceInfo::MiscellaneousDevice:
     297         5704 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(UncategorizedMiscellaneous);
     298          672 :         break;
     299         3216 :     case QBluetoothDeviceInfo::ComputerDevice:
     300         2340 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(UncategorizedComputer);
     301         1770 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(DesktopComputer);
     302         1608 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(ServerComputer);
     303         1446 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(LaptopComputer);
     304         1284 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(HandheldClamShellComputer);
     305         1122 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(HandheldComputer);
     306          960 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(WearableComputer);
     307          672 :         break;
     308         2942 :     case QBluetoothDeviceInfo::PhoneDevice:
     309         2142 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(UncategorizedPhone);
     310         1608 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(CellularPhone);
     311         1446 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(CordlessPhone);
     312         1284 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(SmartPhone);
     313         1122 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(WiredModemOrVoiceGatewayPhone);
     314          960 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(CommonIsdnAccessPhone);
     315          672 :         break;
     316          112 :     #if (QT_VERSION < QT_VERSION_CHECK(5, 13, 0))
     317          432 :     case QBluetoothDeviceInfo::LANAccessDevice: // Deprecated since Qt 5.13.
     318              :     #else
     319         2034 :     case QBluetoothDeviceInfo::NetworkDevice: // Added in Qt 5.13.
     320         1008 :     #endif
     321         1806 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(NetworkFullService);
     322         1332 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(NetworkLoadFactorOne);
     323         1170 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(NetworkLoadFactorTwo);
     324         1008 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(NetworkLoadFactorThree);
     325          846 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(NetworkLoadFactorFour);
     326          684 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(NetworkLoadFactorFive);
     327          522 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(NetworkLoadFactorSix);
     328          360 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(NetworkNoService);
     329          144 :         break;
     330         4932 :     case QBluetoothDeviceInfo::AudioVideoDevice:
     331         3374 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(UncategorizedAudioVideoDevice);
     332         2588 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(WearableHeadsetDevice);
     333         2438 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(HandsFreeDevice);
     334         2288 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(Microphone);
     335         2138 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(Loudspeaker);
     336         1988 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(Headphones);
     337         1838 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(PortableAudioDevice);
     338         1688 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(CarAudio);
     339         1538 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(SetTopBox);
     340         1388 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(HiFiAudioDevice);
     341         1238 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(Vcr);
     342         1088 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(VideoCamera);
     343          938 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(Camcorder);
     344          788 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(VideoMonitor);
     345          638 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(VideoDisplayAndLoudspeaker);
     346          488 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(VideoConferencing);
     347          338 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(GamingDevice);
     348          144 :         break;
     349         3014 :     case QBluetoothDeviceInfo::PeripheralDevice:
     350         2202 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(UncategorizedPeripheral);
     351         1656 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(KeyboardPeripheral);
     352         1494 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(PointingDevicePeripheral);
     353         1332 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(KeyboardWithPointingDevicePeripheral);
     354         1170 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(JoystickPeripheral);
     355         1008 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(GamepadPeripheral);
     356          846 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(RemoteControlPeripheral);
     357          684 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(SensingDevicePeripheral);
     358          522 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(DigitizerTabletPeripheral);
     359          360 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(CardReaderPeripheral);
     360          144 :         break;
     361         1644 :     case QBluetoothDeviceInfo::ImagingDevice:
     362         1212 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(UncategorizedImagingDevice);
     363         1014 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(ImageDisplay);
     364          816 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(ImageCamera);
     365          618 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(ImageScanner);
     366          420 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(ImagePrinter);
     367          144 :         break;
     368         1918 :     case QBluetoothDeviceInfo::WearableDevice:
     369         1410 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(UncategorizedWearableDevice);
     370         1008 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(WearableWristWatch);
     371          846 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(WearablePager);
     372          684 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(WearableJacket);
     373          522 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(WearableHelmet);
     374          360 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(WearableGlasses);
     375          144 :         break;
     376         2466 :     case QBluetoothDeviceInfo::ToyDevice:
     377         1806 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(UncategorizedToy);
     378         1332 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(ToyRobot);
     379         1170 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(ToyVehicle);
     380         1008 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(ToyDoll);
     381          846 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(ToyController);
     382          684 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(ToyGame);
     383          432 :         break;
     384         2466 :     case QBluetoothDeviceInfo::HealthDevice:
     385         1806 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(UncategorizedHealthDevice);
     386         1332 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(HealthBloodPressureMonitor);
     387         1170 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(HealthThermometer);
     388         1008 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(HealthWeightScale);
     389          846 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(HealthGlucoseMeter);
     390          684 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(HealthPulseOximeter);
     391          522 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(HealthDataDisplay);
     392          360 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(HealthStepCounter);
     393          144 :         break;
     394         1032 :     case QBluetoothDeviceInfo::UncategorizedDevice:
     395              :         // There are no minor classes defined (in Qt) for uncategorized devices.
     396         1032 :         break;
     397        17568 :     }
     398         4776 :     #undef DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN
     399        14004 :     qCDebug(lc).noquote() << tr("Unknown minor class %1 for major class %2.")
     400            0 :         .arg(minorClass).arg(majorClass);
     401         4776 :     return QString(); // Null QString indicates unknown minor class.
     402        17568 : }
        

Generated by: LCOV version 2.3.2-1