From 55bdf7fe02ac13ca8f9b63f8c4ca6b897841a91a Mon Sep 17 00:00:00 2001 From: marionbarker Date: Sat, 13 Apr 2024 10:45:55 -0700 Subject: [PATCH 1/4] update message shown to user for probably bluetooth issue --- OmniBLE/PumpManager/PodCommsSession.swift | 7 +++++ .../ViewModels/PairPodViewModel.swift | 26 ++++++++++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/OmniBLE/PumpManager/PodCommsSession.swift b/OmniBLE/PumpManager/PodCommsSession.swift index a3c2e0d0..fd4ce5e1 100644 --- a/OmniBLE/PumpManager/PodCommsSession.swift +++ b/OmniBLE/PumpManager/PodCommsSession.swift @@ -39,6 +39,7 @@ public enum PodCommsError: Error { case noPodsFound case tooManyPodsFound case setupNotComplete + case possibleBluetoothIssue } extension PodCommsError: LocalizedError { @@ -99,6 +100,8 @@ extension PodCommsError: LocalizedError { return LocalizedString("Too many pods found", comment: "Error message for PodCommsError.tooManyPodsFound") case .setupNotComplete: return LocalizedString("Pod setup is not complete", comment: "Error description when pod setup is not complete") + case .possibleBluetoothIssue: + return LocalizedString("Possible Bluetooth issue", comment: "Error description for possible bluetooth issue") } } @@ -162,6 +165,8 @@ extension PodCommsError: LocalizedError { return LocalizedString("Move to a new area away from any other pods and try again.", comment: "Recovery suggestion for PodCommsError.tooManyPodsFound") case .setupNotComplete: return nil + case .possibleBluetoothIssue: + return LocalizedString("Toggle Bluetooth off and then on in iPhone Settings; then try again.", comment: "Recovery suggestion for possible bluetooth issue") } } @@ -248,6 +253,8 @@ public class PodCommsSession { /// - PodCommsError.rejectedMessage /// - PodCommsError.nonceResyncFailed /// - MessageError + /// - PeripheralManagerError + /// - PodProtocolError func send(_ messageBlocks: [MessageBlock], beepBlock: MessageBlock? = nil, expectFollowOnMessage: Bool = false) throws -> T { var triesRemaining = 2 // Retries only happen for nonce resync diff --git a/OmniBLE/PumpManagerUI/ViewModels/PairPodViewModel.swift b/OmniBLE/PumpManagerUI/ViewModels/PairPodViewModel.swift index e8f1e9df..bd8d7a97 100644 --- a/OmniBLE/PumpManagerUI/ViewModels/PairPodViewModel.swift +++ b/OmniBLE/PumpManagerUI/ViewModels/PairPodViewModel.swift @@ -180,6 +180,30 @@ class PairPodViewModel: ObservableObject, Identifiable { } } + // Return a user friendly DashPairingError for the reported PumpManagerError when no pod was found + private func noPodError(_ pumpManagerError: PumpManagerError) -> DashPairingError { + print("### noPodError encountered error \(pumpManagerError.localizedDescription)") + switch (pumpManagerError) { + case .communication(let error): + if let podCommsError = error as? PodCommsError { + switch podCommsError { + case .noPodsFound: + // Just use this error as is for a "No pods found" error + return DashPairingError.pumpManagerError(.communication(error)) + default: + break + } + } + default: + break + } + + // Use a more user friendly possible bluetooth error for any other errors resulting in no pod + let possibleBluetoothError = DashPairingError.pumpManagerError(.communication(PodCommsError.possibleBluetoothIssue)) + print("### noPodError returning error \(possibleBluetoothError.localizedDescription)") + return possibleBluetoothError + } + private func pairAndPrime() { if podPairer.podCommState == .noPod { state = .pairing @@ -193,7 +217,7 @@ class PairPodViewModel: ObservableObject, Identifiable { switch status { case .failure(let error): if self.podPairer.podCommState == .noPod { - let pairAndPrimeError = DashPairingError.pumpManagerError(error) + let pairAndPrimeError = self.noPodError(error) self.state = .error(pairAndPrimeError) } else if self.autoRetryAttempted { self.autoRetryAttempted = false // allow for an auto retry on the next user attempt From 06e1d89bc39a718949482f374535cbfab11fff03 Mon Sep 17 00:00:00 2001 From: marionbarker Date: Sun, 14 Apr 2024 16:47:50 -0700 Subject: [PATCH 2/4] limit possible bluetooth errors to lower level comms errors --- .../ViewModels/PairPodViewModel.swift | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/OmniBLE/PumpManagerUI/ViewModels/PairPodViewModel.swift b/OmniBLE/PumpManagerUI/ViewModels/PairPodViewModel.swift index bd8d7a97..49e1c834 100644 --- a/OmniBLE/PumpManagerUI/ViewModels/PairPodViewModel.swift +++ b/OmniBLE/PumpManagerUI/ViewModels/PairPodViewModel.swift @@ -180,16 +180,18 @@ class PairPodViewModel: ObservableObject, Identifiable { } } - // Return a user friendly DashPairingError for the reported PumpManagerError when no pod was found - private func noPodError(_ pumpManagerError: PumpManagerError) -> DashPairingError { - print("### noPodError encountered error \(pumpManagerError.localizedDescription)") + // Return a suitable DashPairingError for the returned PumpManagerError + private func mapPumpManagerError(_ pumpManagerError: PumpManagerError) -> DashPairingError { + print("### mapPumpManagerError encountered error \(pumpManagerError.localizedDescription)") switch (pumpManagerError) { case .communication(let error): if let podCommsError = error as? PodCommsError { switch podCommsError { - case .noPodsFound: - // Just use this error as is for a "No pods found" error - return DashPairingError.pumpManagerError(.communication(error)) + case .commsError(let error): + // Return a possible bluetooth error for any lower level comms errors + let possibleBluetoothError = DashPairingError.pumpManagerError(.communication(PodCommsError.possibleBluetoothIssue)) + print("### mapPumpManagerError returning error \(possibleBluetoothError.localizedDescription)") + return possibleBluetoothError default: break } @@ -197,11 +199,7 @@ class PairPodViewModel: ObservableObject, Identifiable { default: break } - - // Use a more user friendly possible bluetooth error for any other errors resulting in no pod - let possibleBluetoothError = DashPairingError.pumpManagerError(.communication(PodCommsError.possibleBluetoothIssue)) - print("### noPodError returning error \(possibleBluetoothError.localizedDescription)") - return possibleBluetoothError + return DashPairingError.pumpManagerError(pumpManagerError) } private func pairAndPrime() { @@ -217,11 +215,11 @@ class PairPodViewModel: ObservableObject, Identifiable { switch status { case .failure(let error): if self.podPairer.podCommState == .noPod { - let pairAndPrimeError = self.noPodError(error) + let pairAndPrimeError = self.mapPumpManagerError(error) self.state = .error(pairAndPrimeError) } else if self.autoRetryAttempted { self.autoRetryAttempted = false // allow for an auto retry on the next user attempt - let pairAndPrimeError = DashPairingError.pumpManagerError(error) + let pairAndPrimeError = self.mapPumpManagerError(error) self.state = .error(pairAndPrimeError) } else { self.autoRetryAttempted = true From cb0c0c426966da914220cac1e28ce395c39b4281 Mon Sep 17 00:00:00 2001 From: marionbarker Date: Fri, 19 Apr 2024 20:52:12 -0700 Subject: [PATCH 3/4] revert this version of improved error messages --- OmniBLE/PumpManager/PodCommsSession.swift | 7 ----- .../ViewModels/PairPodViewModel.swift | 26 ++----------------- 2 files changed, 2 insertions(+), 31 deletions(-) diff --git a/OmniBLE/PumpManager/PodCommsSession.swift b/OmniBLE/PumpManager/PodCommsSession.swift index fd4ce5e1..a3c2e0d0 100644 --- a/OmniBLE/PumpManager/PodCommsSession.swift +++ b/OmniBLE/PumpManager/PodCommsSession.swift @@ -39,7 +39,6 @@ public enum PodCommsError: Error { case noPodsFound case tooManyPodsFound case setupNotComplete - case possibleBluetoothIssue } extension PodCommsError: LocalizedError { @@ -100,8 +99,6 @@ extension PodCommsError: LocalizedError { return LocalizedString("Too many pods found", comment: "Error message for PodCommsError.tooManyPodsFound") case .setupNotComplete: return LocalizedString("Pod setup is not complete", comment: "Error description when pod setup is not complete") - case .possibleBluetoothIssue: - return LocalizedString("Possible Bluetooth issue", comment: "Error description for possible bluetooth issue") } } @@ -165,8 +162,6 @@ extension PodCommsError: LocalizedError { return LocalizedString("Move to a new area away from any other pods and try again.", comment: "Recovery suggestion for PodCommsError.tooManyPodsFound") case .setupNotComplete: return nil - case .possibleBluetoothIssue: - return LocalizedString("Toggle Bluetooth off and then on in iPhone Settings; then try again.", comment: "Recovery suggestion for possible bluetooth issue") } } @@ -253,8 +248,6 @@ public class PodCommsSession { /// - PodCommsError.rejectedMessage /// - PodCommsError.nonceResyncFailed /// - MessageError - /// - PeripheralManagerError - /// - PodProtocolError func send(_ messageBlocks: [MessageBlock], beepBlock: MessageBlock? = nil, expectFollowOnMessage: Bool = false) throws -> T { var triesRemaining = 2 // Retries only happen for nonce resync diff --git a/OmniBLE/PumpManagerUI/ViewModels/PairPodViewModel.swift b/OmniBLE/PumpManagerUI/ViewModels/PairPodViewModel.swift index 49e1c834..e8f1e9df 100644 --- a/OmniBLE/PumpManagerUI/ViewModels/PairPodViewModel.swift +++ b/OmniBLE/PumpManagerUI/ViewModels/PairPodViewModel.swift @@ -180,28 +180,6 @@ class PairPodViewModel: ObservableObject, Identifiable { } } - // Return a suitable DashPairingError for the returned PumpManagerError - private func mapPumpManagerError(_ pumpManagerError: PumpManagerError) -> DashPairingError { - print("### mapPumpManagerError encountered error \(pumpManagerError.localizedDescription)") - switch (pumpManagerError) { - case .communication(let error): - if let podCommsError = error as? PodCommsError { - switch podCommsError { - case .commsError(let error): - // Return a possible bluetooth error for any lower level comms errors - let possibleBluetoothError = DashPairingError.pumpManagerError(.communication(PodCommsError.possibleBluetoothIssue)) - print("### mapPumpManagerError returning error \(possibleBluetoothError.localizedDescription)") - return possibleBluetoothError - default: - break - } - } - default: - break - } - return DashPairingError.pumpManagerError(pumpManagerError) - } - private func pairAndPrime() { if podPairer.podCommState == .noPod { state = .pairing @@ -215,11 +193,11 @@ class PairPodViewModel: ObservableObject, Identifiable { switch status { case .failure(let error): if self.podPairer.podCommState == .noPod { - let pairAndPrimeError = self.mapPumpManagerError(error) + let pairAndPrimeError = DashPairingError.pumpManagerError(error) self.state = .error(pairAndPrimeError) } else if self.autoRetryAttempted { self.autoRetryAttempted = false // allow for an auto retry on the next user attempt - let pairAndPrimeError = self.mapPumpManagerError(error) + let pairAndPrimeError = DashPairingError.pumpManagerError(error) self.state = .error(pairAndPrimeError) } else { self.autoRetryAttempted = true From 35d5bcbc89f96f281bc7cc8691fbae48b0809976 Mon Sep 17 00:00:00 2001 From: marionbarker Date: Sat, 20 Apr 2024 20:47:02 -0700 Subject: [PATCH 4/4] update message shown to user for Bluetooth issues --- OmniBLE/PumpManager/PodCommsSession.swift | 34 +++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/OmniBLE/PumpManager/PodCommsSession.swift b/OmniBLE/PumpManager/PodCommsSession.swift index a3c2e0d0..5d223ee2 100644 --- a/OmniBLE/PumpManager/PodCommsSession.swift +++ b/OmniBLE/PumpManager/PodCommsSession.swift @@ -74,6 +74,9 @@ extension PodCommsError: LocalizedError { let faultDescription = String(describing: fault.faultEventCode) return String(format: LocalizedString("Pod Fault: %1$@", comment: "Format string for pod fault code"), faultDescription) case .commsError(let error): + if isVerboseBluetoothCommsError(error) { + return LocalizedString("Possible Bluetooth issue", comment: "Error description for possible bluetooth issue") + } return error.localizedDescription case .unacknowledgedMessage(_, let error): return error.localizedDescription @@ -136,7 +139,10 @@ extension PodCommsError: LocalizedError { return LocalizedString("Resume delivery", comment: "Recovery suggestion when pod is suspended") case .podFault: return nil - case .commsError: + case .commsError(let error): + if isVerboseBluetoothCommsError(error) { + return LocalizedString("Try adjusting pod position or toggle Bluetooth off and then on in iPhone Settings.", comment: "Recovery suggestion for possible bluetooth issue") + } return nil case .unacknowledgedMessage: return nil @@ -173,6 +179,28 @@ extension PodCommsError: LocalizedError { return false } } + + public func isVerboseBluetoothCommsError(_ error: Error) -> Bool { + if let peripheralManagerError = error as? PeripheralManagerError { + switch peripheralManagerError { + case .cbPeripheralError: + print("### Verbose Bluetooth comms error: \(peripheralManagerError.localizedDescription)") + return true + default: + break + } + } + if let podProtocolError = error as? PodProtocolError { + switch podProtocolError { + case .invalidLTKKey, .pairingException, .messageIOException, .couldNotParseMessageException: + print("### Verbose Bluetooth comms error: \(podProtocolError.localizedDescription)") + return true + default: + break + } + } + return false + } } public protocol PodCommsSessionDelegate: AnyObject { @@ -247,7 +275,9 @@ public class PodCommsSession { /// - PodCommsError.unexpectedResponse /// - PodCommsError.rejectedMessage /// - PodCommsError.nonceResyncFailed - /// - MessageError + /// - PodCommsError.commsError.MessageError + /// - PodCommsError.commsError.PeripheralManagerError + /// - PodCommsError.commsError.PodProtocolError func send(_ messageBlocks: [MessageBlock], beepBlock: MessageBlock? = nil, expectFollowOnMessage: Bool = false) throws -> T { var triesRemaining = 2 // Retries only happen for nonce resync