From 4f1e4771fc592c91b92dd3f7d29929d0647cf4f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Thu, 7 Aug 2025 12:22:19 +0200 Subject: [PATCH] Port bluetooth LE support to Qt6 --- .../bluetooth/bluetoothserver.cpp | 63 ++++++++++++++++++- .../bluetooth/networkservice.cpp | 13 +++- .../bluetooth/networkservice.h | 2 +- .../bluetooth/wirelessservice.cpp | 16 +++-- .../bluetooth/wirelessservice.h | 2 +- .../libnymea-networkmanager.pro | 6 +- 6 files changed, 90 insertions(+), 12 deletions(-) diff --git a/libnymea-networkmanager/bluetooth/bluetoothserver.cpp b/libnymea-networkmanager/bluetooth/bluetoothserver.cpp index 28f70b9..5fb22d3 100644 --- a/libnymea-networkmanager/bluetooth/bluetoothserver.cpp +++ b/libnymea-networkmanager/bluetooth/bluetoothserver.cpp @@ -128,11 +128,19 @@ QLowEnergyServiceData BluetoothServer::deviceInformationServiceData() { QLowEnergyServiceData serviceData; serviceData.setType(QLowEnergyServiceData::ServiceTypePrimary); +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + serviceData.setUuid(QBluetoothUuid::ServiceClassUuid::DeviceInformation); +#else serviceData.setUuid(QBluetoothUuid::DeviceInformation); +#endif // Model number string 0x2a24 QLowEnergyCharacteristicData modelNumberCharData; +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + modelNumberCharData.setUuid(QBluetoothUuid::CharacteristicType::ModelNumberString); +#else modelNumberCharData.setUuid(QBluetoothUuid::ModelNumberString); +#endif if (m_modelName.isEmpty()) { modelNumberCharData.setValue(QString("N.A.").toUtf8()); } else { @@ -144,7 +152,11 @@ QLowEnergyServiceData BluetoothServer::deviceInformationServiceData() // Serial number string 0x2a25 QLowEnergyCharacteristicData serialNumberCharData; +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + serialNumberCharData.setUuid(QBluetoothUuid::CharacteristicType::SerialNumberString); +#else serialNumberCharData.setUuid(QBluetoothUuid::SerialNumberString); +#endif if (m_serialNumber.isNull()) { // Note: if no serialnumber specified use the system uuid from /etc/machine-id qCDebug(dcNetworkManagerBluetoothServer()) << "Serial number not specified. Using system uuid from /etc/machine-id as serialnumber."; @@ -156,28 +168,44 @@ QLowEnergyServiceData BluetoothServer::deviceInformationServiceData() // Firmware revision string 0x2a26 QLowEnergyCharacteristicData firmwareRevisionCharData; +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + firmwareRevisionCharData.setUuid(QBluetoothUuid::CharacteristicType::FirmwareRevisionString); +#else firmwareRevisionCharData.setUuid(QBluetoothUuid::FirmwareRevisionString); +#endif firmwareRevisionCharData.setValue(QString(VERSION_STRING).toUtf8()); firmwareRevisionCharData.setProperties(QLowEnergyCharacteristic::Read); serviceData.addCharacteristic(firmwareRevisionCharData); // Hardware revision string 0x2a27 QLowEnergyCharacteristicData hardwareRevisionCharData; +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + hardwareRevisionCharData.setUuid(QBluetoothUuid::CharacteristicType::HardwareRevisionString); +#else hardwareRevisionCharData.setUuid(QBluetoothUuid::HardwareRevisionString); +#endif hardwareRevisionCharData.setValue(m_hardwareVersion.toUtf8()); hardwareRevisionCharData.setProperties(QLowEnergyCharacteristic::Read); serviceData.addCharacteristic(hardwareRevisionCharData); // Software revision string 0x2a28 QLowEnergyCharacteristicData softwareRevisionCharData; +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + softwareRevisionCharData.setUuid(QBluetoothUuid::CharacteristicType::SoftwareRevisionString); +#else softwareRevisionCharData.setUuid(QBluetoothUuid::SoftwareRevisionString); +#endif softwareRevisionCharData.setValue(m_softwareVersion.toUtf8()); softwareRevisionCharData.setProperties(QLowEnergyCharacteristic::Read); serviceData.addCharacteristic(softwareRevisionCharData); // Manufacturer name string 0x2a29 QLowEnergyCharacteristicData manufacturerNameCharData; +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + manufacturerNameCharData.setUuid(QBluetoothUuid::CharacteristicType::ManufacturerNameString); +#else manufacturerNameCharData.setUuid(QBluetoothUuid::ManufacturerNameString); +#endif manufacturerNameCharData.setValue(QString("nymea GmbH").toUtf8()); manufacturerNameCharData.setProperties(QLowEnergyCharacteristic::Read); serviceData.addCharacteristic(manufacturerNameCharData); @@ -189,11 +217,19 @@ QLowEnergyServiceData BluetoothServer::genericAccessServiceData() { QLowEnergyServiceData serviceData; serviceData.setType(QLowEnergyServiceData::ServiceTypePrimary); +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + serviceData.setUuid(QBluetoothUuid::ServiceClassUuid::GenericAccess); +#else serviceData.setUuid(QBluetoothUuid::GenericAccess); +#endif // Device name 0x2a00 QLowEnergyCharacteristicData nameCharData; +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + nameCharData.setUuid(QBluetoothUuid::CharacteristicType::DeviceName); +#else nameCharData.setUuid(QBluetoothUuid::DeviceName); +#endif if (m_advertiseName.isNull()) { qCWarning(dcNetworkManagerBluetoothServer()) << "Advertise name not specified. Using system host name as device name."; m_advertiseName = QSysInfo::machineHostName(); @@ -204,21 +240,33 @@ QLowEnergyServiceData BluetoothServer::genericAccessServiceData() // Appearance 0x2a01 QLowEnergyCharacteristicData appearanceCharData; +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + appearanceCharData.setUuid(QBluetoothUuid::CharacteristicType::Appearance); +#else appearanceCharData.setUuid(QBluetoothUuid::Appearance); +#endif appearanceCharData.setValue(QByteArray(4, 0)); appearanceCharData.setProperties(QLowEnergyCharacteristic::Read); serviceData.addCharacteristic(appearanceCharData); // Peripheral Privacy Flag 0x2a02 QLowEnergyCharacteristicData privacyFlagCharData; +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + privacyFlagCharData.setUuid(QBluetoothUuid::CharacteristicType::PeripheralPrivacyFlag); +#else privacyFlagCharData.setUuid(QBluetoothUuid::PeripheralPrivacyFlag); +#endif privacyFlagCharData.setValue(QByteArray(2, 0)); privacyFlagCharData.setProperties(QLowEnergyCharacteristic::Read | QLowEnergyCharacteristic::Write); serviceData.addCharacteristic(privacyFlagCharData); // Reconnection Address 0x2a03 QLowEnergyCharacteristicData reconnectionAddressCharData; +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + reconnectionAddressCharData.setUuid(QBluetoothUuid::CharacteristicType::ReconnectionAddress); +#else reconnectionAddressCharData.setUuid(QBluetoothUuid::ReconnectionAddress); +#endif reconnectionAddressCharData.setValue(QByteArray()); reconnectionAddressCharData.setProperties(QLowEnergyCharacteristic::Write); serviceData.addCharacteristic(reconnectionAddressCharData); @@ -230,10 +278,18 @@ QLowEnergyServiceData BluetoothServer::genericAttributeServiceData() { QLowEnergyServiceData serviceData; serviceData.setType(QLowEnergyServiceData::ServiceTypePrimary); +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + serviceData.setUuid(QBluetoothUuid::ServiceClassUuid::GenericAttribute); +#else serviceData.setUuid(QBluetoothUuid::GenericAttribute); +#endif QLowEnergyCharacteristicData charData; +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + charData.setUuid(QBluetoothUuid::CharacteristicType::ServiceChanged); +#else charData.setUuid(QBluetoothUuid::ServiceChanged); +#endif charData.setProperties(QLowEnergyCharacteristic::Indicate); serviceData.addCharacteristic(charData); @@ -452,8 +508,13 @@ void BluetoothServer::start() connect(m_controller, &QLowEnergyController::stateChanged, this, &BluetoothServer::onControllerStateChanged); connect(m_controller, &QLowEnergyController::connected, this, &BluetoothServer::onConnected); connect(m_controller, &QLowEnergyController::disconnected, this, &BluetoothServer::onDisconnected); + +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + connect(m_controller, &QLowEnergyController::errorOccurred, this, &BluetoothServer::onError); +#else connect(m_controller, static_cast - (&QLowEnergyController::error), this, &BluetoothServer::onError); + (&QLowEnergyController::error), this, &BluetoothServer::onError); +#endif // Note: https://www.bluetooth.com/specifications/gatt/services m_deviceInfoService = m_controller->addService(deviceInformationServiceData(), m_controller); diff --git a/libnymea-networkmanager/bluetooth/networkservice.cpp b/libnymea-networkmanager/bluetooth/networkservice.cpp index e708dc8..c1cef7d 100644 --- a/libnymea-networkmanager/bluetooth/networkservice.cpp +++ b/libnymea-networkmanager/bluetooth/networkservice.cpp @@ -54,8 +54,13 @@ NetworkService::NetworkService(QLowEnergyService *service, NetworkManager *netwo connect(m_service, &QLowEnergyService::characteristicRead, this, &NetworkService::characteristicRead); connect(m_service, &QLowEnergyService::characteristicWritten, this, &NetworkService::characteristicWritten); connect(m_service, &QLowEnergyService::descriptorWritten, this, &NetworkService::descriptorWritten); +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + connect(m_service, &QLowEnergyService::errorOccurred, this, &NetworkService::serviceError); +#else connect(m_service, static_cast - (&QLowEnergyService::error), this, &NetworkService::serviceError); + (&QLowEnergyService::error), this, &NetworkService::serviceError); + +#endif // NetworkManager connect(m_networkManager, &NetworkManager::stateChanged, this, &NetworkService::onNetworkManagerStateChanged); @@ -74,7 +79,11 @@ QLowEnergyServiceData NetworkService::serviceData(NetworkManager *networkManager serviceData.setType(QLowEnergyServiceData::ServiceTypePrimary); serviceData.setUuid(networkServiceUuid); +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + QLowEnergyDescriptorData clientConfigDescriptorData(QBluetoothUuid::DescriptorType::ClientCharacteristicConfiguration, QByteArray(2, 0)); +#else QLowEnergyDescriptorData clientConfigDescriptorData(QBluetoothUuid::ClientCharacteristicConfiguration, QByteArray(2, 0)); +#endif // Network manager status ef6d661-b8af-49e0-9eca-ab343513641c QLowEnergyCharacteristicData networkStatusData; @@ -253,7 +262,7 @@ void NetworkService::descriptorWritten(const QLowEnergyDescriptor &descriptor, c qCDebug(dcNetworkManagerBluetoothServer()) << "NetworkService: Descriptor written" << descriptor.uuid().toString() << value; } -void NetworkService::serviceError(const QLowEnergyService::ServiceError &error) +void NetworkService::serviceError(QLowEnergyService::ServiceError error) { QString errorString; switch (error) { diff --git a/libnymea-networkmanager/bluetooth/networkservice.h b/libnymea-networkmanager/bluetooth/networkservice.h index c8c6e8b..f49f557 100644 --- a/libnymea-networkmanager/bluetooth/networkservice.h +++ b/libnymea-networkmanager/bluetooth/networkservice.h @@ -82,7 +82,7 @@ private slots: void characteristicWritten(const QLowEnergyCharacteristic &characteristic, const QByteArray &value); void descriptorRead(const QLowEnergyDescriptor &descriptor, const QByteArray &value); void descriptorWritten(const QLowEnergyDescriptor &descriptor, const QByteArray &value); - void serviceError(const QLowEnergyService::ServiceError &error); + void serviceError(QLowEnergyService::ServiceError error); // Commands void processCommand(const NetworkServiceCommand &command); diff --git a/libnymea-networkmanager/bluetooth/wirelessservice.cpp b/libnymea-networkmanager/bluetooth/wirelessservice.cpp index d5dcb7e..90c7405 100644 --- a/libnymea-networkmanager/bluetooth/wirelessservice.cpp +++ b/libnymea-networkmanager/bluetooth/wirelessservice.cpp @@ -56,8 +56,12 @@ WirelessService::WirelessService(QLowEnergyService *service, NetworkManager *net connect(m_service, &QLowEnergyService::characteristicRead, this, &WirelessService::characteristicRead); connect(m_service, &QLowEnergyService::characteristicWritten, this, &WirelessService::characteristicWritten); connect(m_service, &QLowEnergyService::descriptorWritten, this, &WirelessService::descriptorWritten); +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + connect(m_service, &QLowEnergyService::errorOccurred, this, &WirelessService::serviceError); +#else connect(m_service, static_cast - (&QLowEnergyService::error), this, &WirelessService::serviceError); + (&QLowEnergyService::error), this, &WirelessService::serviceError); +#endif // Get the wireless network device if there is any if (!m_networkManager->wirelessAvailable()) { @@ -83,7 +87,11 @@ QLowEnergyServiceData WirelessService::serviceData(NetworkManager *networkManage serviceData.setType(QLowEnergyServiceData::ServiceTypePrimary); serviceData.setUuid(wirelessServiceUuid); +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + QLowEnergyDescriptorData clientConfigDescriptorData(QBluetoothUuid::DescriptorType::ClientCharacteristicConfiguration, QByteArray(2, 0)); +#else QLowEnergyDescriptorData clientConfigDescriptorData(QBluetoothUuid::ClientCharacteristicConfiguration, QByteArray(2, 0)); +#endif QLowEnergyCharacteristicData versionCharacteristicData; versionCharacteristicData.setUuid(wirelessServiceVersionCharacteristicUuid); @@ -225,13 +233,13 @@ void WirelessService::streamData(const QVariantMap &responseMap) } QByteArray data = QJsonDocument::fromVariant(responseMap).toJson(QJsonDocument::Compact) + '\n'; - qCDebug(dcNetworkManagerBluetoothServer()) << "WirelessService: Start streaming response data:" << data.count() << "bytes"; + qCDebug(dcNetworkManagerBluetoothServer()) << "WirelessService: Start streaming response data:" << data.length() << "bytes"; QByteArray remainingData = data; while (!remainingData.isEmpty()) { QByteArray package = remainingData.left(20); m_service->writeCharacteristic(characteristic, package); - remainingData = remainingData.remove(0, package.count()); + remainingData = remainingData.remove(0, package.length()); } qCDebug(dcNetworkManagerBluetoothServer()) << "WirelessService: Finished streaming response data"; @@ -549,7 +557,7 @@ void WirelessService::descriptorWritten(const QLowEnergyDescriptor &descriptor, qCDebug(dcNetworkManagerBluetoothServer()) << "WirelessService: Descriptor written" << descriptor.uuid().toString() << value; } -void WirelessService::serviceError(const QLowEnergyService::ServiceError &error) +void WirelessService::serviceError(QLowEnergyService::ServiceError error) { QString errorString; switch (error) { diff --git a/libnymea-networkmanager/bluetooth/wirelessservice.h b/libnymea-networkmanager/bluetooth/wirelessservice.h index 8c704a8..a4beaab 100644 --- a/libnymea-networkmanager/bluetooth/wirelessservice.h +++ b/libnymea-networkmanager/bluetooth/wirelessservice.h @@ -106,7 +106,7 @@ private slots: void characteristicWritten(const QLowEnergyCharacteristic &characteristic, const QByteArray &value); void descriptorRead(const QLowEnergyDescriptor &descriptor, const QByteArray &value); void descriptorWritten(const QLowEnergyDescriptor &descriptor, const QByteArray &value); - void serviceError(const QLowEnergyService::ServiceError &error); + void serviceError(QLowEnergyService::ServiceError error); // Commands void processCommand(const QVariantMap &request); diff --git a/libnymea-networkmanager/libnymea-networkmanager.pro b/libnymea-networkmanager/libnymea-networkmanager.pro index 57b22d1..c25da1b 100644 --- a/libnymea-networkmanager/libnymea-networkmanager.pro +++ b/libnymea-networkmanager/libnymea-networkmanager.pro @@ -40,7 +40,9 @@ SOURCES += \ wirelessnetworkdevice.cpp \ networkmanagerutils.cpp -equals(QT_MAJOR_VERSION, 5):!lessThan(QT_MINOR_VERSION, 7) { +lessThan(QT_MAJOR_VERSION, 6):lessThan(QT_MINOR_VERSION, 7) { + message(Bluetooth LE server functionality not supported with Qt $${QT_VERSION}.) +} else { message(Building with Bluetooth LE server functionality. Qt $${QT_VERSION}.) QT += bluetooth @@ -55,8 +57,6 @@ equals(QT_MAJOR_VERSION, 5):!lessThan(QT_MINOR_VERSION, 7) { bluetooth/bluetoothserver.cpp \ bluetooth/networkservice.cpp \ bluetooth/wirelessservice.cpp \ -} else { - message(Bluetooth LE server functionality not supported with Qt $${QT_VERSION}.) } target.path = $$[QT_INSTALL_LIBS]