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 "infocommand.h"
5 : #include "../stringliterals_p.h"
6 :
7 : #include <qtpokit/deviceinfoservice.h>
8 : #include <qtpokit/pokitdevice.h>
9 :
10 : #include <QJsonDocument>
11 : #include <QJsonObject>
12 :
13 : #include <iostream>
14 :
15 : DOKIT_USE_STRINGLITERALS
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 : */
26 2976 : InfoCommand::InfoCommand(QObject * const parent) : DeviceCommand(parent)
27 800 : {
28 :
29 3040 : }
30 :
31 400 : QStringList InfoCommand::requiredOptions(const QCommandLineParser &parser) const
32 280 : {
33 1080 : return DeviceCommand::requiredOptions(parser) + QStringList{
34 935 : };
35 280 : }
36 :
37 160 : QStringList InfoCommand::supportedOptions(const QCommandLineParser &parser) const
38 112 : {
39 272 : return DeviceCommand::supportedOptions(parser);
40 112 : }
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 : */
48 80 : QStringList InfoCommand::processOptions(const QCommandLineParser &parser)
49 56 : {
50 136 : QStringList errors = DeviceCommand::processOptions(parser);
51 56 : if (!errors.isEmpty()) {
52 0 : return errors;
53 0 : }
54 :
55 56 : return errors;
56 56 : }
57 :
58 : /*!
59 : * \copybrief DeviceCommand::getService
60 : *
61 : * This override returns a pointer to a DeviceInfoService object.
62 : */
63 0 : AbstractPokitService * InfoCommand::getService()
64 0 : {
65 0 : Q_ASSERT(device);
66 0 : if (!service) {
67 0 : service = device->deviceInformation();
68 0 : Q_ASSERT(service);
69 0 : }
70 0 : return service;
71 0 : }
72 :
73 : /*!
74 : * \copybrief DeviceCommand::serviceDetailsDiscovered
75 : *
76 : * This override fetches the current device's information, and outputs it in the selected format.
77 : */
78 1920 : void InfoCommand::serviceDetailsDiscovered()
79 576 : {
80 2496 : DeviceCommand::serviceDetailsDiscovered(); // Just logs consistently.
81 2496 : const QLowEnergyController * const controller = (device) ? device->controller() : nullptr;
82 2496 : const QString deviceName = (controller) ? controller->remoteName() : QString();
83 2496 : const QBluetoothAddress deviceAddress = (controller) ? controller->remoteAddress() : QBluetoothAddress();
84 2496 : const QBluetoothUuid deviceUuid = (controller) ? controller->remoteDeviceUuid() : QBluetoothUuid();
85 2496 : const QString serialNumber = service->serialNumber();
86 2496 : switch (format) {
87 832 : case OutputFormat::Csv:
88 1176 : std::cout << qUtf8Printable(tr("device_name,device_address,device_uuid,manufacturer_name,model_number,"
89 192 : "hardware_revision,firmware_revision,software_revision,serial_number\n"));
90 4032 : std::cout << qUtf8Printable(QString::fromLatin1("%1,%2,%3,%4,%5,%6,%7,%8,%9\n").arg(
91 192 : escapeCsvField(deviceName),
92 192 : (deviceAddress.isNull()) ? QString() : deviceAddress.toString(),
93 192 : (deviceUuid.isNull()) ? QString() : deviceUuid.toString(),
94 192 : escapeCsvField(service->manufacturer()), escapeCsvField(service->modelNumber()),
95 192 : escapeCsvField(service->hardwareRevision()), escapeCsvField(service->firmwareRevision()),
96 192 : escapeCsvField(service->softwareRevision()), escapeCsvField(serialNumber)));
97 832 : break;
98 832 : case OutputFormat::Json: {
99 192 : QJsonObject jsonObject{
100 1472 : { u"manufacturerName"_s, service->manufacturer() },
101 1472 : { u"modelNumber"_s, service->modelNumber() },
102 1472 : { u"hardwareRevision"_s, service->hardwareRevision() },
103 1472 : { u"firmwareRevision"_s, service->firmwareRevision() },
104 1472 : { u"softwareRevision"_s, service->softwareRevision() },
105 6536 : };
106 832 : if (!deviceName.isEmpty()) {
107 1477 : jsonObject.insert(u"deviceName"_s, deviceName);
108 168 : }
109 832 : if (!deviceAddress.isNull()) {
110 238 : jsonObject.insert(u"deviceAddress"_s, deviceAddress.toString());
111 24 : }
112 752 : if (!deviceUuid.isNull()) {
113 812 : jsonObject.insert(u"deviceUuid"_s, deviceUuid.toString());
114 76 : }
115 832 : if (!serialNumber.isNull()) {
116 0 : jsonObject.insert(u"serialNumber"_s, serialNumber);
117 0 : }
118 1472 : std::cout << QJsonDocument(jsonObject).toJson().toStdString();
119 832 : } break;
120 192 : case OutputFormat::Text:
121 832 : if (!deviceName.isEmpty()) {
122 1589 : std::cout << qUtf8Printable(tr("Device name: %1\n").arg(deviceName));
123 168 : }
124 832 : if (!deviceAddress.isNull()) {
125 233 : std::cout << qUtf8Printable(tr("Device address: %1\n").arg(deviceAddress.toString()));
126 24 : }
127 752 : if (!deviceUuid.isNull()) {
128 792 : std::cout << qUtf8Printable(tr("Device UUID: %1\n").arg(deviceUuid.toString()));
129 76 : }
130 1896 : std::cout << qUtf8Printable(tr("Manufacturer name: %1\n").arg(service->manufacturer()));
131 1896 : std::cout << qUtf8Printable(tr("Model number: %1\n").arg(service->modelNumber()));
132 1896 : std::cout << qUtf8Printable(tr("Hardware revision: %1\n").arg(service->hardwareRevision()));
133 1896 : std::cout << qUtf8Printable(tr("Firmware revision: %1\n").arg(service->firmwareRevision()));
134 1896 : std::cout << qUtf8Printable(tr("Software revision: %1\n").arg(service->softwareRevision()));
135 832 : if (!serialNumber.isNull()) {
136 0 : std::cout << qUtf8Printable(tr("Serial number: %1\n").arg(serialNumber));
137 0 : }
138 192 : break;
139 576 : }
140 2496 : if (device) disconnect(); // Will exit the application once disconnected.
141 6344 : }
|