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              : 
       6              : #include <qtpokit/pokitdiscoveryagent.h>
       7              : 
       8              : #include <QBluetoothUuid>
       9              : #include <QJsonArray>
      10              : #include <QJsonDocument>
      11              : #include <QJsonObject>
      12              : 
      13              : #include <iostream>
      14              : 
      15              : /*!
      16              :  * \class ScanCommand
      17              :  *
      18              :  * The ScanCommand class implements the `scan` CLI command, by scanning for nearby Pokit Bluetooth
      19              :  * devices. When devices are found, they are logged to stdout in the chosen format.
      20              :  */
      21              : 
      22              : /*!
      23              :  * Construct a new ScanCommand object with \a parent.
      24              :  */
      25         3777 : ScanCommand::ScanCommand(QObject * const parent) : AbstractCommand(parent)
      26         2847 : {
      27         2556 :     #if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)) // Required signal, and Fields, added in Qt 5.12.
      28         4896 :     connect(discoveryAgent, &PokitDiscoveryAgent::pokitDeviceUpdated,
      29         3216 :             this, &ScanCommand::deviceUpdated);
      30         2556 :     #endif
      31         5385 : }
      32              : 
      33          180 : QStringList ScanCommand::requiredOptions(const QCommandLineParser &parser) const
      34          208 : {
      35          388 :     return AbstractCommand::requiredOptions(parser);
      36          208 : }
      37              : 
      38           90 : QStringList ScanCommand::supportedOptions(const QCommandLineParser &parser) const
      39          104 : {
      40          284 :     return AbstractCommand::supportedOptions(parser) + QStringList{
      41          258 :     };
      42          104 : }
      43              : 
      44              : /// \copydoc AbstractCommand::processOptions
      45           45 : QStringList ScanCommand::processOptions(const QCommandLineParser &parser)
      46           52 : {
      47           97 :     QStringList errors = AbstractCommand::processOptions(parser);
      48           52 :     if (!errors.isEmpty()) {
      49            0 :         return errors;
      50            0 :     }
      51              : 
      52           52 :     return errors;
      53           52 : }
      54              : 
      55              : /*!
      56              :  * Begins scanning for Pokit devices.
      57              :  */
      58           45 : bool ScanCommand::start()
      59           22 : {
      60           22 :     Q_ASSERT(discoveryAgent);
      61          146 :     qCInfo(lc).noquote() << tr("Scanning for Pokit devices...");
      62           67 :     discoveryAgent->start();
      63           67 :     return true;
      64           22 : }
      65              : 
      66              : /*!
      67              :  * Handles discovered Pokit devices, writing \a info to stdout.
      68              :  */
      69         3780 : void ScanCommand::deviceDiscovered(const QBluetoothDeviceInfo &info)
      70         4275 : {
      71         8055 :     switch (format) {
      72         1425 :     case OutputFormat::Csv:
      73         4296 :         for (; showCsvHeader; showCsvHeader = false) {
      74         1989 :             std::cout << qUtf8Printable(tr("uuid,address,name,major_class,minor_class,signal_strength\n"));
      75          855 :         }
      76         6165 :         std::cout << qUtf8Printable(QString::fromLatin1("%1,%2,%3,%4,%5,%6\n").arg(info.deviceUuid().toString(),
      77         1425 :             info.address().toString(), escapeCsvField(info.name()), toString(info.majorDeviceClass()),
      78         1425 :             toString(info.majorDeviceClass(), info.minorDeviceClass())).arg(info.rssi()));
      79         2685 :         break;
      80         2685 :     case OutputFormat::Json:
      81         3945 :         std::cout << QJsonDocument(toJson(info)).toJson().toStdString();
      82         2685 :         break;
      83         2685 :     case OutputFormat::Text:
      84         5535 :         std::cout << qUtf8Printable(tr("%1 %2 %3 %4\n").arg(info.deviceUuid().toString(),
      85         1425 :             info.address().toString(), info.name()).arg(info.rssi()));
      86         2685 :         break;
      87         4275 :     }
      88         8055 : }
      89              : 
      90              : /*!
      91              :  * Handles updated Pokit devices, writing \a info to stdout. Currently \a updatedFields us unused.
      92              :  */
      93              : #if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)) // Required signal, and Fields, added in Qt 5.12.
      94         1755 : void ScanCommand::deviceUpdated(const QBluetoothDeviceInfo &info,
      95              :                                 const QBluetoothDeviceInfo::Fields updatedFields)
      96         1935 : {
      97         1935 :     Q_UNUSED(updatedFields)
      98         3690 :     deviceDiscovered(info);
      99         3690 : }
     100              : #endif
     101              : 
     102              : /*!
     103              :  * Handles the completion of device discovery. In this override we simply exit, as the scan command
     104              :  * is nothing more than logging of discovered devices.
     105              :  */
     106           45 : void ScanCommand::deviceDiscoveryFinished()
     107           52 : {
     108          110 :     qCDebug(lc).noquote() << tr("Finished scanning for Pokit devices.");
     109           97 :     QCoreApplication::quit();
     110           97 : }
     111              : 
     112              : /*!
     113              :  * Returns \a info as a JSON object.
     114              :  */
     115         1614 : QJsonObject ScanCommand::toJson(const QBluetoothDeviceInfo &info)
     116         1832 : {
     117         3446 :     if (!info.isValid()) {
     118          276 :         return QJsonObject();
     119          147 :     }
     120         1685 :     QJsonObject json{
     121         4270 :         { QLatin1String("address"), info.address().toString() },
     122         4655 :         { QLatin1String("name"), info.name() },
     123         3135 :         { QLatin1String("isCached"), info.isCached() },
     124         3170 :         { QLatin1String("majorDeviceClass"), info.majorDeviceClass() },
     125         3905 :         { QLatin1String("majorDeviceClass"), toJson(info.majorDeviceClass()) },
     126         3905 :         { QLatin1String("minorDeviceClass"), toJson(info.majorDeviceClass(), info.minorDeviceClass()) },
     127         3905 :         { QLatin1String("signalStrength"), info.rssi() },
     128        16030 :     };
     129         3170 :     if (info.coreConfigurations() != QBluetoothDeviceInfo::UnknownCoreConfiguration) {
     130          447 :         json.insert(QLatin1String("coreConfiguration"), toJson(info.coreConfigurations()));
     131          199 :     }
     132         3231 :     if (!info.deviceUuid().isNull()) {
     133         2847 :         json.insert(QLatin1String("deviceUuid"), info.deviceUuid().toString());
     134         1063 :     }
     135         1505 :     #if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)) // Added in Qt 5.12.
     136         2870 :     if (!info.manufacturerData().isEmpty()) {
     137          342 :         json.insert(QLatin1String("manufacturerData"), toJson(info.manufacturerData()));
     138          129 :     }
     139         1505 :     #endif
     140         3170 :     if (info.serviceClasses() != QBluetoothDeviceInfo::NoService) {
     141          543 :         json.insert(QLatin1String("serviceClasses"), toJson(info.serviceClasses()));
     142          242 :     }
     143         3905 :     if (!info.serviceUuids().isEmpty()) {
     144          138 :         json.insert(QLatin1String("serviceUuids"), toJson(info.serviceUuids()));
     145           52 :     }
     146         2670 :     return json;
     147        14702 : }
     148              : 
     149              : /*!
     150              :  * Returns \a configuration as a JSON array of strings.
     151              :  */
     152          354 : QJsonArray ScanCommand::toJson(const QBluetoothDeviceInfo::CoreConfigurations &configurations)
     153          407 : {
     154          761 :     QJsonArray array;
     155          407 :     #define DOKIT_INTERNAL_IF_SET_THEN_APPEND(flag) \
     156         1221 :         if (configurations.testFlag(QBluetoothDeviceInfo::flag)) \
     157         1221 :             array.append(QLatin1String(#flag))
     158          608 :     DOKIT_INTERNAL_IF_SET_THEN_APPEND(UnknownCoreConfiguration);
     159          767 :     DOKIT_INTERNAL_IF_SET_THEN_APPEND(LowEnergyCoreConfiguration);
     160          641 :     DOKIT_INTERNAL_IF_SET_THEN_APPEND(BaseRateCoreConfiguration);
     161              :   //DOKIT_INTERNAL_IF_SET_THEN_APPEND(BaseRateAndLowEnergyCoreConfiguration); // Combination flag.
     162          407 :     #undef DOKIT_INTERNAL_IF_SET_THEN_APPEND
     163          761 :     return array;
     164          407 : }
     165              : 
     166              : /*!
     167              :  * Returns \a majorClass as a JSON value. This is equivalent to toString, except that if toString
     168              :  * does not recognise \a majorClass, then \a majorClass is returned as a JSON number (not a string).
     169              :  *
     170              :  * \see toString(const QBluetoothDeviceInfo::MajorDeviceClass &majorClass)
     171              :  */
     172         2115 : QJsonValue ScanCommand::toJson(const QBluetoothDeviceInfo::MajorDeviceClass &majorClass)
     173         2413 : {
     174         4528 :     const QString string = toString(majorClass);
     175         6643 :     return (string.isNull() ? QJsonValue(majorClass) : QJsonValue(string));
     176         3499 : }
     177              : 
     178              : /*!
     179              :  * Returns \a minorClass as a JSON value. This is equivalent to toString, except that if toString
     180              :  * does not recognise \a minorClass as a sub-class of \a majorClass, then \a minorClass is returned
     181              :  * as a JSON number (not a string).
     182              :  *
     183              :  * \see toString(const QBluetoothDeviceInfo::MajorDeviceClass &majorClass, const quint8 minorClass)
     184              :  */
     185         5625 : QJsonValue ScanCommand::toJson(const QBluetoothDeviceInfo::MajorDeviceClass &majorClass, const quint8 minorClass)
     186         6469 : {
     187        12094 :     const QString string = toString(majorClass, minorClass);
     188        17719 :     return (string.isNull() ? QJsonValue(minorClass) : QJsonValue(string));
     189         9427 : }
     190              : 
     191              : /*!
     192              :  * Returns \a classes as a JSON array of strings.
     193              :  */
     194          663 : QJsonArray ScanCommand::toJson(const QBluetoothDeviceInfo::ServiceClasses &classes)
     195          762 : {
     196         1425 :     QJsonArray array;
     197          762 :     #define DOKIT_INTERNAL_IF_SET_THEN_APPEND(flag) \
     198         6096 :         if (classes.testFlag(QBluetoothDeviceInfo::flag)) \
     199         6096 :             array.append(QLatin1String(#flag))
     200         1296 :     DOKIT_INTERNAL_IF_SET_THEN_APPEND(PositioningService);
     201         1296 :     DOKIT_INTERNAL_IF_SET_THEN_APPEND(NetworkingService);
     202         1296 :     DOKIT_INTERNAL_IF_SET_THEN_APPEND(RenderingService);
     203         1263 :     DOKIT_INTERNAL_IF_SET_THEN_APPEND(CapturingService);
     204         1263 :     DOKIT_INTERNAL_IF_SET_THEN_APPEND(ObjectTransferService);
     205         1263 :     DOKIT_INTERNAL_IF_SET_THEN_APPEND(AudioService);
     206         1263 :     DOKIT_INTERNAL_IF_SET_THEN_APPEND(TelephonyService);
     207         1263 :     DOKIT_INTERNAL_IF_SET_THEN_APPEND(InformationService);
     208          762 :     #undef DOKIT_INTERNAL_IF_SET_THEN_APPEND
     209         1425 :     return array;
     210          762 : }
     211              : 
     212              : /*!
     213              :  * Returns \a uuids as a JSON array.
     214              :  */
     215          270 : QJsonArray ScanCommand::toJson(const QList<QBluetoothUuid> &uuids)
     216          312 : {
     217          582 :     QJsonArray array;
     218         1434 :     for (const QBluetoothUuid &uuid: uuids) {
     219         1476 :         array.append(uuid.toString());
     220          624 :     }
     221          582 :     return array;
     222          312 : }
     223              : 
     224              : /*!
     225              :  * Returns Bluetooth manufacturer \a data as a JSON object that maps the manufacturer IDs (unsigned
     226              :  * integers as strings) to arrays of one or more values.
     227              :  */
     228          273 : QJsonObject ScanCommand::toJson(const QMultiHash<quint16, QByteArray> &data)
     229          301 : {
     230          574 :     QJsonObject object;
     231          574 :     QList<quint16> keys = data.uniqueKeys();
     232          448 :     std::sort(keys.begin(), keys.end());
     233         1093 :     for (const quint16 key: keys) {
     234              :         // Convert the key's values to a JSON array, reversing the order, because QMultiHash
     235              :         // guarantees that the values are orderer "from the most recently inserted to the least
     236              :         // recently inserted", which is the oppoosit of what we want.
     237          760 :         QList<QByteArray> values = data.values(key);
     238          640 :         std::reverse(values.begin(), values.end());
     239          820 :         QJsonArray array;
     240         1578 :         for (const QByteArray &value: values) {
     241         1974 :             array.append(QLatin1String(value.toBase64()));
     242          627 :         }
     243          990 :         object.insert(QString::number(key), array);
     244          820 :     }
     245          574 :     return object;
     246          427 : }
     247              : 
     248              : /*!
     249              :  * Returns \a majorClass as a human-readable string, or a null QString if \a majorClass is not
     250              :  * recognised.
     251              :  *
     252              :  * For example, if \a majorClass is \c QBluetoothDeviceInfo::ToyDevice, then the string `ToyDevice`
     253              :  * is returned.
     254              :  */
     255         4005 : QString ScanCommand::toString(const QBluetoothDeviceInfo::MajorDeviceClass &majorClass)
     256         4566 : {
     257         4566 :     #define DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(value) \
     258        18866 :         if (majorClass == QBluetoothDeviceInfo::value) \
     259        18866 :             return QLatin1String(#value)
     260         8571 :     DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(MiscellaneousDevice);
     261         2664 :     DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(ComputerDevice);
     262         2180 :     DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(PhoneDevice);
     263          336 :     #if (QT_VERSION < QT_VERSION_CHECK(5, 13, 0))
     264          336 :     DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(LANAccessDevice); // Deprecated since Qt 5.13.
     265              :     #else
     266         1264 :     DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(NetworkDevice); // Added in Qt 5.13.
     267         1160 :     #endif
     268         1496 :     DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(AudioVideoDevice);
     269         1392 :     DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(PeripheralDevice);
     270         1288 :     DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(ImagingDevice);
     271         1184 :     DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(WearableDevice);
     272         1080 :     DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(ToyDevice);
     273          976 :     DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(HealthDevice);
     274          980 :     DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(UncategorizedDevice);
     275          312 :     #undef DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN
     276          660 :     qCDebug(lc).noquote() << tr("Unknown major class %1.").arg(majorClass);
     277          312 :     return QString(); // Null QString indicates unknown minor class.
     278          848 : }
     279              : 
     280              : /*!
     281              :  * Returns \a minorClass as a human-readable string, or a null QString if \a minorClass is not
     282              :  * recognised as a sub-class of \a majorClass.
     283              :  *
     284              :  * For example, if \a majorClass is \c QBluetoothDeviceInfo::ToyDevice, and \a minorClass is
     285              :  * \c QBluetoothDeviceInfo::ToyRobot, then the string `ToyRobot` is returned.
     286              :  */
     287        11025 : QString ScanCommand::toString(const QBluetoothDeviceInfo::MajorDeviceClass &majorClass, const quint8 minorClass)
     288        12678 : {
     289        12678 :     #define DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(value) \
     290        56050 :         if (minorClass == QBluetoothDeviceInfo::value) \
     291        56050 :             return QLatin1String(#value)
     292        23703 :     switch (majorClass) {
     293         3998 :     case QBluetoothDeviceInfo::MiscellaneousDevice:
     294         3998 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(UncategorizedMiscellaneous);
     295          484 :         break;
     296         2268 :     case QBluetoothDeviceInfo::ComputerDevice:
     297         1602 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(UncategorizedComputer);
     298         1240 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(DesktopComputer);
     299         1126 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(ServerComputer);
     300         1012 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(LaptopComputer);
     301          898 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(HandheldClamShellComputer);
     302          784 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(HandheldComputer);
     303          670 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(WearableComputer);
     304          484 :         break;
     305         2074 :     case QBluetoothDeviceInfo::PhoneDevice:
     306         1466 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(UncategorizedPhone);
     307         1126 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(CellularPhone);
     308         1012 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(CordlessPhone);
     309          898 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(SmartPhone);
     310          784 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(WiredModemOrVoiceGatewayPhone);
     311          670 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(CommonIsdnAccessPhone);
     312          484 :         break;
     313           84 :     #if (QT_VERSION < QT_VERSION_CHECK(5, 13, 0))
     314          396 :     case QBluetoothDeviceInfo::LANAccessDevice: // Deprecated since Qt 5.13.
     315              :     #else
     316         1350 :     case QBluetoothDeviceInfo::NetworkDevice: // Added in Qt 5.13.
     317          720 :     #endif
     318         1242 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(NetworkFullService);
     319          934 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(NetworkLoadFactorOne);
     320          820 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(NetworkLoadFactorTwo);
     321          706 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(NetworkLoadFactorThree);
     322          592 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(NetworkLoadFactorFour);
     323          478 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(NetworkLoadFactorFive);
     324          364 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(NetworkLoadFactorSix);
     325          250 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(NetworkNoService);
     326          104 :         break;
     327         3492 :     case QBluetoothDeviceInfo::AudioVideoDevice:
     328         2288 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(UncategorizedAudioVideoDevice);
     329         1792 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(WearableHeadsetDevice);
     330         1688 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(HandsFreeDevice);
     331         1584 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(Microphone);
     332         1480 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(Loudspeaker);
     333         1376 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(Headphones);
     334         1272 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(PortableAudioDevice);
     335         1168 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(CarAudio);
     336         1064 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(SetTopBox);
     337          960 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(HiFiAudioDevice);
     338          856 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(Vcr);
     339          752 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(VideoCamera);
     340          648 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(Camcorder);
     341          544 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(VideoMonitor);
     342          440 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(VideoDisplayAndLoudspeaker);
     343          336 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(VideoConferencing);
     344          232 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(GamingDevice);
     345          104 :         break;
     346         2134 :     case QBluetoothDeviceInfo::PeripheralDevice:
     347         1514 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(UncategorizedPeripheral);
     348         1162 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(KeyboardPeripheral);
     349         1048 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(PointingDevicePeripheral);
     350          934 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(KeyboardWithPointingDevicePeripheral);
     351          820 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(JoystickPeripheral);
     352          706 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(GamepadPeripheral);
     353          592 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(RemoteControlPeripheral);
     354          478 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(SensingDevicePeripheral);
     355          364 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(DigitizerTabletPeripheral);
     356          250 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(CardReaderPeripheral);
     357          104 :         break;
     358         1164 :     case QBluetoothDeviceInfo::ImagingDevice:
     359          834 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(UncategorizedImagingDevice);
     360          698 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(ImageDisplay);
     361          562 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(ImageCamera);
     362          426 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(ImageScanner);
     363          290 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(ImagePrinter);
     364          104 :         break;
     365         1358 :     case QBluetoothDeviceInfo::WearableDevice:
     366          970 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(UncategorizedWearableDevice);
     367          706 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(WearableWristWatch);
     368          592 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(WearablePager);
     369          478 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(WearableJacket);
     370          364 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(WearableHelmet);
     371          250 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(WearableGlasses);
     372          104 :         break;
     373         1746 :     case QBluetoothDeviceInfo::ToyDevice:
     374         1242 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(UncategorizedToy);
     375          934 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(ToyRobot);
     376          820 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(ToyVehicle);
     377          706 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(ToyDoll);
     378          592 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(ToyController);
     379          478 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(ToyGame);
     380          312 :         break;
     381         1746 :     case QBluetoothDeviceInfo::HealthDevice:
     382         1242 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(UncategorizedHealthDevice);
     383          934 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(HealthBloodPressureMonitor);
     384          820 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(HealthThermometer);
     385          706 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(HealthWeightScale);
     386          592 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(HealthGlucoseMeter);
     387          478 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(HealthPulseOximeter);
     388          364 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(HealthDataDisplay);
     389          250 :         DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(HealthStepCounter);
     390          104 :         break;
     391          744 :     case QBluetoothDeviceInfo::UncategorizedDevice:
     392              :         // There are no minor classes defined (in Qt) for uncategorized devices.
     393          744 :         break;
     394        12678 :     }
     395         3444 :     #undef DOKIT_INTERNAL_IF_EQUAL_THEN_RETURN
     396         7350 :     qCDebug(lc).noquote() << tr("Unknown minor class %1 for major class %2.")
     397            0 :         .arg(minorClass).arg(majorClass);
     398         3444 :     return QString(); // Null QString indicates unknown minor class.
     399        12678 : }
        

Generated by: LCOV version 2.3-1