From ba44beb3d1491c453f4f438443c3f8ba29146ab3 Mon Sep 17 00:00:00 2001 From: mnk Date: Fri, 13 Dec 2024 13:54:34 +0200 Subject: [PATCH 1/3] Provide backup impl. for connecting new sensors --- .../G7CGMManager/G7BluetoothManager.swift | 44 +++++++++++++++++-- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/G7SensorKit/G7CGMManager/G7BluetoothManager.swift b/G7SensorKit/G7CGMManager/G7BluetoothManager.swift index 62ab5fc..847013d 100644 --- a/G7SensorKit/G7CGMManager/G7BluetoothManager.swift +++ b/G7SensorKit/G7CGMManager/G7BluetoothManager.swift @@ -101,6 +101,9 @@ class G7BluetoothManager: NSObject { return activePeripheralManager?.peripheral } } + + /// Isolated to `managerQueue` + private var eventRegistrationActive : Bool = false /// Isolated to `managerQueue` private var managedPeripherals: [UUID:G7PeripheralManager] = [:] @@ -131,7 +134,7 @@ class G7BluetoothManager: NSObject { self.centralManager = CBCentralManager(delegate: self, queue: managerQueue, options: [CBCentralManagerOptionRestoreIdentifierKey: "com.loudnate.CGMBLEKit"]) } } - + // MARK: - Actions func scanForPeripheral() { @@ -177,8 +180,24 @@ class G7BluetoothManager: NSObject { } } } - - private func managerQueue_scanForPeripheral() { + + func centralManager(_ central: CBCentralManager, connectionEventDidOccur event: CBConnectionEvent, for peripheral: CBPeripheral) { + + managerQueue.async { + guard self.eventRegistrationActive else { + self.centralManager.registerForConnectionEvents(options: nil) + return + } + + self.managerQueue_establishActivePeripheral() + + if !self.eventRegistrationActive { + self.centralManager.registerForConnectionEvents(options: nil) + } + } + } + + private func managerQueue_establishActivePeripheral() { dispatchPrecondition(condition: .onQueue(managerQueue)) guard centralManager.state == .poweredOn else { @@ -187,6 +206,7 @@ class G7BluetoothManager: NSObject { let currentState = activePeripheral?.state ?? .disconnected guard currentState != .connected else { + eventRegistrationActive = false return } @@ -201,6 +221,16 @@ class G7BluetoothManager: NSObject { handleDiscoveredPeripheral(peripheral) } } + + if activePeripheral != nil { + eventRegistrationActive = false + } + } + + private func managerQueue_scanForPeripheral() { + dispatchPrecondition(condition: .onQueue(managerQueue)) + + managerQueue_establishActivePeripheral() if activePeripheral == nil { log.debug("Scanning for peripherals") @@ -210,6 +240,14 @@ class G7BluetoothManager: NSObject { options: nil ) delegate?.bluetoothManagerScanningStatusDidChange(self) + + if !eventRegistrationActive { + eventRegistrationActive = true + centralManager.registerForConnectionEvents(options: [CBConnectionEventMatchingOption.serviceUUIDs: [ + SensorServiceUUID.advertisement.cbUUID, + SensorServiceUUID.cgmService.cbUUID + ]]) + } } } From d86ac8e9cd523d1267587dd70c96597125eef7ab Mon Sep 17 00:00:00 2001 From: mnk Date: Fri, 21 Feb 2025 11:35:46 +0200 Subject: [PATCH 2/3] Increase delay timeout --- G7SensorKit/G7CGMManager/G7BluetoothManager.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/G7SensorKit/G7CGMManager/G7BluetoothManager.swift b/G7SensorKit/G7CGMManager/G7BluetoothManager.swift index 847013d..588c207 100644 --- a/G7SensorKit/G7CGMManager/G7BluetoothManager.swift +++ b/G7SensorKit/G7CGMManager/G7BluetoothManager.swift @@ -261,7 +261,7 @@ class G7BluetoothManager: NSObject { */ fileprivate func scanAfterDelay() { DispatchQueue.global(qos: .utility).async { - Thread.sleep(forTimeInterval: 2) + Thread.sleep(forTimeInterval: 5) self.scanForPeripheral() } From 205054e7537723c2aec58d807634b4853f687244 Mon Sep 17 00:00:00 2001 From: mnk Date: Fri, 21 Feb 2025 15:16:56 +0200 Subject: [PATCH 3/3] Use scanAfterDelay for connect/disconnect issue --- G7SensorKit/G7CGMManager/G7BluetoothManager.swift | 2 +- G7SensorKit/G7CGMManager/G7CGMManager.swift | 6 +++--- G7SensorKit/G7CGMManager/G7Sensor.swift | 8 ++++++-- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/G7SensorKit/G7CGMManager/G7BluetoothManager.swift b/G7SensorKit/G7CGMManager/G7BluetoothManager.swift index 588c207..8976104 100644 --- a/G7SensorKit/G7CGMManager/G7BluetoothManager.swift +++ b/G7SensorKit/G7CGMManager/G7BluetoothManager.swift @@ -259,7 +259,7 @@ class G7BluetoothManager: NSObject { The sleep gives the transmitter time to shut down, but keeps the app running. */ - fileprivate func scanAfterDelay() { + func scanAfterDelay() { DispatchQueue.global(qos: .utility).async { Thread.sleep(forTimeInterval: 5) diff --git a/G7SensorKit/G7CGMManager/G7CGMManager.swift b/G7SensorKit/G7CGMManager/G7CGMManager.swift index 198d5b3..e2861e6 100644 --- a/G7SensorKit/G7CGMManager/G7CGMManager.swift +++ b/G7SensorKit/G7CGMManager/G7CGMManager.swift @@ -237,14 +237,14 @@ public class G7CGMManager: CGMManager { return nil } - public func scanForNewSensor() { + public func scanForNewSensor(scanAfterDelay: Bool = false) { logDeviceCommunication("Forgetting existing sensor and starting scan for new sensor.", type: .connection) mutateState { state in state.sensorID = nil state.activatedAt = nil } - sensor.scanForNewSensor() + sensor.scanForNewSensor(scanAfterDelay: scanAfterDelay) } private var device: HKDevice? { @@ -319,7 +319,7 @@ extension G7CGMManager: G7SensorDelegate { public func sensorDisconnected(_ sensor: G7Sensor, suspectedEndOfSession: Bool) { logDeviceCommunication("Sensor disconnected: suspectedEndOfSession=\(suspectedEndOfSession)", type: .connection) if suspectedEndOfSession { - scanForNewSensor() + scanForNewSensor(scanAfterDelay: true) } } diff --git a/G7SensorKit/G7CGMManager/G7Sensor.swift b/G7SensorKit/G7CGMManager/G7Sensor.swift index b1745a1..5c51092 100644 --- a/G7SensorKit/G7CGMManager/G7Sensor.swift +++ b/G7SensorKit/G7CGMManager/G7Sensor.swift @@ -99,11 +99,15 @@ public final class G7Sensor: G7BluetoothManagerDelegate { bluetoothManager.delegate = self } - public func scanForNewSensor() { + public func scanForNewSensor(scanAfterDelay: Bool = false) { self.sensorID = nil bluetoothManager.disconnect() bluetoothManager.forgetPeripheral() - bluetoothManager.scanForPeripheral() + if scanAfterDelay { + bluetoothManager.scanAfterDelay() + } else { + bluetoothManager.scanForPeripheral() + } } public func resumeScanning() {