Line data Source code
1 : // SPDX-FileCopyrightText: 2022-2023 Paul Colby <git@colby.id.au>
2 : // SPDX-License-Identifier: LGPL-3.0-or-later
3 :
4 : /*!
5 : * \file
6 : * Defines the PokitDiscoveryAgent and PokitDiscoveryAgentPrivate classes.
7 : */
8 :
9 : #include <qtpokit/pokitdiscoveryagent.h>
10 : #include "pokitdiscoveryagent_p.h"
11 :
12 : #include <qtpokit/statusservice.h>
13 :
14 : #include <QBluetoothUuid>
15 :
16 : /*!
17 : * \class PokitDiscoveryAgent
18 : *
19 : * The PokitDiscoveryAgent class discovers nearby Pokit devices.
20 : *
21 : * After constructing a PokitDiscoveryAgent object, and subscribing to the relevant signals,
22 : * invoke start() to begin discovery.
23 : */
24 :
25 : /*!
26 : * Constructs a new Pokit device discovery agent with \a parent, using \a deviceAdapter for the
27 : * search device.
28 : */
29 0 : PokitDiscoveryAgent::PokitDiscoveryAgent(
30 0 : const QBluetoothAddress &deviceAdapter, QObject *parent)
31 : : QBluetoothDeviceDiscoveryAgent(deviceAdapter, parent),
32 0 : d_ptr(new PokitDiscoveryAgentPrivate(this))
33 : {
34 :
35 0 : }
36 :
37 : /*!
38 : * Constructs a new Pokit device discovery agent with \a parent.
39 : */
40 8345 : PokitDiscoveryAgent::PokitDiscoveryAgent(QObject * parent)
41 : : QBluetoothDeviceDiscoveryAgent(parent),
42 8345 : d_ptr(new PokitDiscoveryAgentPrivate(this))
43 : {
44 :
45 8345 : }
46 :
47 : /*!
48 : * \cond internal
49 : * Constructs a new Pokit device discovery agent with \a parent, using \a deviceAdapter for the
50 : * search device, and private implementation \a d.
51 : */
52 0 : PokitDiscoveryAgent::PokitDiscoveryAgent(
53 : PokitDiscoveryAgentPrivate * const d, const QBluetoothAddress &deviceAdapter,
54 0 : QObject * const parent)
55 0 : : QBluetoothDeviceDiscoveryAgent(deviceAdapter, parent), d_ptr(d)
56 : {
57 :
58 0 : }
59 :
60 : /*!
61 : * Constructs a new Pokit device discovery agent with \a parent, and private implementation \a d.
62 : */
63 0 : PokitDiscoveryAgent::PokitDiscoveryAgent(
64 0 : PokitDiscoveryAgentPrivate * const d, QObject * const parent)
65 0 : : QBluetoothDeviceDiscoveryAgent(parent), d_ptr(d)
66 : {
67 :
68 0 : }
69 : /// \endcond
70 :
71 : /*!
72 : * Destroys this PokitDiscoveryAgent object.
73 : */
74 16370 : PokitDiscoveryAgent::~PokitDiscoveryAgent()
75 : {
76 8345 : delete d_ptr;
77 16370 : }
78 :
79 : /*!
80 : * Returns \c true if \a info describes a Pokit device.
81 : *
82 : * Currently, this is based on whether or not \a info's service UUIDs includes a known Pokit
83 : * service, but this test criteria might be swapped for something else sometime.
84 : */
85 392 : bool PokitDiscoveryAgent::isPokitDevice(const QBluetoothDeviceInfo &info)
86 : {
87 392 : return (isPokitMeter(info) || isPokitPro(info));
88 : }
89 :
90 : /*!
91 : * Returns \c true if \a info describes a Pokit Meter device.
92 : *
93 : * Currently, this is based on whether or not \a info's service UUIDs includes a known Pokit
94 : * service, but this test criteria might be swapped for something else sometime.
95 : */
96 536 : bool PokitDiscoveryAgent::isPokitMeter(const QBluetoothDeviceInfo &info)
97 : {
98 944 : return info.serviceUuids().contains(StatusService::ServiceUuids::pokitMeter);
99 : }
100 :
101 : /*!
102 : * Returns \c true if \a info describes a Pokit Pro device.
103 : *
104 : * Currently, this is based on whether or not \a info's service UUIDs includes a known Pokit
105 : * service, but this test criteria might be swapped for something else sometime.
106 : */
107 438 : bool PokitDiscoveryAgent::isPokitPro(const QBluetoothDeviceInfo &info)
108 : {
109 772 : return info.serviceUuids().contains(StatusService::ServiceUuids::pokitPro);
110 : }
111 :
112 : /*!
113 : * Starts Pokit device discovery.
114 : *
115 : * This override simply enforces that \a method must be \c LowEnergyMethod, as all Pokit devices
116 : * used Bluetooth Low Energy (BLE).
117 : */
118 0 : void PokitDiscoveryAgent::start(QBluetoothDeviceDiscoveryAgent::DiscoveryMethods methods)
119 : {
120 : Q_D(PokitDiscoveryAgent);
121 : Q_ASSERT(methods == QBluetoothDeviceDiscoveryAgent::LowEnergyMethod);
122 0 : qCDebug(d->lc).noquote() << tr("Scanning for Bluetooth Low Energy devices.");
123 0 : QBluetoothDeviceDiscoveryAgent::start(QBluetoothDeviceDiscoveryAgent::LowEnergyMethod);
124 0 : }
125 :
126 : /*!
127 : * Starts Pokit device discovery.
128 : */
129 54 : void PokitDiscoveryAgent::start()
130 : {
131 : Q_D(PokitDiscoveryAgent);
132 54 : qCDebug(d->lc).noquote() << tr("Scanning for Bluetooth Low Energy devices.");
133 54 : QBluetoothDeviceDiscoveryAgent::start(QBluetoothDeviceDiscoveryAgent::LowEnergyMethod);
134 54 : }
135 :
136 : /*!
137 : * \fn void PokitDiscoveryAgent::pokitDeviceDiscovered(const QBluetoothDeviceInfo &info)
138 : *
139 : * This signal is emitted when the Pokit device described by \a info is discovered.
140 : */
141 :
142 : /*!
143 : * \fn void PokitDiscoveryAgent::pokitDeviceUpdated(const QBluetoothDeviceInfo &info, QBluetoothDeviceInfo::Fields updatedFields)
144 : *
145 : * This signal is emitted when the Pokit device described by \a info is updated. The
146 : * \a updatedFields flags tell which information has been updated.
147 : */
148 :
149 : /*!
150 : * \cond internal
151 : * \class PokitDiscoveryAgentPrivate
152 : *
153 : * The PokitDiscoveryAgentPrivate class provides private implementation for
154 : * PokitDiscoveryAgent.
155 : */
156 :
157 : /*!
158 : * \internal
159 : * Constructs a new PokitDiscoveryAgentPrivate object with public implementation \a q.
160 : */
161 8345 : PokitDiscoveryAgentPrivate::PokitDiscoveryAgentPrivate(PokitDiscoveryAgent * const q)
162 8345 : : q_ptr(q)
163 : {
164 8345 : connect(q, &QBluetoothDeviceDiscoveryAgent::canceled,
165 : this, &PokitDiscoveryAgentPrivate::canceled);
166 :
167 8345 : connect(q, &QBluetoothDeviceDiscoveryAgent::deviceDiscovered,
168 : this, &PokitDiscoveryAgentPrivate::deviceDiscovered);
169 :
170 : #if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)) // Signal added in Qt 5.12.
171 6186 : connect(q, &QBluetoothDeviceDiscoveryAgent::deviceUpdated,
172 : this, &PokitDiscoveryAgentPrivate::deviceUpdated);
173 : #endif
174 :
175 8345 : connect(q,
176 : #if (QT_VERSION < QT_VERSION_CHECK(6, 2, 0))
177 : QOverload<PokitDiscoveryAgent::Error>::of(&PokitDiscoveryAgent::error),
178 : #else
179 : &QBluetoothDeviceDiscoveryAgent::errorOccurred,
180 : #endif
181 : this, &PokitDiscoveryAgentPrivate::error);
182 :
183 8345 : connect(q, &QBluetoothDeviceDiscoveryAgent::finished,
184 : this, &PokitDiscoveryAgentPrivate::finished);
185 8345 : }
186 :
187 : /*!
188 : * Handle scan canceled signals, by simply logging the event for diagnostic purposes.
189 : */
190 18 : void PokitDiscoveryAgentPrivate::canceled() const
191 : {
192 18 : qCDebug(lc).noquote() << tr("Pokit device scan cancelled.");
193 18 : }
194 :
195 : /*!
196 : * Handle deviceDiscovered signals.
197 : *
198 : * Here we simply check if \a info describes a Pokit device, and if so, emit pokitDeviceDiscovered().
199 : */
200 144 : void PokitDiscoveryAgentPrivate::deviceDiscovered(const QBluetoothDeviceInfo &info)
201 : {
202 : Q_Q(PokitDiscoveryAgent);
203 144 : if (!q->isPokitDevice(info)) return;
204 54 : qCDebug(lc).noquote() << tr("Discovered Pokit device \"%1\" at %2.")
205 0 : .arg(info.name(), info.address().toString());
206 54 : emit q->pokitDeviceDiscovered(info);
207 : }
208 :
209 : #if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)) // Required signal, and Fields, added in Qt 5.12.
210 : /*!
211 : * Handle deviceUpdated signals.
212 : *
213 : * Here we simply check if \a info describes a Pokit device, and if so, emit pokitDeviceUpdated().
214 : *
215 : * \since Qt 5.12.0
216 : */
217 104 : void PokitDiscoveryAgentPrivate::deviceUpdated(
218 : const QBluetoothDeviceInfo &info, QBluetoothDeviceInfo::Fields updatedFields)
219 : {
220 : Q_Q(PokitDiscoveryAgent);
221 104 : if (!q->isPokitDevice(info)) return;
222 39 : qCDebug(lc).noquote() << tr("Pokit device \"%1\" at %2 updated with RSSI %3.")
223 0 : .arg(info.name(), info.address().toString()).arg(info.rssi());
224 39 : emit q->pokitDeviceUpdated(info, updatedFields);
225 : }
226 : #endif
227 :
228 : /*!
229 : * Handle scan errors, by simply logging \a error for diagnostic purposes.
230 : */
231 66 : void PokitDiscoveryAgentPrivate::error(const QBluetoothDeviceDiscoveryAgent::Error error) const
232 : {
233 198 : qCWarning(lc).noquote() << tr("Pokit device scan error:") << error;
234 66 : }
235 :
236 : /*!
237 : * Handle scan finished signals, by simply logging the event for diagnostic purposes.
238 : */
239 18 : void PokitDiscoveryAgentPrivate::finished() const
240 : {
241 18 : qCDebug(lc).noquote() << tr("Pokit device scan finished.");
242 18 : }
243 :
244 : /// \endcond
|