summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/bluetooth/osx/osxbtcentralmanager.mm24
-rw-r--r--src/bluetooth/osx/osxbtnotifier_p.h1
-rw-r--r--src/bluetooth/qlowenergycontroller_osx.mm17
-rw-r--r--src/bluetooth/qlowenergycontroller_osx_p.h1
4 files changed, 43 insertions, 0 deletions
diff --git a/src/bluetooth/osx/osxbtcentralmanager.mm b/src/bluetooth/osx/osxbtcentralmanager.mm
index 41713909..6b742684 100644
--- a/src/bluetooth/osx/osxbtcentralmanager.mm
+++ b/src/bluetooth/osx/osxbtcentralmanager.mm
@@ -1373,6 +1373,30 @@ QT_USE_NAMESPACE
[self discoverIncludedServices];
}
+- (void)peripheral:(CBPeripheral *)aPeripheral
+ didModifyServices:(NSArray<CBService *> *)invalidatedServices
+{
+ Q_UNUSED(aPeripheral)
+ Q_UNUSED(invalidatedServices)
+
+ qCWarning(QT_BT_OSX) << "The peripheral has modified its services.";
+ // "This method is invoked whenever one or more services of a peripheral have changed.
+ // A peripheral’s services have changed if:
+ // * A service is removed from the peripheral’s database
+ // * A new service is added to the peripheral’s database
+ // * A service that was previously removed from the peripheral’s
+ // database is readded to the database at a different location"
+
+ // In case new services were added - we have to discover them.
+ // In case some were removed - we can end up with dangling pointers
+ // (see our 'watchdogs', for example). To handle the situation
+ // we stop all current operations here, report to QLowEnergyController
+ // so that it can trigger re-discovery.
+ [self reset];
+ managerState = OSXBluetooth::CentralManagerIdle;
+ if (notifier)
+ emit notifier->servicesWereModified();
+}
- (void)peripheral:(CBPeripheral *)aPeripheral didDiscoverIncludedServicesForService:(CBService *)service
error:(NSError *)error
diff --git a/src/bluetooth/osx/osxbtnotifier_p.h b/src/bluetooth/osx/osxbtnotifier_p.h
index 47ee6ba1..dca6c268 100644
--- a/src/bluetooth/osx/osxbtnotifier_p.h
+++ b/src/bluetooth/osx/osxbtnotifier_p.h
@@ -89,6 +89,7 @@ Q_SIGNALS:
void descriptorRead(QLowEnergyHandle descHandle, const QByteArray &value);
void descriptorWritten(QLowEnergyHandle descHandle, const QByteArray &value);
void notificationEnabled(QLowEnergyHandle charHandle, bool enabled);
+ void servicesWereModified();
void LEnotSupported();
void CBManagerError(QBluetoothDeviceDiscoveryAgent::Error error);
diff --git a/src/bluetooth/qlowenergycontroller_osx.mm b/src/bluetooth/qlowenergycontroller_osx.mm
index 8cef621c..8bcdc22e 100644
--- a/src/bluetooth/qlowenergycontroller_osx.mm
+++ b/src/bluetooth/qlowenergycontroller_osx.mm
@@ -339,6 +339,21 @@ void QLowEnergyControllerPrivateOSX::_q_serviceDetailsDiscoveryFinished(QSharedP
qtService->setState(QLowEnergyService::ServiceDiscovered);
}
+void QLowEnergyControllerPrivateOSX::_q_servicesWereModified()
+{
+ if (!(controllerState == QLowEnergyController::DiscoveringState
+ || controllerState == QLowEnergyController::DiscoveredState)) {
+ qCWarning(QT_BT_OSX) << "services were modified while controller is not in Discovered/Discovering state";
+ return;
+ }
+
+ if (controllerState == QLowEnergyController::DiscoveredState)
+ invalidateServices();
+
+ controllerState = QLowEnergyController::ConnectedState;
+ q_ptr->discoverServices();
+}
+
void QLowEnergyControllerPrivateOSX::_q_characteristicRead(QLowEnergyHandle charHandle,
const QByteArray &value)
{
@@ -989,6 +1004,8 @@ bool QLowEnergyControllerPrivateOSX::connectSlots(OSXBluetooth::LECBManagerNotif
this, &QLowEnergyControllerPrivateOSX::_q_serviceDiscoveryFinished);
ok = ok && connect(notifier, &LECBManagerNotifier::serviceDetailsDiscoveryFinished,
this, &QLowEnergyControllerPrivateOSX::_q_serviceDetailsDiscoveryFinished);
+ ok = ok && connect(notifier, &LECBManagerNotifier::servicesWereModified,
+ this, &QLowEnergyControllerPrivateOSX::_q_servicesWereModified);
ok = ok && connect(notifier, &LECBManagerNotifier::characteristicRead,
this, &QLowEnergyControllerPrivateOSX::_q_characteristicRead);
ok = ok && connect(notifier, &LECBManagerNotifier::characteristicWritten,
diff --git a/src/bluetooth/qlowenergycontroller_osx_p.h b/src/bluetooth/qlowenergycontroller_osx_p.h
index 24b7c6e9..da959895 100644
--- a/src/bluetooth/qlowenergycontroller_osx_p.h
+++ b/src/bluetooth/qlowenergycontroller_osx_p.h
@@ -98,6 +98,7 @@ private Q_SLOTS:
void _q_serviceDiscoveryFinished();
void _q_serviceDetailsDiscoveryFinished(QSharedPointer<QLowEnergyServicePrivate> service);
+ void _q_servicesWereModified();
void _q_characteristicRead(QLowEnergyHandle charHandle, const QByteArray &value);
void _q_characteristicWritten(QLowEnergyHandle charHandle, const QByteArray &value);