summaryrefslogtreecommitdiffstats
path: root/src/bluetooth/qlowenergycontroller.cpp
diff options
context:
space:
mode:
authorAlex Blasche <alexander.blasche@qt.io>2017-06-21 15:45:26 +0200
committerAlex Blasche <alexander.blasche@qt.io>2017-06-28 07:05:25 +0000
commit0b475c565843e6c0901558d6342a02722d57acbc (patch)
tree934169816d8379fb8c8f49c9c40d0b7b72929357 /src/bluetooth/qlowenergycontroller.cpp
parent75e933c612b63bd130c19078fdc1201738745e3e (diff)
Provide a way to define GAP/GATT services for central roles
Some devices require the Generic Access (GAP) and Generic Attribute (GATT) services to be defined. Otherwise they refuse a proper interaction. This is done implicitly by Android and BlueZ. The reason why BlueZ does not do this for QtBluetooth is because QtBluetooth sets up its own GATT infrastructure. Normally a QLEController in central role cannot do that via public API as the QLEController::addService() function blocks on peripheral use cases. This patch sets the profiles up. In the future the feature really requires a better form of API (beyond the above env variable) or should be enabled by default but since we need this earlier than Qt 5.10 a more subtle approach was chosen. For now the feature can only be enabled if the QT_DEFAULT_CENTRAL_SERVICES was set. Another limitation is that the characteristics of the added services are completely static. Task-number: QTBUG-61554 Change-Id: Id03bddb2e54cc4f0869838e13ddf281311ad3a26 Reviewed-by: Christian Kandeler <christian.kandeler@qt.io> Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
Diffstat (limited to 'src/bluetooth/qlowenergycontroller.cpp')
-rw-r--r--src/bluetooth/qlowenergycontroller.cpp37
1 files changed, 24 insertions, 13 deletions
diff --git a/src/bluetooth/qlowenergycontroller.cpp b/src/bluetooth/qlowenergycontroller.cpp
index 2337268d..053ca980 100644
--- a/src/bluetooth/qlowenergycontroller.cpp
+++ b/src/bluetooth/qlowenergycontroller.cpp
@@ -931,13 +931,24 @@ QLowEnergyService *QLowEnergyController::addService(const QLowEnergyServiceData
return nullptr;
}
+ Q_D(QLowEnergyController);
+ QLowEnergyService *newService = d->addServiceHelper(service);
+ if (newService)
+ newService->setParent(parent);
+
+ return newService;
+}
+
+QLowEnergyService *QLowEnergyControllerPrivate::addServiceHelper(
+ const QLowEnergyServiceData &service)
+{
// Spec says services "should" be grouped by uuid length (16-bit first, then 128-bit).
// Since this is not mandatory, we ignore it here and let the caller take responsibility
// for it.
const auto servicePrivate = QSharedPointer<QLowEnergyServicePrivate>::create();
servicePrivate->state = QLowEnergyService::LocalService;
- servicePrivate->setController(d_ptr);
+ servicePrivate->setController(this);
servicePrivate->uuid = service.uuid();
servicePrivate->type = service.type() == QLowEnergyServiceData::ServiceTypePrimary
? QLowEnergyService::PrimaryService : QLowEnergyService::IncludedService;
@@ -947,13 +958,13 @@ QLowEnergyService *QLowEnergyController::addService(const QLowEnergyServiceData
}
// Spec v4.2, Vol 3, Part G, Section 3.
- const QLowEnergyHandle oldLastHandle = d_ptr->lastLocalHandle;
- servicePrivate->startHandle = ++d_ptr->lastLocalHandle; // Service declaration.
- d_ptr->lastLocalHandle += servicePrivate->includedServices.count(); // Include declarations.
+ const QLowEnergyHandle oldLastHandle = this->lastLocalHandle;
+ servicePrivate->startHandle = ++this->lastLocalHandle; // Service declaration.
+ this->lastLocalHandle += servicePrivate->includedServices.count(); // Include declarations.
foreach (const QLowEnergyCharacteristicData &cd, service.characteristics()) {
- const QLowEnergyHandle declHandle = ++d_ptr->lastLocalHandle;
+ const QLowEnergyHandle declHandle = ++this->lastLocalHandle;
QLowEnergyServicePrivate::CharData charData;
- charData.valueHandle = ++d_ptr->lastLocalHandle;
+ charData.valueHandle = ++this->lastLocalHandle;
charData.uuid = cd.uuid();
charData.properties = cd.properties();
charData.value = cd.value();
@@ -961,21 +972,21 @@ QLowEnergyService *QLowEnergyController::addService(const QLowEnergyServiceData
QLowEnergyServicePrivate::DescData descData;
descData.uuid = dd.uuid();
descData.value = dd.value();
- charData.descriptorList.insert(++d_ptr->lastLocalHandle, descData);
+ charData.descriptorList.insert(++this->lastLocalHandle, descData);
}
servicePrivate->characteristicList.insert(declHandle, charData);
}
- servicePrivate->endHandle = d_ptr->lastLocalHandle;
- const bool handleOverflow = d_ptr->lastLocalHandle <= oldLastHandle;
+ servicePrivate->endHandle = this->lastLocalHandle;
+ const bool handleOverflow = this->lastLocalHandle <= oldLastHandle;
if (handleOverflow) {
qCWarning(QT_BT) << "Not enough attribute handles left to create this service";
- d_ptr->lastLocalHandle = oldLastHandle;
+ this->lastLocalHandle = oldLastHandle;
return nullptr;
}
- d_ptr->localServices.insert(servicePrivate->uuid, servicePrivate);
- d_ptr->addToGenericAttributeList(service, servicePrivate->startHandle);
- return new QLowEnergyService(servicePrivate, parent);
+ this->localServices.insert(servicePrivate->uuid, servicePrivate);
+ this->addToGenericAttributeList(service, servicePrivate->startHandle);
+ return new QLowEnergyService(servicePrivate);
}
/*!