tiny
Phone gateway·
The phone as ring gateway: what the tiny iOS and Android apps do with the ring, and what a port must get right.
In 10 seconds
The phone in your pocket holds the ring's one BLE link. tiny iOS (OTA 106) and Android carry a RingGateway that
does everything ring-cli bridge does — handshake, live HR, history, memo pull, the agent's command queue — for
both rings at once, no computer. Porting it elsewhere: the codec is ~200 lines, the gotchas are the table below.
What it does·
| step | cmds | notes |
|---|---|---|
| scan · connect | name SR\d+-… / JY-… or manufacturer id 0x594A; subscribe 33F4 |
one device row per MAC; labels are the owner's words |
| handshake | 1 time · 26 app id · 30 auto-HR (owner pref) · 55 features; decode the connect burst 37 · 13-byte echo · 68 · 55 · 29 · 6 | |
| history | 33 / 34 / 36 for day 0 and 1 | wait for each terminator 42 / 43 / 45 |
| live | 7 open → post every 11 tick → 8 close on 17 | 30 s without a tick = "not worn" |
| memos | 0x2F (skip while 0x10 recording) → 0x3D → 0x40 → 0x34 → POST /api/health/media → 0x36 |
delete only after a 2xx |
| flush | POST /api/health/ingest with the phone's fleet token |
cradle: skip day-0 sleep, tag vitals charging |
| commands | claim loop every 15 s (2 s while busy) → execute → post result | the 9 verbs in Agent tools |
The codec is re-implemented per platform — RingCodec.swift (13 tests), RingCodec.kt (9), RingAudio.swift/.kt (Ogg
Opus muxer, decode-identical to ring/audio.py) — from the hex vectors in tests/test_codec.py.
Things a port must get right — six gotchas
| gotcha | rule |
|---|---|
| header order | total then index — only multi-packet audio proves it |
| pacing | writes ≥ 300 ms apart; wait for terminators — two requests too close lost a 43 |
| the 13-byte headerless frame | advertising data echoed after device info; parse, don't log as garbage |
| no failure op | HR/SpO₂ off the finger = silence; time out and say "not worn" |
| cradle | charging = 1 → drop day-0 sleep, tag vitals; the platform excludes them from summaries |
| iOS | no macOS-style adoption, but CoreBluetooth state restoration is needed to keep the link when backgrounded |
Status (2026-09-19)·
| gateway | link · handshake | live HR | history | memos | commands |
|---|---|---|---|---|---|
iOS RingGateway.swift OTA 106 |
✅ both rings | ✅ | ✅ | ✅ memo_pull (first real memo pulled on metal) |
✅ claim loop, 9 verbs |
Android RingGateway.kt |
✅ | ✅ | ✅ | ✅ built, not yet installed on the owner's Pixel | ✅ same 9 verbs, on-metal proof pending |
Mac ring-cli bridge |
✅ | ✅ | ✅ | ✅ | reference |
Row-level detail and proofs: Takeover matrix.