Skip to content

Hang up on a message the pod can't use instead of exiting - #23

Merged
ps2 merged 1 commit into
mainfrom
recover-from-bad-input
Oct 12, 2026
Merged

ps2 merged 1 commit into
mainfrom
recover-from-bad-input

Conversation

@ps2

@ps2 ps2 commented Oct 12, 2026

Copy link
Copy Markdown

Pairing, session setup and the command loop exited the pod with log.Fatal when a message from the phone didn't parse, decrypt or unmarshal, and the packet layer exited on an unexpected command. In the Simulator nothing restarts the pod, so one bad message lost it. #20 hit this: an EAP-AKA Success that didn't parse.

  • Pairing, session setup and commands: the pod logs the error, hangs up and waits for the phone to reconnect and set up a new session. This also covers a response ACK that doesn't decrypt or isn't empty, which used to exit the pod after the command had already been applied.
  • Packet layer: an unexpected command is logged, and the pod carries on.
  • Still exits: errors in the pod's own work, like generating keys, saving state or building a response.

Testing

  • pkg/pod/pod_test.go sends a garbled message during session setup. On main it fails with the pod's EAP-AKA parse error; now the pod hangs up.
  • go test -race ./... passes, and it builds for GOOS=linux GOARCH=arm.
  • With Loop in the iOS Simulator, a session and a status read worked as before. The hang-up path is covered only by the unit test.

Pairing, session setup and the command loop exited the pod with
log.Fatal when the phone's message didn't parse, decrypt or unmarshal,
and the packet layer exited on an unexpected command. In the Simulator
nothing restarts it, so one bad message cost the pod.

The pod now logs the error, hangs up and waits for the phone to
reconnect and set up a new session. The packet layer logs and carries
on. Errors in the pod's own work (generating keys, saving state,
building responses) still exit.
@ps2
ps2 merged commit a491a5e into main Oct 12, 2026
1 check passed
ps2 added a commit that referenced this pull request Oct 28, 2026
main gained the recovery from #23 and the EAP-AKA SQN check from #25 while
this branch was out. Three things had to be reconciled rather than merged
mechanically.

The sequence number pairing leaves behind moved from 1 to 0, because
CheckSqn accepts a session only if its SQN is past the stored one and the
controller's first session uses 1. The Omnipod 5 path was still storing 1,
which would have made every freshly paired pod answer its phone's first
session with a synchronization failure. There is now a test over the AUTN a
controller sends, covering the first session after pairing, a replay and an
older session, so the rule is pinned rather than remembered.

The setup commands an Omnipod 5 is sent now run before the command-length
guard, not after. Their payloads are short ASCII — "G3.12" is five bytes,
"S3.9=8,G3.9" eleven — so the sixteen-byte minimum #23 moved ahead of
command.Unmarshal would have refused them and hung up mid-activation.

The Omnipod 5 pairing and the AID exchange now hang up through startOver
like everything else, instead of ending the process. That was the behaviour
this branch wanted anyway: the pod's own commit for it is now redundant and
gives way to #23's.

The link layer keeps this branch's framing, which already returned the
errors #23 introduced, and upstream's pod_test.go is carried over onto the
mode-aware constructors.
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