summaryrefslogtreecommitdiff
path: root/stacks/crdop/docs/HOST-PROTOCOL-SPEC.md
diff options
context:
space:
mode:
Diffstat (limited to 'stacks/crdop/docs/HOST-PROTOCOL-SPEC.md')
-rw-r--r--stacks/crdop/docs/HOST-PROTOCOL-SPEC.md103
1 files changed, 103 insertions, 0 deletions
diff --git a/stacks/crdop/docs/HOST-PROTOCOL-SPEC.md b/stacks/crdop/docs/HOST-PROTOCOL-SPEC.md
new file mode 100644
index 0000000..d45c7e5
--- /dev/null
+++ b/stacks/crdop/docs/HOST-PROTOCOL-SPEC.md
@@ -0,0 +1,103 @@
+# M25 SoftModem host protocol — implementation spec (frozen for v1.0.0)
+
+**CRDOP** = **MAX25-SoftModem** · Native host wire for MAX25-SoftModem · **Not** ARDOP FEC/ARQ.
+
+**Normative code:** `stacks/crdop/lib/m25_host_protocol.py` · **Consumer:** `max25d` `CrdopTcpBackend`, `audio-dummyd`, `crdopc` launcher.
+
+---
+
+## Transport
+
+| Channel | Default port | Wire |
+|---------|--------------|------|
+| **Control** | **8515** | Line-oriented ASCII, **`\n`** terminated (native) |
+| **Data** | **8516** (= ctrl + 1) | Binary AX.25 UI body **without** HDLC flags or FCS |
+
+| Mode | Control terminator | Data semantics |
+|------|-------------------|----------------|
+| **Native M25/KISS** | `\n` | KISS DATA equivalent — 16+ byte UI body |
+
+### Bench alternate ports
+
+When `soft-crdop` and `audio-dummyd` run on one host, bench daemon may use **8520/8521** via CLI. Production `crdopc` and INI default **8515/8516**.
+
+---
+
+## Control commands (native)
+
+All commands are single lines. Reply is one line ending `\n`.
+
+| Command | Args | Reply | Behaviour |
+|---------|------|-------|-----------|
+| `INITIALIZE` | — | `OK` | Reset session state |
+| `PROTOCOLMODE` | `KISS` | `OK` | Select KISS-semantics data channel |
+| `MYCALL` | `CALL-SSID` | `OK` | Store station ID (uppercase) |
+| `LISTEN` | `TRUE`/`FALSE` | `OK` | RX enable (default true) |
+| `PING` | — | `OK` | Liveness |
+| `STATUS` | — | `STATUS ready mycall=…` | State snapshot |
+| *(unknown)* | — | `ERR unknown command` | |
+
+**Not supported on native path:** `PROTOCOLMODE FEC`, `FECMODE`, ARQ bandwidth commands — ARDOP is a separate optional plugin, not part of CRDOP.
+
+---
+
+## Data channel
+
+### TX (host → modem)
+
+1. TCP connect to data port.
+2. Send **one** AX.25 UI frame body: `dest(7) + src(7) + ctrl(1) + pid(1) + info(0..256)`.
+3. Modem responds `OK` or `ERR …` (ASCII line).
+
+Modem builds on-air: HDLC flags, bit-stuffing, frequency-toggle line code, AFSK PHY — see `acoustic_engine.encode_ax25_ui()`.
+
+### RX (modem → host)
+
+Native bench: optional `STATUS` lines on control channel. Production: `max25d` parses demodulated UI and displays `[CRDOP AX25 UI src>dst] text`.
+
+---
+
+## max25d integration
+
+```ini
+[devices]
+soft-crdop = crdop:default
+
+[device.soft-crdop]
+host = 127.0.0.1
+port = 8515
+listen = yes
+```
+
+`CrdopTcpBackend` on `open()`:
+
+1. TCP connect `host:port` (ctrl), `host:port+1` (data).
+2. Send `INITIALIZE`, `PROTOCOLMODE KISS`, `MYCALL …`, `LISTEN TRUE` (each `\n`).
+
+---
+
+## Layer separation
+
+| Layer | On data TCP | On air |
+|-------|-------------|--------|
+| AX.25 UI body | ✅ | Inside HDLC |
+| HDLC + CRC-16 | ❌ | ✅ |
+| Bell 202 AFSK | ❌ | ✅ |
+
+Same rule as KISS `0x00` DATA frames in `kiss_bridge.py`.
+
+---
+
+## Compliance tests
+
+| Test | Command |
+|------|---------|
+| Unit | `pytest stacks/daemon/test_crdop_backend.py` |
+| Bench host | `python3 stacks/crdop/tools/audio-dummyd.py --ctrl-port 8515 --data-port 8516` |
+| Loopback DSP | `pytest stacks/crdop/test_bell202_line_code.py` |
+
+---
+
+## Version
+
+Frozen for **MAX25-Stack v1.0.0** (dev track `CUR999`). Changes require bump in this file + `PROTOCOL.md` + `test_crdop_backend.py`.
git clone -b <branch> https://cgit.mode42.com/<repo>.git
git clone -b <branch> git://cgit.mode42.com/<repo>.git

info@mode42.com