docs(series4): the event chain, walked end to end
Five events on the bench unit (4 waveform + 1 histogram). The Series III browse walk -- 1E, then 0A/0C per key, then 1F to advance -- works unmodified, and the null sentinel terminated correctly after exactly 5. Findings: - Event keys are a sequential counter (055d4a81..85), NOT flash-buffer addresses. Series III key arithmetic does not carry over; its 5A chunk walk assumes addresses and must not be ported blindly. - The 4 bytes after the key in 1E/1F are the event's SIZE in bytes, where Series III puts an offset to the next key. 4,076 for the histogram and 8.7-13.4 KB for the waveforms, matching real .IDFH/.IDFW file sizes. - SUB 0x0C returns a 210-byte (0xD2) waveform record -- the same length as Series III -- carrying the event key, date/time, the title note "Location", the PROJECT STRING, the serial, channel labels Tran/Vert/Long/Mic and float32 peaks. That last point closes the biggest open question for the call-home receiver: the job identity strings that today arrive only via Thor's .txt sidecar, and which no amount of sample decoding can reconstruct, are readable over the wire. Direct-to-SFM events need not arrive with blank metadata. - SUB 0x0A returns len 0x1E for the histogram and 0x00 for every waveform. The histogram payload holds two timestamps plus a "Vert: 0.300 in/s" trigger string -- structurally the Series III monitor-log partial record. So 0A describes interval records and 0C describes triggered events; Series III's 0x46-vs-0x2C length discriminator does not apply. - DLE stuffing in responses is now confirmed (previously marked untested): the 0C timestamp contains 10 10, which destuffs to one 0x10 and yields a clock reading of 16:33 on 23 Sep 2026 -- matching when the events were recorded. Read-only throughout. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ru8Lg9HkkYvX9VWWo65SmL
This commit is contained in:
@@ -241,12 +241,105 @@ the final 8 bytes; untestable until the unit holds events.
|
||||
|
||||
---
|
||||
|
||||
## The event chain — walked end to end (2026-09-23, 5 events)
|
||||
|
||||
With 5 events on the bench unit (4 waveform + 1 histogram), the Series III
|
||||
browse walk works unmodified:
|
||||
|
||||
```
|
||||
1E (all-zero params) -> first key + size
|
||||
0A (key) -> partial record, histogram only
|
||||
0C (key) -> 210-byte waveform record
|
||||
1F (all-zero params/browse) -> next key + size
|
||||
... repeat ...
|
||||
1F -> all-zero key = NULL SENTINEL, chain ends
|
||||
```
|
||||
|
||||
The sentinel terminated correctly after exactly 5 events.
|
||||
|
||||
### Event keys are sequential, not addresses
|
||||
|
||||
```
|
||||
055d4a81 055d4a82 055d4a83 055d4a84 055d4a85
|
||||
```
|
||||
|
||||
**This is a real divergence.** Series III keys are flash-buffer *addresses*
|
||||
(`01110000`, `011121F2`, …) that advance by the event's byte length, which is
|
||||
why its 5A chunk walk is address-arithmetic. Micromate keys are a plain
|
||||
incrementing counter. Any port of the Series III download walk must not
|
||||
assume key arithmetic means anything.
|
||||
|
||||
### The 4 bytes after the key are the event's size
|
||||
|
||||
`1E`/`1F` return `[key 4B][size 4B]`. Series III uses that slot as an offset
|
||||
to the next key; here it is a byte count:
|
||||
|
||||
| key | size | kind |
|
||||
|---|---|---|
|
||||
| `055d4a81` | 4,076 | histogram |
|
||||
| `055d4a82` | 11,032 | waveform |
|
||||
| `055d4a83` | 11,502 | waveform |
|
||||
| `055d4a84` | 13,424 | waveform |
|
||||
| `055d4a85` | 8,746 | waveform |
|
||||
|
||||
Consistent with real file sizes (corpus `.IDFH` ≈ 3.7–25 KB, `.IDFW` ≈
|
||||
8.6–15.8 KB), and the histogram is unmistakably the small one. ⚠ Inferred,
|
||||
not proven: the sizes sum to 48,780 while monitor status reports 57,344 bytes
|
||||
used, so ~8.5 KB of overhead is unaccounted for.
|
||||
|
||||
### `SUB 0x0C` — waveform record, and it carries the job metadata
|
||||
|
||||
**Length `0xD2` = 210 bytes — identical to Series III.** Contents confirmed
|
||||
across all 5 events:
|
||||
|
||||
- the event key, echoed
|
||||
- date + time (`17 09 07 ea` → 23 Sep 2026, then `10 21` → 16:33 — matching
|
||||
the actual bench recording time)
|
||||
- title note `"Location"`
|
||||
- **the project string** — `"Univ of Pitt-1st Yr Housing-Loc1 Ruskin"`
|
||||
- serial `"UM12947"`
|
||||
- channel labels `Tran` / `Vert` / `Long` / `Mic` — the same labels Series III
|
||||
uses, and the same label-relative float32 layout
|
||||
- per-event float32 peaks: 3.5152, 1.3720, 2.3542, 3.5152, 0.4227 in/s
|
||||
across the five events (varied deliberately during recording)
|
||||
|
||||
**This closes the biggest open question for the call-home-receiver goal.**
|
||||
The job identity strings (`project` / `client` / `operator` / `setup`) that
|
||||
today arrive only via Thor's `.txt` sidecar — and which no amount of sample
|
||||
decoding can reconstruct — are **available over the wire from `0x0C`**. A
|
||||
direct-to-SFM event need not arrive with blank metadata.
|
||||
|
||||
### `SUB 0x0A` — partial record, histogram only
|
||||
|
||||
`0x0A` returned `len = 0x1E` (30 B) for the histogram and `len = 0x00` for all
|
||||
four waveforms. The histogram payload carries **two timestamps** and the
|
||||
ASCII string `"\r Vert: 0.300 in/s"` — structurally the Series III
|
||||
**monitor-log partial record** (`0x2C` type), which likewise holds a start/stop
|
||||
pair and a `"Geo: <float> in/s"` trigger string.
|
||||
|
||||
So on the Micromate the division of labour is: `0x0A` describes interval-style
|
||||
records, `0x0C` describes triggered events. Series III uses `0x0A`'s
|
||||
*response length* (`0x46` vs `0x2C`) to tell real events from boundaries;
|
||||
that discriminator does not apply here.
|
||||
|
||||
### DLE stuffing in responses — confirmed present
|
||||
|
||||
Earlier marked untested. The `0x0C` timestamp field contains `10 10`, which
|
||||
destuffs to a single `0x10` and yields a sensible clock reading. **Responses
|
||||
are DLE-stuffed**, so a parser must destuff before applying field offsets.
|
||||
|
||||
---
|
||||
|
||||
## Divergences from Series III (running list)
|
||||
|
||||
1. **No `DLE` prefix on responses** — bare `STX`.
|
||||
2. **Response flags byte is `0xC5`**, not `0x10`.
|
||||
3. **Call-home config is 126 bytes**, not 124.
|
||||
4. **Data lengths are discoverable** from the probe response at `payload[9]`.
|
||||
4b. **Event keys are a sequential counter**, not flash addresses.
|
||||
4c. **`1E`/`1F` return the event size**, where Series III returns an offset.
|
||||
4d. **`0x0A` vs `0x0C` split by record type**, not by the `0x46`/`0x2C`
|
||||
length discriminator Series III uses.
|
||||
5. **Modem serial rate is 115200**, not 38400 (per TMI provisioning practice;
|
||||
not independently verified here).
|
||||
|
||||
|
||||
Reference in New Issue
Block a user