LCOV - code coverage report
Current view: top level - src/app - scancommand.cpp (source / functions) Hit Total Coverage
Project: QtPokit Lines: 204 208 98.1 %
Version: Functions: 18 18 100.0 %

          Line data    Source code
       1             : // SPDX-FileCopyrightText: 2022 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         885 : ScanCommand::ScanCommand(QObject * const parent) : AbstractCommand(parent), showCsvHeader(true)
      26             : {
      27             :     #if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)) // Required signal, and Fields, added in Qt 5.12.
      28         720 :     connect(discoveryAgent, &PokitDiscoveryAgent::pokitDeviceUpdated,
      29             :             this, &ScanCommand::deviceUpdated);
      30             :     #endif
      31         885 : }
      32             : 
      33          68 : QStringList ScanCommand::requiredOptions(const QCommandLineParser &parser) const
      34             : {
      35          68 :     return AbstractCommand::requiredOptions(parser);
      36             : }
      37             : 
      38          34 : QStringList ScanCommand::supportedOptions(const QCommandLineParser &parser) const
      39             : {
      40          68 :     return AbstractCommand::supportedOptions(parser) + QStringList{
      41          68 :     };
      42             : }
      43             : 
      44             : /// \copydoc AbstractCommand::processOptions
      45          17 : QStringList ScanCommand::processOptions(const QCommandLineParser &parser)
      46             : {
      47          17 :     QStringList errors = AbstractCommand::processOptions(parser);
      48             :     if (!errors.isEmpty()) {
      49             :         return errors;
      50             :     }
      51             : 
      52             :     return errors;
      53             : }
      54             : 
      55             : /*!
      56             :  * Begins scanning for Pokit devices.
      57             :  */
      58          17 : bool ScanCommand::start()
      59             : {
      60             :     Q_ASSERT(discoveryAgent);
      61          37 :     qCInfo(lc).noquote() << tr("Scanning for Pokit devices...");
      62          17 :     discoveryAgent->start();
      63          17 :     return true;
      64             : }
      65             : 
      66             : /*!
      67             :  * Handles discovered Pokit devices, writing \a info to stdout.
      68             :  */
      69        1305 : void ScanCommand::deviceDiscovered(const QBluetoothDeviceInfo &info)
      70             : {
      71        1305 :     switch (format) {
      72         456 :     case OutputFormat::Csv:
      73         696 :         for (; showCsvHeader; showCsvHeader = false) {
      74         315 :             std::cout << qUtf8Printable(tr("uuid,address,name,major_class,minor_class,signal_strength\n"));
      75             :         }
      76        1275 :         std::cout << qUtf8Printable(QString::fromLatin1("%1,%2,%3,%4,%5,%6\n").arg(info.deviceUuid().toString(),
      77             :             info.address().toString(), escapeCsvField(info.name()), toString(info.majorDeviceClass()),
      78             :             toString(info.majorDeviceClass(), info.minorDeviceClass())).arg(info.rssi()));
      79         435 :         break;
      80         435 :     case OutputFormat::Json:
      81         870 :         std::cout << QJsonDocument(toJson(info)).toJson().toStdString();
      82         435 :         break;
      83         150 :     case OutputFormat::Text:
      84        1275 :         std::cout << qUtf8Printable(tr("%1 %2 %3 %4\n").arg(info.deviceUuid().toString(),
      85             :             info.address().toString(), info.name()).arg(info.rssi()));
      86         435 :         break;
      87             :     }
      88        1305 : }
      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         540 : void ScanCommand::deviceUpdated(const QBluetoothDeviceInfo &info,
      95             :                                 const QBluetoothDeviceInfo::Fields updatedFields)
      96             : {
      97             :     Q_UNUSED(updatedFields)
      98         540 :     deviceDiscovered(info);
      99         540 : }
     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          17 : void ScanCommand::deviceDiscoveryFinished()
     107             : {
     108          17 :     qCDebug(lc).noquote() << tr("Finished scanning for Pokit devices.");
     109          17 :     QCoreApplication::quit();
     110          17 : }
     111             : 
     112             : /*!
     113             :  * Returns \a info as a JSON object.
     114             :  */
     115         566 : QJsonObject ScanCommand::toJson(const QBluetoothDeviceInfo &info)
     116             : {
     117         566 :     if (!info.isValid()) {
     118          46 :         return QJsonObject();
     119             :     }
     120             :     QJsonObject json{
     121        1040 :         { QLatin1String("address"), info.address().toString() },
     122        1040 :         { QLatin1String("name"), info.name() },
     123         520 :         { QLatin1String("isCached"), info.isCached() },
     124         520 :         { QLatin1String("majorDeviceClass"), info.majorDeviceClass() },
     125        1040 :         { QLatin1String("majorDeviceClass"), toJson(info.majorDeviceClass()) },
     126        1040 :         { QLatin1String("minorDeviceClass"), toJson(info.majorDeviceClass(), info.minorDeviceClass()) },
     127         520 :         { QLatin1String("signalStrength"), info.rssi() },
     128        6795 :     };
     129         520 :     if (info.coreConfigurations() != QBluetoothDeviceInfo::UnknownCoreConfiguration) {
     130          98 :         json.insert(QLatin1String("coreConfiguration"), toJson(info.coreConfigurations()));
     131             :     }
     132         520 :     if (!info.deviceUuid().isNull()) {
     133         504 :         json.insert(QLatin1String("deviceUuid"), info.deviceUuid().toString());
     134             :     }
     135             :     #if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)) // Added in Qt 5.12.
     136         420 :     if (!info.manufacturerData().isEmpty()) {
     137          51 :         json.insert(QLatin1String("manufacturerData"), toJson(info.manufacturerData()));
     138             :     }
     139             :     #endif
     140         520 :     if (info.serviceClasses() != QBluetoothDeviceInfo::NoService) {
     141         115 :         json.insert(QLatin1String("serviceClasses"), toJson(info.serviceClasses()));
     142             :     }
     143         625 :     if (!info.serviceUuids().isEmpty()) {
     144          27 :         json.insert(QLatin1String("serviceUuids"), toJson(info.serviceUuids()));
     145             :     }
     146         215 :     return json;
     147         180 : }
     148             : 
     149             : /*!
     150             :  * Returns \a configuration as a JSON array of strings.
     151             :  */
     152         131 : QJsonArray ScanCommand::toJson(const QBluetoothDeviceInfo::CoreConfigurations &configurations)
     153             : {
     154         131 :     QJsonArray array;
     155             :     #define QTPOKIT_INTERNAL_IF_SET_THEN_APPEND(flag) \
     156             :         if (configurations.testFlag(QBluetoothDeviceInfo::flag)) \
     157             :             array.append(QLatin1String(#flag))
     158          91 :     QTPOKIT_INTERNAL_IF_SET_THEN_APPEND(UnknownCoreConfiguration);
     159         119 :     QTPOKIT_INTERNAL_IF_SET_THEN_APPEND(LowEnergyCoreConfiguration);
     160          97 :     QTPOKIT_INTERNAL_IF_SET_THEN_APPEND(BaseRateCoreConfiguration);
     161             :   //QTPOKIT_INTERNAL_IF_SET_THEN_APPEND(BaseRateAndLowEnergyCoreConfiguration); // Combination flag.
     162             :     #undef QTPOKIT_INTERNAL_IF_SET_THEN_APPEND
     163         131 :     return array;
     164           0 : }
     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         758 : QJsonValue ScanCommand::toJson(const QBluetoothDeviceInfo::MajorDeviceClass &majorClass)
     173             : {
     174        1105 :     const QString string = toString(majorClass);
     175        1516 :     return (string.isNull() ? QJsonValue(majorClass) : QJsonValue(string));
     176         264 : }
     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        2084 : QJsonValue ScanCommand::toJson(const QBluetoothDeviceInfo::MajorDeviceClass &majorClass, const quint8 minorClass)
     186             : {
     187        3055 :     const QString string = toString(majorClass, minorClass);
     188        4168 :     return (string.isNull() ? QJsonValue(minorClass) : QJsonValue(string));
     189         732 : }
     190             : 
     191             : /*!
     192             :  * Returns \a classes as a JSON array of strings.
     193             :  */
     194         245 : QJsonArray ScanCommand::toJson(const QBluetoothDeviceInfo::ServiceClasses &classes)
     195             : {
     196         245 :     QJsonArray array;
     197             :     #define QTPOKIT_INTERNAL_IF_SET_THEN_APPEND(flag) \
     198             :         if (classes.testFlag(QBluetoothDeviceInfo::flag)) \
     199             :             array.append(QLatin1String(#flag))
     200         197 :     QTPOKIT_INTERNAL_IF_SET_THEN_APPEND(PositioningService);
     201         197 :     QTPOKIT_INTERNAL_IF_SET_THEN_APPEND(NetworkingService);
     202         197 :     QTPOKIT_INTERNAL_IF_SET_THEN_APPEND(RenderingService);
     203         191 :     QTPOKIT_INTERNAL_IF_SET_THEN_APPEND(CapturingService);
     204         191 :     QTPOKIT_INTERNAL_IF_SET_THEN_APPEND(ObjectTransferService);
     205         191 :     QTPOKIT_INTERNAL_IF_SET_THEN_APPEND(AudioService);
     206         191 :     QTPOKIT_INTERNAL_IF_SET_THEN_APPEND(TelephonyService);
     207         191 :     QTPOKIT_INTERNAL_IF_SET_THEN_APPEND(InformationService);
     208             :     #undef QTPOKIT_INTERNAL_IF_SET_THEN_APPEND
     209         245 :     return array;
     210           0 : }
     211             : 
     212             : /*!
     213             :  * Returns \a uuids as a JSON array.
     214             :  */
     215         102 : QJsonArray ScanCommand::toJson(const QList<QBluetoothUuid> &uuids)
     216             : {
     217         102 :     QJsonArray array;
     218         306 :     for (const QBluetoothUuid &uuid: uuids) {
     219         204 :         array.append(uuid.toString());
     220             :     }
     221         102 :     return array;
     222           0 : }
     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          84 : QJsonObject ScanCommand::toJson(const QMultiHash<quint16, QByteArray> &data)
     229             : {
     230          84 :     QJsonObject object;
     231         119 :     QList<quint16> keys = data.uniqueKeys();
     232          21 :     std::sort(keys.begin(), keys.end());
     233         204 :     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         170 :         QList<QByteArray> values = data.values(key);
     238          30 :         std::reverse(values.begin(), values.end());
     239         120 :         QJsonArray array;
     240         285 :         for (const QByteArray &value: values) {
     241         330 :             array.append(QLatin1String(value.toBase64()));
     242             :         }
     243         150 :         object.insert(QString::number(key), array);
     244          40 :     }
     245          84 :     return object;
     246          28 : }
     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        1431 : QString ScanCommand::toString(const QBluetoothDeviceInfo::MajorDeviceClass &majorClass)
     256             : {
     257             :     #define QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(value) \
     258             :         if (majorClass == QBluetoothDeviceInfo::value) \
     259             :             return QLatin1String(#value)
     260        1431 :     QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(MiscellaneousDevice);
     261         525 :     QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(ComputerDevice);
     262         427 :     QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(PhoneDevice);
     263             :     #if (QT_VERSION < QT_VERSION_CHECK(5, 13, 0))
     264         143 :     QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(LANAccessDevice); // Deprecated since Qt 5.13.
     265             :     #else
     266         186 :     QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(NetworkDevice); // Added in Qt 5.13.
     267             :     #endif
     268         307 :     QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(AudioVideoDevice);
     269         285 :     QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(PeripheralDevice);
     270         263 :     QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(ImagingDevice);
     271         241 :     QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(WearableDevice);
     272         219 :     QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(ToyDevice);
     273         197 :     QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(HealthDevice);
     274         175 :     QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(UncategorizedDevice);
     275             :     #undef QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN
     276         102 :     qCDebug(lc).noquote() << QObject::tr("Unknown major class %1.").arg(majorClass);
     277             :     return QString(); // Null QString indicates unknown minor class.
     278             : }
     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        4083 : QString ScanCommand::toString(const QBluetoothDeviceInfo::MajorDeviceClass &majorClass, const quint8 minorClass)
     288             : {
     289             :     #define QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(value) \
     290             :         if (minorClass == QBluetoothDeviceInfo::value) \
     291             :             return QLatin1String(#value)
     292        4083 :     switch (majorClass) {
     293         658 :     case QBluetoothDeviceInfo::MiscellaneousDevice:
     294         658 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(UncategorizedMiscellaneous);
     295             :         break;
     296         388 :     case QBluetoothDeviceInfo::ComputerDevice:
     297         388 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(UncategorizedComputer);
     298         230 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(DesktopComputer);
     299         208 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(ServerComputer);
     300         186 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(LaptopComputer);
     301         164 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(HandheldClamShellComputer);
     302         142 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(HandheldComputer);
     303         120 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(WearableComputer);
     304             :         break;
     305         354 :     case QBluetoothDeviceInfo::PhoneDevice:
     306         354 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(UncategorizedPhone);
     307         208 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(CellularPhone);
     308         186 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(CordlessPhone);
     309         164 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(SmartPhone);
     310         142 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(WiredModemOrVoiceGatewayPhone);
     311         120 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(CommonIsdnAccessPhone);
     312             :         break;
     313             :     #if (QT_VERSION < QT_VERSION_CHECK(5, 13, 0))
     314         144 :     case QBluetoothDeviceInfo::LANAccessDevice: // Deprecated since Qt 5.13.
     315             :     #else
     316         162 :     case QBluetoothDeviceInfo::NetworkDevice: // Added in Qt 5.13.
     317             :     #endif
     318         306 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(NetworkFullService);
     319         176 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(NetworkLoadFactorOne);
     320         154 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(NetworkLoadFactorTwo);
     321         132 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(NetworkLoadFactorThree);
     322         110 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(NetworkLoadFactorFour);
     323          88 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(NetworkLoadFactorFive);
     324          66 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(NetworkLoadFactorSix);
     325          44 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(NetworkNoService);
     326             :         break;
     327         612 :     case QBluetoothDeviceInfo::AudioVideoDevice:
     328         612 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(UncategorizedAudioVideoDevice);
     329         374 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(WearableHeadsetDevice);
     330         352 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(HandsFreeDevice);
     331         330 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(Microphone);
     332         308 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(Loudspeaker);
     333         286 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(Headphones);
     334         264 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(PortableAudioDevice);
     335         242 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(CarAudio);
     336         220 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(SetTopBox);
     337         198 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(HiFiAudioDevice);
     338         176 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(Vcr);
     339         154 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(VideoCamera);
     340         132 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(Camcorder);
     341         110 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(VideoMonitor);
     342          88 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(VideoDisplayAndLoudspeaker);
     343          66 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(VideoConferencing);
     344          44 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(GamingDevice);
     345             :         break;
     346         374 :     case QBluetoothDeviceInfo::PeripheralDevice:
     347         374 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(UncategorizedPeripheral);
     348         220 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(KeyboardPeripheral);
     349         198 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(PointingDevicePeripheral);
     350         176 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(KeyboardWithPointingDevicePeripheral);
     351         154 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(JoystickPeripheral);
     352         132 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(GamepadPeripheral);
     353         110 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(RemoteControlPeripheral);
     354          88 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(SensingDevicePeripheral);
     355          66 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(DigitizerTabletPeripheral);
     356          44 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(CardReaderPeripheral);
     357             :         break;
     358         204 :     case QBluetoothDeviceInfo::ImagingDevice:
     359         204 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(UncategorizedImagingDevice);
     360         170 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(ImageDisplay);
     361         136 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(ImageCamera);
     362         102 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(ImageScanner);
     363          68 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(ImagePrinter);
     364             :         break;
     365         238 :     case QBluetoothDeviceInfo::WearableDevice:
     366         238 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(UncategorizedWearableDevice);
     367         132 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(WearableWristWatch);
     368         110 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(WearablePager);
     369          88 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(WearableJacket);
     370          66 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(WearableHelmet);
     371          44 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(WearableGlasses);
     372             :         break;
     373         306 :     case QBluetoothDeviceInfo::ToyDevice:
     374         306 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(UncategorizedToy);
     375         176 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(ToyRobot);
     376         154 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(ToyVehicle);
     377         132 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(ToyDoll);
     378         110 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(ToyController);
     379          88 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(ToyGame);
     380             :         break;
     381         306 :     case QBluetoothDeviceInfo::HealthDevice:
     382         306 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(UncategorizedHealthDevice);
     383         176 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(HealthBloodPressureMonitor);
     384         154 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(HealthThermometer);
     385         132 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(HealthWeightScale);
     386         110 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(HealthGlucoseMeter);
     387          88 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(HealthPulseOximeter);
     388          66 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(HealthDataDisplay);
     389          44 :         QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN(HealthStepCounter);
     390             :         break;
     391             :     case QBluetoothDeviceInfo::UncategorizedDevice:
     392             :         // There are no minor classes defined (in Qt) for uncategorized devices.
     393             :         break;
     394             :     }
     395             :     #undef QTPOKIT_INTERNAL_IF_EQUAL_THEN_RETURN
     396        1093 :     qCDebug(lc).noquote() << QObject::tr("Unknown minor class %1 for major class %2.")
     397           0 :         .arg(minorClass).arg(majorClass);
     398             :     return QString(); // Null QString indicates unknown minor class.
     399             : }
     400             : 
     401             : QTPOKIT_END_NAMESPACE

Generated by: LCOV version 1.14