feat: prefer CR5L BLE characteristics on macOS#207
Conversation
Teach the Darwin BLE bridge to prefer the CREST CR5L Nordic UART Service characteristics and subscribe to the CR5L response paths. This keeps the Submersion-side change narrow while allowing a downstream CR5L-capable libdivecomputer to communicate with the watch correctly on macOS.
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
Thanks for the thorough writeup and the gist links.
Overall the approach makes sense. A few things I'd like to flag before merge though:
-
Scope of the read-buffer change. The switch from
readBuffer: DatatoreadPackets: [Data]+partialReadBufferaffects every device, not just CR5L — aperformReadcall can no longer span packet boundaries. I think that's fine under libdivecomputer's partial-read contract, but it's worth calling out explicitly in the PR description since it touches Pelagic Gen1 and anything else on the existing path. -
"CR5L" behavior is actually keyed on the generic NUS RX UUID (
6E400002-B5A3-F393-E0A9-E50E24DCCA9E), so any NUS-speaking peripheral would hit the multi-subscribe + write-with-response path. Might want to either narrow the gate (peripheral.nameprefix) or rename/broaden the framing so it's honest about what's happening. -
A couple of correctness issues in the state machine and notify handling (detailed inline) - one is a genuine silent-drop path I'd want to fix before merging.
Specifics inline. Happy to pair on any of these.
There was a problem hiding this comment.
Pull request overview
This PR updates the macOS (Darwin) BLE bridge in libdivecomputer_plugin to prefer CREST CR5L’s Nordic UART Service (NUS) UUIDs and to support subscribing to multiple notify/indicate characteristics so downstream libdivecomputer transport can receive CR5L response paths correctly.
Changes:
- Add NUS service/write/notify UUIDs to the bridge’s preferred UUID scoring.
- Introduce multi-characteristic subscription (
subscribedCharacteristics) for CR5L-style services. - Refactor read buffering from a single byte buffer into queued notification packets.
Narrow the Nordic UART handling to likely CREST devices, harden the notify state machine, ignore empty notifications, add fallback diagnostics, and enforce the packet-based read contract expected by libdivecomputer transports.
|
Thanks. I addressed the requested changes in 02a1eaf. Summary:
On the read-path change: I also aligned it with libdivecomputer's packet-transport expectations from jefdriesen's comment. In particular, if a single queued BLE packet is larger |
|
Two extra points for context:
|
|
Quick update from additional live testing. I hit and fixed a new robustness issue locally that is not in this PR branch yet:
Those fixes are currently in my local Separately, I also wired explicit Related context: I’m currently working with Jef on the libdivecomputer PR to settle final CR5L protocol framing details using the raw capture. Since this Submersion support depends on that backend behaviour, it may be cleaner to let that resolve first and then finalise here. No rush on my side. |
|
Thanks for the update. Feel free to bring all of the things you mentioned into this branch if you'd like to. Happy to merge it whenever you feel it's ready. |
|
Thanks Eric, will do. I will try and get this done before I go on annual leave end of May but cant promise anything. Either way we will be waiting on the libdivecomp side so no rush I guess. |
Summary
Prefer the CREST CR5L Nordic UART Service characteristics in the macOS BLE bridge.
This is the Submersion-side companion to pending
libdivecomputerCR5L support. On its own, this PR does not add CR5L parsing or transport to Submersion. It adjusts the Darwin BLE bridge so that once the vendoredlibdivecomputeris updated to a CR5L-capable revision, Submersion selects the correct CoreBluetooth service/characteristics for the watch.This PR should not be merged before the corresponding
libdivecomputerCR5L support is available and vendored into Submersion.Changes
CREST-CR5L.libdivecomputertransport can receive control responses, list packets, and bulk data packets.Why
The CR5L uses a Nordic UART Service layout with multiple response paths:
6E400001-B5A3-F393-E0A9-E50E24DCCA9E6E400002-B5A3-F393-E0A9-E50E24DCCA9E6E400002-B5A3-F393-E0A9-E50E24DCCA9E6E400003-B5A3-F393-E0A9-E50E24DCCA9E6E400004-B5A3-F393-E0A9-E50E24DCCA9EWithout this preference logic, the macOS bridge can connect to the watch but route packets incorrectly, which prevents the downstream CR5L transport from completing a download.
Scope
Included in this PR:
packages/libdivecomputer_plugin/darwin/Sources/LibDCDarwin/BleIoStream.swiftExplicitly not included in this PR:
LIBDIVECOMPUTER_FORK_PATH.txtlibdivecomputerfork build wiring used only for developmentthird_party/libdivecomputerupdatesDependency
This PR depends on the corresponding
libdivecomputerCR5L support PR. During local development, Submersion was tested against an external locallibdivecomputerfork via an untracked pointer file and build override. That local development mechanism is intentionally not part of this PR.The intended merge sequence is:
libdivecomputerCR5L support upstream.libdivecomputerrevision into Submersion.Background Material
Optional background material for reviewers who want the reverse-engineering and validation context:
These are intentionally not required to review this PR. The code change here is narrow and only handles the macOS BLE bridge side.
Test Plan
flutter testpassesflutter analyzepasses (failed only because of the unrelated local-onlypackages/google_sign_in_ios_patched package)CREST-CR5Lwatch using a local CR5L-enabledlibdivecomputerforkManual testing performed locally:
CREST-CR5LlibdivecomputerNotes For Reviewers
libdivecomputerPR.libdivecomputersubtree is updated in a follow-up PR.