Dokit
Internal development documentation
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Pages
infocommand.cpp
1// SPDX-FileCopyrightText: 2022-2025 Paul Colby <git@colby.id.au>
2// SPDX-License-Identifier: LGPL-3.0-or-later
3
4#include "infocommand.h"
6
9
10#include <QJsonDocument>
11#include <QJsonObject>
12
13#include <iostream>
14
16
17/*!
18 * \class InfoCommand
19 *
20 * The InfoCommand class implements the `info` CLI command.
21 */
22
23/*!
24 * Construct a new InfoCommand object with \a parent.
25 */
30
36
41
42/*!
43 * \copybrief DeviceCommand::processOptions
44 *
45 * This implementation extends DeviceCommand::processOptions to process additional CLI options
46 * supported (or required) by this command.
47 */
49{
51 if (!errors.isEmpty()) {
52 return errors;
53 }
54
55 return errors;
56}
57
58/*!
59 * \copybrief DeviceCommand::getService
60 *
61 * This override returns a pointer to a DeviceInfoService object.
62 */
64{
65 Q_ASSERT(device);
66 if (!service) {
67 service = device->deviceInformation();
68 Q_ASSERT(service);
69 }
70 return service;
71}
72
73/*!
74 * \copybrief DeviceCommand::serviceDetailsDiscovered
75 *
76 * This override fetches the current device's information, and outputs it in the selected format.
77 */
79{
80 DeviceCommand::serviceDetailsDiscovered(); // Just logs consistently.
81 const QLowEnergyController * const controller = (device) ? device->controller() : nullptr;
82 const QString deviceName = (controller) ? controller->remoteName() : QString();
83 const QBluetoothAddress deviceAddress = (controller) ? controller->remoteAddress() : QBluetoothAddress();
84 const QBluetoothUuid deviceUuid = (controller) ? controller->remoteDeviceUuid() : QBluetoothUuid();
85 const QString serialNumber = service->serialNumber();
86 switch (format) {
88 std::cout << qUtf8Printable(tr("device_name,device_address,device_uuid,manufacturer_name,model_number,"
89 "hardware_revision,firmware_revision,software_revision,serial_number\n"));
90 std::cout << qUtf8Printable(QString::fromLatin1("%1,%2,%3,%4,%5,%6,%7,%8,%9\n").arg(
91 escapeCsvField(deviceName),
92 (deviceAddress.isNull()) ? QString() : deviceAddress.toString(),
93 (deviceUuid.isNull()) ? QString() : deviceUuid.toString(),
94 escapeCsvField(service->manufacturer()), escapeCsvField(service->modelNumber()),
95 escapeCsvField(service->hardwareRevision()), escapeCsvField(service->firmwareRevision()),
96 escapeCsvField(service->softwareRevision()), escapeCsvField(serialNumber)));
97 break;
98 case OutputFormat::Json: {
99 QJsonObject jsonObject{
100 { u"manufacturerName"_s, service->manufacturer() },
101 { u"modelNumber"_s, service->modelNumber() },
102 { u"hardwareRevision"_s, service->hardwareRevision() },
103 { u"firmwareRevision"_s, service->firmwareRevision() },
104 { u"softwareRevision"_s, service->softwareRevision() },
105 };
106 if (!deviceName.isEmpty()) {
107 jsonObject.insert(u"deviceName"_s, deviceName);
108 }
109 if (!deviceAddress.isNull()) {
110 jsonObject.insert(u"deviceAddress"_s, deviceAddress.toString());
111 }
112 if (!deviceUuid.isNull()) {
113 jsonObject.insert(u"deviceUuid"_s, deviceUuid.toString());
114 }
115 if (!serialNumber.isNull()) {
116 jsonObject.insert(u"serialNumber"_s, serialNumber);
117 }
118 std::cout << QJsonDocument(jsonObject).toJson().toStdString();
119 } break;
121 if (!deviceName.isEmpty()) {
122 std::cout << qUtf8Printable(tr("Device name: %1\n").arg(deviceName));
123 }
124 if (!deviceAddress.isNull()) {
125 std::cout << qUtf8Printable(tr("Device address: %1\n").arg(deviceAddress.toString()));
126 }
127 if (!deviceUuid.isNull()) {
128 std::cout << qUtf8Printable(tr("Device UUID: %1\n").arg(deviceUuid.toString()));
129 }
130 std::cout << qUtf8Printable(tr("Manufacturer name: %1\n").arg(service->manufacturer()));
131 std::cout << qUtf8Printable(tr("Model number: %1\n").arg(service->modelNumber()));
132 std::cout << qUtf8Printable(tr("Hardware revision: %1\n").arg(service->hardwareRevision()));
133 std::cout << qUtf8Printable(tr("Firmware revision: %1\n").arg(service->firmwareRevision()));
134 std::cout << qUtf8Printable(tr("Software revision: %1\n").arg(service->softwareRevision()));
135 if (!serialNumber.isNull()) {
136 std::cout << qUtf8Printable(tr("Serial number: %1\n").arg(serialNumber));
137 }
138 break;
139 }
140 if (device) disconnect(); // Will exit the application once disconnected.
141}
virtual QStringList supportedOptions(const QCommandLineParser &parser) const
Returns a list of CLI option names supported by this command.
OutputFormat format
Selected output format.
@ Text
Plain unstructured text.
@ Csv
RFC 4180 compliant CSV text.
@ Json
RFC 8259 compliant JSON text.
virtual QStringList processOptions(const QCommandLineParser &parser)
Processes the relevant options from the command line parser.
static QString escapeCsvField(const QString &field)
Returns an RFC 4180 compliant version of field.
virtual QStringList requiredOptions(const QCommandLineParser &parser) const
Returns a list of CLI option names required by this command.
The AbstractPokitService class provides a common base for Pokit services classes.
PokitDevice * device
Pokit Bluetooth device (if any) this command interacts with.
DeviceCommand(QObject *const parent=nullptr)
Construct a new DeviceCommand object with parent.
virtual void serviceDetailsDiscovered()
Handles service detail discovery events.
void disconnect(int exitCode=EXIT_SUCCESS)
Disconnects the underlying Pokit device, and sets exitCode to be return to the OS once the disconnect...
QStringList requiredOptions(const QCommandLineParser &parser) const override
Returns a list of CLI option names required by this command.
void serviceDetailsDiscovered() override
Handles service detail discovery events.
QStringList supportedOptions(const QCommandLineParser &parser) const override
Returns a list of CLI option names supported by this command.
DeviceInfoService * service
Bluetooth service this command interacts with.
Definition infocommand.h:28
AbstractPokitService * getService() override
Returns a Pokit service object for the derived command class.
QStringList processOptions(const QCommandLineParser &parser) override
Processes the relevant options from the command line parser.
InfoCommand(QObject *const parent=nullptr)
Construct a new InfoCommand object with parent.
Declares the DeviceInfoService class.
Declares the PokitDevice class.
bool isNull() const const
QString toString() const const
std::string toStdString() const const
QByteArray toJson() const const
bool isEmpty() const const
QBluetoothAddress remoteAddress() const const
QBluetoothUuid remoteDeviceUuid() const const
QString remoteName() const const
QObject(QObject *parent)
QObject * parent() const const
QString tr(const char *sourceText, const char *disambiguation, int n)
QString fromLatin1(const char *str, int size)
bool isEmpty() const const
bool isNull() const const
bool isNull() const const
QString toString() const const
Declares the DOKIT_USE_STRINGLITERALS macro, and related functions.
#define DOKIT_USE_STRINGLITERALS
Internal macro for using either official Qt string literals (added in Qt 6.4), or our own equivalent ...