Point the local lab at GeuReflector and document the Config window.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+9
-1
@@ -17,7 +17,7 @@ The conference that forwards audio among stations that have joined the same talk
|
|||||||
_Avoid_: server, bridge
|
_Avoid_: server, bridge
|
||||||
|
|
||||||
**Talk group**:
|
**Talk group**:
|
||||||
A numbered audio room on the reflector. The station joins one talk group for the whole run.
|
A numbered audio room on the reflector. The station is joined to one talk group at a time; changing it in the config starts a new session after Save.
|
||||||
_Avoid_: channel, room
|
_Avoid_: channel, room
|
||||||
|
|
||||||
**Talker**:
|
**Talker**:
|
||||||
@@ -51,3 +51,11 @@ _Avoid_: TYPE, a config field the operator sets
|
|||||||
**Push-to-talk**:
|
**Push-to-talk**:
|
||||||
The operator holding the control that makes this station the talker. Releasing it returns the station to listening.
|
The operator holding the control that makes this station the talker. Releasing it returns the station to listening.
|
||||||
_Avoid_: voice-operated transmit, a mute toggle
|
_Avoid_: voice-operated transmit, a mute toggle
|
||||||
|
|
||||||
|
**Config**:
|
||||||
|
The JSON file that names how this station joins a reflector (host, port, callsign, auth key, talk group, certificate directory, logging). Default path `~/.funknetz.json`; `-c` may select another file.
|
||||||
|
_Avoid_: settings file, preferences, treating PEMs as config fields
|
||||||
|
|
||||||
|
**Config window**:
|
||||||
|
The in-app form that edits the config. It is a modal over the station UI, not a separate OS window.
|
||||||
|
_Avoid_: settings window, preferences dialog, a raw JSON editor as the primary UI
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
# Hand-edited config in the home directory
|
# Home-directory config and Config window
|
||||||
|
|
||||||
The operator edits connection settings by hand. There is no settings window in version 1. The default file is `~/.funknetz.json`, created mode 0600 when missing. Application Support would match other Mac apps and would be a worse place to open in an editor. That default path is part of the station's contract; moving it later strands existing files. `-c` / `--config` may select another file; create, rewrite, and validate rules are the same—only the path changes.
|
The station config is a JSON file. The default path is `~/.funknetz.json`; that path is part of the contract because moving it later strands existing files. Application Support would match other Mac apps but is a worse place for hand-editing, which remains supported alongside `-c` / `--config`. The primary editor is the in-app Config window (a modal form over the station UI). When the resolved file is missing or has never loaded successfully, the app opens that window and does not create the file until Save (mode 0600 on first create); Cancel in that state quits. Create, rewrite, and validate rules are the same for every path—only the path changes.
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@
|
|||||||
**Scope:** The TCP control and UDP audio protocol a station uses to join one SvxReflector, as implemented by upstream SvxLink. Two self-contained memos: Protocol Version 2.0 and Protocol Version 3.0. Shared byte encoding is specified once and cited by both. Protocol 1.x is a short historical section because this server still accepts it and still emits a distinct talker body.
|
**Scope:** The TCP control and UDP audio protocol a station uses to join one SvxReflector, as implemented by upstream SvxLink. Two self-contained memos: Protocol Version 2.0 and Protocol Version 3.0. Shared byte encoding is specified once and cited by both. Protocol 1.x is a short historical section because this server still accepts it and still emits a distinct talker body.
|
||||||
**Not this:** A Go client; production FM-Funknetz credentials or a live probe of that reflector; reflector-to-reflector trunking; MQTT; talk-group mapping policy.
|
**Not this:** A Go client; production FM-Funknetz credentials or a live probe of that reflector; reflector-to-reflector trunking; MQTT; talk-group mapping policy.
|
||||||
**Upstream:** GitHub `sm0svx/svxlink` `master` HEAD on 2026-10-07 was still commit [`fcd13014810af75d1852b3f2cfc8d9806178d0ab`](https://github.com/sm0svx/svxlink/commit/fcd13014810af75d1852b3f2cfc8d9806178d0ab) (2026-07-26, “Prepare for release 26.05.1”). In that commit [`src/versions`](https://github.com/sm0svx/svxlink/blob/fcd13014810af75d1852b3f2cfc8d9806178d0ab/src/versions): `PROJECT=26.05.1`, `SVXLINK=1.10.1`, `SVXREFLECTOR=1.4.1`. There is no IETF RFC. If this text and the cited source disagree, the source wins.
|
**Upstream:** GitHub `sm0svx/svxlink` `master` HEAD on 2026-10-07 was still commit [`fcd13014810af75d1852b3f2cfc8d9806178d0ab`](https://github.com/sm0svx/svxlink/commit/fcd13014810af75d1852b3f2cfc8d9806178d0ab) (2026-07-26, “Prepare for release 26.05.1”). In that commit [`src/versions`](https://github.com/sm0svx/svxlink/blob/fcd13014810af75d1852b3f2cfc8d9806178d0ab/src/versions): `PROJECT=26.05.1`, `SVXLINK=1.10.1`, `SVXREFLECTOR=1.4.1`. There is no IETF RFC. If this text and the cited source disagree, the source wins.
|
||||||
**Fork check:** `dj1jay/jayReflector` `main` on 2026-10-07 was still [`50997ed21a37c7c05c132eca5ebb07bab4b80fc7`](https://github.com/dj1jay/jayReflector/commit/50997ed21a37c7c05c132eca5ebb07bab4b80fc7). Client-facing TCP and UDP message types match upstream; see the note after the memos.
|
**Fork check:** `dj1jay/jayReflector` `main` on 2026-10-07 was still [`50997ed21a37c7c05c132eca5ebb07bab4b80fc7`](https://github.com/dj1jay/jayReflector/commit/50997ed21a37c7c05c132eca5ebb07bab4b80fc7). Client-facing TCP and UDP message types match upstream; see the note after the memos. The lab binary is now [GeuReflector](https://github.com/audric/GeuReflector) at [`dbad88e8c3e0f1adb8342db190bb0b3ad00106f4`](https://github.com/audric/GeuReflector/commit/dbad88e8c3e0f1adb8342db190bb0b3ad00106f4); the station message table in this file is unchanged.
|
||||||
|
|
||||||
This note is **factual** except sections labeled **Inference**.
|
This note is **factual** except sections labeled **Inference**.
|
||||||
|
|
||||||
|
|||||||
+14
-13
@@ -2,13 +2,13 @@
|
|||||||
|
|
||||||
Funknetz must be proven against a local reflector before it touches the live network. This document is that lab: how to run the reflector, what it will accept from a station, and what the wire protocol actually does—so a headset client can be tested without FM-Funknetz credentials.
|
Funknetz must be proven against a local reflector before it touches the live network. This document is that lab: how to run the reflector, what it will accept from a station, and what the wire protocol actually does—so a headset client can be tested without FM-Funknetz credentials.
|
||||||
|
|
||||||
The lab runs **[jayReflector](https://github.com/dj1jay/jayReflector)** (DJ1JAY / FM-Funknetz), a Trunk/Satellite-capable fork of SvxReflector. The process is still named `svxreflector`. You do **not** need the `svxlink` node binary, LocalRx/LocalTx, or EchoLink to exercise the headset client.
|
The lab runs **[GeuReflector](https://github.com/audric/GeuReflector)** (IW1GEU), a Trunk/Satellite-capable fork of SvxReflector. The process is still named `svxreflector`. You do **not** need the `svxlink` node binary, LocalRx/LocalTx, or EchoLink to exercise the headset client.
|
||||||
|
|
||||||
Funknetz is a station on the conference: it connects to the local reflector on TCP+UDP. Optional FM-Funknetz uplink is Satellite (outbound) or Trunk — configured separately when DJ1JAY provides parameters.
|
Funknetz is a station on the conference: it connects to the local reflector on TCP+UDP. Optional FM-Funknetz uplink is Satellite (outbound) or Trunk — configured separately when the parent operator provides parameters.
|
||||||
|
|
||||||
## Running a local reflector
|
## Running a local reflector
|
||||||
|
|
||||||
Lab compose lives in [`svxlink-docker/`](../svxlink-docker/). It builds jayReflector, mounts a minimal `svxreflector.conf`, publishes TCP **and** UDP on the listen port, and runs only `svxreflector`.
|
Lab compose lives in [`svxlink-docker/`](../svxlink-docker/). It builds GeuReflector, mounts a minimal `svxreflector.conf`, publishes TCP **and** UDP on the listen port, and runs only `svxreflector`.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
cd svxlink-docker
|
cd svxlink-docker
|
||||||
@@ -18,7 +18,7 @@ docker compose up -d --build
|
|||||||
|
|
||||||
| Item | Lab value |
|
| Item | Lab value |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| Binary | jayReflector → `/usr/bin/svxreflector` |
|
| Binary | GeuReflector → `/usr/bin/svxreflector` |
|
||||||
| Listen port | **5300** TCP **and** UDP (local clients; FM-Funknetz production client port is often 5308) |
|
| Listen port | **5300** TCP **and** UDP (local clients; FM-Funknetz production client port is often 5308) |
|
||||||
| Config | `config/svxreflector.conf` → `/etc/svxlink/svxreflector.conf` |
|
| Config | `config/svxreflector.conf` → `/etc/svxlink/svxreflector.conf` |
|
||||||
| Auth (protocol 2.0) | `[USERS]` → `[PASSWORDS]`; station `authKey` matches that secret |
|
| Auth (protocol 2.0) | `[USERS]` → `[PASSWORDS]`; station `authKey` matches that secret |
|
||||||
@@ -56,7 +56,7 @@ A second station can use callsign `DL0FN-2` with the same auth key. Do not reuse
|
|||||||
|
|
||||||
Default: `ENABLE_FM_LINK=0` — local island only. No network uplink.
|
Default: `ENABLE_FM_LINK=0` — local island only. No network uplink.
|
||||||
|
|
||||||
When DJ1JAY provides parameters:
|
When the parent operator provides parameters:
|
||||||
|
|
||||||
1. Edit [`config/svxreflector.link.conf`](../svxlink-docker/config/svxreflector.link.conf) (prefer **Satellite** for home labs).
|
1. Edit [`config/svxreflector.link.conf`](../svxlink-docker/config/svxreflector.link.conf) (prefer **Satellite** for home labs).
|
||||||
2. Set `ENABLE_FM_LINK=1` in `.env`.
|
2. Set `ENABLE_FM_LINK=1` in `.env`.
|
||||||
@@ -69,21 +69,22 @@ The entrypoint appends the link file after the base conf. Local Funknetz setting
|
|||||||
With Satellite, **your container dials out** to the parent on TCP **5303**. The network does **not** open a connection toward you. You do **not** need public DNS, a static IP, or inbound port-forwarding for the uplink. Only your **local** clients need to reach host `:5300` (typically localhost).
|
With Satellite, **your container dials out** to the parent on TCP **5303**. The network does **not** open a connection toward you. You do **not** need public DNS, a static IP, or inbound port-forwarding for the uplink. Only your **local** clients need to reach host `:5300` (typically localhost).
|
||||||
|
|
||||||
```text
|
```text
|
||||||
Funknetz ──:5300──► jayReflector (lab) ──outbound :5303──► FM-Funknetz parent
|
Funknetz ──:5300──► GeuReflector (lab) ──outbound :5303──► FM-Funknetz parent
|
||||||
```
|
```
|
||||||
|
|
||||||
Fill from DJ1JAY (jayReflector README shape):
|
Fill under `[GLOBAL]` in the link stub (GeuReflector README shape). `SATELLITE_ID` may contain only letters, digits, and dashes:
|
||||||
|
|
||||||
- `SATELLITE_OF=parent.example.org:5303`
|
- `SATELLITE_OF=parent.example.org`
|
||||||
|
- `SATELLITE_PORT=5303`
|
||||||
- `SATELLITE_ID=…`
|
- `SATELLITE_ID=…`
|
||||||
- `SATELLITE_SECRET=…`
|
- `SATELLITE_SECRET=…`
|
||||||
- optional `SATELLITE_FILTER=…` for “only some TGs”
|
- optional `SATELLITE_FILTER=…` for “only some TGs”
|
||||||
|
|
||||||
### Trunk (only if agreed)
|
### Trunk (only if agreed)
|
||||||
|
|
||||||
Equal mesh peer: mutual TCP **5302**, matching `[TRUNK_x]` section name and `SECRET`, plus filters (`ALLOW_TGS` / `TG_MAP`). That **does** require the peer to reach your trunk port — not the default lab layout. Prefer Satellite unless DJ1JAY asks for Trunk.
|
Equal mesh peer: mutual TCP **5302**, matching `[TRUNK_x]` section name and `SECRET`, plus filters (`ALLOW_TGS` / `TG_MAP`). That **does** require the peer to reach your trunk port — not the default lab layout. Prefer Satellite unless the parent operator asks for Trunk.
|
||||||
|
|
||||||
Research baseline: [docs/research/2026-10-07-jayreflector-fm-funknetz.md](../../docs/research/2026-10-07-jayreflector-fm-funknetz.md).
|
Research baseline: [docs/research/2026-10-11-geureflector-lab-baseline.md](../../docs/research/2026-10-11-geureflector-lab-baseline.md).
|
||||||
|
|
||||||
## What the reflector admits
|
## What the reflector admits
|
||||||
|
|
||||||
@@ -103,7 +104,7 @@ For the lab and for production as FM-Funknetz documents it, the station speaks *
|
|||||||
|
|
||||||
## Wire protocol
|
## Wire protocol
|
||||||
|
|
||||||
The byte-level specification is [rfc.md](./rfc.md). It describes the protocol as implemented by SvxLink. The contract in that source is the message types in SvxLink / jayReflector (`ReflectorMsg.h` and the client logics). Control rides **TCP** as length-prefixed frames (4-byte big-endian length, then payload). Audio and UDP keepalives ride **UDP** to the same host and port. Message types are numeric. Protocol **2.0** authenticates with the auth-key HMAC and sends plaintext UDP with a header of type, client id, and sequence. Protocol **3.0** uses X.509/TLS and encrypts UDP (AES-128-GCM). Funknetz targets 2.0.
|
The byte-level specification is [rfc.md](./rfc.md). It describes the protocol as implemented by SvxLink. The contract in that source is the message types in SvxLink / GeuReflector (`ReflectorMsg.h` and the client logics). Control rides **TCP** as length-prefixed frames (4-byte big-endian length, then payload). Audio and UDP keepalives ride **UDP** to the same host and port. Message types are numeric. Protocol **2.0** authenticates with the auth-key HMAC and sends plaintext UDP with a header of type, client id, and sequence. Protocol **3.0** uses X.509/TLS and encrypts UDP (AES-128-GCM). Funknetz targets 2.0.
|
||||||
|
|
||||||
Typical protocol 2.0 login:
|
Typical protocol 2.0 login:
|
||||||
|
|
||||||
@@ -155,7 +156,7 @@ The codec name is negotiated in `MsgServerInfo`, not per audio packet. When Opus
|
|||||||
| Concept | What it is in this lab |
|
| Concept | What it is in this lab |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| Stock `sm0svx` peering | **Unsupported** — not what we build. |
|
| Stock `sm0svx` peering | **Unsupported** — not what we build. |
|
||||||
| jayReflector **Satellite** | Lab dials parent `:5303`; optional `SATELLITE_FILTER` for some TGs. Outbound only. |
|
| GeuReflector **Satellite** | Lab dials parent `:5303`; optional `SATELLITE_FILTER` for some TGs. Outbound only. |
|
||||||
| jayReflector **Trunk** | Mesh peer on `:5302` with filters / `TG_MAP`. Needs mutual reachability. |
|
| GeuReflector **Trunk** | Mesh peer on `:5302` with filters / `TG_MAP`. Needs mutual reachability. |
|
||||||
| `svxlink` dual ReflectorLogic bridge | Not required here; Satellite/Trunk replace that for FM-Funknetz attach. |
|
| `svxlink` dual ReflectorLogic bridge | Not required here; Satellite/Trunk replace that for FM-Funknetz attach. |
|
||||||
| Same reflector, same TG, two stations | Normal conference — local test without any uplink. |
|
| Same reflector, same TG, two stations | Normal conference — local test without any uplink. |
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ TZ=Europe/Berlin
|
|||||||
LISTEN_PORT=5300
|
LISTEN_PORT=5300
|
||||||
|
|
||||||
# 0 = local lab only (default). 1 = append config/svxreflector.link.conf
|
# 0 = local lab only (default). 1 = append config/svxreflector.link.conf
|
||||||
# (Satellite/Trunk from DJ1JAY). Satellite dials out — no public DNS needed.
|
# (GeuReflector Satellite/Trunk). Satellite dials out — no public DNS needed.
|
||||||
ENABLE_FM_LINK=0
|
ENABLE_FM_LINK=0
|
||||||
|
|
||||||
SVXREFLECTOR_CONF=/etc/svxlink/svxreflector.conf
|
SVXREFLECTOR_CONF=/etc/svxlink/svxreflector.conf
|
||||||
|
|||||||
+13
-11
@@ -1,6 +1,7 @@
|
|||||||
# Build jayReflector (DJ1JAY / FM-Funknetz) for the Funknetz local lab.
|
# Build GeuReflector (IW1GEU) for the Funknetz local lab.
|
||||||
# Binary name remains svxreflector; Trunk/Satellite are opt-in via config.
|
# Binary name remains svxreflector; Trunk/Satellite are opt-in via config.
|
||||||
# Upstream pattern: dj1jay/jayReflector Dockerfile (clone + cmake, not stock sm0svx).
|
# Pin: audric/GeuReflector dbad88e8c3e0f1adb8342db190bb0b3ad00106f4
|
||||||
|
# (master, 2026-07-16; release line v1.3.17).
|
||||||
|
|
||||||
# =========================================================
|
# =========================================================
|
||||||
# STAGE 1 — BUILD
|
# STAGE 1 — BUILD
|
||||||
@@ -13,27 +14,27 @@ RUN apt-get update && apt-get -y install --no-install-recommends \
|
|||||||
build-essential cmake \
|
build-essential cmake \
|
||||||
libsigc++-2.0-dev libssl-dev libjsoncpp-dev libpopt-dev \
|
libsigc++-2.0-dev libssl-dev libjsoncpp-dev libpopt-dev \
|
||||||
libopus-dev libgsm1-dev \
|
libopus-dev libgsm1-dev \
|
||||||
|
libmosquitto-dev libhiredis-dev \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
ARG GIT_URL=https://github.com/dj1jay/jayReflector.git
|
ARG GIT_URL=https://github.com/audric/GeuReflector.git
|
||||||
ARG GIT_BRANCH=main
|
ARG GIT_BRANCH=master
|
||||||
ARG GIT_REF=
|
ARG GIT_REF=
|
||||||
ARG NUM_CORES=4
|
ARG NUM_CORES=4
|
||||||
|
|
||||||
WORKDIR /build
|
WORKDIR /build
|
||||||
RUN set -eux; \
|
RUN set -eux; \
|
||||||
if [ -n "${GIT_REF}" ]; then \
|
if [ -n "${GIT_REF}" ]; then \
|
||||||
git clone --recursive "${GIT_URL}" jayReflector; \
|
git clone --recursive "${GIT_URL}" GeuReflector; \
|
||||||
cd jayReflector && git checkout "${GIT_REF}"; \
|
cd GeuReflector && git checkout "${GIT_REF}"; \
|
||||||
else \
|
else \
|
||||||
git clone --recursive --depth 1 --branch "${GIT_BRANCH}" "${GIT_URL}" jayReflector; \
|
git clone --recursive --depth 1 --branch "${GIT_BRANCH}" "${GIT_URL}" GeuReflector; \
|
||||||
fi
|
fi
|
||||||
|
|
||||||
WORKDIR /build/jayReflector
|
WORKDIR /build/GeuReflector
|
||||||
RUN set -eux; \
|
RUN set -eux; \
|
||||||
cmake -S src -B build \
|
cmake -S src -B build \
|
||||||
-DLOCAL_STATE_DIR=/var \
|
-DLOCAL_STATE_DIR=/var \
|
||||||
-DUSE_QT=OFF \
|
|
||||||
-DUSE_ALSA=OFF \
|
-DUSE_ALSA=OFF \
|
||||||
-DCMAKE_BUILD_TYPE=Release; \
|
-DCMAKE_BUILD_TYPE=Release; \
|
||||||
cmake --build build --target svxreflector -j"${NUM_CORES}"
|
cmake --build build --target svxreflector -j"${NUM_CORES}"
|
||||||
@@ -48,10 +49,11 @@ RUN apt-get update && apt-get -y install --no-install-recommends \
|
|||||||
ca-certificates openssl \
|
ca-certificates openssl \
|
||||||
libsigc++-2.0-0v5 libssl3 libjsoncpp25 libpopt0 \
|
libsigc++-2.0-0v5 libssl3 libjsoncpp25 libpopt0 \
|
||||||
libopus0 libgsm1 \
|
libopus0 libgsm1 \
|
||||||
|
libmosquitto1 libhiredis0.14 \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
COPY --from=builder /build/jayReflector/build/bin/svxreflector /usr/bin/svxreflector
|
COPY --from=builder /build/GeuReflector/build/bin/svxreflector /usr/bin/svxreflector
|
||||||
COPY --from=builder /build/jayReflector/build/lib/lib*.so* /usr/lib/
|
COPY --from=builder /build/GeuReflector/build/lib/lib*.so* /usr/lib/
|
||||||
|
|
||||||
RUN mkdir -p /etc/svxlink /etc/svxlink/pki /var/log/svxlink /var/lib/svxlink && \
|
RUN mkdir -p /etc/svxlink /etc/svxlink/pki /var/log/svxlink /var/lib/svxlink && \
|
||||||
ldconfig && \
|
ldconfig && \
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
###################################################################
|
###################################################################
|
||||||
# Local lab jayReflector for Funknetz (protocol 2.0 / ReflectorV2)
|
# Local lab GeuReflector for Funknetz (protocol 2.0 / ReflectorV2)
|
||||||
# Secrets here are placeholders — do not reuse production keys.
|
# Secrets here are placeholders — do not reuse production keys.
|
||||||
#
|
#
|
||||||
# Standalone by default: local clients only. FM-Funknetz Satellite/Trunk
|
# Standalone by default: local clients only. FM-Funknetz Satellite/Trunk
|
||||||
@@ -17,8 +17,8 @@ CERT_PKI_DIR=/etc/svxlink/pki/
|
|||||||
# Optional status JSON (publish 8080 in compose if you enable this):
|
# Optional status JSON (publish 8080 in compose if you enable this):
|
||||||
# HTTP_SRV_PORT=8080
|
# HTTP_SRV_PORT=8080
|
||||||
|
|
||||||
# jayReflector / modern SvxReflector bootstraps a local PKI even for
|
# GeuReflector bootstraps a local PKI even for protocol 2.0 AUTH_KEY
|
||||||
# protocol 2.0 AUTH_KEY clients. COMMON_NAME is required on first start.
|
# clients. COMMON_NAME is required on first start.
|
||||||
[SERVER_CERT]
|
[SERVER_CERT]
|
||||||
COMMON_NAME=funknetz-lab.local
|
COMMON_NAME=funknetz-lab.local
|
||||||
SUBJECT_ALT_NAME=DNS:funknetz-lab.local,DNS:localhost,IP:127.0.0.1
|
SUBJECT_ALT_NAME=DNS:funknetz-lab.local,DNS:localhost,IP:127.0.0.1
|
||||||
|
|||||||
@@ -1,33 +1,43 @@
|
|||||||
###################################################################
|
###################################################################
|
||||||
# Optional FM-Funknetz link stub (jayReflector)
|
# Optional FM-Funknetz link stub (GeuReflector)
|
||||||
#
|
#
|
||||||
# Default: leave ENABLE_FM_LINK=0 in .env — this file is ignored.
|
# Default: leave ENABLE_FM_LINK=0 in .env — this file is ignored.
|
||||||
# When DJ1JAY provides values:
|
# When the parent operator provides values:
|
||||||
# 1. Fill ONE of the blocks below (prefer Satellite for home/NAT labs).
|
# 1. Uncomment ONE of the blocks below (prefer Satellite for home/NAT labs).
|
||||||
# 2. Set ENABLE_FM_LINK=1 in .env
|
# 2. Set ENABLE_FM_LINK=1 in .env
|
||||||
# 3. docker compose up -d
|
# 3. docker compose up -d
|
||||||
#
|
#
|
||||||
|
# The entrypoint appends this file after the base lab conf, which already
|
||||||
|
# ends in [PASSWORDS]. Satellite keys belong in [GLOBAL]; the section
|
||||||
|
# header below merges with the base [GLOBAL] section.
|
||||||
|
#
|
||||||
# Satellite (recommended): this reflector dials OUT to the parent on
|
# Satellite (recommended): this reflector dials OUT to the parent on
|
||||||
# TCP 5303. No public DNS, no inbound peer port, no port-forward required
|
# TCP 5303. No public DNS, no inbound peer port, no port-forward required
|
||||||
# for the link. Local Funknetz clients still use host :5300 only.
|
# for the link. Local Funknetz clients still use host :5300 only.
|
||||||
|
# SATELLITE_ID may contain only letters, digits, and dashes.
|
||||||
|
# Do not set LOCAL_PREFIX or a [TRUNK_x] section on a satellite.
|
||||||
#
|
#
|
||||||
# Trunk: equal mesh peer; needs mutual reachability on TCP 5302 and a
|
# Trunk: equal mesh peer; needs mutual reachability on TCP 5302 and a
|
||||||
# matching [TRUNK_x] section name + SECRET on both sides.
|
# matching [TRUNK_x] section name + SECRET on both sides.
|
||||||
|
# Do not enable Satellite and Trunk in the same file.
|
||||||
#
|
#
|
||||||
# Do not commit real secrets. Prefer a local override or keep secrets
|
# Do not commit real secrets.
|
||||||
# only in your private .env workflow if you copy this file.
|
# Docs: docs/research/2026-10-11-geureflector-lab-baseline.md
|
||||||
# Docs: docs/research/2026-10-07-jayreflector-fm-funknetz.md
|
# README: https://github.com/audric/GeuReflector#satellite-reflectors
|
||||||
# README: https://github.com/dj1jay/jayReflector
|
|
||||||
###################################################################
|
###################################################################
|
||||||
|
|
||||||
# --- Satellite (fill from DJ1JAY; uncomment to use) ---
|
# --- Satellite (uncomment the section and keys to use) ---
|
||||||
# SATELLITE_OF=parent.example.org:5303
|
# [GLOBAL]
|
||||||
|
# SATELLITE_OF=parent.example.org
|
||||||
|
# SATELLITE_PORT=5303
|
||||||
# SATELLITE_ID=lab-yourcall
|
# SATELLITE_ID=lab-yourcall
|
||||||
# SATELLITE_SECRET="replace-with-secret-from-dj1jay"
|
# SATELLITE_SECRET="replace-with-secret-from-operator"
|
||||||
# Only these TGs cross to/from the parent (bidirectional). Omit for all TGs.
|
# Only these TGs cross to/from the parent (bidirectional). Omit for all TGs.
|
||||||
|
# Syntax: exact "26200", prefix "24*", range "2427-2438", comma-separated.
|
||||||
# SATELLITE_FILTER=2621,2629,20
|
# SATELLITE_FILTER=2621,2629,20
|
||||||
|
|
||||||
# --- Trunk peer alternative (fill from DJ1JAY; usually leave commented) ---
|
# --- Trunk peer alternative (uncomment to use; leave Satellite commented) ---
|
||||||
|
# [GLOBAL]
|
||||||
# LOCAL_PREFIX=9
|
# LOCAL_PREFIX=9
|
||||||
# TRUNK_LISTEN_PORT=5302
|
# TRUNK_LISTEN_PORT=5302
|
||||||
#
|
#
|
||||||
@@ -38,4 +48,5 @@
|
|||||||
# REMOTE_PREFIX=262
|
# REMOTE_PREFIX=262
|
||||||
# ALLOW_TGS=2621,2629,20
|
# ALLOW_TGS=2621,2629,20
|
||||||
# # TG_MAP=1:2624100
|
# # TG_MAP=1:2624100
|
||||||
# MQTT_NAME=Lab-YourCall
|
# MQTT stays off. If enabled later, MQTT_NAME belongs in a [MQTT] section,
|
||||||
|
# not under [TRUNK_x].
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
# Local jayReflector lab for Funknetz.
|
# Local GeuReflector lab for Funknetz.
|
||||||
# Build once, then: docker compose up -d --build
|
# Build once, then: docker compose up -d --build
|
||||||
# Connect the app with host/port/callsign/authKey from .env (see FUNKNETZ_*).
|
# Connect the app with host/port/callsign/authKey from .env (see FUNKNETZ_*).
|
||||||
#
|
#
|
||||||
# FM-Funknetz link (optional): fill config/svxreflector.link.conf from DJ1JAY,
|
# FM-Funknetz link (optional): fill config/svxreflector.link.conf,
|
||||||
# set ENABLE_FM_LINK=1, recreate. Satellite mode is outbound-only (no DNS/inbound).
|
# set ENABLE_FM_LINK=1, recreate. Satellite mode is outbound-only (no DNS/inbound).
|
||||||
|
|
||||||
services:
|
services:
|
||||||
@@ -11,11 +11,11 @@ services:
|
|||||||
context: .
|
context: .
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
args:
|
args:
|
||||||
GIT_URL: https://github.com/dj1jay/jayReflector.git
|
GIT_URL: https://github.com/audric/GeuReflector.git
|
||||||
GIT_BRANCH: main
|
GIT_BRANCH: master
|
||||||
# Optional pin (overrides branch clone when set), e.g.:
|
# Pin (overrides the branch clone). master on 2026-10-11; release line v1.3.17.
|
||||||
# GIT_REF: 50997ed21a37c7c05c132eca5ebb07bab4b80fc7
|
GIT_REF: dbad88e8c3e0f1adb8342db190bb0b3ad00106f4
|
||||||
image: funknetz-jayreflector:local
|
image: funknetz-geureflector:local
|
||||||
container_name: funknetz-svxreflector
|
container_name: funknetz-svxreflector
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
env_file:
|
env_file:
|
||||||
|
|||||||
@@ -55,11 +55,11 @@ stop_all() {
|
|||||||
|
|
||||||
trap 'stop_all; exit 0' INT TERM
|
trap 'stop_all; exit 0' INT TERM
|
||||||
|
|
||||||
command -v svxreflector >/dev/null 2>&1 || die "svxreflector binary not found (jayReflector build)"
|
command -v svxreflector >/dev/null 2>&1 || die "svxreflector binary not found (GeuReflector build)"
|
||||||
[ -f "$SVXREFLECTOR_CONF" ] || die "Config not found: $SVXREFLECTOR_CONF (expected volume mount)"
|
[ -f "$SVXREFLECTOR_CONF" ] || die "Config not found: $SVXREFLECTOR_CONF (expected volume mount)"
|
||||||
|
|
||||||
# Local-only by default. When ENABLE_FM_LINK=1, append the link stub
|
# Local-only by default. When ENABLE_FM_LINK=1, append the link stub
|
||||||
# (Satellite or Trunk keys from DJ1JAY) after the base lab conf.
|
# (GeuReflector Satellite or Trunk keys) after the base lab conf.
|
||||||
if [ "$ENABLE_FM_LINK" = "1" ]; then
|
if [ "$ENABLE_FM_LINK" = "1" ]; then
|
||||||
[ -f "$SVXREFLECTOR_LINK_CONF" ] || die "ENABLE_FM_LINK=1 but link config missing: $SVXREFLECTOR_LINK_CONF"
|
[ -f "$SVXREFLECTOR_LINK_CONF" ] || die "ENABLE_FM_LINK=1 but link config missing: $SVXREFLECTOR_LINK_CONF"
|
||||||
{
|
{
|
||||||
@@ -82,7 +82,7 @@ mkdir -p /etc/svxlink/pki /var/lib/svxlink/pki
|
|||||||
|
|
||||||
start_bg "svxreflector" svxreflector --config "$conf_path" $SVXREFLECTOR_ARGS
|
start_bg "svxreflector" svxreflector --config "$conf_path" $SVXREFLECTOR_ARGS
|
||||||
|
|
||||||
log "jayReflector (svxreflector) is running. Waiting…"
|
log "GeuReflector (svxreflector) is running. Waiting…"
|
||||||
|
|
||||||
exit_code=0
|
exit_code=0
|
||||||
for pid in $pids; do
|
for pid in $pids; do
|
||||||
|
|||||||
Reference in New Issue
Block a user