Skip to content

XLX/urfd Interlink

vex-xlx-bridge links a Vexillum DExtra (D-Star) module to modules on an XLX or urfd reflector, the way xlxd and urfd interlink with each other. It is for linking reflector to reflector, not for reaching some other kind of network.

XLX and urfd interlink with a tag-based handshake: Connect (L), Ack (A), Nack (N), Disconnect (U), and a bare-callsign keepalive. Voice travels as DSVT packets: a 56-byte D-Star header and a 27-byte or 45-byte (extended) voice frame.

Vexillum’s DExtra listener speaks classic DExtra, which uses a different handshake. However, the DSVT header and frame layout is the same in both protocols. The bridge therefore only translates the handshake, and relays voice packets almost unchanged. When the remote reflector sends an extended 45-byte frame, the bridge trims it to the 27-byte form Vexillum uses. The first 27 bytes are identical in both, so nothing is re-encoded.

The XLX protocol code is an original Go implementation, written from the byte-level behavior of urfd’s interlink protocol. No urfd source is copied.

  • Ask the remote reflector’s operator to add an interlink entry for your bridge’s callsign and the module(s) you want. This is the same as a line in their urfd.interlink (or xlxd.interlink) file.
  • Note the address of your Vexillum DExtra listener (default port 30001) and the module to link.
git clone https://repo.kc1awv.net/Vexillum/vex-xlx-bridge.git
cd vex-xlx-bridge
go build ./cmd/vex-xlx-bridge
./vex-xlx-bridge \
  -remote-master xlx123.example.net:10017 \
  -remote-callsign N0CALL \
  -remote-modules A \
  -vex-listen 127.0.0.1:30001 \
  -vex-callsign N0CALL \
  -vex-remote-module A \
  -status-addr 127.0.0.1:8098

This bridge uses no passwords.

Once it’s running, designate the bridge on the DExtra instance, matching its -vex-callsign, so calls from the remote reflector are reported as bridged rather than as local talkers.

Flag Default Description
-remote-master (required) Remote XLX/urfd interlink address, host:port. General XLX interlink uses port 10017.
-remote-callsign (required) Callsign the bridge presents to the remote reflector
-remote-modules (required) Module letter(s) to request, such as A or ABE. Same as the module column of an interlink entry.
-vex-listen (required) Vexillum DExtra listener, host:port
-vex-callsign (required) Callsign the bridge presents to Vexillum
-vex-remote-module (required) Vexillum DExtra module to link into, a single letter A–Z
-vex-local-module same as -vex-remote-module Module the bridge claims to be. Cosmetic only; Vexillum doesn’t check it.
-status-addr :8098 Address for the /status endpoint

GET /status reports both sides:

{
  "remote": {"state": "running", "last_event": "connected", "updated_at": "..."},
  "vex": {"state": "running", "last_event": "connected", "updated_at": "..."}
}

This bridge does not connect to Brandmeister. An earlier version tried to use Brandmeister’s “XLX Bridge” feature, which uses a nearly identical protocol, but traffic wasn’t reliably delivered to Brandmeister listeners and the approach was dropped. Use vex-openbridge-bridge for Brandmeister instead.