debug(protocol): event-N probe is now at counter = start_offset instead of start_offset + 0x46

This commit is contained in:
2026-05-05 16:46:35 -04:00
parent 6b76934a04
commit 7444738883
4 changed files with 80 additions and 11 deletions
+23
View File
@@ -4,6 +4,29 @@ All notable changes to seismo-relay are documented here.
--- ---
## v0.14.1 — 2026-05-04
### Fixed
- **`read_bulk_waveform_stream` — event-N probe counter off-by-`0x46`.**
Continuation events (start_key[2:4] != 0) were being probed at counter
`start_offset + 0x0046` instead of just `start_offset`. In the iteration
walk, `cur_key` from 1F is already the off=0x46 WAVEHDR record key, so the
earlier formula effectively double-counted the WAVEHDR offset. The probe
landed one WAVEHDR past the actual event start, the response no longer
contained the STRT record at byte 17, `parse_strt_end_offset` returned
`None`, and the chunk loop fell back to the `max_chunks=128` cap — walking
~110 chunks of post-event circular-buffer garbage. Verified against the
5-1-26 "copy 2nd address" and 5-4-26 BW 2-sec event captures: BW probes
counter=`0x2238` with key=`01112238` and STRT is present at byte 17 of
the response (end_offset=`0x417E`).
- **CLAUDE.md / docs/instantel_protocol_reference.md** — corrected the
event-N section to clarify that `start_key` in those formulas is the
off=0x46 key, not the off=0x2C boundary key, and removed the spurious
`+0x46` from the chunk-walk pseudocode.
---
## v0.12.6 — 2026-05-01 ## v0.12.6 — 2026-05-01
### Fixed ### Fixed
+24 -3
View File
@@ -2,7 +2,7 @@
Ground-up Python replacement for **Blastware**, Instantel's Windows-only software for Ground-up Python replacement for **Blastware**, Instantel's Windows-only software for
managing MiniMate Plus seismographs. Connects over direct RS-232 or cellular modem managing MiniMate Plus seismographs. Connects over direct RS-232 or cellular modem
(Sierra Wireless RV50 / RV55). Current version: **v0.13.2**. (Sierra Wireless RV50 / RV55). Current version: **v0.14.1**.
When new information about the protocol is discovered, please update the instantel_protocol_reference.md with the findings in addition to this document When new information about the protocol is discovered, please update the instantel_protocol_reference.md with the findings in addition to this document
@@ -160,13 +160,28 @@ firmware reserved area for the first slot in a freshly-erased buffer. Harmless
#### Event 2+ case — start_key[2:4] != 0x0000 (continuation events) #### Event 2+ case — start_key[2:4] != 0x0000 (continuation events)
``` ```
1. First chunk at counter = start_key[2:4] + 0x0046 (this IS the probe — response 1. First chunk at counter = start_key[2:4] (this IS the probe — response
contains STRT) contains STRT at byte 17)
2. Sample chunks: counter += 0x0200 each, up to but 2. Sample chunks: counter += 0x0200 each, up to but
not including end_offset not including end_offset
3. TERM frame 3. TERM frame
``` ```
**`start_key` here is the off=0x46 WAVEHDR record key returned by 1F** (e.g. `01112238`),
NOT the off=0x2C boundary key that immediately precedes it. An earlier draft of this
doc described event-N as "probe at start + 0x46" — that formula came from naming the
boundary key as `start_key`. In the iteration walk, `cur_key` passed to
`read_bulk_waveform_stream` is always the off=0x46 key (the partial-record skip path in
`get_events` re-runs 1F to advance past boundary records before invoking 5A), so the
probe counter is just `cur_key[2:4]` with no extra offset. **Adding +0x46 caused the
probe to overshoot, miss the STRT record at byte 17 of the response, fall back to the
`max_chunks=128` cap, and walk ~110 chunks of post-event garbage** — observed in
SFM 5-4-26 capture before the fix.
Confirmed across:
- 5-1-26 "copy 2nd address" BW capture: probe counter=0x2238, key=01112238, STRT@17 end=0x417E.
- 5-4-26 BW 2-sec event capture: probe counter=0x2238, key=01112238, TERM offset_word=0x0146 → end=0x417E.
No metadata pages — those have already been read during event 1 in the same Blastware No metadata pages — those have already been read during event 1 in the same Blastware
session, and BW caches them. Note that the metadata-page reads happen ONCE per session, and BW caches them. Note that the metadata-page reads happen ONCE per
Blastware-session-on-the-device, not once per event, so an SFM session that downloads Blastware-session-on-the-device, not once per event, so an SFM session that downloads
@@ -180,6 +195,12 @@ several events should read 0x1002/0x1004 only once at the start.
- 2026-04-26: `max(key4[2:4], 0x0400) + (chunk_num-1) * 0x0400` (broken — over-read past event end). - 2026-04-26: `max(key4[2:4], 0x0400) + (chunk_num-1) * 0x0400` (broken — over-read past event end).
- 2026-05-01: Increments are 0x0200 not 0x0400; absolute addresses inside event range; bounded - 2026-05-01: Increments are 0x0200 not 0x0400; absolute addresses inside event range; bounded
by STRT end_key, not by `max_chunks` cap or device-side timeout. by STRT end_key, not by `max_chunks` cap or device-side timeout.
- 2026-05-04: Removed spurious `+0x0046` from event-N probe counter. `cur_key` from 1F
is already the off=0x46 WAVEHDR key, so adding +0x46 would have placed the probe one
WAVEHDR past the actual event start. This caused probe responses to lack a STRT
record (no `end_offset` parsed → `0xFFFF` fallback → `max_chunks=128` cap), walking
~110 chunks of post-event circular-buffer garbage. Fixed in protocol.py
`read_bulk_waveform_stream`.
### SUB 5A — STRT record encodes end_offset (NEW 2026-05-01) ### SUB 5A — STRT record encodes end_offset (NEW 2026-05-01)
+18 -3
View File
@@ -1383,12 +1383,26 @@ the first slot in a freshly-erased buffer. Harmless to skip; BW does the same.
**Event 2+ / start_key[2:4] != 0x0000** (continuation events in a populated buffer): **Event 2+ / start_key[2:4] != 0x0000** (continuation events in a populated buffer):
``` ```
1. First chunk at counter = start_key[2:4] + 0x0046 ← acts as both probe and first 1. First chunk at counter = start_key[2:4] ← acts as both probe and first
sample chunk; response carries STRT sample chunk; response carries STRT at byte 17
2. Walk sample chunks counter += 0x0200 each 2. Walk sample chunks counter += 0x0200 each
3. TERM 3. TERM
``` ```
**`start_key` here is the off=0x46 WAVEHDR record key returned by 1F** (e.g. `01112238`),
NOT the off=0x2C boundary key that immediately precedes it. An earlier draft of this
spec described event-N as "probe at start + 0x46" — that formula was correct only if
"start" meant the boundary key (0x21F2 in the 5-1-26 event 2 case). In the iteration
walk used by SFM and BW, `cur_key` passed into the 5A flow is always the off=0x46 key,
so the probe counter equals `cur_key[2:4]` with no extra offset. Adding +0x46 places
the probe one WAVEHDR past the actual event start, the response no longer contains
STRT at byte 17, and the chunk loop falls back to the `max_chunks` cap.
Confirmed:
- 5-1-26 "copy 2nd address" BW capture: probe counter=0x2238 with key=01112238; A5[0]
has STRT@17 with end_offset=0x417E.
- 5-4-26 BW 2-sec event capture: same probe counter=0x2238, same end_offset=0x417E.
**No metadata-page reads.** Pages 0x1002/0x1004 are session-global and were already read **No metadata-page reads.** Pages 0x1002/0x1004 are session-global and were already read
during event 1 in the same Blastware session. In SFM, treat metadata pages as a once- during event 1 in the same Blastware session. In SFM, treat metadata pages as a once-
per-`MiniMateClient.connect()` (or once-per-call-home) read, not per-event. per-`MiniMateClient.connect()` (or once-per-call-home) read, not per-event.
@@ -1399,7 +1413,8 @@ per-`MiniMateClient.connect()` (or once-per-call-home) read, not per-event.
|---|---|---|---|---|---| |---|---|---|---|---|---|
| 4-27-26 "open 2sec" / "copy event to disk" | `01110000` | `01111ABE` | `0x1ABE` | 6,846 B | 0x0600 (event-1 case) | | 4-27-26 "open 2sec" / "copy event to disk" | `01110000` | `01111ABE` | `0x1ABE` | 6,846 B | 0x0600 (event-1 case) |
| 5-1-26 "copy 3sec" / Download All event 1 | `01110000` | `011121F2` | `0x21F2` | 8,690 B | 0x0600 (event-1 case) | | 5-1-26 "copy 3sec" / Download All event 1 | `01110000` | `011121F2` | `0x21F2` | 8,690 B | 0x0600 (event-1 case) |
| 5-1-26 "copy 2nd address" / DA event 2 | `011121F2` | `0111417E` | event 2 size = 0x1F8C = 8,076 B | 0x2238 (= 0x21F2 + 0x46) | | 5-1-26 "copy 2nd address" / DA event 2 | `01112238` (= 1F result) | `0111417E` | `0x417E`, span 0x1F8C = 8,076 B | 0x2238 (= cur_key[2:4]) |
| 5-4-26 BW 2-sec event | `01112238` | `0111417E` | `0x417E` | 0x2238 (= cur_key[2:4]) |
#### 7.8.6 TERM Frame Formula (NEW 2026-05-01) ✅ #### 7.8.6 TERM Frame Formula (NEW 2026-05-01) ✅
+15 -5
View File
@@ -608,13 +608,23 @@ class MiniMateProtocol:
probe_params = bulk_waveform_params(key4, 0, is_probe=True) probe_params = bulk_waveform_params(key4, 0, is_probe=True)
log.debug("5A probe (event-1) key=%s counter=0x0000", key4.hex()) log.debug("5A probe (event-1) key=%s counter=0x0000", key4.hex())
else: else:
# Continuation events: first 5A request lands at start+0x0046, # Continuation events: first 5A request lands at counter = key[2:4]
# acting as both probe and first sample chunk. Confirmed from # (i.e. the address of the off=0x46 WAVEHDR record returned by 1F).
# 5-1-26 "copy 2nd address event" capture. # The probe response carries STRT at byte 17 with end_offset.
probe_counter = start_offset + 0x0046 #
# Confirmed 2026-05-04 from 5-1-26 "copy 2nd address" capture
# (BW probes counter=0x2238 with key=01112238, STRT@17 end=0x417E)
# and 5-4-26 BW captures (2-sec event probes counter=0x2238).
#
# The earlier "+0x46" formula in the doc came from calling
# start_key the BOUNDARY (off=0x2C) key, but the iteration walk
# uses 1F's off=0x46 key as cur_key, which already incorporates
# the +0x46 offset relative to the boundary. Adding it again
# caused the probe to overshoot, miss STRT, and run uncapped.
probe_counter = start_offset
probe_params = bulk_waveform_params(key4, probe_counter) probe_params = bulk_waveform_params(key4, probe_counter)
log.debug( log.debug(
"5A probe (event-N) key=%s counter=0x%04X (start+0x46)", "5A probe (event-N) key=%s counter=0x%04X",
key4.hex(), probe_counter, key4.hex(), probe_counter,
) )