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://git.brandmeister.network/public/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