Skip to content

suunto_nautic: send and receive packets through one layer, and verify them - #14

Merged
latishab merged 1 commit into
mainfrom
fix/nautic-send-recv
Oct 16, 2026
Merged

latishab merged 1 commit into
mainfrom
fix/nautic-send-recv

Conversation

@latishab

Copy link
Copy Markdown
Contributor

The transport from the upstream PR (libdivecomputer/libdivecomputer#73), reworked after Jef's review comments there.

  • One send/recv layer. Every packet from the watch is checked (start byte, length, CRC) and matched to its request by opcode and sequence number. Replies to another app's requests on the same link (the Suunto app's session, including its 0x07 PUT replies) are skipped by sequence number instead of being taken as ours. That's the Sep 23 field failure: the old driver read a Hello reply as its GET ACK and fetched a garbage handle.
  • /Data ends on the watch's zero length end marker, with each chunk's offset checked: a missing chunk is an error, a repeated one is skipped.
  • /Logbook/Entries is parsed by its records (count at +6, 24-byte records at +18) instead of scanning for timestamps.
  • /Info is required, since the fingerprint depends on it.

The extension API is rebuilt on the same layer with the same outputs (request/fetch/fetch_raw return the reply packets as before). Two fork-only behaviours are kept: the open carries on without a hello reply and flags it (the sleeping watch hint), and sequence numbers continue across connections.

Testing

  • LibDCSwift-Package tests: 123 run, 0 failures, including the 33 fake-watch transport tests, whose fake now frames packets like a real watch (real CRCs, stream offsets, end marker).
  • A replay of a real Nautic session (urbamax's Sep 7 debug log, two full dives) through the driver: same dives as before, every request answered.
  • The same replay with the 32 foreign frames from the Sentry trace injected: both dives download. The current driver fails that case with DC_STATUS_TIMEOUT, as in the field.
  • A corrupted stream chunk is caught by the CRC check and the stream is retried.
  • Not yet on a real watch: that's what DC Tester build 22 is for.

🤖 Generated with Claude Code

… them

The transport from the upstream PR (libdivecomputer/libdivecomputer#73),
reworked after Jef's review: every reply is checked (start byte,
length, CRC) and matched by opcode and sequence number, so the replies
to the Suunto app's requests on the same link are skipped instead of
taken as ours. The /Data stream ends on its end marker with each
chunk's offset checked, and /Logbook/Entries is parsed by its records.

The extension API is rebuilt on the same layer, with the same outputs:
request/fetch/fetch_raw return the reply packets as before.

Unlike upstream, the open carries on without a reply to the hello and
flags it, so the apps can tell the diver the watch may be asleep, and
the sequence numbers carry on from the previous connection.
@latishab
latishab merged commit 1f7c4ff into main Oct 16, 2026
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant