File indexing completed on 2025-01-19 06:44:36
0001 /* 0002 * BluezQt - Asynchronous Bluez wrapper library 0003 * 0004 * SPDX-FileCopyrightText: 2021 Ivan Podkurkov <podkiva2@gmail.com> 0005 * 0006 * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0007 */ 0008 0009 #include "gattserviceremote_p.h" 0010 #include "gattserviceremote.h" 0011 #include "gattcharacteristicremote_p.h" 0012 #include "gattcharacteristicremote.h" 0013 #include "device_p.h" 0014 #include "device.h" 0015 #include "adapter.h" 0016 #include "input.h" 0017 #include "input_p.h" 0018 #include "mediaplayer.h" 0019 #include "mediaplayer_p.h" 0020 #include "utils.h" 0021 #include "macros.h" 0022 0023 namespace BluezQt 0024 { 0025 0026 GattServiceRemotePrivate::GattServiceRemotePrivate(const QString &path, const QVariantMap &properties, const DevicePtr &device) 0027 : QObject() 0028 , m_dbusProperties(nullptr) 0029 , m_primary(false) 0030 , m_device(device) 0031 , m_handle(0) 0032 { 0033 m_bluezGattService = new BluezGattService(Strings::orgBluez(), path, DBusConnection::orgBluez(), this); 0034 0035 init(properties); 0036 } 0037 0038 void GattServiceRemotePrivate::init(const QVariantMap &properties) 0039 { 0040 m_dbusProperties = new DBusProperties(Strings::orgBluez(), m_bluezGattService->path(), 0041 DBusConnection::orgBluez(), this); 0042 0043 // Init properties 0044 m_uuid = properties.value(QStringLiteral("UUID")).toString(); 0045 m_primary = properties.value(QStringLiteral("Primary")).toBool(); 0046 m_includes = properties.value(QStringLiteral("Includes")).value<QList<QDBusObjectPath>>(); 0047 m_handle = static_cast<quint16>(properties.value(QStringLiteral("Handle")).toUInt()); 0048 0049 } 0050 0051 void GattServiceRemotePrivate::interfacesAdded(const QString &path, const QVariantMapMap &interfaces) 0052 { 0053 bool changed = false; 0054 QVariantMapMap::const_iterator it; 0055 0056 for (it = interfaces.constBegin(); it != interfaces.constEnd(); ++it) { 0057 if (it.key() == Strings::orgBluezGattCharacteristic1()) { 0058 addGattCharacteristic(path,it.value()); 0059 changed = true; 0060 } 0061 } 0062 0063 for (auto& ch: m_characteristics) { 0064 if (path.startsWith(ch->ubi())) { 0065 ch->d->interfacesAdded(path, interfaces); 0066 changed = true; 0067 } 0068 } 0069 0070 if (changed) { 0071 Q_EMIT q.lock().data()->serviceChanged(q.toStrongRef()); 0072 } 0073 } 0074 0075 void GattServiceRemotePrivate::interfacesRemoved(const QString &path, const QStringList &interfaces) 0076 { 0077 Q_UNUSED(path) 0078 bool changed = false; 0079 0080 for (auto& interface : interfaces) { 0081 if (interface == Strings::orgBluezGattCharacteristic1()) { 0082 removeGattCharacteristic(path); 0083 changed = true; 0084 } 0085 } 0086 0087 for (auto& ch: m_characteristics) { 0088 if (path.startsWith(ch->ubi())) { 0089 ch->d->interfacesRemoved(path, interfaces); 0090 changed = true; 0091 } 0092 } 0093 0094 if (changed) { 0095 Q_EMIT q.lock().data()->serviceChanged(q.toStrongRef()); 0096 } 0097 } 0098 0099 void GattServiceRemotePrivate::addGattCharacteristic(const QString &gattCharacteristicPath, const QVariantMap &properties) 0100 { 0101 // Check if we have the right path 0102 if (m_bluezGattService->path() != properties.value(QStringLiteral("Service")).value<QDBusObjectPath>().path()) { 0103 return; 0104 } 0105 0106 GattServiceRemotePtr service = GattServiceRemotePtr(this->q); 0107 0108 if (!service) { 0109 return; 0110 } 0111 0112 GattCharacteristicRemotePtr gattCharacteristic = GattCharacteristicRemotePtr(new GattCharacteristicRemote(gattCharacteristicPath, properties, service)); 0113 gattCharacteristic->d->q = gattCharacteristic.toWeakRef(); 0114 m_characteristics.append(gattCharacteristic); 0115 0116 Q_EMIT service->gattCharacteristicAdded(gattCharacteristic); 0117 Q_EMIT service->characteristicsChanged(m_characteristics); 0118 0119 // Connections 0120 connect(gattCharacteristic.data(),&GattCharacteristicRemote::characteristicChanged,q.lock().data(),&GattServiceRemote::gattCharacteristicChanged); 0121 } 0122 0123 void GattServiceRemotePrivate::removeGattCharacteristic(const QString &gattCharacteristicPath) 0124 { 0125 GattServiceRemotePtr service = GattServiceRemotePtr(this->q); 0126 0127 if (!service) { 0128 return; 0129 } 0130 0131 GattCharacteristicRemotePtr gattCharacteristic = nullptr; 0132 for (int i=0; i < service->characteristics().size(); ++i) { 0133 if (service->characteristics().at(i)->ubi() == gattCharacteristicPath) { 0134 gattCharacteristic = service->characteristics().at(i); 0135 } 0136 } 0137 0138 if (gattCharacteristic == nullptr) { 0139 return; 0140 } 0141 0142 m_characteristics.removeOne(gattCharacteristic); 0143 0144 Q_EMIT service->gattCharacteristicRemoved(gattCharacteristic); 0145 Q_EMIT service->characteristicsChanged(m_characteristics); 0146 0147 // Connections 0148 disconnect(gattCharacteristic.data(),&GattCharacteristicRemote::characteristicChanged,q.lock().data(),&GattServiceRemote::gattCharacteristicChanged); 0149 } 0150 0151 QDBusPendingReply<> GattServiceRemotePrivate::setDBusProperty(const QString &name, const QVariant &value) 0152 { 0153 return m_dbusProperties->Set(Strings::orgBluezGattService1(), name, QDBusVariant(value)); 0154 } 0155 0156 void GattServiceRemotePrivate::propertiesChanged(const QString &path, const QString &interface, const QVariantMap &changed, const QStringList &invalidated) 0157 { 0158 if (interface == Strings::orgBluezGattCharacteristic1() || interface == Strings::orgBluezGattDescriptor1()) { 0159 for (GattCharacteristicRemotePtr characteristic : m_characteristics) { 0160 if (path.startsWith(characteristic->ubi())) { 0161 characteristic->d->propertiesChanged(path, interface, changed, invalidated); 0162 return; 0163 } 0164 } 0165 } else if (interface != Strings::orgBluezGattService1()) { 0166 return; 0167 } 0168 0169 QVariantMap::const_iterator i; 0170 for (i = changed.constBegin(); i != changed.constEnd(); ++i) { 0171 const QVariant &value = i.value(); 0172 const QString &property = i.key(); 0173 0174 if (property == QLatin1String("UUID")) { 0175 PROPERTY_CHANGED(m_uuid, toString, uuidChanged); 0176 } else if (property == QLatin1String("Primary")) { 0177 PROPERTY_CHANGED(m_primary, toBool, primaryChanged); 0178 } else if (property == QLatin1String("Includes")) { 0179 PROPERTY_CHANGED2(m_includes, value.value<QList<QDBusObjectPath>>(), includesChanged); 0180 } else if (property == QLatin1String("Handle")) { 0181 PROPERTY_CHANGED2(m_handle, value.value<quint16>(), handleChanged); 0182 } 0183 } 0184 0185 for (auto& property : invalidated) { 0186 if (property == QLatin1String("UUID")) { 0187 PROPERTY_INVALIDATED(m_uuid, QString(), uuidChanged); 0188 } else if (property == QLatin1String("Primary")) { 0189 PROPERTY_INVALIDATED(m_primary, false, primaryChanged); 0190 } else if (property == QLatin1String("Includes")) { 0191 PROPERTY_INVALIDATED(m_includes, QList<QDBusObjectPath>(), includesChanged); 0192 } else if (property == QLatin1String("Handle")) { 0193 PROPERTY_INVALIDATED(m_handle, quint16(), handleChanged); 0194 } 0195 } 0196 0197 q.lock().data()->serviceChanged(q.toStrongRef()); 0198 } 0199 0200 } // namespace BluezQt 0201 0202 #include "moc_gattserviceremote_p.cpp"