21 m_objectPath(QString(appObjectPathTemplate).
22 arg(sanitizeNameForDBus(QCoreApplication::applicationName())).
23 arg(QCoreApplication::applicationPid()).
24 arg(QRandomGenerator::global()->generate()))
26 m_objectManager =
new OrgFreedesktopDBusObjectManagerAdaptor(
this);
27 m_gattManager =
new OrgBluezGattManager1Interface(
"org.bluez"_L1, hostAdapterPath,
28 QDBusConnection::systemBus(),
this);
38 if (m_applicationRegistered) {
40 qCDebug(QT_BT_BLUEZ) <<
"Bluez peripheral application already registered";
44 if (m_services.isEmpty()) {
46 qCDebug(QT_BT_BLUEZ) <<
"No services, omiting Bluez peripheral application registration";
50 qCDebug(QT_BT_BLUEZ) <<
"Registering bluez peripheral application:" << m_objectPath;
53 if (!QDBusConnection::systemBus().registerObject(m_objectPath, m_objectManager,
54 QDBusConnection::ExportAllContents)) {
55 qCWarning(QT_BT_BLUEZ) <<
"Peripheral application object registration failed";
66 auto reply = m_gattManager->RegisterApplication(QDBusObjectPath(m_objectPath), {});
67 QDBusPendingCallWatcher* watcher =
new QDBusPendingCallWatcher(reply,
this);
68 QObject::connect(watcher, &QDBusPendingCallWatcher::finished,
this,
69 [
this](QDBusPendingCallWatcher* watcher) {
70 QDBusPendingReply<> reply = *watcher;
71 if (reply.isError()) {
72 qCWarning(QT_BT_BLUEZ) <<
"Application registration failed" << reply.error();
73 QDBusConnection::systemBus().unregisterObject(m_objectPath);
76 qCDebug(QT_BT_BLUEZ) <<
"Peripheral application registered as" << m_objectPath;
77 m_applicationRegistered =
true;
80 watcher->deleteLater();
136 QSharedPointer<QLowEnergyServicePrivate> servicePrivate,
137 QLowEnergyHandle serviceHandle)
139 if (m_applicationRegistered) {
140 qCWarning(QT_BT_BLUEZ) <<
"Adding services to a registered application is not supported "
141 "on Bluez DBus. Add services only before first advertisement or "
142 "after disconnection";
153 serviceData, m_objectPath, m_services.size(), serviceHandle,
this);
154 m_services.insert(serviceHandle, service);
157 for (
const auto includedService : serviceData.includedServices()) {
159 for (
const auto s : std::as_const(m_services)) {
160 if (QBluetoothUuid(s->uuid) == includedService->serviceUuid()) {
161 service->addIncludedService(s->objectPath);
167 quint16 characteristicOrdinal{0};
168 for (
const auto& characteristicData : serviceData.characteristics()) {
169 auto characteristicHandle = handleForCharacteristic(
170 characteristicData.uuid(), servicePrivate);
171 QtBluezPeripheralCharacteristic* characteristic =
172 new QtBluezPeripheralCharacteristic(characteristicData,
173 service->objectPath, characteristicOrdinal++,
174 characteristicHandle,
this);
175 m_characteristics.insert(characteristicHandle, characteristic);
176 QObject::connect(characteristic, &QtBluezPeripheralCharacteristic::valueUpdatedByRemote,
177 this, &QtBluezPeripheralApplication::characteristicValueUpdatedByRemote);
178 QObject::connect(characteristic, &QtBluezPeripheralCharacteristic::remoteDeviceAccessEvent,
179 this, &QtBluezPeripheralApplication::remoteDeviceAccessEvent);
181 quint16 descriptorOrdinal{0};
182 for (
const auto& descriptorData : characteristicData.descriptors()) {
187 if (descriptorData.uuid()
188 == QBluetoothUuid::DescriptorType::ClientCharacteristicConfiguration
189 || descriptorData.uuid()
190 == QBluetoothUuid::DescriptorType::CharacteristicExtendedProperties) {
193 auto descriptorHandle = handleForDescriptor(descriptorData.uuid(),
195 characteristicHandle);
196 QtBluezPeripheralDescriptor* descriptor =
197 new QtBluezPeripheralDescriptor(descriptorData,
198 characteristic->objectPath, descriptorOrdinal++,
199 descriptorHandle, characteristicHandle,
this);
200 QObject::connect(descriptor, &QtBluezPeripheralDescriptor::valueUpdatedByRemote,
201 this, &QtBluezPeripheralApplication::descriptorValueUpdatedByRemote);
202 QObject::connect(descriptor, &QtBluezPeripheralCharacteristic::remoteDeviceAccessEvent,
203 this, &QtBluezPeripheralApplication::remoteDeviceAccessEvent);
204 m_descriptors.insert(descriptorHandle, descriptor);
242 ManagedObjectList managedObjects;
243 for (
const auto service: std::as_const(m_services))
244 managedObjects.insert(QDBusObjectPath(service->objectPath), service->properties());
245 for (
const auto& charac : std::as_const(m_characteristics))
246 managedObjects.insert(QDBusObjectPath(charac->objectPath), charac->properties());
247 for (
const auto& descriptor : std::as_const(m_descriptors))
248 managedObjects.insert(QDBusObjectPath(descriptor->objectPath), descriptor->properties());
250 return managedObjects;