Update main for Omnipod 5 support using ble-heartbeat method - #143
Conversation
…pse single certificate, update text strings
* resolve conflict in OmnipodKit/PumpManagerUI/Views/OmniSettingsView.swift; * build to update Localization/Localizable.xcstrings
…-RileyLink Fix for loop-next-dev branch: Remove unneeded reference to release RLs when switching pump types
…, connectionless fault detection
Update CODEOWNERS
Three related fixes in the DASH/O5 pairing path:
- pairAndPrime: a failed connectToNewPod invoked the caller completion
twice (completion + completionFailure). The first call schedules the
pairing UI's silent auto-retry; the second immediately resets the
auto-retry latch and shows the error, leaving a hidden retry running
concurrently with the user's manual Retry. OmniBLE calls the
completion once here; the second call crept in during the OmnipodKit
rewrite.
- connectToNewPod: the discovery polling Timer was scheduled on the
calling thread. On a thread with no running run loop (the pairing
auto-retry path) the timer never fires, so that discovery attempt
never completes, never times out, and never calls endPodDiscovery,
leaving discovery mode enabled and the scan running. Schedule the
timer on the main run loop, and return after each terminal condition
so a single tick cannot invoke the completion twice.
- PairPodViewModel: perform the pairing auto-retry via
DispatchQueue.main.asyncAfter instead of Thread.sleep on a utility
QoS thread, so the retry attempt runs with a live run loop.
Also fixes a malformed %{public} os_log format specifier in
BluetoothManager.
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
When no host refreshes the reading schedule — an app that only calls the legacy setMustProvideBLEHeartbeat sets the heartbeat target once and never updates it — the fixed target goes chronically overdue, so every StartDelay probe pins to heartbeatMinDelaySeconds (the 60s floor). That ~60s background wake cadence is ~5x the intended ~interval cadence, burns the iOS background execution budget, and gets the app suspended for long stretches (Trio field report on LoopKit/LoopKit#599: 99% of heartbeat intervals were 61s, with six 16–128 min suspension gaps). Track the reading interval and when the target was last set. When the target hasn't been refreshed within ~1.5 reading intervals, advance it by whole intervals in issueDelayedConnectProbe so we hold the expected ~interval cadence. A host that refreshes the schedule every reading (Loop) keeps the set-at timestamp fresh, so its floor-based late-reading retry is unaffected. Scheduler simulation: set-once host 60s -> 300s; per-reading-refresh host 300s unchanged; a single late reading still retries at the floor.
Heartbeat: advance a stale target instead of collapsing to the 60s floor
Backport the Omnipod BLE Heartbeat API from next-dev
A stale fresh-discovery cold-connect fallback timer could fire ~4s after a connection had already succeeded, run freshConnect() → cancelPeripheralConnection() against the LIVE link, and tear it down. didDisconnect (error == nil, i.e. locally initiated) then saw commandConnectInFlight still set, logged it as an unintended "keep-alive — reconnecting after drop", and armed another fresh-discovery cycle — which repeated. Field logs show this spinning for minutes: thousands of nil (self) disconnects, ~99% mislabeled as drops, zero CBError Code 6 (RF) and only a handful of Code 7 (pod-initiated). The pod was reachable and close the whole time. Two surgical fixes: 1. didConnect clears pendingFreshConnectID for the connected peripheral, so a still-pending 4s fallback timer no-ops instead of cancelling the live link. 2. freshConnect returns early if the peripheral is already .connected — it exists only to unstick a wedged .connecting state, never to drop a healthy connection. Leaves for follow-up: fresh-discovery never matching (iOS advertisement coalescing without allowDuplicates → always the cold-connect fallback), and the "reconnecting after drop" wording that reports our own cancels as drops.
…d-self-disconnect-loop Backport to dev: Fix self-inflicted connect→cancel→reconnect loop in connect-on-demand
…vert surfacePodConditionAndQuiet ran on managerQueue (called from centralManager didDiscover) and invoked connectionDelegate.omnipodDidDetectAlert synchronously. The host handles that by driving getPodStatus -> runSession -> bleRunSession -> peripheralManager(forIdentifier:), which does managerQueue.sync. Being already on managerQueue, that's a sync-to-self deadlock. It triggered on a fresh launch when a DASH pod advertised a fault/alert transition before any connection had established BlePodComms.manager (so bleRunSession took the peripheralManager(forIdentifier:) branch). Field report: an iAPS user's app crash-looped on launch until, after enough restarts, a connection happened to establish first. Introduced in a715d9a. Dispatch the delegate notification off managerQueue so the downstream managerQueue.sync is a real cross-queue sync. Quieting the alarm scan stays on managerQueue. Fixes #126.
…d-self-disconnect-loop Fix backport: re-entrant managerQueue deadlock surfacing a pod alert from an advert
* Remove brief pod type name from Pair Pod view title * Remove unused podType.fullName and add briefName usage comment
Remove brief pod type name from Pair Pod view title
Check HistoryThere was a flurry of work in the next-dev branch. Some was to fix/improve various items in OmnipodKit, some was to prepare the ble-heartbeat Bluetooth connection method and later, some to prepare the eager-commit Bluetooth connection method. When checked the first time, discovered PR #119 and #139 had not been back-ported from next-dev to dev (at commit 8fdf5af). After commit 65f067b, update the status and the table. Confirm Correct version for this PRThis PR is intended to have all the various fixes for OmnipodKit plus the latest version of the ble-heartbeat connection method without any of the changes that are associated with eager-commit. Comparison of ChangesThis table provides the list of PR for next-dev, dev along with some updates that were introduced without a PR.
|
itsmojo
left a comment
There was a problem hiding this comment.
The git diff of update/main matches dev. I read through the many changes and it all appears to be good.
Prior to this PR, Omnipod 5 support was only available in the dev branch of OmnipodKit
Plan: