Bluez DBus peripheral add support for extended properties

Task-number: QTBUG-107511
Change-Id: Ia94262a29457489f8b7d5ffd2f5b50f943eb4b21
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
This commit is contained in:
Juha Vuolle 2022-11-28 10:06:53 +02:00
parent e7499c2cca
commit 6beab27c53
3 changed files with 34 additions and 8 deletions

View File

@ -180,9 +180,13 @@ void QtBluezPeripheralApplication::addService(const QLowEnergyServiceData &servi
quint16 descriptorOrdinal{0};
for (const auto& descriptorData : characteristicData.descriptors()) {
// With bluez we don't use the CCCD user has provided, because Bluez
// generates it if 'notify/indicate' flag is set. Duplicate CCCDs would ensue
// generates it if 'notify/indicate' flag is set. Similarly the extended properties
// descriptor is generated by Bluez if the related flags are set. Using the application
// provided descriptors would result in duplicate descriptors.
if (descriptorData.uuid()
== QBluetoothUuid::DescriptorType::ClientCharacteristicConfiguration) {
== QBluetoothUuid::DescriptorType::ClientCharacteristicConfiguration
|| descriptorData.uuid()
== QBluetoothUuid::DescriptorType::CharacteristicExtendedProperties) {
continue;
}
auto descriptorHandle = handleForDescriptor(descriptorData.uuid(),

View File

@ -280,11 +280,24 @@ void QtBluezPeripheralCharacteristic::initializeFlags(const QLowEnergyCharacteri
m_flags.append("indicate"_L1);
if (data.properties() & QLowEnergyCharacteristic::PropertyType::WriteSigned)
m_flags.append("authenticated-signed-writes"_L1);
// TODO how to interpet ExtendedProperty? (reliable-write and writable-auxiliaries?)
// (Note: Bluez will generate any needed special descriptors). Also: check
// the secure-read and secure-write flags
if (data.properties() & QLowEnergyCharacteristic::PropertyType::ExtendedProperty)
m_flags.append("extended-properties"_L1);
if (data.properties() & QLowEnergyCharacteristic::PropertyType::ExtendedProperty) {
// If extended properties property is set, check if we have the descriptor
// describing them. Bluez will generate the actual descriptor based on these
// flags. For clarity: the 'extended-properties' token mentioned in the Bluez
// API is implied by these flags.
for (const auto& descriptor : data.descriptors()) {
// Core Bluetooth v5.3 Vol 3, Part G, 3.3.3.1
if (descriptor.uuid()
== QBluetoothUuid::DescriptorType::CharacteristicExtendedProperties
&& descriptor.value().size() == 2) {
const auto properties = descriptor.value().at(0);
if (properties & 0x01)
m_flags.append("reliable-write"_L1);
if (properties & 0x02)
m_flags.append("writable-auxiliaries"_L1);
}
}
}
if (data.readConstraints() & QBluetooth::AttAccessConstraint::AttEncryptionRequired)
m_flags.append("encrypt-read"_L1);

View File

@ -957,7 +957,8 @@ void BtLocalDevice::peripheralAddServices()
charData.setValueLength(leCharacteristicSize, leCharacteristicSize);
charData.setProperties(QLowEnergyCharacteristic::PropertyType::Read
| QLowEnergyCharacteristic::PropertyType::Write
| QLowEnergyCharacteristic::PropertyType::Notify);
| QLowEnergyCharacteristic::PropertyType::Notify
| QLowEnergyCharacteristic::ExtendedProperty);
const QLowEnergyDescriptorData clientConfig(
QBluetoothUuid::DescriptorType::ClientCharacteristicConfiguration,
@ -968,6 +969,14 @@ void BtLocalDevice::peripheralAddServices()
QBluetoothUuid::DescriptorType::CharacteristicUserDescription,
leDescriptorValue);
charData.addDescriptor(userDescription);
const QLowEnergyDescriptorData extendedProperties(
QBluetoothUuid::DescriptorType::CharacteristicExtendedProperties,
// From bluetooth specs: length 2 bytes
// bit 0: reliable write, bit 1: writable auxiliaries
QByteArray::fromHex("0300"));
charData.addDescriptor(extendedProperties);
sd.addCharacteristic(charData);
// Set another characteristic without notifications