Repository navigation
Answer a stale EAP-AKA SQN with a synchronization failure - #25
Merged
Merged
Conversation
The pod took any SQN a controller sent: the session keys don't depend on it and AUTN wasn't checked. So a controller whose SQN had fallen behind, because another controller had sessions with the pod since its last, connected as if nothing had happened, and OmnipodKit's resynchronization path never ran in the Simulator. The pod now reads the controller's SQN from AUTN, verifies MAC-A, and answers an SQN that isn't past the last one it accepted with a synchronization failure: AUTS carries its own SQN, as a real pod's does. It then waits for the retry on the same connection. An AUTN that doesn't verify hangs up. The pod stores the controller's SQN, starting from 0 at pairing, since the controller's first session uses 1.
jeremybarnum
pushed a commit
to jeremybarnum/sportmode-sim
that referenced
this pull request
Oct 26, 2026
The pod holds the phone's bolus while the phone leaves its reach, so the pod gives it and the answer is lost; the watch starts without the phone. Back, the phone stands aside, its pod driver drops the unconfirmed command at the resync and lets go, and the bolus is booked once. Needs a pod simulator that resyncs (LoopKit/pod#25 through POD_SIM), so it is in no tier yet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ps2
marked this pull request as ready for review
October 26, 2026 21:08
Author
|
For the record, a real DASH pod behaves the way this models it. On Sport Mode (Jeremy's The pod answered the phone's stale SQN 7 with its last accepted SQN, 10, not 11 (the simulator's |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The simulator accepted any SQN a controller sent. The session keys don't depend on it, and AUTN wasn't checked, so a controller whose SQN had fallen behind connected as if nothing had happened. A real pod answers that with a synchronization failure, which is how a controller learns another controller has had sessions with the pod since its last. That path in OmnipodKit, and the Sport Mode work that relies on it (loopandlearn/OmnipodKit#177), never ran in the Simulator.
Now the pod:
establishNewSessiondoes it;One resync on an existing pod. The simulator used to store one more than the controller's SQN, so a pod paired before this change resyncs once at its next session, and OmnipodKit logs that. A pod paired after it doesn't.
Testing
go test ./...passes.MilenageandEapMessagein a throwaway OmniTests case: same AUTN for the controller's SQN, and the simulator's synchronization failure parses, decodes to the pod's SQN and passes the MAC-S check.