QLowEnergyService Class
The QLowEnergyService class represents an individual service on a Bluetooth Low Energy Device. More...
Header: | #include <QLowEnergyService> |
qmake: | QT += bluetooth |
Since: | Qt 5.4 |
Inherits: | QObject. |
Public Types
enum | ServiceError { NoError, OperationError, CharacteristicWriteError, DescriptorWriteError } |
enum | ServiceState { InvalidService, DiscoveryRequired, DiscoveringServices, ServiceDiscovered } |
enum | ServiceType { PrimaryService, IncludedService } |
flags | ServiceTypes |
enum | WriteMode { WriteWithResponse, WriteWithoutResponse } |
Public Functions
~QLowEnergyService() | |
QLowEnergyCharacteristic | characteristic(const QBluetoothUuid & uuid) const |
QList<QLowEnergyCharacteristic> | characteristics() const |
bool | contains(const QLowEnergyCharacteristic & characteristic) const |
bool | contains(const QLowEnergyDescriptor & descriptor) const |
void | discoverDetails() |
ServiceError | error() const |
QList<QBluetoothUuid> | includedServices() const |
QString | serviceName() const |
QBluetoothUuid | serviceUuid() const |
QLowEnergyService::ServiceState | state() const |
QLowEnergyService::ServiceTypes | type() const |
void | writeCharacteristic(const QLowEnergyCharacteristic & characteristic, const QByteArray & newValue, WriteMode mode = WriteWithResponse) |
void | writeDescriptor(const QLowEnergyDescriptor & descriptor, const QByteArray & newValue) |
- 31 public functions inherited from QObject
Signals
void | characteristicChanged(const QLowEnergyCharacteristic & characteristic, const QByteArray & newValue) |
void | characteristicWritten(const QLowEnergyCharacteristic & characteristic, const QByteArray & newValue) |
void | descriptorWritten(const QLowEnergyDescriptor & descriptor, const QByteArray & newValue) |
void | error(QLowEnergyService::ServiceError newError) |
void | stateChanged(QLowEnergyService::ServiceState newState) |
- 2 signals inherited from QObject
Additional Inherited Members
- 1 property inherited from QObject
- 1 public slot inherited from QObject
- 11 static public members inherited from QObject
- 9 protected functions inherited from QObject
Detailed Description
The QLowEnergyService class represents an individual service on a Bluetooth Low Energy Device.
QLowEnergyService provides access to the details of Bluetooth Low Energy services. The class facilitates the discovery and publification of service details, permits reading and writing of the contained data and notifies about data changes.
Service Structure
A Bluetooth Low Energy peripheral device can contain multiple services. In turn each service may include further services. This class represents a single service of the peripheral device and is created via QLowEnergyController::createServiceObject(). The type() indicates whether this service is a primary (top-level) service or whether the service is part of another service. Each service may contain one or more characteristics and each characteristic may contain descriptors. The resulting structure may look like the following diagram:
A characteristic is the principle information carrier. It has a value() and properties() describing the access permissions for the value. The general purpose of the contained descriptor is to further define the nature of the characteristic. For example, it might specify how the value is meant to be interpreted or whether it can notify the value consumer about value changes.
Service Interaction
Once a service object was created for the first time, its details are yet to be discovered. This is indicated by its current state() being DiscoveryRequired. It is only possible to retrieve the serviceUuid() and serviceName().
The discovery of its included services, characteristics and descriptors is triggered when calling discoverDetails(). During the discovery the state() transitions from DiscoveryRequired via DiscoveringServices to its final ServiceDiscovered state. This transition is advertised via the stateChanged() signal. Once the details are known, all of the contained characteristics, descriptors and included services are known and can be read or written.
The values of characteristics and descriptors can be retrieved via QLowEnergyCharacteristic and QLowEnergyDescriptor, respectively. However writing those attributes requires the service object. The writeCharacteristic() function attempts to write a new value to the given characteristic. If the write attempt is successful, the characteristicWritten() signal is emitted. A failure to write triggers the CharacteristicWriteError. Writing a descriptor follows the same pattern.
Note: Currently, it is not possible to send signed write or reliable write requests.
In some cases the peripheral generates value updates which the central is interested in receiving. In order for a characteristic to support such notifications it must have the QLowEnergyCharacteristic::Notify or QLowEnergyCharacteristic::Indicate property and a descriptor of type QBluetoothUuid::ClientCharacteristicConfiguration. Provided those conditions are fulfilled notifications can be enabled as shown in the following code segment:
//PreCondition: service details already discovered QLowEnergyCharacteristic batteryLevel = service->characteristic( QBluetoothUuid::BatteryLevel); if (!batteryLevel.isValid()) return; QLowEnergyDescriptor notification = batteryLevel.descriptor( QBluetoothUuid::ClientCharacteristicConfiguration); if (!notification.isValid()) return; // establish hook into notifications connect(service, SIGNAL(characteristicChanged(QLowEnergyCharacteristic,QByteArray)), this, SLOT(characteristicChanged(QLowEnergyCharacteristic,QByteArray))); // enable notification service->writeDescriptor(notification, QByteArray::fromHex("0100")); // disable notification //service->writeDescriptor(notification, QByteArray::fromHex("0000")); // wait until descriptorWritten() signal is emitted // to confirm successful write
The example shows a battery level characteristic which updates the central on every value change. The notifications are provided via the characteristicChanged() signal. More details about this mechanism are provided by the Bluetooth Specification.
Service Data Sharing
Each QLowEnergyService instance shares its internal states and information with other QLowEnergyService instance of the same service. If one instance initiates the discovery of the service details, all remaining instances automatically follow. Therefore the following snippet always works:
QLowEnergyService *first, *second; QLowEnergyController control(remoteDevice); control.connectToDevice(); // waiting for connection first = control.createServiceObject(QBluetoothUuid::BatteryService); second = control.createServiceObject(QBluetoothUuid::BatteryService); Q_ASSERT(first->state() == QLowEnergyService::DiscoveryRequired); Q_ASSERT(first->state() == second->state()); first->discoverDetails(); Q_ASSERT(first->state() == QLowEnergyService::DiscoveringServices); Q_ASSERT(first->state() == second->state());
Other operations such as calls to writeCharacteristic(), writeDescriptor() or the invalidation of the service due to the related QLowEnergyController disconnecting from the device are shared the same way.
Note: This class is provided by Qt 5.4 as part of a Bluetooth Low Energy Tech Preview. Some API elements may change until the final release of the feature.
See also QLowEnergyController, QLowEnergyCharacteristic, and QLowEnergyDescriptor.
Member Type Documentation
enum QLowEnergyService::ServiceError
This enum describes all possible error conditions during the service's existence. The error() function returns the last occurred error.
Constant | Value | Description |
---|---|---|
QLowEnergyService::NoError | 0 | No error has occurred. |
QLowEnergyService::OperationError | 1 | An operation was attempted while the service was not ready. An example might be the attempt to write to the service while it was not yet in the ServiceDiscovered state() or the service is invalid due to a loss of connection to the peripheral device. |
QLowEnergyService::CharacteristicWriteError | 2 | An attempt to write a new value to a characteristic failed. For example, it might be triggered when attempting to write to a read-only characteristic. |
QLowEnergyService::DescriptorWriteError | 3 | An attempt to write a new value to a descriptor failed. For example, it might be triggered when attempting to write to a read-only descriptor. |
enum QLowEnergyService::ServiceState
This enum describes the state() of the service object.
Constant | Value | Description |
---|---|---|
QLowEnergyService::InvalidService | 0 | A service can become invalid when it looses the connection to the underlying device. Even though the connection may be lost it retains its last information. An invalid service cannot become valid anymore even if the connection to the device is re-established. |
QLowEnergyService::DiscoveryRequired | 1 | The service details are yet to be discovered by calling discoverDetails(). The only reliable pieces of information are its serviceUuid() and serviceName(). |
QLowEnergyService::DiscoveringServices | 2 | The service details are being discovered. |
QLowEnergyService::ServiceDiscovered | 3 | The service details have been discovered. |
enum QLowEnergyService::ServiceType
flags QLowEnergyService::ServiceTypes
This enum describes the type of the service.
Constant | Value | Description |
---|---|---|
QLowEnergyService::PrimaryService | 0x0001 | 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 IncludedService. |
QLowEnergyService::IncludedService | 0x0002 | The service is included by another service. |
The ServiceTypes type is a typedef for QFlags<ServiceType>. It stores an OR combination of ServiceType values.
enum QLowEnergyService::WriteMode
This enum describes the mode to be used when writing a characteristic value. The characteristic advertises its supported write modes via its properties.
Constant | Value | Description |
---|---|---|
QLowEnergyService::WriteWithResponse | 0 | If a characteristic is written using this mode, the peripheral shall send a write confirmation. If the operation is successful, the confirmation is emitted via the characteristicWritten() signal. Otherwise the CharacteristicWriteError is emitted. A characteristic must have set the QLowEnergyCharacteristic::Write property to support this write mode. |
QLowEnergyService::WriteWithoutResponse | 1 | If a characteristic is written using this mode, the remote peripheral shall not send a write confirmation. The operation's success cannot be determined and the payload must not be longer than 20 bytes. A characteristic must have set the QLowEnergyCharacteristic::WriteNoResponse property to support this write mode. Its adavantage is a quicker write operation as it may happen in between other device interactions. |
Member Function Documentation
QLowEnergyService::~QLowEnergyService()
Destroys the QLowEnergyService instance.
QLowEnergyCharacteristic QLowEnergyService::characteristic(const QBluetoothUuid & uuid) const
Returns the matching characteristic for uuid; otherwise an invalid characteristic.
See also characteristics().
[signal]
void QLowEnergyService::characteristicChanged(const QLowEnergyCharacteristic & characteristic, const QByteArray & newValue)
This signal is emitted when the value of characteristic is changed by an event on the peripheral. The newValue parameter contains the updated value of the characteristic.
The signal emission implies that change notifications must have been activated via the characteristic's ClientCharacteristicConfiguration descriptor prior to the change event on the peripheral. More details on how this might be done can be found further above.
[signal]
void QLowEnergyService::characteristicWritten(const QLowEnergyCharacteristic & characteristic, const QByteArray & newValue)
This signal is emitted when the value of characteristic is successfully changed to newValue. The change must have been triggered by calling writeCharacteristic(). If the write operation is not successful, the error() signal is emitted using the CharacteristicWriteError flag.
Note: If writeCharacteristic() is called using the WriteWithoutResponse mode, this signal and the error() are never emitted.
See also writeCharacteristic().
QList<QLowEnergyCharacteristic> QLowEnergyService::characteristics() const
Returns all characteristics associated with this QLowEnergyService
instance.
The returned list is empty if this service instance's discoverDetails() was not yet called or there are no known characteristics.
See also characteristic(), state(), and discoverDetails().
bool QLowEnergyService::contains(const QLowEnergyCharacteristic & characteristic) const
Returns true
if characteristic belongs to this service; otherwise false
.
A characteristic belongs to a service if characteristics() contains the characteristic.
bool QLowEnergyService::contains(const QLowEnergyDescriptor & descriptor) const
Returns true
if descriptor belongs to this service; otherwise false
.
[signal]
void QLowEnergyService::descriptorWritten(const QLowEnergyDescriptor & descriptor, const QByteArray & newValue)
This signal is emitted when the value of descriptor is successfully changed to newValue. The change must have been caused by calling writeDescriptor().
See also writeDescriptor().
void QLowEnergyService::discoverDetails()
Initiates the discovery of the services, characteristics and descriptors contained by the service. The discovery process is indicated via the stateChanged() signal.
See also state().
ServiceError QLowEnergyService::error() const
Returns the last occurred error or NoError.
[signal]
void QLowEnergyService::error(QLowEnergyService::ServiceError newError)
This signal is emitted when an error occurrs. The newError parameter describes the error that occurred.
QList<QBluetoothUuid> QLowEnergyService::includedServices() const
Returns the UUIDs of all services which are included by the current service.
It is possible that an included service contains yet another service. Such second level includes have to be obtained via their relevant first level QLowEnergyService instance. Technically, this could create a circular dependency.
QLowEnergyController::createServiceObject() should be used to obtain service instances for each of the UUIDs.
See also createServiceObject().
QString QLowEnergyService::serviceName() const
Returns the name of the service; otherwise an empty string.
The returned name can only be retrieved if serviceUuid() is a well-known UUID.
QBluetoothUuid QLowEnergyService::serviceUuid() const
Returns the UUID of the service; otherwise a null UUID.
QLowEnergyService::ServiceState QLowEnergyService::state() const
Returns the current state of the service.
If the device's service was instantiated for the first time, the object's state is DiscoveryRequired. The state of all service objects which point to the same service on the peripheral device are always equal. This is caused by the shared nature of the internal object data. Therefore any service object instance created after the first one has a state equal to already existing instances.
A service becomes invalid if the QLowEnergyController disconnects from the remote device. An invalid service retains its internal state at the time of the disconnect event. This implies that once the service details are discovered they can even be retrieved from an invalid service. This permits scenarios where the device connection is established, the service details are retrieved and the device immediately disconnected to permit the next device to connect to the peripheral device.
However, under normal circumstances the connection should remain to avoid repeated discovery of services and their details. The discovery may take a while and the client can subscribe to ongoing change notifications.
See also stateChanged().
[signal]
void QLowEnergyService::stateChanged(QLowEnergyService::ServiceState newState)
This signal is emitted when the service's state changes. The newState can also be retrieved via state().
See also state().
QLowEnergyService::ServiceTypes QLowEnergyService::type() const
Returns the type of the service.
void QLowEnergyService::writeCharacteristic(const QLowEnergyCharacteristic & characteristic, const QByteArray & newValue, WriteMode mode = WriteWithResponse)
Writes newValue as value for the characteristic. If the operation is successful, the characteristicWritten() signal is emitted; otherwise the CharacteristicWriteError is set.
The mode parameter determines whether the remote device should send a write confirmation. The to-be-written characteristic must support the relevant write mode. The characteristic's supported write modes are indicated by its QLowEnergyCharacteristic::Write and QLowEnergyCharacteristic::WriteNoResponse properties.
Note: Currently, it is not possible to use signed or reliable writes as defined by the Bluetooth specification.
A characteristic can only be written if this service is in the ServiceDiscovered state, belongs to the service and is writable.
See also QLowEnergyCharacteristic::properties().
void QLowEnergyService::writeDescriptor(const QLowEnergyDescriptor & descriptor, const QByteArray & newValue)
Writes newValue as value for descriptor. If the operation is successful, the descriptorWritten() signal is emitted; otherwise the DescriptorWriteError is emitted.
A descriptor can only be written if this service is in the ServiceDiscovered state, belongs to the service and is writable.
© 2015 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.