EchoLink® software allows licensed Amateur Radio stations to communicate with one another over the Internet, using streaming-audio technology.
To create cross-link you need several things:
Patch is available here - https://code.brandmeister.network/r3abm/AutoPatch.git
Patched version of SVXLink is available here = https://github.com/stefansaraev/svxlink/tree/autopatch
# create user and group groupadd svxlink useradd -r -g nogroup -s /sbin/nologin -d /opt/SVXLink -c "SvxLink Daemon" svxlink usermod -G audio,nogroup,svxlink svxlink # fetch patched sources, compile and install into /opt/SVXLink cd /usr/src git clone https://github.com/stefansaraev/svxlink.git -b autopatch cd svxlink ./build.sh # install the systemd unit if you want to run svxlink as systemd service cp bm/svxlink.service /etc/systemd/system/ systemctl enable svxlink
The supplied patch used to translate callsigns that come from EchoLink into DMR IDs.
[GLOBAL] LOGICS=SimplexLogic CFG_DIR=svxlink.d TIMESTAMP_FORMAT="%c" # CARD_SAMPLE_RATE should be 8000 CARD_SAMPLE_RATE=8000 CARD_CHANNELS=1 [SimplexLogic] TYPE=Simplex RX=Rx1 TX=Tx1 MODULES=ModuleEchoLink CALLSIGN=NOCALL EVENT_HANDLER=/opt/SVXLink/share/svxlink/events.tcl [Rx1] TYPE=Local AUDIO_DEV=alsa:hw:Loopback,1,2 AUDIO_CHANNEL=0 SQL_DET=VOX SQL_START_DELAY=0 SQL_HANGTIME=1500 SQL_TIMEOUT=180 VOX_FILTER_DEPTH=20 VOX_THRESH=50 [Tx1] TYPE=Local AUDIO_DEV=alsa:hw:Loopback,0,0 AUDIO_CHANNEL=0 PTT_TYPE=NONE TIMEOUT=180
[ModuleEchoLink] # DMR ID to use as a default when SVXLink cannot provide a source callsign BRIDGE_DEFAULT=nnn # MASTER ID : AUTOPATCH ID BRIDGE_PROXY=xxx1:10 # Encoding of text used by EchoLink in your region BRIDGE_ENCODING=cp1251 NAME=EchoLink ID=2 TIMEOUT=0 SERVERS=servers.echolink.org CALLSIGN=N0CALL-L PASSWORD=trololol SYSOPNAME=N0CALL LOCATION=BrandMeister TGxxx0 MAX_QSOS=50 MAX_CONNECTIONS=51 LINK_IDLE_TIMEOUT=300 DESCRIPTION="Link to BrandMeister TGxxx0\n"
require('Global') local bit = require('bit') local fio = require('fio') local log = require('log') --[[ SvxLink PTY SQL_DET Plug-In ]]-- local cfg = { [2840] = { 20, '/tmp/sql.2840', nil }, [28430] = { 10, '/tmp/sql.28430', nil }, [284359] = { 11, '/tmp/sql.284359', nil } } local function setSquelch(destination, state) local file = fio.readlink(cfg[destination][2]) if file ~= nil then local handle = fio.open(file, { 'O_WRONLY' }) handle:write(state) handle:close() end end local function resetSquelch(state) for k, v in pairs(cfg) do -- log.info("SvxLink: reset %s %s %s", k, v[1], v[2], v[3]) setSquelch(k, state) end end local function checkSquelch(destination, state, newSessionID) if state == 'O' and cfg[destination][3] == nil then setSquelch(destination, state) cfg[destination][3] = newSessionID -- log.info("SvxLink: open %d %s", destination, newSessionID) end if state == 'Z' and cfg[destination][3] == newSessionID then setSquelch(destination, state) cfg[destination][3] = nil -- log.info("SvxLink: close %d %s", destination, newSessionID) end end local SvxLink = { } function SvxLink.start() resetSquelch('Z') end function SvxLink.handleSystemEvent(network, data) -- work around to detect brandmeister core restart if data['Event'] == 'Initialize' and data['LinkName'] == 'FastForward' then resetSquelch('Z') end end function SvxLink.handleSessionEvent(network, data) if data['Event'] == 'Session-Start-Extended' or data['Event'] == 'Session-Stop-Extended' then local kind = tonumber(data['LinkType' ]) local flavor = tonumber(data['SessionType' ]) local number = tonumber(data['Number' ]) local destination = tonumber(data['DestinationID']) local sessionid = data['SessionID' ] if cfg[destination] ~= nil then if number ~= cfg[destination][1] and bit.band(flavor, SESSION_TYPE_FLAG_VOICE) ~= 0 and bit.band(flavor, SESSION_TYPE_FLAG_GROUP) ~= 0 then if data['Event'] == 'Session-Start-Extended' then checkSquelch(destination, 'O', sessionid) else checkSquelch(destination, 'Z', sessionid) end end end end end return SvxLink
EchoLink® software allows licensed Amateur Radio stations to communicate with one another over the Internet, using streaming-audio technology.
To create cross-link you need several things:
Patch is available here - https://code.brandmeister.network/r3abm/AutoPatch.git
Patched version of SVXLink is available here = https://github.com/stefansaraev/svxlink/tree/autopatch
# create user and group groupadd svxlink useradd -r -g nogroup -s /sbin/nologin -d /opt/SVXLink -c "SvxLink Daemon" svxlink usermod -G audio,nogroup,svxlink svxlink # fetch patched sources, compile and install into /opt/SVXLink cd /usr/src git clone https://github.com/stefansaraev/svxlink.git -b autopatch cd svxlink ./build.sh # install the systemd unit if you want to run svxlink as systemd service cp bm/svxlink.service /etc/systemd/system/ systemctl enable svxlink
The supplied patch used to translate callsigns that come from EchoLink into DMR IDs.
[GLOBAL] LOGICS=SimplexLogic CFG_DIR=svxlink.d TIMESTAMP_FORMAT="%c" # CARD_SAMPLE_RATE should be 8000 CARD_SAMPLE_RATE=8000 CARD_CHANNELS=1 [SimplexLogic] TYPE=Simplex RX=Rx1 TX=Tx1 MODULES=ModuleEchoLink CALLSIGN=NOCALL EVENT_HANDLER=/opt/SVXLink/share/svxlink/events.tcl [Rx1] TYPE=Local AUDIO_DEV=alsa:hw:Loopback,1,2 AUDIO_CHANNEL=0 SQL_DET=VOX SQL_START_DELAY=0 SQL_HANGTIME=1500 SQL_TIMEOUT=180 VOX_FILTER_DEPTH=20 VOX_THRESH=50 [Tx1] TYPE=Local AUDIO_DEV=alsa:hw:Loopback,0,0 AUDIO_CHANNEL=0 PTT_TYPE=NONE TIMEOUT=180
[ModuleEchoLink] # DMR ID to use as a default when SVXLink cannot provide a source callsign BRIDGE_DEFAULT=nnn # MASTER ID : AUTOPATCH ID BRIDGE_PROXY=xxx1:10 # Encoding of text used by EchoLink in your region BRIDGE_ENCODING=cp1251 NAME=EchoLink ID=2 TIMEOUT=0 SERVERS=servers.echolink.org CALLSIGN=N0CALL-L PASSWORD=trololol SYSOPNAME=N0CALL LOCATION=BrandMeister TGxxx0 MAX_QSOS=50 MAX_CONNECTIONS=51 LINK_IDLE_TIMEOUT=300 DESCRIPTION="Link to BrandMeister TGxxx0\n"
require('Global') local bit = require('bit') local fio = require('fio') local log = require('log') --[[ SvxLink PTY SQL_DET Plug-In ]]-- local cfg = { [2840] = { 20, '/tmp/sql.2840', nil }, [28430] = { 10, '/tmp/sql.28430', nil }, [284359] = { 11, '/tmp/sql.284359', nil } } local function setSquelch(destination, state) local file = fio.readlink(cfg[destination][2]) if file ~= nil then local handle = fio.open(file, { 'O_WRONLY' }) handle:write(state) handle:close() end end local function resetSquelch(state) for k, v in pairs(cfg) do -- log.info("SvxLink: reset %s %s %s", k, v[1], v[2], v[3]) setSquelch(k, state) end end local function checkSquelch(destination, state, newSessionID) if state == 'O' and cfg[destination][3] == nil then setSquelch(destination, state) cfg[destination][3] = newSessionID -- log.info("SvxLink: open %d %s", destination, newSessionID) end if state == 'Z' and cfg[destination][3] == newSessionID then setSquelch(destination, state) cfg[destination][3] = nil -- log.info("SvxLink: close %d %s", destination, newSessionID) end end local SvxLink = { } function SvxLink.start() resetSquelch('Z') end function SvxLink.handleSystemEvent(network, data) -- work around to detect brandmeister core restart if data['Event'] == 'Initialize' and data['LinkName'] == 'FastForward' then resetSquelch('Z') end end function SvxLink.handleSessionEvent(network, data) if data['Event'] == 'Session-Start-Extended' or data['Event'] == 'Session-Stop-Extended' then local kind = tonumber(data['LinkType' ]) local flavor = tonumber(data['SessionType' ]) local number = tonumber(data['Number' ]) local destination = tonumber(data['DestinationID']) local sessionid = data['SessionID' ] if cfg[destination] ~= nil then if number ~= cfg[destination][1] and bit.band(flavor, SESSION_TYPE_FLAG_VOICE) ~= 0 and bit.band(flavor, SESSION_TYPE_FLAG_GROUP) ~= 0 then if data['Event'] == 'Session-Start-Extended' then checkSquelch(destination, 'O', sessionid) else checkSquelch(destination, 'Z', sessionid) end end end end end return SvxLink