Skip to content

DMR ↔ YSF Bridge

vex-dmr-ysf-bridge links a Vexillum DMR instance to a Vexillum YSF instance, so DMR and YSF users share one conversation. This matches the DMR ↔ YSF module bridging that XLX and urfd provide.

Any DMR traffic that reaches the DMR instance is included. That covers local hotspots, plus outside networks connected with vex-dmr-bridge or vex-openbridge-bridge. Combined with vex-nxdn-ysf-bridge, NXDN users join too (see Cross-mode mesh).

The bridge logs into the DMR instance as a Homebrew repeater and into the YSF instance as a hotspot. DMR and YSF both carry AMBE-family voice frames, so no audio is transcoded. The bridge only regroups the frames: DMR puts 3 AMBE frames in each burst, and YSF puts 5 in each V/D mode 2 frame.

DMR identifies users by numeric ID, and YSF identifies them by callsign. The bridge can use a radioid.net-format CSV to translate between them. With the database, YSF users see the real callsign of whoever is talking on DMR, and DMR users see the real ID of whoever is talking on YSF. XLX shows real identities on both modes the same way.

When -dmr-id-db is set, the bridge loads that file at startup. If the file is missing or unreadable, it downloads a fresh copy. It then re-downloads the database every -dmr-id-db-refresh (24 hours by default).

When a lookup fails, or when no database is configured, the bridge uses -default-callsign on YSF and -default-dmr-id on DMR.

  • In the Vexillum admin interface, note the DMR instance’s Talk TG and password, and the YSF instance’s listen address.
  • Choose a callsign dedicated to the bridge. Vexillum credits “last heard” activity to the callsign a session registers with. If the bridge used a real operator’s callsign, every relayed call would show up as that operator.
git clone https://repo.kc1awv.net/Vexillum/vex-dmr-ysf-bridge.git
cd vex-dmr-ysf-bridge
go build ./cmd/vex-dmr-ysf-bridge
export VEX_DMR_PASSWORD='...'

./vex-dmr-ysf-bridge \
  -vex-master 127.0.0.1:62031 \
  -vex-id 9990002 \
  -vex-callsign N0CALL-Y \
  -vex-talkgroup 7 \
  -ysf-master 127.0.0.1:42000 \
  -ysf-callsign N0CALL-D \
  -dmr-id-db /var/lib/vex-dmr-ysf-bridge/dmr-users.csv \
  -default-dmr-id 9990002 \
  -status-addr 127.0.0.1:8096

Once it’s running, designate the bridge on both instances with the same label: on the DMR instance by its -vex-id repeater ID, and on the YSF instance by its -ysf-callsign. Otherwise every bridged call shows up as a second talker on the other mode.

Flag Default Description
-vex-master (required) Vexillum DMR instance, host:port
-vex-id (required) Repeater ID the bridge presents to Vexillum
-vex-callsign (required) Callsign the bridge presents to the DMR instance
-vex-talkgroup (required) Must exactly match the DMR instance’s Talk TG
-vex-password-env VEX_DMR_PASSWORD Environment variable holding the instance password
-vex-power 1 Power in watts reported to Vexillum
-vex-location (empty) Location reported to Vexillum
-vex-description YSF link Description reported to Vexillum (max 19 bytes)
-color-code 1 Color code for Vexillum’s repeater metadata and for DMR bursts the bridge builds
Flag Default Description
-ysf-master (required) Vexillum YSF instance, host:port
-ysf-callsign (required) Callsign the bridge presents to the YSF instance. Also used as the YSF rpt1 field.
Flag Default Description
-dmr-id-db (none) Path to a local radioid.net-format CSV (RADIO_ID,CALLSIGN,...). Downloaded refreshes are written here.
-dmr-id-db-url https://radioid.net/static/user.csv Where to download the database from
-dmr-id-db-refresh 24h How often to re-download the database. Only applies when -dmr-id-db is set.
-default-dmr-id 0 DMR source ID used when a YSF callsign has no match
-default-callsign N0CALL YSF callsign used when a DMR ID has no match
Flag Default Description
-status-addr :8098 Address for the /status endpoint

GET /status reports the DMR and YSF sessions as JSON.