docs(series4): the firmware images are unencrypted and self-documenting
Both MICROMATE(CB).BIN and MICROMATE(BD).BIN are plain code and data --
entropy 6.08 bits/byte, big-endian vector table at 0x4010_30xx, ~16,700
extractable strings including the developers' own debug printf formats with
function names intact.
This answers, from strings alone, questions I had scoped as needing a live
modem capture.
The call-home state machine, verbatim:
ACH_NOT_STARTED -> ACH_IDLE -> ACH_INITIALIZING -> ACH_CONNECTING
-> ACH_CONNECTED -> ACH_TRANSFER_DATA -> ACH_RETRY / ACH_QUITTING
And with it:
- Retry limit is three ("three attempts and it's over").
- ExpectedCommunicationsDetected() gates the session: if the host does not say
something the unit recognises, the call is cancelled and rescheduled after
TimeBetweenRetries. A homebrew receiver must satisfy this check or units
retry forever -- exactly the BE12599 failure mode.
- The unit stops monitoring to call home and restarts after
(Send CMD_STOP_MONITOR / CMD_START_MONITOR), so monitoring state around a
call is the device's own doing.
- Calls are not re-entrant.
- CMD_CALLHOME_CONNECTION_CONFIRMED exists as a state distinct from
CONNECTION_COMPLETE, implying a handshake the host must complete before data
flows.
Event delivery, inferred not confirmed: "All Events Uploaded" plus
"Mark/Unmark File" / "Delete Marked Events" / CMD_PURGE_EVENT_FLASH suggest
events are marked as transferred rather than deleted on send, with purging a
separate explicit act. If so, a receiver that fails to mark would see the same
events re-offered every call. Needs a live capture or disassembly to confirm.
The firmware also embeds its own HTML user manual, documenting modem mode
(Generic vs USB to PC), the modem baud options (9600-230400, confirming 115200
is a setting not a fixed rate), modem relay/warmup, record modes, and a
scheduler downloaded from THOR that pairs with CMD_CALLHOME_SET_SCHEDULE.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ru8Lg9HkkYvX9VWWo65SmL
This commit is contained in:
@@ -426,6 +426,104 @@ memory 15,000,000 total and free (no events stored).
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## The firmware images are unencrypted — and they document themselves
|
||||||
|
|
||||||
|
`ref-stuff/micromate-firmware/MICROMATE(CB).BIN` and `MICROMATE(BD).BIN`,
|
||||||
|
~2.77 MB each and within 192 bytes of one another.
|
||||||
|
|
||||||
|
- **Entropy 6.08 bits/byte** — neither encrypted nor compressed. Plain code
|
||||||
|
and data.
|
||||||
|
- Header is a **big-endian vector table**, handlers at `0x4010_30xx`.
|
||||||
|
- **~16,700 extractable strings**, including the developers' own debug
|
||||||
|
`printf` format strings with function names intact.
|
||||||
|
|
||||||
|
This is a legitimate interoperability reference for hardware TMI owns, and it
|
||||||
|
short-circuits work I had scoped as "only answerable from a live modem
|
||||||
|
capture".
|
||||||
|
|
||||||
|
### The call-home state machine, verbatim
|
||||||
|
|
||||||
|
```
|
||||||
|
ACH_NOT_STARTED → ACH_IDLE → ACH_INITIALIZING → ACH_CONNECTING
|
||||||
|
→ ACH_CONNECTED → ACH_TRANSFER_DATA
|
||||||
|
→ ACH_RETRY / ACH_QUITTING (also ACH_STARTED)
|
||||||
|
```
|
||||||
|
|
||||||
|
Supporting strings:
|
||||||
|
|
||||||
|
```
|
||||||
|
ACH: Entry StartCallHome()
|
||||||
|
ACH: CallHome_task ; CheckAliveTime CANCEL ; TimeBetweenRetries = %d
|
||||||
|
ACH: CallHome_task ; !ExpectedCommunicationsDetected() CANCEL ; TimeBetweenRetries = %d
|
||||||
|
ACH: CallHomeCommectionCompleteProcessing() ACH=%s EAMWC=%s
|
||||||
|
ACH: %s() three attempts and it's over
|
||||||
|
ACH: %s() Send CMD_START_MONITOR
|
||||||
|
ACH: %s() Send CMD_STOP_MONITOR
|
||||||
|
ACH: Start Ignore request, Call Home is in progress
|
||||||
|
```
|
||||||
|
|
||||||
|
What this tells us without a single captured packet:
|
||||||
|
|
||||||
|
1. **Retry limit is three** — "three attempts and it's over".
|
||||||
|
2. **`ExpectedCommunicationsDetected()` gates the session.** If the host does
|
||||||
|
not say something the unit recognises, the call is *cancelled* and
|
||||||
|
rescheduled after `TimeBetweenRetries`. A homebrew receiver must satisfy
|
||||||
|
this check or units will retry forever — which is exactly the failure mode
|
||||||
|
seen on BE12599.
|
||||||
|
3. **The unit stops monitoring to call home and restarts afterwards**
|
||||||
|
(`Send CMD_STOP_MONITOR` / `CMD_START_MONITOR`). Relevant to any
|
||||||
|
wedged-unit rescue: the monitoring state around a call is the device's own
|
||||||
|
doing, not ours.
|
||||||
|
4. **Calls are not re-entrant** — "Call Home is in progress" is ignored.
|
||||||
|
|
||||||
|
### Internal command table
|
||||||
|
|
||||||
|
`CMD_CALLHOME`, `CMD_CALLHOME_CANCEL`, **`CMD_CALLHOME_CONNECTION_CONFIRMED`**,
|
||||||
|
`CMD_CALLHOME_CONNECTION_COMPLETE`, `CMD_CALLHOME_SET_SCHEDULE`,
|
||||||
|
`CMD_CALLHOME_CLEAR_SCHEDULE`, `CMD_STOP_CALLHOME_FILETRANSFER`,
|
||||||
|
`CMD_DUTYCYCLE_AUTOCALLHOME`, `CMD_PURGE_EVENT_FLASH`.
|
||||||
|
|
||||||
|
`CONNECTION_CONFIRMED` as a distinct state from `CONNECTION_COMPLETE` implies
|
||||||
|
a **handshake the host must complete before data flows** — the concrete shape
|
||||||
|
of `ExpectedCommunicationsDetected()`.
|
||||||
|
|
||||||
|
### Event delivery — the mechanism, probably
|
||||||
|
|
||||||
|
```
|
||||||
|
All Events Uploaded
|
||||||
|
Mark/Unmark File Delete Marked Events Marked Events were Deleted
|
||||||
|
MONITOR::MESG PURGE_EVENT_FLASH BEGIN / END
|
||||||
|
```
|
||||||
|
|
||||||
|
A **marking** mechanism exists, alongside a distinct "all uploaded" terminal
|
||||||
|
state. 🔶 **Inferred:** events are *marked* as transferred rather than
|
||||||
|
deleted on send, and purging is a separate explicit act. If so, a receiver
|
||||||
|
that fails to mark would see the same events re-offered every call — the
|
||||||
|
question that gates a safe homebrew receiver. **Not yet confirmed**; needs
|
||||||
|
either a live call-home capture or disassembly around these strings.
|
||||||
|
|
||||||
|
### A full user manual is embedded
|
||||||
|
|
||||||
|
The firmware carries its own HTML help, which documents configuration we would
|
||||||
|
otherwise have to infer:
|
||||||
|
|
||||||
|
- **Modem mode**: `Generic` (through a modem) vs `USB to PC`.
|
||||||
|
- **Modem baud**: 9600 / 19200 / 38400 / 57600 / 115200 / 230400 — "must match
|
||||||
|
the expected rate of the PC or modem". Confirms 115200 is a *setting*, not
|
||||||
|
a fixed rate.
|
||||||
|
- **Modem relay + warmup** (0–300 s), auxiliary mode, warning/alarm hold.
|
||||||
|
- **Record modes**: Waveform, Waveform Manual, Histogram, Histogram-Combo;
|
||||||
|
sample rates 1024 / 2048 / 4096.
|
||||||
|
- **A scheduler downloaded from THOR** that can start/stop monitoring, change
|
||||||
|
record mode, trigger a call home, or run a self check on a daily/weekly
|
||||||
|
schedule. Pairs with `CMD_CALLHOME_SET_SCHEDULE`.
|
||||||
|
|
||||||
|
### Still worth doing
|
||||||
|
|
||||||
|
Diffing the two images should isolate exactly what the CB/BD split changes —
|
||||||
|
we know the wire protocol is not it, and the flags byte (`0xC5` vs `0x03`)
|
||||||
|
gives a concrete anchor to search for.
|
||||||
|
|
||||||
## ⚠ Untested and unsafe-until-agreed
|
## ⚠ Untested and unsafe-until-agreed
|
||||||
|
|
||||||
Nothing below has been sent to a unit, and nothing should be without an
|
Nothing below has been sent to a unit, and nothing should be without an
|
||||||
|
|||||||
Reference in New Issue
Block a user