From 5400f1bef7afbd47156c58ed3bddb852cc42e087 Mon Sep 17 00:00:00 2001 From: serversdown Date: Thu, 24 Sep 2026 19:18:58 -0400 Subject: [PATCH] docs(series4): monitoring control, the setup-list walk, and the device clock Thor started monitoring, listed the unit's setups and stopped monitoring while seismo_lab recorded. 40 requests, 40 responses, every checksum valid. As before, Thor did all of it -- we have still never originated any of these. Confirmed identical to Series III: * SUB 0x96 start monitoring -> ack 0x69 * SUB 0x97 stop monitoring -> ack 0x68 Both bare frames, no params, no data. These were on the unsafe-until-agreed list as entirely unobserved; they are now observed but still never sent by us. Erase (0xA3/0xA2) is now the only genuinely untouched destructive path. NOT identical to Series III, and worth not reusing constants for: * The monitoring flag is SUB 0x1C data[12] = 0x0E monitoring / 0x00 idle. Series III uses 0x10. * SUB 0x49 -> 0xB6 is a second, cheaper monitoring indicator at data[11] (0x02 monitoring / 0x00 idle) in a 21-byte response rather than 60. Thor puts it in its preamble before every operation, so it is the routine check. New this capture: * SUB 0x1C carries the DEVICE CLOCK at data[13:21] -- day, month, year (u16 BE), hour, minute, second. Verified against the capture's own wall time. Nothing else read so far reports the unit's time. data[17] remains unidentified (32 monitoring, 100 idle) -- not claimed as anything. * Memory total is exactly 15,000,000 bytes; free dropped 4,096 bytes across a ~70s monitoring session, so free memory is not stable to compare against. * SUB 0x3F/0x40 walk the setup-file list, the same first/next shape as Series III's 1E/1F event walk. 0x3F -> 0xC0 first, 0x40 -> 0xBF next, terminating on an empty name. 23 setups on this unit. * Setup records carry ONLY the name -- 11-byte header, null-terminated name, zero padding. There is no active-setup flag; the header is byte-identical on every record including the terminator. The active setup is identified solely by SUB 0x41, which uses the same record format. The asterisk on the unit's screen is UI decoration, not a field. * TEST1.mmb, created over the wire earlier today, appears in the list and is what 0x41 reports as active -- a written setup becomes a real enumerable file. Also: Thor greys out send-to-unit while a unit is monitoring, and transmits nothing (this capture contains no 0xDA or 0x71). That is Thor policy, not a device refusal -- nothing suggests the Micromate would reject it, and a push to the active setup overwrites silently. Thor is guarding the footgun the protocol leaves open, and any client we write should do the same. Checking 0x49 data[11] first makes that cheap. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Ru8Lg9HkkYvX9VWWo65SmL --- docs/micromate_protocol_reference.md | 124 ++++++++++++++++++++++++++- 1 file changed, 122 insertions(+), 2 deletions(-) diff --git a/docs/micromate_protocol_reference.md b/docs/micromate_protocol_reference.md index e55a682..6350d69 100644 --- a/docs/micromate_protocol_reference.md +++ b/docs/micromate_protocol_reference.md @@ -442,6 +442,13 @@ memory 15,000,000 total and free (no events stored). scan targets. 12. **The geophone scale factor is `3.10308`**, exactly half Series III's `6.206053`, with an ADC of 10,000 counts per volt. +13. **The monitoring flag is `0x0E`**, where Series III uses `0x10` — and it + sits at `SUB 0x1C` `data[12]`. A second indicator lives at `SUB 0x49` + `data[11]` (`0x02` monitoring), which Series III has no equivalent of. +14. **Setup files are enumerated** with a `0x3F`/`0x40` first/next walk. + Series III has one config and nothing to enumerate. +15. **`SUB 0x1C` carries the device clock** (day/month/year/h/m/s at + `data[13:21]`). Nothing else read so far reports the unit's own time. --- @@ -913,6 +920,118 @@ a create and an overwrite. We have never seen this protocol report a *failed* write, so **do not treat a zero ack as proof a write was applied.** Read the config back and compare; `SUB 0x41` plus `SUB 0x1A` make that cheap. +## Monitoring control and the setup list (2026-09-24) + +Capture: `bridges/captures/9-24-26 - micromate2/*_turn_on_monitormode_*`. +Thor started monitoring, listed the unit's setups, and stopped monitoring. +**40 request frames and 40 responses, every checksum valid.** + +### Thor's per-operation preamble + +Thor re-runs this before *every* operation — three times in this one capture: + +``` +POLL (0x5B) → SERIAL (0x15) → 0x49 → POLL (0x5B) → +``` + +A client should mirror it. Note `POLL` here carries `offset = 0x0030` (its data +length), not `0xFFFF` — `POLL` is the one read Thor still addresses by length. + +### `SUB 0x96` / `0x97` — start and stop monitoring ✅ + +Identical to Series III, including the acks: + +| request | ack | effect | +|---|---|---| +| `0x96` | `0x69` | **start monitoring** | +| `0x97` | `0x68` | **stop monitoring** | + +Both are bare frames — no params, no data — and both ack with the usual 16-byte +zero-data response. Thor follows each with a `SUB 0x1C` status read to confirm. + +### `SUB 0x1C` — monitor status, 55-byte data + +``` +data[12] monitoring flag 0x0E monitoring / 0x00 idle +data[13] day +data[14] month +data[15:17] year, uint16 BE +data[17] ⚠ unidentified — 32 while monitoring, 100 when idle +data[18] hour ─┐ device clock, verified against the capture's +data[19] minute │ own wall time (19:12:25 → 19:13:34 EDT) +data[20] second ─┘ +data[-8:-4] memory total, uint32 BE = 15,000,000 bytes exactly +data[-4:] memory free, uint32 BE +``` + +⚠ **The monitoring flag is `0x0E`, not Series III's `0x10`.** Do not reuse the +Series III constant. Only five bytes differ between the monitoring and idle +responses: the flag, `data[17]`, the clock, and the memory-free field. + +Memory free dropped by exactly **4,096 bytes** across the ~70-second monitoring +session — monitoring allocates as it runs, so free memory is not a stable value +to compare against. + +The device clock is free here, on a command Thor already sends. That is worth +having: nothing else read so far reports the unit's own time. + +### `SUB 0x49` → `0xB6` — a cheap state check + +16-byte data, in Thor's preamble before every operation: + +``` +05 00 00 00 00 00 00 00 00 00 00 [ST] e8 00 0b 00 + ↑ data[11]: 0x02 monitoring, 0x00 idle +``` + +**A second monitoring indicator, in a 21-byte response instead of `0x1C`'s 60.** +Different encoding from `0x1C`'s flag (`0x02` vs `0x0E`), so they are separate +fields, not the same byte read twice. For a polling client this is the cheaper +of the two, and Thor evidently treats it as the routine one. + +### `SUB 0x3F` / `0x40` — walking the setup-file list ✅ + +The same first/next shape as Series III's `1E`/`1F` event walk, applied to +setup files: + +| request | ack | meaning | +|---|---|---| +| `0x3F` | `0xC0` | **first** setup record | +| `0x40` | `0xBF` | **next** setup record; repeat until the name is empty | + +Every record is 266 bytes of data and carries **nothing but the name**: + +``` +ff 00 00 00 00 00 00 00 00 00 00 00 … +└──────────── 11-byte header ─────┘ +``` + +The walk ends on a record whose name is empty — 24 records for 23 setups. +`factory.MMB` comes first, from `0x3F`. + +**There is no active-setup flag in the list.** The header is byte-identical on +every record including the terminator, and the tail is all zeros. The active +setup is identified only by `SUB 0x41`, whose response uses this exact record +format. (On the unit's own screen the active setup is marked with a trailing +asterisk — that is a UI decoration, not a field.) + +`TEST1.mmb`, created over the wire earlier the same day, appears in the list and +is what `0x41` reports as active — independent confirmation that a written setup +becomes a real, enumerable file. + +### Thor refuses to send a setup while a unit is monitoring + +Send-to-unit is **greyed out in Thor's UI** when the unit is monitoring, and +nothing is transmitted — this capture contains no `0xDA` or `0x71` at all. + +That is a Thor-side policy, not a device refusal: nothing observed suggests the +Micromate would reject the write. It squares with the earlier finding that a +push to the **active** setup overwrites silently — Thor is preventing exactly +the footgun the protocol leaves open. + +**Any client we write should adopt the same rule**, and it is now cheap to +enforce: check `0x49` data[11] (or `0x1C` data[12]) before offering a write. + ## Static analysis of the firmware (2026-09-23, solo session) ### Architecture @@ -1061,8 +1180,9 @@ is known; our encoder is unwritten and unproven. - **Writes** (`0x68`–`0x83`) — format now known, never sent by us - **Call-home write** (`0x7E` / `0x7F`) — not observed at all -- **Erase** (`0xA3` / `0xA2`) -- **Start / stop monitoring** (`0x96` / `0x97`) +- **Erase** (`0xA3` / `0xA2`) — **the only genuinely untouched destructive path** +- **Start / stop monitoring** (`0x96` / `0x97`) — observed via Thor 2026-09-24, + acks `0x69` / `0x68`; still never originated by us - `0x1F` (advance event pointer) — non-destructive on Series III but it does move device state, so it is parked with the rest