summaryrefslogtreecommitdiff
path: root/share/max25
diff options
context:
space:
mode:
authorinfo@mode42.com <info@mode42.com>2026-08-07 18:25:13 +0000
committerinfo@mode42.com <info@mode42.com>2026-08-07 18:25:13 +0000
commit04d965d67a7264a1c7c211494aebda1953df7603 (patch)
tree0ebd700a6e219f84a26a656f4bee8778bc75da7b /share/max25
Initial push
Diffstat (limited to 'share/max25')
-rw-r--r--share/max25/max25-ws-proxy.service.example13
-rw-r--r--share/max25/max25d.freebsd.bcpr.ini.example39
-rw-r--r--share/max25/max25d.freebsd.ini.example35
-rw-r--r--share/max25/max25d.freebsd.secondary.ini.example38
-rw-r--r--share/max25/max25d.freebsd.tmodem.ini.example38
-rw-r--r--share/max25/max25d.full-station.ini.example55
-rw-r--r--share/max25/max25d.ini.example173
-rw-r--r--share/max25/max25d.ini.host.example95
-rw-r--r--share/max25/max25d.main.ini.example27
-rw-r--r--share/max25/max25d.netdev.ini.example12
-rw-r--r--share/max25/max25d.secondary-linux.ini.example46
-rw-r--r--share/max25/max25d.service.example13
-rw-r--r--share/max25/max25d.tmodem.ini.example38
-rw-r--r--share/max25/serial/README.md22
-rw-r--r--share/max25/serial/pccom-kiss-serial.env.example9
-rw-r--r--share/max25/serial/pktnc2-serial.env.example5
-rw-r--r--share/max25/serial/tnc2c-serial.env.example8
17 files changed, 666 insertions, 0 deletions
diff --git a/share/max25/max25-ws-proxy.service.example b/share/max25/max25-ws-proxy.service.example
new file mode 100644
index 0000000..7620ac9
--- /dev/null
+++ b/share/max25/max25-ws-proxy.service.example
@@ -0,0 +1,13 @@
+[Unit]
+Description=MAX25 WebSocket forward-proxy (M25/1 bridge)
+Documentation=file:$PREFIX/share/max25/reverse-proxy/README.txt
+After=network.target max25d.service
+Wants=max25d.service
+
+[Service]
+Type=simple
+ExecStart=/usr/local/bin/max25-ws-proxy -c /etc/max25/web-proxy.ini
+Restart=on-failure
+
+[Install]
+WantedBy=multi-user.target
diff --git a/share/max25/max25d.freebsd.bcpr.ini.example b/share/max25/max25d.freebsd.bcpr.ini.example
new file mode 100644
index 0000000..5789e15
--- /dev/null
+++ b/share/max25/max25d.freebsd.bcpr.ini.example
@@ -0,0 +1,39 @@
+; max25d — FreeBSD + PC-COM / max25-bcpr (ExSys cuau2 default)
+; Copy: cp share/max25/max25d.freebsd.bcpr.ini.example /usr/local/etc/max25/max25d.ini
+; Start bcpr first: max25-bcpr-ctl start --ini /usr/local/etc/max25/max25-bcpr.ini
+
+[features]
+baycom = no
+pccom = no
+max25_bcpr = yes
+tmodem = no
+
+[daemon]
+mode = standalone
+hardware = tncs
+device = max25e0
+; user = akb
+; group = dialer
+
+[devices]
+default = max25e0
+max25e0 = max25-bcpr:bc0
+
+[network]
+tcp_host = 0.0.0.0
+tcp_port = 7325
+unix_socket = /var/run/max25/modem.sock
+tcp_password =
+
+[modem]
+callerid = CB-0
+callid = QST
+ax25_ui = yes
+
+[stack]
+auto_start = yes
+serial_watch = no
+
+[device.max25e0]
+kiss_link = /tmp/max25-bcpr/kiss-bc0
+max25_bcpr_ini = /usr/local/etc/max25/max25-bcpr.ini
diff --git a/share/max25/max25d.freebsd.ini.example b/share/max25/max25d.freebsd.ini.example
new file mode 100644
index 0000000..4a913f9
--- /dev/null
+++ b/share/max25/max25d.freebsd.ini.example
@@ -0,0 +1,35 @@
+; MAX25-Stack — FreeBSD Secondary (CRDOP/OSS, modular TCP/IP service)
+; Copy: cp share/max25/max25d.freebsd.ini.example /usr/local/etc/max25/max25d.ini
+; Audio: pkg install sox — set capture/playback in share/crdop/crdop.freebsd.ini.example
+
+[daemon]
+mode = standalone
+hardware = soft-modems
+device = soft-crdop
+
+[devices]
+default = soft-crdop
+soft-crdop = crdop:default
+
+[device.soft-crdop]
+host = 127.0.0.1
+port = 8515
+
+[modular_tcp]
+enabled = yes
+role = secondary
+service_name = modular-tcp-server
+instance_id = secondary-1
+
+[network]
+tcp_host = 0.0.0.0
+tcp_port = 7326
+unix_socket = /var/run/max25/modem.sock
+
+[modem]
+callerid = CB-0
+callid = QST
+ax25_ui = yes
+
+[stack]
+auto_start = yes
diff --git a/share/max25/max25d.freebsd.secondary.ini.example b/share/max25/max25d.freebsd.secondary.ini.example
new file mode 100644
index 0000000..7c781fe
--- /dev/null
+++ b/share/max25/max25d.freebsd.secondary.ini.example
@@ -0,0 +1,38 @@
+; max25d — FreeBSD Secondary (PC-COM / max25-bcpr)
+; Use with Main tmodem @ :7325 — one RF backend per max25d.
+; Copy: cp share/max25/max25d.freebsd.secondary.ini.example /usr/local/etc/max25/max25d-secondary.ini
+; Start bcpr first: max25-bcpr-ctl start --ini /usr/local/etc/max25/max25-bcpr.ini
+
+[features]
+baycom = no
+pccom = no
+max25_bcpr = yes
+tmodem = no
+
+[daemon]
+mode = standalone
+hardware = tncs
+device = max25e0
+
+[devices]
+default = max25e0
+max25e0 = max25-bcpr:bc0
+
+[network]
+tcp_host = 0.0.0.0
+tcp_port = 7327
+unix_socket = /var/run/max25/modem-secondary.sock
+tcp_password =
+
+[modem]
+callerid = CB-0
+callid = QST
+ax25_ui = yes
+
+[stack]
+auto_start = yes
+serial_watch = no
+
+[device.max25e0]
+kiss_link = /tmp/max25-bcpr/kiss-bc0
+max25_bcpr_ini = /usr/local/etc/max25/max25-bcpr.ini
diff --git a/share/max25/max25d.freebsd.tmodem.ini.example b/share/max25/max25d.freebsd.tmodem.ini.example
new file mode 100644
index 0000000..e4537e2
--- /dev/null
+++ b/share/max25/max25d.freebsd.tmodem.ini.example
@@ -0,0 +1,38 @@
+; max25d — FreeBSD + T-Modem-c1224 USB KISS (prototype)
+; Copy: cp share/max25/max25d.freebsd.tmodem.ini.example /usr/local/etc/max25/max25d.ini
+; Device: /dev/cuaU0 (callout) — adjust uhub / by-id symlink as needed.
+
+[features]
+baycom = no
+pccom = no
+max25_bcpr = no
+tmodem = yes
+
+[daemon]
+mode = standalone
+hardware = tncs
+device = tmodem
+
+[devices]
+default = tmodem
+tmodem = /dev/cuaU0
+
+[network]
+tcp_host = 0.0.0.0
+tcp_port = 7325
+unix_socket = /var/run/max25/modem.sock
+tcp_password =
+
+[modem]
+callerid = CB-0
+callid = QST
+ax25_ui = yes
+
+[stack]
+auto_start = yes
+serial_watch = no
+
+[serial.tmodem]
+baud = 115200
+line = 8n1
+dtr_rts = no
diff --git a/share/max25/max25d.full-station.ini.example b/share/max25/max25d.full-station.ini.example
new file mode 100644
index 0000000..5a2d197
--- /dev/null
+++ b/share/max25/max25d.full-station.ini.example
@@ -0,0 +1,55 @@
+; DEPRECATED for new Linux sites — heterogeneous multi-id station (legacy only).
+; Policy: one RF device per max25d host. Use separate Linux hosts for additional radios.
+; See docs/ARCHITECTURE.md § Linux host policy — one RF device.
+;
+; Full heterogeneous station - TNC2C + PK-TNC2 + BayCom/based (max25e0/bcpr) + CRDOP
+; Copy to /etc/max25/max25d.ini and adjust paths for your site.
+; BayCom + CRDOP backends are architecturally wired; live RF may be untested.
+
+[daemon]
+mode = standalone
+hardware = tncs
+device = tnc2c
+
+[devices]
+default = tnc2c
+tnc2c = /dev/ttyS4
+pktnc2 = /dev/ttyS5
+; baycom-ser12 = baycom:a ; LEGACY kernel - prefer max25e0 = max25-bcpr:bc0
+soft-crdop = crdop:default
+
+[network]
+tcp_host = 0.0.0.0
+tcp_port = 7325
+unix_socket = /run/max25/modem.sock
+tcp_password =
+
+[modem]
+callerid = CB-0
+callid = QST
+ax25_ui = yes
+
+[stack]
+auto_start = yes
+
+[serial.tnc2c]
+baud = 19200
+line = 8n1
+dtr_rts = yes
+kiss_entry = kiss_on
+
+[serial.pktnc2]
+baud = 9600
+line = 8n1
+dtr_rts = no
+kiss_entry = auto
+
+[device.baycom-ser12]
+kiss_link = /var/run/baycom-pr/kiss
+modem = a
+baycom_ini = /etc/baycom/baycom-pr.ini
+
+[device.soft-crdop]
+host = 127.0.0.1
+port = 8515
+listen = yes
diff --git a/share/max25/max25d.ini.example b/share/max25/max25d.ini.example
new file mode 100644
index 0000000..fdac117
--- /dev/null
+++ b/share/max25/max25d.ini.example
@@ -0,0 +1,173 @@
+; MainAX25-Stack — max25d daemon (Linux only)
+; Copy to /etc/max25/max25d.ini or pass MAX25D_INI=
+
+[features]
+; PC-COM / SER12: max25-bcpr userspace (BayCom/based). Kernel baycom = legacy.
+baycom = yes
+pccom = yes
+max25_bcpr = yes
+; T-Modem-c1224 USB KISS half-TNC (Pico) — off unless stuffed
+tmodem = no
+
+[daemon]
+; Operating mode: standalone | service | hybbx-main | hybbx-cohost | hybbx-host
+; HyBBX attach (release serial/KISS to hybbxd): hybbx-main | hybbx-cohost | hybbx-host
+; or [hybbx] release_attach=yes on standalone
+mode = standalone
+; Drop to unprivileged user after stack prep (when started as root via run-max25d.sh)
+; user = max25
+; group = max25
+; Default hardware when per-device hardware= is omitted
+hardware = tncs
+; Legacy single-device id (used when [devices] is absent)
+device = tnc2c
+
+[devices]
+; Linux host: ONE RF device per max25d (design rule). Pick one id below.
+; Layout examples still under design — do not enable two backends on one host.
+; Serial path, baycom:<modem>, or crdop:<profile>
+default = tnc2c
+tnc2c = /dev/ttyS4
+; pktnc2 = /dev/ttyS5
+; --- PC-COM / BayCom/based: max25-bcpr userspace SER12 (default product path) ---
+; Uncomment ONE RF device — max25e0 for PC-COM on ttyS0 (adjust serial in max25-bcpr.ini)
+; default = max25e0
+; max25e0 = max25-bcpr:bc0
+; baycom-kiss = /dev/ttyUSB0
+; pccom-kiss = /dev/ttyUSB0
+; baycom-ser12 = baycom:a ; LEGACY kernel path — avoid
+; soft-crdop = crdop:default
+; --- T-Modem-c1224 USB KISS half-TNC (not BayCom/based) ---
+; tmodem = yes ; under [features]
+; tmodem = /dev/ttyACM0
+; Acoustic bench (loopback / ALSA sniff / host daemon):
+; audio-dummy = audio:loopback
+; enabled = tnc2c ; optional — single id recommended
+
+[network]
+; Terminal clients connect here (TCP). Unix socket always enabled on Linux.
+tcp_host = 0.0.0.0
+tcp_port = 7325
+unix_socket = /run/max25/modem.sock
+; Plain-text TCP auth for remote terminals (empty = disabled; Unix socket exempt)
+tcp_password =
+
+[modem]
+; Default IDs — terminal may override live (session scope)
+callerid = CB-0
+callid = QST
+; Send lines as AX.25 UI when yes (CRDOP uses native AX.25 UI display when ax25_ui=yes)
+ax25_ui = yes
+; Banned AX.25 source callsigns — silent RX drop (one per line in file)
+; bans_file = /etc/max25/bans.txt
+
+[reporting]
+; Client-visible error/voice telemetry in STATUS (and EVENT on decode failure).
+; yes = participate in STATUS; no = always report invalid for that field.
+error_transmissions = yes
+voice_transmissions = yes
+; Data quality: N timed passes (good/bad only; voice/noise ignored), min % good.
+; Each pass lasts up to data_pass_seconds (default 20s); full cycle = 3 × 20s.
+data_passes = 3
+data_quality_min = 50
+data_pass_seconds = 20
+
+[stack]
+; Auto-start hardware on daemon start (boot-wait / baycom-pr-ctl / crdopc per device)
+auto_start = yes
+; TNC serial stability: periodic probe + software recovery (power-cycle stays rescue-only)
+serial_watch = yes
+serial_watch_interval = 60
+serial_repair_cooldown = 20
+serial_watch_startup_grace = 45
+; max25d uses --recover-only for TNC stack prep (no power cycle on daemon start)
+stack_recover_only = yes
+stack_retry_interval = 120
+; After N inline repair failures (error-host), escalate to boot-wait subprocess
+serial_bootwait_escalate = yes
+serial_bootwait_escalate_after = 3
+serial_bootwait_escalate_cooldown = 300
+
+; Software TOT (host policy for max25-bcpr / BayCom/based — not radio TOT)
+; Synced into max25-bcpr.ini on stack start. Trip → stop bcpr, tot-paused, auto recover.
+[tot]
+enabled = yes
+max_key_sec = 25
+min_gap_sec = 1.5
+max_consecutive = 3
+max_bursts = 8
+recover_sec = 300
+
+; Detached operator session (CLI — not parsed from ini):
+; max25d --session tmux -c /etc/max25/max25d.ini
+; max25d session start --tmux
+; max25d-session attach
+; Env: MAX25D_SESSION=max25d MAX25D_SESSION_BACKEND=tmux|screen
+
+[serial]
+; Legacy single-device overrides — ignored when [devices] is present.
+; device = /dev/ttyS4
+; baud = 19200
+; line = 8n1
+; dtr_rts = yes
+; kiss_entry = kiss_on
+
+[serial.tnc2c]
+; Per-device serial profile (optional — defaults from stacks/tncs/tnc2c-serial.env)
+; baud = 19200
+; line = 8n1
+; dtr_rts = yes
+; kiss_entry = kiss_on
+
+[serial.pktnc2]
+; pktnc2: 9600 8N1, DTR+RTS off, kiss_entry=auto
+; baud = 9600
+; line = 8n1
+; dtr_rts = no
+; kiss_entry = auto
+
+[serial.tmodem]
+; T-Modem-c1224 USB CDC KISS half-TNC (not BayCom/based)
+; baud = 115200
+; line = 8n1
+; dtr_rts = no
+
+; --- BayCom kernel (LEGACY — prefer bcpr above) ---
+; baycom-ser12 = baycom:a
+; [device.baycom-ser12]
+; kiss_link = /var/run/baycom-pr/kiss
+; modem = a
+; baycom_ini = /etc/baycom/baycom-pr.ini
+
+; --- max25-bcpr device block (when max25e0 enabled above) ---
+; [device.max25e0]
+; kiss_link = /tmp/max25-bcpr/kiss-bc0
+; max25_bcpr_ini = /etc/max25/max25-bcpr.ini
+; ipv4 = 127.0.0.25/8
+; ipv6 = ::25/128
+; Forks max25e0:bcN inherit ipv4/ipv6 from max25e0 unless overridden.
+; Built by default (MAX25_BUILD_MAX25_BCPR=ON). See share/max25-bcpr/max25-bcpr.ini.example
+
+; --- HyBBX co-host / standalone attach (max25d preps, HyBBX opens KISS) ---
+; [hybbx]
+; release_attach = yes
+
+; --- USB/async BayCom KISS serial ---
+; [serial.baycom-kiss]
+; baud = 9600
+; line = 8n1
+; dtr_rts = no
+
+; --- CRDOP sound-card modem (MAX25-SoftModem) ---
+; [device.soft-crdop]
+; host = 127.0.0.1
+; port = 8515
+; listen = yes
+
+; --- Virtual IP netdev (TUN max25d0 — planned near term) ---
+; Full doc: docs/NETDEV.md · interface name is always max25d0
+; [netdev]
+; enabled = no
+; mode = tun
+; ipv4 = 127.0.0.25/8
+; ipv6 = ::25/128
diff --git a/share/max25/max25d.ini.host.example b/share/max25/max25d.ini.host.example
new file mode 100644
index 0000000..fc05b9d
--- /dev/null
+++ b/share/max25/max25d.ini.host.example
@@ -0,0 +1,95 @@
+; MainAX25-Stack — max25d Linux host (example setup)
+; Copy: sudo cp share/max25/max25d.ini.host.example /etc/max25/max25d.ini
+; Unified workflow: docs/PLUGINS-DEVICE-MODEL.md
+;
+; Example onboard-UART map (single BayCom — no dual on this layout):
+; /dev/ttyS0 BayCom PC-COM (kernel-ser12) — Path B below
+; /dev/ttyS4 TNC2C (packet_radio) — Path A (default)
+; /dev/ttyS5 PK-TNC2 (packet_radio) — NOT BayCom
+;
+; Enable exactly ONE hardware path: comment out Path A [devices] when switching to B or C.
+
+[daemon]
+mode = standalone
+; Path A (default): TNC2C on ttyS4
+hardware = tncs
+device = tnc2c
+; Path B BayCom: hardware = modems · device = max25e0
+; Path C CRDOP: hardware = soft-modems · device = soft-crdop
+
+[network]
+; Listen on all interfaces — remote max25-terminal over LAN
+tcp_host = 0.0.0.0
+tcp_port = 7325
+; systemd RuntimeDirectory=max25 → /run/max25/modem.sock
+unix_socket = /run/max25/modem.sock
+; Set a password before exposing tcp_host = 0.0.0.0 on LAN
+tcp_password = changeme
+
+[modem]
+callerid = CB-0
+callid = QST
+ax25_ui = yes
+; Banned AX.25 source callsigns — silent RX drop (one per line in file)
+; bans_file = /etc/max25/bans.txt
+
+[reporting]
+error_transmissions = yes
+voice_transmissions = yes
+data_passes = 3
+data_quality_min = 50
+data_pass_seconds = 20
+
+[stack]
+; Starts max25-ctl stack on daemon boot (recover-only for TNC — no power cycle)
+auto_start = yes
+serial_watch = yes
+serial_watch_interval = 60
+stack_recover_only = yes
+serial_bootwait_escalate = yes
+serial_bootwait_escalate_after = 3
+
+; --- Path A: TNC2C (default host) ---
+[devices]
+default = tnc2c
+tnc2c = /dev/ttyS4
+
+[serial.tnc2c]
+baud = 19200
+line = 8n1
+dtr_rts = yes
+kiss_entry = kiss_on
+
+; Second TNC — not on same Linux host (use another machine):
+; pktnc2 = /dev/ttyS5
+; [serial.pktnc2]
+; baud = 9600
+; line = 8n1
+; dtr_rts = no
+; kiss_entry = auto
+
+; --- Path B: BayCom PC-COM (single modem on ttyS0) ---
+; Comment Path A [devices] + [serial.tnc2c] above, then uncomment:
+; [devices]
+; default = max25e0
+; baycom-ser12 = baycom:a
+; [device.baycom-ser12]
+; kiss_link = /var/run/baycom-pr/kiss
+; modem = a
+; baycom_ini = /etc/baycom/baycom-pr.ini
+; Prep: sudo cp share/baycom/baycom-pr.pccom-ttyS0-only.ini.example /etc/baycom/baycom-pr.ini
+; sudo baycom-pr-ctl -c /etc/baycom/baycom-pr.ini setup
+
+; --- Path C: CRDOP sound-card modem (CB profile) ---
+; Comment Path A [devices] above, set [daemon] soft-modems/soft-crdop, then uncomment:
+; [devices]
+; default = soft-crdop
+; soft-crdop = crdop:default
+; [device.soft-crdop]
+; host = 127.0.0.1
+; port = 8515
+; listen = yes
+; Prep: cp stacks/crdop/share/crdop.ini.example ~/.config/crdop/crdop.ini (CB / 500MAX)
+
+; Serial env search: /etc/max25/ → local/ → share/max25/serial/ → stacks/tncs/
+; USB TNC example: tnc2c = /dev/ttyUSB0 (edit [serial.tnc2c] or tnc2c-serial.env)
diff --git a/share/max25/max25d.main.ini.example b/share/max25/max25d.main.ini.example
new file mode 100644
index 0000000..86dd292
--- /dev/null
+++ b/share/max25/max25d.main.ini.example
@@ -0,0 +1,27 @@
+; MAX25-Stack — Modular TCP/IP Servers Service — Main (central router)
+; No local RF required on Main — Secondaries own CRDOP/devices.
+; Typical split: Main on FreeBSD; list FreeBSD CRDOP + remote Linux Secondaries below.
+; Copy: cp share/max25/max25d.main.ini.example /usr/local/etc/max25/max25d.ini
+
+[daemon]
+mode = service
+hardware = soft-modems
+device = soft-crdop
+
+[modular_tcp]
+enabled = yes
+role = main
+service_name = modular-tcp-server
+; secondaries = 127.0.0.1:7326,linux-host.example:7327
+
+[modular_tcp.secondaries]
+secondary-1 = 127.0.0.1:7326
+; secondary-linux-1 = linux-host.example:7327
+
+[network]
+tcp_host = 0.0.0.0
+tcp_port = 7325
+unix_socket =
+
+[stack]
+auto_start = no
diff --git a/share/max25/max25d.netdev.ini.example b/share/max25/max25d.netdev.ini.example
new file mode 100644
index 0000000..f8f147c
--- /dev/null
+++ b/share/max25/max25d.netdev.ini.example
@@ -0,0 +1,12 @@
+; Defaults match [device.max25e0] ipv4/ipv6 (127.0.0.25/8, ::25/128).
+; MAX25 virtual netdev (TUN) — merge into max25d.ini
+; Planned: max25-tun sidecar creates interface max25d0 (fixed name)
+
+[netdev]
+enabled = no
+; interface = max25d0 ; always max25d0 — do not change
+mode = tun
+ipv4 = 127.0.0.25/8
+ipv6 = ::25/128
+encap = ax25-ui
+m25_unix = /run/max25/modem.sock
diff --git a/share/max25/max25d.secondary-linux.ini.example b/share/max25/max25d.secondary-linux.ini.example
new file mode 100644
index 0000000..180e5b0
--- /dev/null
+++ b/share/max25/max25d.secondary-linux.ini.example
@@ -0,0 +1,46 @@
+; MAX25-Stack — Linux Secondary (hardware TNC, modular TCP/IP service)
+; Use when FreeBSD hosts Main + CRDOP — this Linux host extends RF only.
+; Copy: cp share/max25/max25d.secondary-linux.ini.example /etc/max25/max25d.ini
+; Register instance_id + host:port in FreeBSD Main [modular_tcp.secondaries].
+
+[features]
+baycom = no
+pccom = no
+
+[daemon]
+mode = service
+hardware = tncs
+device = tnc2c
+
+[devices]
+default = tnc2c
+tnc2c = /dev/ttyS4
+; max25e0 = max25-bcpr:bc0 ; BayCom/based via bcpr
+; baycom-ser12 = baycom:default ; LEGACY kernel — prefer max25e0
+
+[modular_tcp]
+enabled = yes
+role = secondary
+service_name = modular-tcp-server
+instance_id = secondary-linux-1
+
+[network]
+tcp_host = 0.0.0.0
+tcp_port = 7327
+unix_socket = /run/max25/modem.sock
+
+[modem]
+callerid = CB-0
+callid = QST
+ax25_ui = yes
+
+[stack]
+auto_start = yes
+
+; [device.baycom-ser12] ; LEGACY — prefer [device.max25e0]
+kiss_link = /var/run/baycom-pr/kiss
+baycom_ini = /etc/baycom/baycom-pr.ini
+
+; Optional TUN on Linux Secondary — interface name max25d0 only
+; [netdev]
+; enabled = no
diff --git a/share/max25/max25d.service.example b/share/max25/max25d.service.example
new file mode 100644
index 0000000..e3281fb
--- /dev/null
+++ b/share/max25/max25d.service.example
@@ -0,0 +1,13 @@
+[Unit]
+Description=MAX25 daemon (MainAX25-Stack)
+After=network.target
+
+[Service]
+Type=simple
+ExecStart=/usr/local/bin/max25d -c /etc/max25/max25d.ini
+Restart=on-failure
+RuntimeDirectory=max25
+# Unix socket: /run/max25/modem.sock (writable when RuntimeDirectory=max25)
+
+[Install]
+WantedBy=multi-user.target
diff --git a/share/max25/max25d.tmodem.ini.example b/share/max25/max25d.tmodem.ini.example
new file mode 100644
index 0000000..7302625
--- /dev/null
+++ b/share/max25/max25d.tmodem.ini.example
@@ -0,0 +1,38 @@
+; max25d — T-Modem-c1224 USB KISS half-TNC (prototype)
+; Copy toward /etc/max25/max25d.ini or pass MAX25D_INI=
+; RX before TX for any live RF test.
+
+[features]
+baycom = no
+pccom = no
+max25_bcpr = no
+tmodem = yes
+
+[daemon]
+mode = standalone
+hardware = tncs
+device = tmodem
+
+[devices]
+default = tmodem
+tmodem = /dev/ttyACM0
+
+[network]
+tcp_host = 0.0.0.0
+tcp_port = 7325
+unix_socket = /run/max25/modem.sock
+tcp_password =
+
+[modem]
+callerid = CB-0
+callid = QST
+ax25_ui = yes
+
+[stack]
+auto_start = yes
+serial_watch = no
+
+[serial.tmodem]
+baud = 115200
+line = 8n1
+dtr_rts = no
diff --git a/share/max25/serial/README.md b/share/max25/serial/README.md
new file mode 100644
index 0000000..aa05b1c
--- /dev/null
+++ b/share/max25/serial/README.md
@@ -0,0 +1,22 @@
+# Per-device serial env (max25d / boot-wait)
+
+Install copies for site-specific paths:
+
+```bash
+sudo mkdir -p /etc/max25
+sudo cp share/max25/serial/tnc2c-serial.env.example /etc/max25/tnc2c-serial.env
+# edit device path and baud
+```
+
+Search order (`paths.py`): `/etc/max25/` → `local/` → `share/max25/serial/` → `stacks/tncs/`.
+
+**Other device families** use different site config (same `[devices]` pattern in `max25d.ini`):
+
+| Hardware | Site config (not serial env) |
+|----------|------------------------------|
+| BayCom/based (`max25e0` / bcpr) | `share/baycom/baycom-pr.pccom-ttyS0-only.ini.example` → `/etc/baycom/baycom-pr.ini` |
+| CRDOP (`soft-crdop`) | `stacks/crdop/share/crdop.ini.example` |
+
+Unified workflow: [docs/PLUGINS-DEVICE-MODEL.md](../../docs/PLUGINS-DEVICE-MODEL.md).
+
+Terminal client profiles (connection only): [`../clients/`](../clients/README.md).
diff --git a/share/max25/serial/pccom-kiss-serial.env.example b/share/max25/serial/pccom-kiss-serial.env.example
new file mode 100644
index 0000000..6fbbe00
--- /dev/null
+++ b/share/max25/serial/pccom-kiss-serial.env.example
@@ -0,0 +1,9 @@
+# PC-COM / USB KISS serial — copy to /etc/max25/pccom-kiss-serial.env
+# Used by max25d devices pccom-kiss and baycom-kiss (kiss-raw-serial backend).
+# Stable path preferred: /dev/serial/by-id/usb-...
+PCCOM_KISS_DEV=/dev/ttyUSB0
+PCCOM_KISS_BAUD=9600
+PCCOM_KISS_LINE=8n1
+PCCOM_KISS_DTR_RTS=no
+PCCOM_KISS_RADIO_BAUD=1200
+HYBBX_SERIAL_LINE=8n1
diff --git a/share/max25/serial/pktnc2-serial.env.example b/share/max25/serial/pktnc2-serial.env.example
new file mode 100644
index 0000000..ba25cc7
--- /dev/null
+++ b/share/max25/serial/pktnc2-serial.env.example
@@ -0,0 +1,5 @@
+# PK-TNC2 serial — copy to /etc/max25/pktnc2-serial.env
+# Example: onboard UART /dev/ttyS5
+PKTNC2_DEV=/dev/ttyS5
+PKTNC2_BAUD=9600
+PKTNC2_LINE=8n1
diff --git a/share/max25/serial/tnc2c-serial.env.example b/share/max25/serial/tnc2c-serial.env.example
new file mode 100644
index 0000000..10b2576
--- /dev/null
+++ b/share/max25/serial/tnc2c-serial.env.example
@@ -0,0 +1,8 @@
+# TNC2C serial — copy to /etc/max25/tnc2c-serial.env
+# Example: onboard UART /dev/ttyS4
+TNC2C_DEV=/dev/ttyS4
+TNC2C_BAUD=19200
+TNC2C_LINE=8n1
+TNC2C_RADIO_BAUD=2400
+TNC2C_MODEM=tcm3105
+HYBBX_SERIAL_LINE=8n1
git clone -b <branch> https://cgit.mode42.com/<repo>.git
git clone -b <branch> git://cgit.mode42.com/<repo>.git

info@mode42.com