diff options
author | Alex Blasche <alexander.blasche@digia.com> | 2014-07-22 11:59:27 +0200 |
---|---|---|
committer | Alex Blasche <alexander.blasche@digia.com> | 2014-07-23 15:28:49 +0200 |
commit | 199bd8306541c3987cc4aae7d7f93af31717d3b5 (patch) | |
tree | 004d9a1a034d0abc39145b79d9c4b9edda4e6502 | |
parent | 58d1b5bdffc25f4ff22dcd00f0572c9c4fac3f88 (diff) |
Detect secondary services and display service type in lowenergyscanner
QLowEnergyService::ServiceState was converted to a flag because a
primary and secondary service can be included by other services.
Change-Id: I425ce8e3f39ee07cccee2763b57a049a624f6178
Reviewed-by: Fabian Bumberger <fbumberger@rim.com>
-rw-r--r-- | examples/bluetooth/lowenergyscanner/assets/Services.qml | 6 | ||||
-rw-r--r-- | examples/bluetooth/lowenergyscanner/serviceinfo.cpp | 19 | ||||
-rw-r--r-- | examples/bluetooth/lowenergyscanner/serviceinfo.h | 2 | ||||
-rw-r--r-- | src/bluetooth/qlowenergycontroller_bluez.cpp | 31 | ||||
-rw-r--r-- | src/bluetooth/qlowenergycontroller_p.h | 3 | ||||
-rw-r--r-- | src/bluetooth/qlowenergyservice.cpp | 14 | ||||
-rw-r--r-- | src/bluetooth/qlowenergyservice.h | 7 | ||||
-rw-r--r-- | src/bluetooth/qlowenergyserviceprivate_p.h | 2 |
8 files changed, 69 insertions, 15 deletions
diff --git a/examples/bluetooth/lowenergyscanner/assets/Services.qml b/examples/bluetooth/lowenergyscanner/assets/Services.qml index 361f14c1..e4e802d2 100644 --- a/examples/bluetooth/lowenergyscanner/assets/Services.qml +++ b/examples/bluetooth/lowenergyscanner/assets/Services.qml @@ -108,6 +108,12 @@ Rectangle { } Label { + textContent: modelData.serviceType + font.pointSize: serviceName.font.pointSize * 0.5 + anchors.top: serviceName.bottom + } + + Label { id: serviceUuid font.pointSize: serviceName.font.pointSize * 0.5 textContent: modelData.serviceUuid diff --git a/examples/bluetooth/lowenergyscanner/serviceinfo.cpp b/examples/bluetooth/lowenergyscanner/serviceinfo.cpp index 19b99b9f..c05422ca 100644 --- a/examples/bluetooth/lowenergyscanner/serviceinfo.cpp +++ b/examples/bluetooth/lowenergyscanner/serviceinfo.cpp @@ -64,6 +64,25 @@ QString ServiceInfo::getName() const return m_service->serviceName(); } +QString ServiceInfo::getType() const +{ + if (!m_service) + return QString(); + + QString result; + if (m_service->type() & QLowEnergyService::PrimaryService) + result += QStringLiteral("primary"); + else + result += QStringLiteral("secondary"); + + if (m_service->type() & QLowEnergyService::IncludedService) + result += QStringLiteral(" included"); + + result.prepend('<').append('>'); + + return result; +} + QString ServiceInfo::getUuid() const { if (!m_service) diff --git a/examples/bluetooth/lowenergyscanner/serviceinfo.h b/examples/bluetooth/lowenergyscanner/serviceinfo.h index d02c79ba..1d35b1b7 100644 --- a/examples/bluetooth/lowenergyscanner/serviceinfo.h +++ b/examples/bluetooth/lowenergyscanner/serviceinfo.h @@ -48,12 +48,14 @@ class ServiceInfo: public QObject Q_OBJECT Q_PROPERTY(QString serviceName READ getName NOTIFY serviceChanged) Q_PROPERTY(QString serviceUuid READ getUuid NOTIFY serviceChanged) + Q_PROPERTY(QString serviceType READ getType NOTIFY serviceChanged) public: ServiceInfo(); ServiceInfo(QLowEnergyService *service); QLowEnergyService *service() const; QString getUuid() const; QString getName() const; + QString getType() const; Q_SIGNALS: void serviceChanged(); diff --git a/src/bluetooth/qlowenergycontroller_bluez.cpp b/src/bluetooth/qlowenergycontroller_bluez.cpp index d3c7e024..795bdfb8 100644 --- a/src/bluetooth/qlowenergycontroller_bluez.cpp +++ b/src/bluetooth/qlowenergycontroller_bluez.cpp @@ -56,6 +56,7 @@ #define ATT_MAX_LE_MTU 0x200 #define GATT_PRIMARY_SERVICE 0x2800 +#define GATT_SECONDARY_SERVICE 0x2801 #define GATT_CHARACTERISTIC 0x2803 // GATT commands @@ -396,8 +397,13 @@ void QLowEnergyControllerPrivate::processReply( // Discovering services Q_ASSERT(request.command == ATT_OP_READ_BY_GROUP_REQUEST); + const quint16 type = request.reference.toUInt(); + if (isErrorResponse) { - q->discoveryFinished(); + if (type == GATT_SECONDARY_SERVICE) + q->discoveryFinished(); + else // search for secondary services + sendReadByGroupRequest(0x0001, 0xFFFF, GATT_SECONDARY_SERVICE); break; } @@ -427,6 +433,8 @@ void QLowEnergyControllerPrivate::processReply( priv->uuid = uuid; priv->startHandle = start; priv->endHandle = end; + if (type != GATT_PRIMARY_SERVICE) //unset PrimaryService bit + priv->type &= ~QLowEnergyService::PrimaryService; priv->setController(this); QSharedPointer<QLowEnergyServicePrivate> pointer(priv); @@ -435,10 +443,14 @@ void QLowEnergyControllerPrivate::processReply( emit q->serviceDiscovered(uuid); } - if (end != 0xFFFF) - sendReadByGroupRequest(end+1, 0xFFFF); - else - emit q->discoveryFinished(); + if (end != 0xFFFF) { + sendReadByGroupRequest(end+1, 0xFFFF, type); + } else { + if (type == GATT_SECONDARY_SERVICE) + emit q->discoveryFinished(); + else // search for secondary services + sendReadByGroupRequest(0x0001, 0xFFFF, GATT_SECONDARY_SERVICE); + } } break; case ATT_OP_READ_BY_TYPE_REQUEST: //in case of error @@ -689,19 +701,19 @@ void QLowEnergyControllerPrivate::processReply( void QLowEnergyControllerPrivate::discoverServices() { - sendReadByGroupRequest(0x0001, 0xFFFF); + sendReadByGroupRequest(0x0001, 0xFFFF, GATT_PRIMARY_SERVICE); } void QLowEnergyControllerPrivate::sendReadByGroupRequest( - QLowEnergyHandle start, QLowEnergyHandle end) + QLowEnergyHandle start, QLowEnergyHandle end, quint16 type) { - //call for primary services + //call for primary and secondary services quint8 packet[GRP_TYPE_REQ_SIZE]; packet[0] = ATT_OP_READ_BY_GROUP_REQUEST; bt_put_unaligned(htobs(start), (quint16 *) &packet[1]); bt_put_unaligned(htobs(end), (quint16 *) &packet[3]); - bt_put_unaligned(htobs(GATT_PRIMARY_SERVICE), (quint16 *) &packet[5]); + bt_put_unaligned(htobs(type), (quint16 *) &packet[5]); QByteArray data(GRP_TYPE_REQ_SIZE, Qt::Uninitialized); memcpy(data.data(), packet, GRP_TYPE_REQ_SIZE); @@ -711,6 +723,7 @@ void QLowEnergyControllerPrivate::sendReadByGroupRequest( Request request; request.payload = data; request.command = ATT_OP_READ_BY_GROUP_REQUEST; + request.reference = type; openRequests.enqueue(request); sendNextPendingRequest(); diff --git a/src/bluetooth/qlowenergycontroller_p.h b/src/bluetooth/qlowenergycontroller_p.h index e00e7a87..38178028 100644 --- a/src/bluetooth/qlowenergycontroller_p.h +++ b/src/bluetooth/qlowenergycontroller_p.h @@ -132,7 +132,8 @@ private: void sendNextPendingRequest(); void processReply(const Request &request, const QByteArray &reply); - void sendReadByGroupRequest(QLowEnergyHandle start, QLowEnergyHandle end); + void sendReadByGroupRequest(QLowEnergyHandle start, QLowEnergyHandle end, + quint16 type); void sendReadByTypeRequest(QSharedPointer<QLowEnergyServicePrivate> serviceData, QLowEnergyHandle nextHandle); void sendReadValueRequest(QLowEnergyHandle attributeHandle, bool isDescriptor); diff --git a/src/bluetooth/qlowenergyservice.cpp b/src/bluetooth/qlowenergyservice.cpp index 11485183..0bc9dc55 100644 --- a/src/bluetooth/qlowenergyservice.cpp +++ b/src/bluetooth/qlowenergyservice.cpp @@ -51,6 +51,18 @@ QT_BEGIN_NAMESPACE /*! + \enum QBluetoothDeviceInfo::ServiceType + + This enum describes the type of the service. + + \value PrimaryService The service is a top-level/primary service. + If this type flag is not set the service is considered + to be a secondary service. Each service may be included + by another service which is indicated by \l IncludedService. + \value IncludedService The service is included by another service. +*/ + +/*! \internal QLowEnergyControllerPrivate creates instances of this class. @@ -92,7 +104,7 @@ QLowEnergyService::ServiceState QLowEnergyService::state() const return d_ptr->state; } -QLowEnergyService::ServiceType QLowEnergyService::type() const +QLowEnergyService::ServiceTypes QLowEnergyService::type() const { return d_ptr->type; } diff --git a/src/bluetooth/qlowenergyservice.h b/src/bluetooth/qlowenergyservice.h index 9fe56280..541d6c61 100644 --- a/src/bluetooth/qlowenergyservice.h +++ b/src/bluetooth/qlowenergyservice.h @@ -54,9 +54,10 @@ class Q_BLUETOOTH_EXPORT QLowEnergyService : public QObject Q_OBJECT public: enum ServiceType { - PrimaryService = 0, - IncludedService + PrimaryService = 0x0001, + IncludedService = 0x0002 }; + Q_DECLARE_FLAGS(ServiceTypes, ServiceType) enum ServiceError { NoError = 0, @@ -76,7 +77,7 @@ public: ~QLowEnergyService(); QList<QSharedPointer<QLowEnergyService> > includedServices() const; - QLowEnergyService::ServiceType type() const; + QLowEnergyService::ServiceTypes type() const; QLowEnergyService::ServiceState state() const; QLowEnergyCharacteristic characteristic(const QBluetoothUuid &uuid) const; diff --git a/src/bluetooth/qlowenergyserviceprivate_p.h b/src/bluetooth/qlowenergyserviceprivate_p.h index 25b18e2d..ab19aa95 100644 --- a/src/bluetooth/qlowenergyserviceprivate_p.h +++ b/src/bluetooth/qlowenergyserviceprivate_p.h @@ -96,7 +96,7 @@ public: QLowEnergyHandle endHandle; QBluetoothUuid uuid; - QLowEnergyService::ServiceType type; + QLowEnergyService::ServiceTypes type; QLowEnergyService::ServiceState state; QLowEnergyService::ServiceError lastError; |