summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJuha Vuolle <juha.vuolle@insta.fi>2022-11-28 10:06:53 +0200
committerJuha Vuolle <juha.vuolle@insta.fi>2022-12-07 11:48:00 +0200
commit6beab27c5393920884bbb1d0fba68971ab19ca8d (patch)
treee25da630e54a946f5aedafd00cc625d2a8d0e510
parente7499c2cca615eaff3bd4c9ffe5f72d7112055cf (diff)
downloadqtconnectivity-6beab27c5393920884bbb1d0fba68971ab19ca8d.tar.gz
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>
-rw-r--r--src/bluetooth/bluez/bluezperipheralapplication.cpp8
-rw-r--r--src/bluetooth/bluez/bluezperipheralobjects.cpp23
-rw-r--r--tests/bttestui/btlocaldevice.cpp11
3 files changed, 34 insertions, 8 deletions
diff --git a/src/bluetooth/bluez/bluezperipheralapplication.cpp b/src/bluetooth/bluez/bluezperipheralapplication.cpp
index 0da243e4..5a8e4899 100644
--- a/src/bluetooth/bluez/bluezperipheralapplication.cpp
+++ b/src/bluetooth/bluez/bluezperipheralapplication.cpp
@@ -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(),
diff --git a/src/bluetooth/bluez/bluezperipheralobjects.cpp b/src/bluetooth/bluez/bluezperipheralobjects.cpp
index 090005ab..877b17ca 100644
--- a/src/bluetooth/bluez/bluezperipheralobjects.cpp
+++ b/src/bluetooth/bluez/bluezperipheralobjects.cpp
@@ -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);
diff --git a/tests/bttestui/btlocaldevice.cpp b/tests/bttestui/btlocaldevice.cpp
index 9306c482..b0c55ca7 100644
--- a/tests/bttestui/btlocaldevice.cpp
+++ b/tests/bttestui/btlocaldevice.cpp
@@ -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