Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qlowenergycontrollerbase.cpp
Go to the documentation of this file.
1// Copyright (C) 2017 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5
6#include <QtCore/QLoggingCategory>
7
8#include <QtBluetooth/QBluetoothLocalDevice>
9#include <QtBluetooth/QLowEnergyCharacteristicData>
10#include <QtBluetooth/QLowEnergyDescriptorData>
11#include <QtBluetooth/QLowEnergyServiceData>
12
14
16
21
25
27{
28#if defined(QT_WINRT_BLUETOOTH) || defined(Q_OS_DARWIN)
29 return true;
30#endif
31 if (localAdapter.isNull())
32 return false;
33
34 const QList<QBluetoothHostInfo> foundAdapters = QBluetoothLocalDevice::allDevices();
35 bool adapterFound = false;
36
37 for (const QBluetoothHostInfo &info : foundAdapters) {
38 if (info.address() == localAdapter) {
39 adapterFound = true;
40 break;
41 }
42 }
43
44 return adapterFound;
45}
46
47
50{
52 error = newError;
53
54 switch (newError) {
56 errorString = QLowEnergyController::tr("Remote device cannot be found");
57 break;
59 errorString = QLowEnergyController::tr("Cannot find local adapter");
60 break;
62 errorString = QLowEnergyController::tr("Error occurred during connection I/O");
63 break;
65 errorString = QLowEnergyController::tr("Error occurred trying to connect to remote device.");
66 break;
68 errorString = QLowEnergyController::tr("Error occurred trying to start advertising");
69 break;
71 errorString = QLowEnergyController::tr("Remote device closed the connection");
72 break;
74 errorString = QLowEnergyController::tr("Failed to authorize on the remote device");
75 break;
77 errorString = QLowEnergyController::tr("Missing permissions error");
78 break;
80 errorString = QLowEnergyController::tr("Error reading RSSI value");
81 break;
83 return;
84 default:
86 errorString = QLowEnergyController::tr("Unknown Error");
87 break;
88 }
89
90 emit q->errorOccurred(newError);
91}
92
95{
96 qCDebug(QT_BT) << "QLowEnergyControllerPrivate setting state to" << newState;
98 if (state == newState)
99 return;
100
101 state = newState;
104 remoteDevice.clear();
105 }
106 emit q->stateChanged(state);
107}
108
109QSharedPointer<QLowEnergyServicePrivate> QLowEnergyControllerPrivate::serviceForHandle(
111{
112 ServiceDataMap &currentList = serviceList;
114 currentList = localServices;
115
116 const QList<QSharedPointer<QLowEnergyServicePrivate>> values = currentList.values();
117 for (auto service: values)
118 if (service->startHandle <= handle && handle <= service->endHandle)
119 return service;
120
121 return QSharedPointer<QLowEnergyServicePrivate>();
122}
123
130{
131 QSharedPointer<QLowEnergyServicePrivate> service = serviceForHandle(handle);
132 if (service.isNull())
134
135 if (service->characteristicList.isEmpty())
137
138 // check whether it is the handle of a characteristic header
139 if (service->characteristicList.contains(handle))
140 return QLowEnergyCharacteristic(service, handle);
141
142 // check whether it is the handle of the characteristic value or its descriptors
143 QList<QLowEnergyHandle> charHandles = service->characteristicList.keys();
144 std::sort(charHandles.begin(), charHandles.end());
145 for (qsizetype i = charHandles.size() - 1; i >= 0; --i) {
146 if (charHandles.at(i) > handle)
147 continue;
148
149 return QLowEnergyCharacteristic(service, charHandles.at(i));
150 }
151
153}
154
161{
163 if (!matchingChar.isValid())
164 return QLowEnergyDescriptor();
165
166 const QLowEnergyServicePrivate::CharData charData = matchingChar.
167 d_ptr->characteristicList[matchingChar.attributeHandle()];
168
169 if (charData.descriptorList.contains(handle))
170 return QLowEnergyDescriptor(matchingChar.d_ptr, matchingChar.attributeHandle(),
171 handle);
172
173 return QLowEnergyDescriptor();
174}
175
180 QLowEnergyHandle charHandle,const QByteArray &value, bool appendValue)
181{
182 QSharedPointer<QLowEnergyServicePrivate> service = serviceForHandle(charHandle);
183 if (!service.isNull()) {
184 CharacteristicDataMap::iterator charIt = service->characteristicList.find(charHandle);
185 if (charIt != service->characteristicList.end()) {
186 QLowEnergyServicePrivate::CharData &charDetails = charIt.value();
187
188 if (appendValue)
189 charDetails.value += value;
190 else
191 charDetails.value = value;
192
193 return charDetails.value.size();
194 }
195 }
196
197 return 0;
198}
199
204 QLowEnergyHandle charHandle, QLowEnergyHandle descriptorHandle,
205 const QByteArray &value, bool appendValue)
206{
207 QSharedPointer<QLowEnergyServicePrivate> service = serviceForHandle(charHandle);
208 if (!service.isNull()) {
209 CharacteristicDataMap::iterator charIt = service->characteristicList.find(charHandle);
210 if (charIt != service->characteristicList.end()) {
211 QLowEnergyServicePrivate::CharData &charDetails = charIt.value();
212
213 DescriptorDataMap::iterator descIt = charDetails.descriptorList.find(descriptorHandle);
214 if (descIt != charDetails.descriptorList.end()) {
215 QLowEnergyServicePrivate::DescData &descDetails = descIt.value();
216
217 if (appendValue)
218 descDetails.value += value;
219 else
220 descDetails.value = value;
221
222 return descDetails.value.size();
223 }
224 }
225 }
226
227 return 0;
228}
229
231{
232 for (QSharedPointer<QLowEnergyServicePrivate> service : serviceList.values())
233 service->setController(nullptr);
234
235 for (QSharedPointer<QLowEnergyServicePrivate> service : localServices.values())
236 service->setController(nullptr);
237
238 serviceList.clear();
239 localServices.clear();
240 lastLocalHandle = {};
241}
242
244 const QLowEnergyServiceData &service)
245{
246 // Spec says services "should" be grouped by uuid length (16-bit first, then 128-bit).
247 // Since this is not mandatory, we ignore it here and let the caller take responsibility
248 // for it.
249
250 const auto servicePrivate = QSharedPointer<QLowEnergyServicePrivate>::create();
251 servicePrivate->setController(this);
252 servicePrivate->state = QLowEnergyService::LocalService;
253 servicePrivate->uuid = service.uuid();
254 servicePrivate->type = service.type() == QLowEnergyServiceData::ServiceTypePrimary
256 const QList<QLowEnergyService *> includedServices = service.includedServices();
257 for (QLowEnergyService * const includedService : includedServices) {
258 servicePrivate->includedServices << includedService->serviceUuid();
259 includedService->d_ptr->type |= QLowEnergyService::IncludedService;
260 }
261
262 // Spec v4.2, Vol 3, Part G, Section 3.
263 const QLowEnergyHandle oldLastHandle = this->lastLocalHandle;
264 servicePrivate->startHandle = ++this->lastLocalHandle; // Service declaration.
265 this->lastLocalHandle += servicePrivate->includedServices.size(); // Include declarations.
266 const QList<QLowEnergyCharacteristicData> characteristics = service.characteristics();
267 for (const QLowEnergyCharacteristicData &cd : characteristics) {
268 const QLowEnergyHandle declHandle = ++this->lastLocalHandle;
270 charData.valueHandle = ++this->lastLocalHandle;
271 charData.uuid = cd.uuid();
272 charData.properties = cd.properties();
273 charData.value = cd.value();
274 const QList<QLowEnergyDescriptorData> descriptors = cd.descriptors();
275 for (const QLowEnergyDescriptorData &dd : descriptors) {
277 descData.uuid = dd.uuid();
278 descData.value = dd.value();
279 charData.descriptorList.insert(++this->lastLocalHandle, descData);
280 }
281 servicePrivate->characteristicList.insert(declHandle, charData);
282 }
283 servicePrivate->endHandle = this->lastLocalHandle;
284 const bool handleOverflow = this->lastLocalHandle <= oldLastHandle;
285 if (handleOverflow) {
286 qCWarning(QT_BT) << "Not enough attribute handles left to create this service";
287 this->lastLocalHandle = oldLastHandle;
288 return nullptr;
289 }
290
291 if (localServices.contains(servicePrivate->uuid)) {
292 qCWarning(QT_BT) << "Overriding existing local service with uuid"
293 << servicePrivate->uuid;
294 }
295 this->localServices.insert(servicePrivate->uuid, servicePrivate);
296
297 this->addToGenericAttributeList(service, servicePrivate->startHandle);
298 return new QLowEnergyService(servicePrivate);
299}
300
302{
303 qCWarning(QT_BT, "This platform does not support reading RSSI");
305}
306
308
309#include "moc_qlowenergycontrollerbase_p.cpp"
\inmodule QtBluetooth
static QList< QBluetoothHostInfo > allDevices()
Returns a list of all available local Bluetooth devices.
\inmodule QtCore
Definition qbytearray.h:57
QByteArray & insert(qsizetype i, QByteArrayView data)
The QLowEnergyCharacteristicData class is used to set up GATT service data. \inmodule QtBluetooth.
QLowEnergyCharacteristic characteristicForHandle(QLowEnergyHandle handle)
Returns a valid characteristic if the given handle is the handle of the characteristic itself or one ...
QSharedPointer< QLowEnergyServicePrivate > serviceForHandle(QLowEnergyHandle handle)
quint16 updateValueOfDescriptor(QLowEnergyHandle charHandle, QLowEnergyHandle descriptorHandle, const QByteArray &value, bool appendValue)
Returns the length of the updated descriptor value.
QLowEnergyDescriptor descriptorForHandle(QLowEnergyHandle handle)
Returns a valid descriptor if handle belongs to a descriptor; otherwise an invalid one.
QLowEnergyController::Error error
void setError(QLowEnergyController::Error newError)
quint16 updateValueOfCharacteristic(QLowEnergyHandle charHandle, const QByteArray &value, bool appendValue)
Returns the length of the updated characteristic value.
virtual void addToGenericAttributeList(const QLowEnergyServiceData &service, QLowEnergyHandle startHandle)=0
virtual QLowEnergyService * addServiceHelper(const QLowEnergyServiceData &service)
QLowEnergyController::ControllerState state
void setState(QLowEnergyController::ControllerState newState)
\inmodule QtBluetooth
ControllerState
Indicates the state of the controller object.
Error
Indicates all possible error conditions found during the controller's existence.
The QLowEnergyDescriptorData class is used to create GATT service data. \inmodule QtBluetooth.
\inmodule QtBluetooth
The QLowEnergyServiceData class is used to set up GATT service data. \inmodule QtBluetooth.
\inmodule QtBluetooth
\inmodule QtCore
Definition qobject.h:103
QScopedPointer< QObjectData > d_ptr
Definition qobject.h:373
static QSharedPointer create(Args &&...arguments)
This is an overloaded member function, provided for convenience. It differs from the above function o...
void newState(QList< State > &states, const char *token, const char *lexem, bool pre)
Combined button and popup list for selecting options.
quint16 QLowEnergyHandle
Definition qbluetooth.h:42
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define qCWarning(category,...)
#define qCDebug(category,...)
#define Q_DECLARE_LOGGING_CATEGORY(name)
QT_BEGIN_NAMESPACE typedef QMap< QBluetoothUuid, QSharedPointer< QLowEnergyServicePrivate > > ServiceDataMap
GLenum GLsizei GLsizei GLint * values
[15]
GLuint64 GLenum void * handle
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
#define emit
unsigned short quint16
Definition qtypes.h:48
ptrdiff_t qsizetype
Definition qtypes.h:165
QHostInfo info
[0]