From 243db8a80ff4cfeba5eda13f900fd11e1144e367 Mon Sep 17 00:00:00 2001 From: Alex Blasche Date: Wed, 18 Jun 2014 12:24:09 +0200 Subject: Connect QLowEnergyService and QLowEnergyControllerNew classes Ensures that the two classes have sufficient references to each other. When the controller disconnects the related QLES classes should become invalid. Introduces an error flag for QLowEnergyService. Change-Id: I28aee49e45f93c68c4ac69a5e489c0a3cc33dbf5 Reviewed-by: Alex Blasche --- src/bluetooth/qlowenergycontrollernew.cpp | 10 +++- src/bluetooth/qlowenergycontrollernew_bluez.cpp | 4 +- src/bluetooth/qlowenergycontrollernew_p.cpp | 2 +- src/bluetooth/qlowenergycontrollernew_p.h | 3 +- src/bluetooth/qlowenergyservice.cpp | 66 ++++++++++++++++++++++++- src/bluetooth/qlowenergyservice.h | 20 ++++++-- 6 files changed, 96 insertions(+), 9 deletions(-) (limited to 'src/bluetooth') diff --git a/src/bluetooth/qlowenergycontrollernew.cpp b/src/bluetooth/qlowenergycontrollernew.cpp index 967b1a87..0a9800ae 100644 --- a/src/bluetooth/qlowenergycontrollernew.cpp +++ b/src/bluetooth/qlowenergycontrollernew.cpp @@ -100,6 +100,14 @@ void QLowEnergyControllerNewPrivate::setState( emit q->stateChanged(state); } +void QLowEnergyControllerNewPrivate::invalidateServices() +{ + foreach (const QBluetoothUuid &service, serviceList.keys()) { + ServiceDetails detail = serviceList.take(service); + detail.service.data()->setState(QLowEnergyService::InvalidService); + } +} + QLowEnergyControllerNew::QLowEnergyControllerNew( const QBluetoothAddress &remoteDevice, QObject *parent) @@ -175,6 +183,7 @@ void QLowEnergyControllerNew::disconnectFromDevice() if (state() == QLowEnergyControllerNew::UnconnectedState) return; + d->invalidateServices(); d->disconnectFromDevice(); } @@ -185,7 +194,6 @@ void QLowEnergyControllerNew::discoverServices() if (d->state != QLowEnergyControllerNew::ConnectedState) return; - d->serviceList.clear(); d->discoverServices(); } diff --git a/src/bluetooth/qlowenergycontrollernew_bluez.cpp b/src/bluetooth/qlowenergycontrollernew_bluez.cpp index 90b12fa1..a2a0bac2 100644 --- a/src/bluetooth/qlowenergycontrollernew_bluez.cpp +++ b/src/bluetooth/qlowenergycontrollernew_bluez.cpp @@ -138,6 +138,7 @@ void QLowEnergyControllerNewPrivate::l2cpErrorChanged(QBluetoothSocket::SocketEr break; } + invalidateServices(); setState(QLowEnergyControllerNew::UnconnectedState); } @@ -184,6 +185,7 @@ void QLowEnergyControllerNewPrivate::l2cpReadyRead() details.endHandle = end; QLowEnergyService *service = new QLowEnergyService(uuid); + service->setController(this); QSharedPointer pointer(service); details.service = pointer; @@ -236,7 +238,7 @@ void QLowEnergyControllerNewPrivate::sendReadByGroupRequest( void QLowEnergyControllerNewPrivate::discoverServiceDetails(const QBluetoothUuid &/*service*/) { - + //TODO Implement discoverServiceDetails() } diff --git a/src/bluetooth/qlowenergycontrollernew_p.cpp b/src/bluetooth/qlowenergycontrollernew_p.cpp index b6a89ccd..f8536b4b 100644 --- a/src/bluetooth/qlowenergycontrollernew_p.cpp +++ b/src/bluetooth/qlowenergycontrollernew_p.cpp @@ -45,7 +45,7 @@ QT_BEGIN_NAMESPACE void QLowEnergyControllerNewPrivate::connectToDevice() { - + setError(QLowEnergyControllerNew::UnknownError); } void QLowEnergyControllerNewPrivate::disconnectFromDevice() diff --git a/src/bluetooth/qlowenergycontrollernew_p.h b/src/bluetooth/qlowenergycontrollernew_p.h index 41824239..b5a66aeb 100644 --- a/src/bluetooth/qlowenergycontrollernew_p.h +++ b/src/bluetooth/qlowenergycontrollernew_p.h @@ -59,7 +59,7 @@ struct ServiceDetails { QSharedPointer service; }; -class QLowEnergyControllerNewPrivate : QObject +class QLowEnergyControllerNewPrivate : public QObject { Q_OBJECT Q_DECLARE_PUBLIC(QLowEnergyControllerNew) @@ -82,6 +82,7 @@ public: void disconnectFromDevice(); void discoverServices(); + void invalidateServices(); void discoverServiceDetails(const QBluetoothUuid &); diff --git a/src/bluetooth/qlowenergyservice.cpp b/src/bluetooth/qlowenergyservice.cpp index e60f7cc1..0e25c9b3 100644 --- a/src/bluetooth/qlowenergyservice.cpp +++ b/src/bluetooth/qlowenergyservice.cpp @@ -40,9 +40,12 @@ ****************************************************************************/ #include +#include #include #include +#include "qlowenergycontrollernew_p.h" + QT_BEGIN_NAMESPACE class QLowEnergyServicePrivate { @@ -50,16 +53,61 @@ public: QBluetoothUuid uuid; QLowEnergyService::ServiceType type; QLowEnergyService::ServiceState state; + QLowEnergyService::ServiceError lastError; + + QPointer controller; }; +/*! + \internal + + QLowEnergyControllerNewPrivate creates instances of this class. + The user gets access to class instances via + \l QLowEnergyControllerNew::services(). + */ QLowEnergyService::QLowEnergyService(const QBluetoothUuid &uuid, QObject *parent) : QObject(parent) { d_ptr = new QLowEnergyServicePrivate(); d_ptr->uuid = uuid; - d_ptr->state = QLowEnergyService::DiscoveryRequired; + d_ptr->state = QLowEnergyService::InvalidService; d_ptr->type = QLowEnergyService::PrimaryService; + d_ptr->lastError = QLowEnergyService::NoError; +} + +/*! + \internal + + Called by Controller right after construction. + */ +void QLowEnergyService::setController(QLowEnergyControllerNewPrivate *control) +{ + Q_D(QLowEnergyService); + if (!control) + return; + + d->state = QLowEnergyService::DiscoveryRequired; + d->controller = control; +} + +/*! + \internal + + Called by Controller. + */ +void QLowEnergyService::setError(QLowEnergyService::ServiceError newError) +{ + Q_D(QLowEnergyService); + d->lastError = newError; + emit error(newError); +} + +void QLowEnergyService::setState(QLowEnergyService::ServiceState newState) +{ + Q_D(QLowEnergyService); + d->state = newState; + emit stateChanged(newState); } QLowEnergyService::~QLowEnergyService() @@ -117,7 +165,21 @@ QString QLowEnergyService::serviceName() const void QLowEnergyService::discoverDetails() { - //TODO discoverDetails + Q_D(QLowEnergyService); + if (d->state != QLowEnergyService::DiscoveryRequired) + return; + + if (!d->controller) { + setError(QLowEnergyService::ServiceNotValidError); + return; + } + + d->controller->discoverServiceDetails(d->uuid); +} + +QLowEnergyService::ServiceError QLowEnergyService::error() const +{ + return d_ptr->lastError; } diff --git a/src/bluetooth/qlowenergyservice.h b/src/bluetooth/qlowenergyservice.h index 20ff6c9c..03505e30 100644 --- a/src/bluetooth/qlowenergyservice.h +++ b/src/bluetooth/qlowenergyservice.h @@ -47,6 +47,7 @@ QT_BEGIN_NAMESPACE class QLowEnergyServicePrivate; +class QLowEnergyControllerNewPrivate; class Q_BLUETOOTH_EXPORT QLowEnergyService : public QObject { Q_OBJECT @@ -56,6 +57,11 @@ public: IncludedService }; + enum ServiceError { + NoError = 0, + ServiceNotValidError + }; + enum ServiceState { InvalidService = 0, // when underlying controller disconnects DiscoveryRequired, // we know start/end handle but nothing more @@ -76,22 +82,30 @@ public: void discoverDetails(); + ServiceError error() const; + + Q_SIGNALS: void stateChanged(QLowEnergyService::ServiceState newState); void characteristicChanged(const QLowEnergyCharacteristicInfo &info, const QByteArray &value); void descriptorChanged(const QLowEnergyDescriptorInfo &info, const QByteArray &value); + void error(QLowEnergyService::ServiceError error); private: Q_DECLARE_PRIVATE(QLowEnergyService) QLowEnergyServicePrivate *d_ptr; - //somehow we need to connect this to QLowEnergyControllerNew - //which owns the communication + // the symbols below are used by QLowEnergyControllerNewPrivate + // TODO check whether there are other ways of accessing the internals + friend class QLowEnergyControllerNewPrivate; + QLowEnergyService(const QBluetoothUuid &uuid, QObject *parent = 0); - friend class QLowEnergyControllerNewPrivate; + void setController(QLowEnergyControllerNewPrivate* control); + void setError(QLowEnergyService::ServiceError newError); + void setState(QLowEnergyService::ServiceState newState); }; QT_END_NAMESPACE -- cgit v1.2.3