diff options
author | Juha Vuolle <juha.vuolle@insta.fi> | 2021-12-07 12:54:37 +0200 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2021-12-15 11:54:48 +0000 |
commit | f26b0a2cfd9f4ca9090414ad440738a9beadf88a (patch) | |
tree | 7e2f84e9d358be2b10d27a2bf37b25c8adc29263 | |
parent | 95aea43ff693584618f0dfa3f850c3fc568ee705 (diff) |
Don't disconnect Darwin BT LE server on characteristic unsubscribe
The darwin CoreBluetooth does not really report client-device
(dis)connect events on the server side. Instead we use some heuristics
on the Qt backend to detect these. One heuristic for disconnection
was unsubscription from a characteristic, which however causes a
problem; there may still be several clients connected (and possibly
subscribed) and we shouldn't shut down the server.
Checking if there are subscriptions left on any of the characteristics
wouldn't be adequate either, as a client can be connected and
functional without any subscriptions too.
Fixes: QTBUG-98878
Change-Id: I36a37484ef3c98449ad43fd0463f682994c53568
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
(cherry picked from commit 95f349237bc37b9e3e5f47b4e2aa85855bccc2cd)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r-- | src/bluetooth/darwin/btperipheralmanager.mm | 42 |
1 files changed, 5 insertions, 37 deletions
diff --git a/src/bluetooth/darwin/btperipheralmanager.mm b/src/bluetooth/darwin/btperipheralmanager.mm index e65d8318..b7521b9e 100644 --- a/src/bluetooth/darwin/btperipheralmanager.mm +++ b/src/bluetooth/darwin/btperipheralmanager.mm @@ -162,7 +162,6 @@ bool qt_validate_value_range(const QLowEnergyCharacteristicData &data) @interface QT_MANGLE_NAMESPACE(DarwinBTPeripheralManager) (PrivateAPI) - (void)addConnectedCentral:(CBCentral *)central; -- (void)removeConnectedCentral:(CBCentral *)central; - (CBService *)findIncludedService:(const QBluetoothUuid &)qtUUID; - (void)addIncludedServices:(const QLowEnergyServiceData &)data @@ -200,8 +199,6 @@ bool qt_validate_value_range(const QLowEnergyCharacteristicData &data) std::deque<UpdateRequest> updateQueue; - ObjCScopedPointer<NSMutableSet> connectedCentrals; - PeripheralState state; NSUInteger maxNotificationValueLength; decltype(services.size()) nOfFailedAds; @@ -214,8 +211,6 @@ bool qt_validate_value_range(const QLowEnergyCharacteristicData &data) notifier = aNotifier; state = PeripheralState::idle; nextServiceToAdd = {}; - connectedCentrals.reset([[NSMutableSet alloc] init], - DarwinBluetooth::RetainPolicy::noInitialRetain); maxNotificationValueLength = std::numeric_limits<NSUInteger>::max(); } @@ -446,7 +441,7 @@ bool qt_validate_value_range(const QLowEnergyCharacteristicData &data) advertising has stopped and that any connected centrals have been disconnected." */ - [connectedCentrals removeAllObjects]; + maxNotificationValueLength = std::numeric_limits<NSUInteger>::max(); if (state == PeripheralState::advertising) { state = PeripheralState::waitingForPowerOn; @@ -529,12 +524,10 @@ bool qt_validate_value_range(const QLowEnergyCharacteristicData &data) if (peripheral != manager || !notifier) return; - [self removeConnectedCentral:central]; - - if (![connectedCentrals count]) { - if (const auto handle = charMap.key(characteristic)) + const auto handle = charMap.key(characteristic); + if (![static_cast<CBMutableCharacteristic*>(characteristic).subscribedCentrals count] + && handle) emit notifier->notificationEnabled(handle, false); - } } - (void)peripheralManager:(CBPeripheralManager *)peripheral @@ -665,8 +658,7 @@ bool qt_validate_value_range(const QLowEnergyCharacteristicData &data) while (updateQueue.size()) { const auto &request = updateQueue.front(); if (charMap.contains(request.charHandle)) { - if ([connectedCentrals count] - && maxNotificationValueLength < [request.value length]) { + if (maxNotificationValueLength < [request.value length]) { qCWarning(QT_BT_DARWIN) << "value of length" << [request.value length] << "will possibly be truncated to" << maxNotificationValueLength; @@ -706,30 +698,6 @@ bool qt_validate_value_range(const QLowEnergyCharacteristicData &data) [manager stopAdvertising]; emit notifier->connected(); } - - if (![connectedCentrals containsObject:central.identifier]) - [connectedCentrals addObject:central.identifier]; -} - -- (void)removeConnectedCentral:(CBCentral *)central -{ - if (!notifier) { - // Detached. - return; - } - - QT_BT_MAC_AUTORELEASEPOOL - - if ([connectedCentrals containsObject:central.identifier]) - [connectedCentrals removeObject:central.identifier]; - - if (state == PeripheralState::connected && ![connectedCentrals count]) { - state = PeripheralState::idle; - emit notifier->disconnected(); - } - - if (![connectedCentrals count]) - maxNotificationValueLength = std::numeric_limits<NSUInteger>::max(); } - (CBService *)findIncludedService:(const QBluetoothUuid &)qtUUID |