8.7 KiB
seismo-relay
Tools for capturing and reverse-engineering the RS-232 serial protocol between Blastware software and Instantel MiniMate Plus seismographs.
Built for Windows, stdlib-only (plus pyserial for the bridge).
What's in here
seismo-relay/
├── bridges/
│ ├── s3-bridge/
│ │ └── s3_bridge.py ← The serial bridge (core capture tool)
│ ├── gui_bridge.py ← Tkinter GUI wrapper for s3_bridge
│ └── raw_capture.py ← Simpler raw-only capture tool
└── parsers/
├── s3_parser.py ← Low-level DLE frame extractor
├── s3_analyzer.py ← Protocol analyzer (sessions, diffs, exports)
├── gui_analyzer.py ← Tkinter GUI for the analyzer
└── frame_db.py ← SQLite frame database
How it all fits together
The workflow has two phases: capture, then analyze.
Blastware PC
│
Virtual COM (e.g. COM4)
│
s3_bridge.py ←─── sits in the middle, forwards all bytes both ways
│ writes raw_bw.bin and raw_s3.bin
Physical COM (e.g. COM5)
│
MiniMate Plus seismograph
After capturing, you point the analyzer at the two .bin files to inspect
what happened.
Part 1 — The Bridge
s3_bridge.py — Serial bridge
Transparently forwards bytes between Blastware and the seismograph while logging everything to disk. Blastware operates normally and has no idea the bridge is there.
Run it:
python bridges/s3-bridge/s3_bridge.py --bw COM4 --s3 COM5 --logdir captures/
Key flags:
| Flag | Default | Description |
|---|---|---|
--bw |
required | COM port connected to Blastware |
--s3 |
required | COM port connected to the seismograph |
--baud |
38400 | Baud rate (match your device) |
--logdir |
. |
Where to write log/bin files |
--raw-bw |
off | Also write a flat raw file for BW→S3 traffic |
--raw-s3 |
off | Also write a flat raw file for S3→BW traffic |
Output files (in --logdir):
s3_session_<timestamp>.bin— structured binary log with timestamps and direction tags (record format:[type:1][ts_us:8][len:4][payload])s3_session_<timestamp>.log— human-readable hex dump (text)raw_bw.bin— flat BW→S3 byte stream (if--raw-bwused)raw_s3.bin— flat S3→BW byte stream (if--raw-s3used)
The analyzer needs
raw_bw.bin+raw_s3.bin. Always use--raw-bwand--raw-s3when capturing.
Interactive commands (type while bridge is running):
m+ Enter → prompts for a label and inserts a MARK record into the logq+ Enter → quit
gui_bridge.py — Bridge GUI
A simple point-and-click wrapper around s3_bridge.py. Easier than the
command line if you don't want to type flags every time.
python bridges/gui_bridge.py
Set your COM ports, log directory, and tick the raw tap checkboxes before hitting Start. The Add Mark button lets you annotate the capture at any point (e.g. "changed record time to 13s").
Part 2 — The Analyzer
After capturing, you have raw_bw.bin (bytes Blastware sent) and raw_s3.bin
(bytes the seismograph replied with). The analyzer parses these into protocol
frames, groups them into sessions, and helps you figure out what each byte means.
What's a "session"?
Each time you open the settings dialog in Blastware and click Apply/OK, that's
one session — a complete read/modify/write cycle. The bridge detects session
boundaries by watching for the final write-confirm packet (SUB 0x74).
Each session contains a sequence of request/response frame pairs:
- Blastware sends a request (BW→S3): "give me your config block"
- The seismograph sends a response (S3→BW): here it is
- At the end, Blastware sends the modified settings back in a series of write packets
The analyzer lines these up and diffs consecutive sessions to show you exactly which bytes changed.
gui_analyzer.py — Analyzer GUI
python parsers/gui_analyzer.py
This is the main tool. It has five tabs:
Toolbar
- S3 raw / BW raw — browse to your
raw_s3.binandraw_bw.binfiles - Analyze — parse and load the captures
- Live: OFF/ON — watch the files grow in real time while the bridge is running
- Export for Claude — generate a self-contained
.mdreport for AI-assisted analysis
Inventory tab
Shows all frames in the selected session — direction, SUB command, page, length, and checksum status. Click any frame in the left tree to drill in.
Hex Dump tab
Full hex dump of the selected frame's payload. If the frame had changed bytes vs the previous session, those are listed below the dump with before/after values and field names where known.
Diff tab
Side-by-side byte-level diff between the current session and the previous one. Only SUBs (command types) that actually changed are shown.
Full Report tab
Raw text version of the session report — useful for copying into notes.
Query DB tab
Search across all your captured sessions using the built-in database.
s3_analyzer.py — Analyzer (command line)
If you prefer the terminal:
python parsers/s3_analyzer.py --s3 raw_s3.bin --bw raw_bw.bin
Flags:
| Flag | Description |
|---|---|
--s3 |
Path to raw_s3.bin |
--bw |
Path to raw_bw.bin |
--live |
Tail files in real time (poll mode) |
--export |
Also write a claude_export_<ts>.md file |
--outdir |
Where to write .report files (default: same folder as input) |
--poll |
Live mode poll interval in seconds (default: 0.05) |
Writes one .report file per session and prints a summary to the console.
The Frame Database
Every time you click Analyze, the frames are automatically saved to a SQLite database at:
C:\Users\<you>\.seismo_lab\frames.db
This accumulates captures over time so you can query across sessions and dates.
Query DB tab
Use the filter bar to search:
- Capture — narrow to a specific capture (timestamp shown)
- Dir — BW (requests) or S3 (responses) only
- SUB — filter by command type (e.g.
0xF7= EVENT_INDEX_RESPONSE) - Offset — filter to frames that have a specific byte offset
- Value — combined with Offset: "show frames where byte 85 = 0x0A"
Click any result row, then use the Byte interpretation panel at the bottom to see what that offset's bytes look like as uint8, int8, uint16 BE/LE, uint32 BE/LE, and float32 BE/LE simultaneously.
This is the main tool for mapping unknown fields — if you change one setting in Blastware, capture before and after, then query for frames where that offset moved, you can pin down exactly which byte controls what.
Export for Claude
The Export for Claude button (orange, in the toolbar) generates a single
.md file containing:
- Protocol background and known field map
- Capture summary (session count, frame counts, what changed)
- Per-diff tables — before/after bytes for every changed offset, with field names where known
- Full hex dumps of all frames in the baseline session
Paste this file into a Claude conversation to get help mapping unknown fields, interpreting data structures, or understanding sequences.
Protocol quick-reference
| Term | Value | Meaning |
|---|---|---|
| DLE | 0x10 |
Data Link Escape |
| STX | 0x02 |
Start of frame |
| ETX | 0x03 |
End of frame |
| ACK | 0x41 |
Frame start marker (BW side) |
| DLE stuffing | 10 10 on wire |
Literal 0x10 in payload |
S3-side frame (seismograph → Blastware): DLE STX [payload] DLE ETX
BW-side frame (Blastware → seismograph): ACK STX [payload] ETX
De-stuffed payload header (first 5 bytes after de-stuffing):
[0] CMD 0x10 = BW request, 0x00 = S3 response
[1] ? 0x00 (BW) or 0x10 (S3)
[2] SUB Command/response identifier ← the key field
[3] OFFSET_HI Page address high byte
[4] OFFSET_LO Page address low byte
[5+] DATA Payload content
Response SUB rule: response_SUB = 0xFF - request_SUB
Example: request SUB 0x08 → response SUB 0xF7
Requirements
pip install pyserial
Python 3.10+. Everything else is stdlib (Tkinter, sqlite3, struct, hashlib).
Tkinter is included with the standard Python installer on Windows. If it's missing, reinstall Python and make sure "tcl/tk and IDLE" is checked.
Virtual COM ports
The bridge needs two COM ports on the same PC — one that Blastware connects to, and one wired to the actual seismograph. On Windows, use a virtual COM port pair (e.g. com0com or VSPD) to give Blastware a port to talk to while the bridge sits in the middle.
Blastware → COM4 (virtual) ↔ s3_bridge ↔ COM5 (physical) → MiniMate