summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Alex Blasche <alexander.blasche@qt.io>2017-06-27 14:56:30 +0200
committerGravatar Linus Torvalds <torvalds@linux-foundation.org>2017-06-27 11:03:19 -0700
commit57753321b069c93050a40eaddef9a49f1a2c9e19 (patch)
tree7e8636e31b5b84bec7a969ff78fc4ecfdcda7825
parent81dabe5ace3091656cdbac57598699bb3b9beea7 (diff)
downloadsubsurface-57753321b069c93050a40eaddef9a49f1a2c9e19.tar.gz
Ensure all found BLE services are tracked
If a device has more than one service the order of service discovery determined the selection of the service that we intend to interact with. This assumption is not accurate and is even platform dependent. Thinking ahead, it is likely that some devices may require us to keep track and interact with multiple services at the time. The new logic still suffers from the fact that there is no way to select the correct service for interaction. This will require higher level stack changes. Signed-off-by: Alex Blasche <alexander.blasche@qt.io> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--core/qt-ble.cpp25
-rw-r--r--core/qt-ble.h10
2 files changed, 26 insertions, 9 deletions
diff --git a/core/qt-ble.cpp b/core/qt-ble.cpp
index bed5f5feb..3b165aa94 100644
--- a/core/qt-ble.cpp
+++ b/core/qt-ble.cpp
@@ -22,7 +22,9 @@ void BLEObject::serviceStateChanged(QLowEnergyService::ServiceState s)
{
QList<QLowEnergyCharacteristic> list;
- list = service->characteristics();
+ auto service = qobject_cast<QLowEnergyService*>(sender());
+ if (service)
+ list = service->characteristics();
Q_FOREACH(QLowEnergyCharacteristic c, list) {
qDebug() << " " << c.uuid().toString();
@@ -50,9 +52,10 @@ void BLEObject::addService(const QBluetoothUuid &newService)
return;
}
- service = controller->createServiceObject(newService, this);
+ auto service = controller->createServiceObject(newService, this);
qDebug() << " .. created service object" << service;
if (service) {
+ services.append(service);
connect(service, &QLowEnergyService::stateChanged, this, &BLEObject::serviceStateChanged);
connect(service, &QLowEnergyService::characteristicChanged, this, &BLEObject::characteristcStateChanged);
connect(service, &QLowEnergyService::descriptorWritten, this, &BLEObject::writeCompleted);
@@ -72,7 +75,7 @@ BLEObject::~BLEObject()
dc_status_t BLEObject::write(const void* data, size_t size, size_t *actual)
{
- QList<QLowEnergyCharacteristic> list = service->characteristics();
+ QList<QLowEnergyCharacteristic> list = preferredService()->characteristics();
QByteArray bytes((const char *)data, (int) size);
if (!list.isEmpty()) {
@@ -83,7 +86,7 @@ dc_status_t BLEObject::write(const void* data, size_t size, size_t *actual)
QLowEnergyService::WriteWithoutResponse :
QLowEnergyService::WriteWithResponse;
- service->writeCharacteristic(c, bytes, mode);
+ preferredService()->writeCharacteristic(c, bytes, mode);
return DC_STATUS_SUCCESS;
}
@@ -93,7 +96,7 @@ dc_status_t BLEObject::write(const void* data, size_t size, size_t *actual)
dc_status_t BLEObject::read(void* data, size_t size, size_t *actual)
{
if (receivedPackets.isEmpty()) {
- QList<QLowEnergyCharacteristic> list = service->characteristics();
+ QList<QLowEnergyCharacteristic> list = preferredService()->characteristics();
if (list.isEmpty())
return DC_STATUS_IO;
@@ -188,11 +191,19 @@ dc_status_t qt_ble_open(dc_custom_io_t *io, dc_context_t *context, const char *d
loop.exec();
qDebug() << " .. done waiting";
+ if (ble->preferredService() == nullptr) {
+ qDebug() << "failed to find suitable service on" << devaddr;
+ report_error("Failed to find suitable service on '%s'", devaddr);
+ controller->disconnectFromDevice();
+ delete controller;
+ return DC_STATUS_IO;
+ }
+
qDebug() << " .. enabling notifications";
/* Enable notifications */
- QList<QLowEnergyCharacteristic> list = ble->service->characteristics();
+ QList<QLowEnergyCharacteristic> list = ble->preferredService()->characteristics();
if (!list.isEmpty()) {
const QLowEnergyCharacteristic &c = list.constLast();
@@ -209,7 +220,7 @@ dc_status_t qt_ble_open(dc_custom_io_t *io, dc_context_t *context, const char *d
d = l.first();
qDebug() << "now writing \"0x0100\" to the first descriptor";
- ble->service->writeDescriptor(d, QByteArray::fromHex("0100"));
+ ble->preferredService()->writeDescriptor(d, QByteArray::fromHex("0100"));
}
}
diff --git a/core/qt-ble.h b/core/qt-ble.h
index f1e353946..cd27423a4 100644
--- a/core/qt-ble.h
+++ b/core/qt-ble.h
@@ -2,6 +2,7 @@
#ifndef QT_BLE_H
#define QT_BLE_H
+#include <QVector>
#include <QLowEnergyController>
#include <QEventLoop>
@@ -14,7 +15,10 @@ public:
~BLEObject();
dc_status_t write(const void* data, size_t size, size_t *actual);
dc_status_t read(void* data, size_t size, size_t *actual);
- QLowEnergyService *service;
+
+ //TODO: need better mode of selecting the desired service than below
+ inline QLowEnergyService *preferredService()
+ { return services.isEmpty() ? nullptr : services[0]; }
public slots:
void addService(const QBluetoothUuid &newService);
@@ -23,7 +27,9 @@ public slots:
void writeCompleted(const QLowEnergyDescriptor &d, const QByteArray &value);
private:
- QLowEnergyController *controller;
+ QVector<QLowEnergyService *> services;
+
+ QLowEnergyController *controller = nullptr;
QList<QByteArray> receivedPackets;
QEventLoop waitForPacket;
};