Try to enable also indications if possible with bluez version

master
Simon Stürz 2021-01-25 14:24:11 +01:00
parent 68ca8605f3
commit a004724b0f
5 changed files with 73 additions and 8 deletions

View File

@ -72,6 +72,17 @@ QList<BluetoothGattDescriptor *> BluetoothGattCharacteristic::descriptors() cons
return m_descriptors;
}
BluetoothGattDescriptor *BluetoothGattCharacteristic::getDescriptor(const QBluetoothUuid &desciptorUuid) const
{
foreach (BluetoothGattDescriptor *descriptor, m_descriptors) {
if (descriptor->uuid() == desciptorUuid) {
return descriptor;
}
}
return nullptr;
}
BluetoothGattCharacteristic::BluetoothGattCharacteristic(const QDBusObjectPath &path, const QVariantMap &properties, QObject *parent) :
QObject(parent),
m_path(path),

View File

@ -82,7 +82,7 @@ public:
Properties properties() const;
QByteArray value() const;
QList<BluetoothGattDescriptor *> descriptors() const;
BluetoothGattDescriptor *getDescriptor(const QBluetoothUuid &desciptorUuid) const;
private:
explicit BluetoothGattCharacteristic(const QDBusObjectPath &path, const QVariantMap &properties, QObject *parent = 0);

View File

@ -75,10 +75,17 @@ BluetoothGattDescriptor::BluetoothGattDescriptor(const QDBusObjectPath &path, co
QDBusConnection::systemBus().connect(orgBluez, m_path.path(), "org.freedesktop.DBus.Properties", "PropertiesChanged", this, SLOT(onPropertiesChanged(QString,QVariantMap,QStringList)));
processProperties(properties);
// QDBusPendingCall readingCall = m_descriptorInterface->asyncCall("GetAll", QVariantMap());
// QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(readingCall, this);
// connect(watcher, &QDBusPendingCallWatcher::finished, this, [=](){
// qCDebug(dcBluez()) << "Get descriptor properties finished";
// });
}
void BluetoothGattDescriptor::processProperties(const QVariantMap &properties)
{
qCDebug(dcBluez()) << "Descriptor properties" << properties;
foreach (const QString &propertyName, properties.keys()) {
if (propertyName == "UUID") {
m_uuid = QBluetoothUuid(properties.value(propertyName).toString());

View File

@ -150,9 +150,9 @@ void Nuki::printServices()
foreach (BluetoothGattService *service, m_bluetoothDevice->services()) {
qCDebug(dcNuki()) << service;
foreach (BluetoothGattCharacteristic *characteristic, service->characteristics()) {
qCDebug(dcNuki()) << " " << characteristic->chararcteristicName() << characteristic->uuid().toString();
qCDebug(dcNuki()) << " " << characteristic;
foreach (BluetoothGattDescriptor *descriptor, characteristic->descriptors()) {
qCDebug(dcNuki()) << " " << descriptor->name() << descriptor->uuid().toString();
qCDebug(dcNuki()) << " " << descriptor;
}
}
}
@ -202,6 +202,45 @@ void Nuki::executeCurrentAction()
}
}
bool Nuki::enableNotificationsIndications(BluetoothGattCharacteristic *characteristic)
{
qCDebug(dcNuki()) << "Start enable notifications/indications for" << characteristic;
// Get the client configuration descriptor
// https://www.bluetooth.com/wp-content/uploads/Sitecore-Media-Library/Gatt/Xml/Descriptors/org.bluetooth.descriptor.gatt.client_characteristic_configuration.xml
BluetoothGattDescriptor *clientConfiguration = characteristic->getDescriptor(QBluetoothUuid::ClientCharacteristicConfiguration);
if (!clientConfiguration) {
qCWarning(dcNuki()) << "Could not start notification/indications for" << characteristic << "because the client configuration descriptor is missing";
return false;
}
qCDebug(dcNuki()) << "Enable notifications on" << characteristic;
if (!characteristic->startNotifications()) {
qCDebug(dcNuki()) << "Failed to start notifications on" << characteristic;
return false;
}
if (characteristic->properties().testFlag(BluetoothGattCharacteristic::Indicate)) {
qCDebug(dcNuki()) << "Enable indications on" << characteristic;
QByteArray configuration;
QDataStream stream(&configuration, QIODevice::WriteOnly);
stream.setByteOrder(QDataStream::LittleEndian);
stream << static_cast<quint16>(0x02);
if (!clientConfiguration->writeValue(configuration)) {
qCWarning(dcNuki()) << "Failed to write client configuration descriptor on" << characteristic;
return false;
}
} else {
qCWarning(dcNuki()) << "Could not enable notifications. Access properties do not allow indicate or notify" << characteristic;
return false;
}
clientConfiguration->readValue();
return true;
}
void Nuki::onBluetoothDeviceStateChanged(const BluetoothDevice::State &state)
{
qCDebug(dcNuki()) << m_bluetoothDevice << "state changed --> " << state;
@ -433,29 +472,36 @@ bool Nuki::init()
qCWarning(dcNuki()) << "Could not find user data characteristc on device" << m_bluetoothDevice;
return false;
}
// Set key turner characteristics for data and user data
if (!m_keyturnerService->hasCharacteristic(keyturnerDataCharacteristicUuid)) {
qCWarning(dcNuki()) << "Could not find data characteristc on device" << m_bluetoothDevice;
return false;
}
// Enable notifications/indications
m_keyturnerUserDataCharacteristic = m_keyturnerService->getCharacteristic(keyturnerUserDataCharacteristicUuid);
if (!m_keyturnerUserDataCharacteristic->startNotifications()) {
qCWarning(dcNuki()) << "Could not enable notifications for user data characteristic.";
if (!enableNotificationsIndications(m_keyturnerUserDataCharacteristic)) {
qCWarning(dcNuki()) << "Could not enable notifications/indications for user data characteristic.";
return false;
}
m_keyturnerDataCharacteristic = m_keyturnerService->getCharacteristic(keyturnerDataCharacteristicUuid);
if (!m_keyturnerDataCharacteristic->startNotifications()) {
qCWarning(dcNuki()) << "Could not enable notifications for data characteristic.";
if (!enableNotificationsIndications(m_keyturnerDataCharacteristic)) {
qCWarning(dcNuki()) << "Could not enable notifications/indications for key turner data characteristic.";
return false;
}
// Pairing service
m_pairingService = m_bluetoothDevice->getService(pairingServiceUuid);
if (!m_pairingService->hasCharacteristic(pairingDataCharacteristicUuid)) {
qCWarning(dcNuki()) << "Could not find pairing data characteristc on device" << m_bluetoothDevice;
return false;
}
m_pairingDataCharacteristic = m_pairingService->getCharacteristic(pairingDataCharacteristicUuid);
if (!m_pairingDataCharacteristic->startNotifications()) {
if (!enableNotificationsIndications(m_pairingDataCharacteristic)) {
qCWarning(dcNuki()) << "Could not enable notifications for pairing characteristic.";
return false;
}

View File

@ -115,6 +115,7 @@ private:
void readDeviceInformationCharacteristics();
void executeCurrentAction();
bool enableNotificationsIndications(BluetoothGattCharacteristic *characteristic);
signals:
void availableChanged(bool available);