/* * BluezQt - Asynchronous Bluez wrapper library * * SPDX-FileCopyrightText: 2021 Ivan Podkurkov * * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL */ #include "gattcharacteristicremote_p.h" #include "gattcharacteristicremote.h" #include "gattdescriptorremote.h" #include "gattdescriptorremote_p.h" #include "device_p.h" #include "device.h" #include "adapter.h" #include "input.h" #include "input_p.h" #include "mediaplayer.h" #include "mediaplayer_p.h" #include "utils.h" #include "macros.h" namespace BluezQt { GattCharacteristicRemotePrivate::GattCharacteristicRemotePrivate(const QString &path, const QVariantMap &properties, const GattServiceRemotePtr &service) : QObject() , m_dbusProperties(nullptr) , m_writeAcquired(false) , m_notifyAcquired(false) , m_notifying(false) , m_handle() , m_MTU() , m_service(service) { m_bluezGattCharacteristic = new BluezGattCharacteristic(Strings::orgBluez(), path, DBusConnection::orgBluez(), this); init(properties); } void GattCharacteristicRemotePrivate::init(const QVariantMap &properties) { m_dbusProperties = new DBusProperties(Strings::orgBluez(), m_bluezGattCharacteristic->path(), DBusConnection::orgBluez(), this); // Init properties m_uuid = properties.value(QStringLiteral("UUID")).toString(); m_value = properties.value(QStringLiteral("Value")).toByteArray(); m_writeAcquired = properties.value(QStringLiteral("WriteAcquired")).toBool(); m_notifyAcquired = properties.value(QStringLiteral("NotifyAcquired")).toBool(); m_notifying = properties.value(QStringLiteral("Notifying")).toBool(); m_flags = properties.value(QStringLiteral("Flags")).toStringList(); m_handle = properties.value(QStringLiteral("Handle")).value(); m_MTU = properties.value(QStringLiteral("MTU")).value(); } void GattCharacteristicRemotePrivate::interfacesAdded(const QString &path, const QVariantMapMap &interfaces) { bool changed = false; QVariantMapMap::const_iterator it; for (it = interfaces.constBegin(); it != interfaces.constEnd(); ++it) { if (it.key() == Strings::orgBluezGattDescriptor1()) { addGattDescriptor(path,it.value()); changed = true; } } if (changed) { Q_EMIT q.lock().data()->characteristicChanged(q.toStrongRef()); } } void GattCharacteristicRemotePrivate::interfacesRemoved(const QString &path, const QStringList &interfaces) { Q_UNUSED(path) bool changed = false; for (auto& interface : interfaces) { if (interface == Strings::orgBluezGattDescriptor1()) { removeGattDescriptor(path); changed = true; } } if (changed) { Q_EMIT q.lock().data()->characteristicChanged(q.toStrongRef()); } } void GattCharacteristicRemotePrivate::addGattDescriptor(const QString &gattDescriptorPath, const QVariantMap &properties) { // Check if we have the right path if (m_bluezGattCharacteristic->path() != properties.value(QStringLiteral("Characteristic")).value().path()) { return; } GattCharacteristicRemotePtr characteristic = GattCharacteristicRemotePtr(this->q); if (!characteristic) { return; } GattDescriptorRemotePtr gattDescriptor = GattDescriptorRemotePtr(new GattDescriptorRemote(gattDescriptorPath, properties, characteristic)); gattDescriptor->d->q = gattDescriptor.toWeakRef(); m_descriptors.append(gattDescriptor); Q_EMIT characteristic->gattDescriptorAdded(gattDescriptor); Q_EMIT characteristic->descriptorsChanged(m_descriptors); // Connections connect(gattDescriptor.data(),&GattDescriptorRemote::descriptorChanged,q.lock().data(),&GattCharacteristicRemote::gattDescriptorChanged); } void GattCharacteristicRemotePrivate::removeGattDescriptor(const QString &gattDescriptorPath) { GattCharacteristicRemotePtr characteristic = GattCharacteristicRemotePtr(this->q); if (!characteristic) { return; } GattDescriptorRemotePtr gattDescriptor = nullptr; for (int i=0; i < characteristic->descriptors().size(); ++i) { if (characteristic->descriptors().at(i)->ubi() == gattDescriptorPath) { gattDescriptor = characteristic->descriptors().at(i); } } if (gattDescriptor == nullptr) { return; } m_descriptors.removeOne(gattDescriptor); Q_EMIT characteristic->gattDescriptorRemoved(gattDescriptor); Q_EMIT characteristic->descriptorsChanged(m_descriptors); // Connections disconnect(gattDescriptor.data(),&GattDescriptorRemote::descriptorChanged,q.lock().data(),&GattCharacteristicRemote::gattDescriptorChanged); } QDBusPendingReply<> GattCharacteristicRemotePrivate::setDBusProperty(const QString &name, const QVariant &value) { return m_dbusProperties->Set(Strings::orgBluezGattCharacteristic1(), name, QDBusVariant(value)); } void GattCharacteristicRemotePrivate::propertiesChanged(const QString &path, const QString &interface, const QVariantMap &changed, const QStringList &invalidated) { Q_UNUSED(path) if (interface == Strings::orgBluezGattDescriptor1()) { for (GattDescriptorRemotePtr descriptor : m_descriptors) { if (path.startsWith(descriptor->ubi())) { descriptor->d->propertiesChanged(path, interface, changed, invalidated); return; } } } else if (interface != Strings::orgBluezGattCharacteristic1()) { return; } QVariantMap::const_iterator i; for (i = changed.constBegin(); i != changed.constEnd(); ++i) { const QVariant &value = i.value(); const QString &property = i.key(); if (property == QLatin1String("UUID")) { PROPERTY_CHANGED(m_uuid, toString, uuidChanged); } else if (property == QLatin1String("Value")) { PROPERTY_CHANGED(m_value, toByteArray, valueChanged); } else if (property == QLatin1String("WriteAcquired")) { PROPERTY_CHANGED(m_writeAcquired, toBool, writeAcquiredChanged); } else if (property == QLatin1String("NotifyAcquired")) { PROPERTY_CHANGED(m_writeAcquired, toBool, writeAcquiredChanged); } else if (property == QLatin1String("Notifying")) { PROPERTY_CHANGED(m_notifying, toBool, notifyingChanged); } else if (property == QLatin1String("Flags")) { PROPERTY_CHANGED2(m_flags, value.toStringList(), flagsChanged); } else if (property == QLatin1String("Handle")) { PROPERTY_CHANGED2(m_handle, value.value(), handleChanged); } else if (property == QLatin1String("MTU")) { PROPERTY_CHANGED2(m_MTU, value.value(), MTUChanged); } } for (auto& property : invalidated) { if (property == QLatin1String("UUID")) { PROPERTY_INVALIDATED(m_uuid, QString(), uuidChanged); } else if (property == QLatin1String("Value")) { PROPERTY_INVALIDATED(m_value, QByteArray(), valueChanged); } else if (property == QLatin1String("WriteAcquired")) { PROPERTY_INVALIDATED(m_writeAcquired, false, writeAcquiredChanged); } else if (property == QLatin1String("NotifyAcquired")) { PROPERTY_INVALIDATED(m_writeAcquired, false, writeAcquiredChanged); } else if (property == QLatin1String("Notifying")) { PROPERTY_INVALIDATED(m_notifying, false, notifyingChanged); } else if (property == QLatin1String("Flags")) { PROPERTY_INVALIDATED(m_flags, QStringList(), flagsChanged); } else if (property == QLatin1String("Handle")) { PROPERTY_INVALIDATED(m_handle, quint16(), handleChanged); } else if (property == QLatin1String("MTU")) { PROPERTY_INVALIDATED(m_MTU, quint16(), MTUChanged); } } q.lock().data()->characteristicChanged(q.toStrongRef()); } } // namespace BluezQt #include "moc_gattcharacteristicremote_p.cpp"