-[[.:]]
** MB7AZE is now QRT and the NoV has expired.**
The following is for historical interest only….
====== MB7AZE SvxLink Config ======
===== Main config file =====
++++ svxlink.conf |
###############################################################################
# #
# Configuration file for the SvxLink server #
# #
###############################################################################
[GLOBAL]
#MODULE_PATH=/usr/lib/arm-linux-gnueabihf/svxlink
LOGICS=SimplexLogic,ReflectorLogic
CFG_DIR=svxlink.d
TIMESTAMP_FORMAT="%c"
CARD_SAMPLE_RATE=48000
#CARD_CHANNELS=1
LOCATION_INFO=LocationInfo
LINKS=LinkToReflector
[SimplexLogic]
TYPE=Simplex
RX=Rx1
TX=Tx1
DEFAULT_LANG=en_US
MODULES=ModuleHelp,ModuleEchoLink,ModuleParrot
CALLSIGN=MB7AZE
SHORT_IDENT_INTERVAL=15
SHORT_CW_ID_ENABLE=1
SHORT_VOICE_ID_ENABLE=0
LONG_VOICE_ID_ENABLE=1
CW_AMP=-20
CW_PITCH=1000
CW_WPM=20
LONG_IDENT_INTERVAL=60
#IDENT_ONLY_AFTER_TX=4
#EXEC_CMD_ON_SQL_CLOSE=500
EVENT_HANDLER=/usr/local/share/svxlink/events.tcl
RGR_SOUND_DELAY=0
#REPORT_CTCSS=77.0
TX_CTCSS=ALWAYS
MACROS=Macros
FX_GAIN_NORMAL=0
FX_GAIN_LOW=-12
#ACTIVATE_MODULE_ON_LONG_CMD=4:EchoLink
#QSO_RECORDER=8:QsoRecorder
ONLINE_CMD=998877
#MUTE_RX_ON_TX=1
#MUTE_TX_ON_RX=1
#STATE_PTY=/var/run/svxlink/state
#DTMF_CTRL_PTY=/dev/shm/simplex_dtmf_ctrl
TIME_FORMAT=24
RGR_SOUND_ALWAYS=1
[RepeaterLogic]
TYPE=Repeater
RX=Rx1
TX=Tx1
MODULES=ModuleHelp,ModuleParrot,ModuleEchoLink,ModuleTclVoiceMail
CALLSIGN=MYCALL
SHORT_IDENT_INTERVAL=10
LONG_IDENT_INTERVAL=60
#IDENT_ONLY_AFTER_TX=4
#EXEC_CMD_ON_SQL_CLOSE=500
EVENT_HANDLER=/usr/local/share/svxlink/events.tcl
DEFAULT_LANG=en_US
RGR_SOUND_DELAY=0
REPORT_CTCSS=136.5
#TX_CTCSS=SQL_OPEN
MACROS=Macros
#SEL5_MACRO_RANGE=03400,03499
FX_GAIN_NORMAL=0
FX_GAIN_LOW=-12
#QSO_RECORDER=8:QsoRecorder
#NO_REPEAT=1
IDLE_TIMEOUT=30
OPEN_ON_1750=1000
#OPEN_ON_CTCSS=136:2000
#OPEN_ON_DTMF=*
#OPEN_ON_SQL=5000
#OPEN_ON_SEL5=01234
#OPEN_SQL_FLANK=OPEN
#OPEN_ON_SQL_AFTER_RPT_CLOSE=10
IDLE_SOUND_INTERVAL=3000
#SQL_FLAP_SUP_MIN_TIME=1000
#SQL_FLAP_SUP_MAX_COUNT=10
#ACTIVATE_MODULE_ON_LONG_CMD=4:EchoLink
#IDENT_NAG_TIMEOUT=15
#IDENT_NAG_MIN_TIME=2000
#ONLINE_CMD=998877
#STATE_PTY=/var/run/svxlink/state
#DTMF_CTRL_PTY=/dev/shm/repeater_dtmf_ctrl
[ReflectorLogic]
TYPE=Reflector
DEFAULT_LANG=en_US
HOSTS="put the right server address in here"
HOST_PORT=5300
CALLSIGN=MB7AZE
AUTH_KEY="put the right password in here"
JITTER_BUFFER_DELAY=0
DEFAULT_TG=0
MONITOR_TGS=8,91,235,2350,2351,23520,23590,23561
TG_SELECT_TIMEOUT=60
ANNOUNCE_REMOTE_MIN_INTERVAL=300
MUTE_FIRST_TX_LOC=0
MUTE_FIRST_TX_REM=0
TMP_MONITOR_TIMEOUT=3600
EVENT_HANDLER=/usr/local/share/svxlink/events.tcl
NODE_INFO_FILE=/usr/local/etc/svxlink/node_info.json
[LinkToReflector]
CONNECT_LOGICS=SimplexLogic:9:,ReflectorLogic
DEFAULT_ACTIVE=1
#TIMEOUT=300
#AUTOACTIVATE_ON_SQL=RepeaterLogic
OPTIONS=DEFAULT_CONNECT,NO_DISCONNECT
[QsoRecorder]
REC_DIR=/var/spool/svxlink/qso_recorder
#MIN_TIME=1000
MAX_TIME=3600
SOFT_TIME=300
MAX_DIRSIZE=1024
#DEFAULT_ACTIVE=1
#TIMEOUT=300
#QSO_TIMEOUT=300
#ENCODER_CMD=/usr/bin/oggenc -Q \"%f\" && rm \"%f\"
[Voter]
TYPE=Voter
RECEIVERS=Rx1,Rx2,Rx3
VOTING_DELAY=200
BUFFER_LENGTH=0
#REVOTE_INTERVAL=1000
#HYSTERESIS=50
#SQL_CLOSE_REVOTE_DELAY=500
#RX_SWITCH_DELAY=500
#COMMAND_PTY=/dev/shm/voter_ctrl
[MultiTx]
TYPE=Multi
TRANSMITTERS=Tx1,Tx2,Tx3
[NetRx]
TYPE=Net
HOST=remote.rx.host
TCP_PORT=5210
#LOG_DISCONNECTS_ONCE=0
AUTH_KEY="Change this key now!"
CODEC=S16
#SPEEX_ENC_FRAMES_PER_PACKET=4
#SPEEX_ENC_QUALITY=4
#SPEEX_ENC_BITRATE=15000
#SPEEX_ENC_COMPLEXITY=2
#SPEEX_ENC_VBR=0
#SPEEX_ENC_VBR_QUALITY=4
#SPEEX_ENC_ABR=15000
#SPEEX_DEC_ENHANCER=1
#OPUS_ENC_FRAME_SIZE=20
#OPUS_ENC_COMPLEXITY=10
#OPUS_ENC_BITRATE=20000
#OPUS_ENC_VBR=1
[NetTx]
TYPE=Net
HOST=remote.tx.host
TCP_PORT=5210
#LOG_DISCONNECTS_ONCE=0
AUTH_KEY="Change this key now!"
CODEC=S16
#SPEEX_ENC_FRAMES_PER_PACKET=4
#SPEEX_ENC_QUALITY=4
#SPEEX_ENC_BITRATE=15000
#SPEEX_ENC_COMPLEXITY=2
#SPEEX_ENC_VBR=0
#SPEEX_ENC_VBR_QUALITY=4
#SPEEX_ENC_ABR=15000
#SPEEX_DEC_ENHANCER=1
#OPUS_ENC_FRAME_SIZE=20
#OPUS_ENC_COMPLEXITY=10
#OPUS_ENC_BITRATE=20000
#OPUS_ENC_VBR=1
[Rx1]
TYPE=Local
AUDIO_DEV=alsa:plughw:1,0
AUDIO_CHANNEL=0
SQL_DET=CTCSS
SQL_START_DELAY=0
SQL_DELAY=0
SQL_HANGTIME=200
#SQL_EXTENDED_HANGTIME=1000
#SQL_EXTENDED_HANGTIME_THRESH=15
#SQL_TIMEOUT=600
VOX_FILTER_DEPTH=20
VOX_THRESH=1000
#CTCSS_MODE=2
CTCSS_FQ=77.0
#CTCSS_SNR_OFFSET=0
#CTCSS_OPEN_THRESH=15
#CTCSS_CLOSE_THRESH=9
#CTCSS_BPF_LOW=60
#CTCSS_BPF_HIGH=270
#SERIAL_PORT=/dev/ttyUSB0
#SERIAL_PIN=CTS
#SERIAL_SET_PINS=
#EVDEV_DEVNAME=/dev/input/by-id/usb-SYNIC_SYNIC_Wireless_Audio-event-if03
#EVDEV_OPEN=1,163,1
#EVDEV_CLOSE=1,163,0
#GPIO_PATH=/sys/class/gpio
#GPIO_SQL_PIN=gpio25
#PTY_PATH=/tmp/rx1_sql
HID_DEVICE=/dev/hidraw0
HID_SQL_PIN=!VOL_DN
#SIGLEV_DET=NOISE
SIGLEV_SLOPE=1
SIGLEV_OFFSET=0
#SIGLEV_BOGUS_THRESH=120
#TONE_SIGLEV_MAP=100,84,60,50,37,32,28,23,19,8
SIGLEV_OPEN_THRESH=30
SIGLEV_CLOSE_THRESH=10
DEEMPHASIS=1
#SQL_TAIL_ELIM=300
PREAMP=-0.5
#PEAK_METER=1
DTMF_DEC_TYPE=INTERNAL
DTMF_MUTING=1
DTMF_HANGTIME=40
DTMF_SERIAL=/dev/ttyS0
#DTMF_PTY=/tmp/rx1_dtmf
#DTMF_MAX_FWD_TWIST=8
#DTMF_MAX_REV_TWIST=4
#1750_MUTING=1
#SEL5_DEC_TYPE=INTERNAL
#SEL5_TYPE=ZVEI1
#FQ=433475000
#MODULATION=FM
#WBRX=WbRx1
[WbRx1]
#TYPE=RtlUsb
#DEV_MATCH=0
#HOST=localhost
#PORT=1234
#CENTER_FQ=435075000
#FQ_CORR=0
#GAIN=0
#PEAK_METER=1
#SAMPLE_RATE=960000
[Tx1]
TYPE=Local
AUDIO_DEV=alsa:plughw:1,0
AUDIO_CHANNEL=0
PTT_TYPE=Hidraw
#PTT_PORT=/dev/ttyS0
#PTT_PIN=HIDRAW
HID_DEVICE=/dev/hidraw0
HID_PTT_PIN=GPIO3
#SERIAL_SET_PINS=DTR!RTS
#GPIO_PATH=/sys/class/gpio
#PTT_HANGTIME=1000
TIMEOUT=300
TX_DELAY=500
CTCSS_FQ=77.0
CTCSS_LEVEL=20
PREEMPHASIS=1
DTMF_TONE_LENGTH=100
DTMF_TONE_SPACING=50
DTMF_DIGIT_PWR=-15
MASTER_GAIN=-3.5
[LocationInfo]
APRS_SERVER_LIST=euro.aprs2.net:14580
STATUS_SERVER_LIST=aprs.echolink.org:5199
LON_POSITION=1.25.30W
LAT_POSITION=60.17.18N
CALLSIGN=EL-MB7AZE
FREQUENCY=430.050
TX_POWER=1
ANTENNA_GAIN=0
ANTENNA_HEIGHT=1m
ANTENNA_DIR=-1
#PATH=WIDE1-1
BEACON_INTERVAL=60
TONE=77
COMMENT=Connected to UK Svx Reflector
[Macros]
1=EchoLink:9999#
2=EchoLink:973498#
3=EchoLink:662666#
4=:91235#
5=:9123561#
9=:910#
++++
===== Audio levels =====
==== Devcal ====
Use the ''devcal'' program to set RX and TX audio levels.
This allows adjustment of ''alsamixer'' settings and then for fine tuning adjustment of ''PRE-AMP'' (for ''RX'') and ''MASTER GAIN'' (for ''TX'') config options to set the correct audio level INPUT on ''RX'' and deviation on ''TX''.
Once the correct ''PRE-AMP'' or ''MASTER GAIN'' values have been determined in ''DEVCAL'' they are added to the relevant sections in ''svxlink.conf''
To use ''DEVCAL'' first ''sudo killall svxlink''
=== For Receive audio input: ===
sudo devcal -r -m=3000 -d=3000 /usr/local/etc/svxlink/svxlink.conf Rx1
Inject a signal to the radio @ ±3kHz deviation Adjust audio input level via
* radio volume control
* alsamixer Mic Capture level
* devcal +/- to adjust PRE-AMP setting
until the displayed deviation agrees with the input signal's deviation.
**Q**uit ''devcal''
Transfer the displayed ''PRE-AMP'' value to the conf file.
=== For Transmit audio output ===
Monitor TX deviation
sudo devcal -t -m=3000 -d=3000 /usr/local/etc/svxlink/svxlink.conf Tx1
Toggle TX with ''T''
Adjust
* Alsamixer output
* devcal +/-
to achieve ±3kHz TX deviation.
Turn off TX with ''T''
**Q**uit ''devcal''
Copy the displayed ''MASTER GAIN'' value to the conf file.
sudo alsactl store
to save current mixer levels.
===== To prevent Echolink incoming connections while a Talkgroup is active =====
Uncomment :
proc tg_selected {new_tg old_tg} {
puts "### tg_selected #$new_tg (old #$old_tg)"
# Reject incoming Echolink connections while a talkgroup is active
if {$new_tg != 0} {
setConfigValue "ModuleEchoLink" "REJECT_INCOMING" "^.*$"
} else {
setConfigValue "ModuleEchoLink" "REJECT_INCOMING" "^$"
}
}
in ''/usr/local/share/svxlink/events.d/local/ReflectorLogic.tcl''
===== /events.d/local/ =====
Here are the 3 files containing tweaks to the standard behaviour.
Editing the original files (in ''events.d/'') would work, but would get overwritten if the software is upgraded/re-installed. Putting local copies in ''events.d/local'' means the changes survive upgrades etc.
The actual path is:
''/usr/local/share/svxlink/events.d/local/''
I'll try to document what is different once I refresh my memory.
++++ ReflectorLogic.tcl |
###############################################################################
#
# ReflectorLogic event handlers
#
###############################################################################
#
# This is the namespace in which all functions below will exist. The name
# must match the corresponding section "[ReflectorLogic]" in the configuration
# file. The name may be changed but it must be changed in both places.
#
namespace eval ReflectorLogic {
# The currently selected TG. Variable set from application.
variable selected_tg 0
# The previously selected TG. Variable set from application.
variable previous_tg 0
# Timestamp for previous TG announcement
variable prev_announce_time 0
# The previously announced TG
variable prev_announce_tg 0
# The minimum time between announcements of the same TG.
# Change through ANNOUNCE_REMOTE_MIN_INTERVAL config variable.
variable announce_remote_min_interval 0
# This variable will be set to 1 if the QSY pending feature ("QSY on squelch
# activity") is active. See configuration variable QSY_PENDING_TIMEOUT.
variable qsy_pending_active 0
#
# Checking to see if this is the correct logic core
#
if {$logic_name != [namespace tail [namespace current]]} {
return;
}
#
# Executed when an unknown command is received
# cmd - The command string
#
proc unknown_command {cmd} {
Logic::unknown_command $cmd;
}
#
# Executed when a received command fails
#
proc command_failed {cmd} {
Logic::command_failed $cmd;
}
#
# Executed when manual TG announcement is triggered
#
proc report_tg_status {} {
variable selected_tg
variable previous_tg
variable prev_announce_time
variable prev_announce_tg
playSilence 100
if {$selected_tg > 0} {
set prev_announce_time [clock seconds]
set prev_announce_tg $selected_tg
playMsg "Core" "talk_group"
spellNumber $selected_tg
} else {
playMsg "Core" "previous"
playMsg "Core" "talk_group"
spellNumber $previous_tg
}
}
#
# Executed when a TG has been selected
# This function is called immediately when a change in talkgroup selection
# occurs. In constrast, the other more specific talkgroup selection event
# functions below is called with a delay in order to make announcement ordering
# more logical.
#
# new_tg -- The talk group that has been activated
# old_tg -- The talk group that was active
#
proc tg_selected {new_tg old_tg} {
puts "### tg_selected #$new_tg (old #$old_tg)"
# Reject incoming Echolink connections while a talkgroup is active
if {$new_tg != 0} {
setConfigValue "ModuleEchoLink" "REJECT_INCOMING" "^.*$"
} else {
setConfigValue "ModuleEchoLink" "REJECT_INCOMING" "^$"
}
}
#
# Executed when a TG has been selected due to local activity
#
# new_tg -- The talk group that has been activated
# old_tg -- The talk group that was active
#
proc tg_local_activation {new_tg old_tg} {
variable prev_announce_time
variable prev_announce_tg
variable selected_tg
puts "### tg_local_activation"
if {$new_tg != $old_tg} {
set prev_announce_time [clock seconds]
set prev_announce_tg $new_tg
playSilence 100
playMsg "Core" "talk_group"
spellNumber $new_tg
}
}
#
# Executed when a TG has been selected due to remote activity
#
# new_tg -- The talk group that has been activated
# old_tg -- The talk group that was active
#
proc tg_remote_activation {new_tg old_tg} {
variable prev_announce_time
variable prev_announce_tg
variable announce_remote_min_interval
puts "### tg_remote_activation"
set now [clock seconds];
if {($new_tg == $prev_announce_tg) && \
($now - $prev_announce_time < $announce_remote_min_interval)} {
return;
}
if {$new_tg != $old_tg} {
set prev_announce_time $now
set prev_announce_tg $new_tg
playSilence 100
playMsg "Core" "talk_group"
spellNumber $new_tg
}
}
#
# Executed when a TG has been selected due to remote activity on a prioritized
# monitored talk group while a lower prio talk group is selected
#
# new_tg -- The talk group that has been activated
# old_tg -- The talk group that was active
#
proc tg_remote_prio_activation {new_tg old_tg} {
tg_remote_activation $new_tg $old_tg
}
#
# Executed when a TG has been selected by DTMF command
#
# new_tg -- The talk group that has been activated
# old_tg -- The talk group that was active
#
proc tg_command_activation {new_tg old_tg} {
variable prev_announce_time
variable prev_announce_tg
puts "### tg_command_activation"
set prev_announce_time [clock seconds]
set prev_announce_tg $new_tg
playSilence 100
playMsg "Core" "talk_group"
spellNumber $new_tg
}
#
# Executed when a TG has been selected due to DEFAULT_TG configuration
#
# new_tg -- The talk group that has been activated
# old_tg -- The talk group that was active
#
proc tg_default_activation {new_tg old_tg} {
#variable prev_announce_time
#variable prev_announce_tg
#variable selected_tg
puts "### tg_default_activation"
#if {$new_tg != $old_tg} {
# set prev_announce_time [clock seconds]
# set prev_announce_tg $new_tg
# playSilence 100
# playMsg "Core" "talk_group"
# spellNumber $new_tg
#}
}
#
# Executed when a TG QSY request have been acted upon
#
# new_tg -- The talk group that has been activated
# old_tg -- The talk group that was active
#
proc tg_qsy {new_tg old_tg} {
variable prev_announce_time
variable prev_announce_tg
puts "### tg_qsy"
set prev_announce_time [clock seconds]
set prev_announce_tg $new_tg
playSilence 100
playMsg "Core" "qsy"
#playMsg "Core" "talk_group"
spellNumber $new_tg
}
#
# Executed when a QSY is followed due to squelch open (see QSY_PENDING_TIMEOUT)
#
# tg -- The talk group that has been activated
#
proc tg_qsy_on_sql {tg} {
playSilence 100
playMsg "Core" "qsy"
}
#
# Executed when a TG QSY request fails
#
# A TG QSY may fail for primarily two reasons, either no talk group is
# currently active or there is no connection to the reflector server.
#
proc tg_qsy_failed {} {
puts "### tg_qsy_failed"
playSilence 100
playMsg "Core" "qsy"
playSilence 200
playMsg "Core" "operation_failed"
}
#
# Executed when a TG QSY request is pending
#
# tg -- The talk group requested in the QSY
#
proc tg_qsy_pending {tg} {
playSilence 100
playMsg "Core" "qsy"
spellNumber $tg
playMsg "Core" "pending"
}
#
# Executed when a TG QSY request is ignored
#
# tg -- The talk group requested in the QSY
#
proc tg_qsy_ignored {tg} {
variable qsy_pending_active
playSilence 100
if {!$qsy_pending_active} {
playMsg "Core" "qsy"
spellNumber $tg
}
playMsg "Core" "ignored"
playSilence 500
playTone 880 200 50
playTone 659 200 50
playTone 440 200 50
playSilence 100
}
#
# Executed when a TG selection has timed out
#
# new_tg -- Always 0
# old_tg -- The talk group that was active
#
proc tg_selection_timeout {new_tg old_tg} {
puts "### tg_selection_timeout"
if {$old_tg != 0} {
playSilence 50
playTone 880 200 50
playTone 659 200 50
playTone 440 200 50
playSilence 50
# } else {
# playSilence 50
# playTone 440 200 150
# playSilence 50
}
}
#
# Executed on talker start
#
# tg -- The talk group
# callsign -- The callsign of the talker node
#
proc talker_start {tg callsign} {
#puts "### Talker DID start on TG #$tg: $callsign"
}
#
# Executed on talker stop
#
# tg -- The talk group
# callsign -- The callsign of the talker node
#
proc talker_stop {tg callsign} {
variable selected_tg
variable ::Logic::CFG_CALLSIGN
#puts "### Talker DID stop on TG #$tg: $callsign"
if {($tg == $selected_tg) && ($callsign != $::Logic::CFG_CALLSIGN)} {
playSilence 100
playTone 440 200 50
playTone 659 200 50
playTone 880 200 50
playSilence 100
}
}
#
# A talk group was added for temporary monitoring
#
# tg -- The added talk group
#
proc tmp_monitor_add {tg} {
puts "### tmp_monitor_add: $tg"
playSilence 50
playMsg "Default" "activating"
playMsg "Core" "monitor"
spellNumber $tg
}
#
# A talk group was removed from temporary monitoring
#
# tg -- The removed talk group
#
proc tmp_monitor_remove {tg} {
puts "### tmp_monitor_remove: $tg"
playSilence 50
playMsg "Default" "deactivating"
playMsg "Core" "monitor"
spellNumber $tg
}
if [info exists ::Logic::CFG_ANNOUNCE_REMOTE_MIN_INTERVAL] {
set announce_remote_min_interval $::Logic::CFG_ANNOUNCE_REMOTE_MIN_INTERVAL
}
if [info exists ::Logic::CFG_QSY_PENDING_TIMEOUT] {
if {$::Logic::CFG_QSY_PENDING_TIMEOUT > 0} {
set qsy_pending_active 1
}
}
# end of namespace
}
#
# This file has not been truncated
#
++++
++++ Logic.tcl |
###############################################################################
#
# Generic Logic event handlers
#
###############################################################################
#
# This is the namespace in which all functions and variables below will exist.
#
namespace eval Logic {
#
# A variable used to store a timestamp for the last identification.
#
variable prev_ident 0;
#
# A constant that indicates the minimum time in seconds to wait between two
# identifications. Manual and long identifications is not affected.
#
variable min_time_between_ident 120;
#
# Short and long identification intervals. They are setup from config
# variables below.
#
variable short_ident_interval 0;
variable long_ident_interval 0;
variable short_voice_id_enable 1
variable short_cw_id_enable 0
variable short_announce_enable 0
variable short_announce_file ""
variable long_voice_id_enable 1
variable long_cw_id_enable 0
variable long_announce_enable 0
variable long_announce_file ""
#
# The ident_only_after_tx variable indicates if identification is only to
# occur after the node has transmitted. The variable is setup below from the
# configuration variable with the same name.
# The need_ident variable indicates if identification is needed.
#
variable ident_only_after_tx 0;
variable need_ident 0;
#
# List of functions that should be called periodically. Use the
# addMinuteTickSubscriber and addSecondTickSubscriber functions to
# add subscribers.
#
variable minute_tick_subscribers [list];
variable second_tick_subscribers [list];
#
# Contains the ID of the last receiver that indicated squelch activity
#
variable sql_rx_id "?";
#
# Executed when the SvxLink software is started
#
proc startup {} {
#playMsg "Core" "online"
#send_short_ident
}
#
# Executed when a specified module could not be found
# module_id - The numeric ID of the module
#
proc no_such_module {module_id} {
playMsg "Core" "no_such_module";
playNumber $module_id;
}
#
# Executed when a manual identification is initiated with the * DTMF code
#
proc manual_identification {} {
global mycall;
global report_ctcss;
global active_module;
global loaded_modules;
variable CFG_TYPE;
variable prev_ident;
set epoch [clock seconds];
set hour [clock format $epoch -format "%k"];
regexp {([1-5]?\d)$} [clock format $epoch -format "%M"] -> minute;
set prev_ident $epoch;
playMsg "Core" "online";
spellWord $mycall;
if {$CFG_TYPE == "Repeater"} {
playMsg "Core" "repeater";
}
playSilence 250;
playMsg "Core" "the_time_is";
playTime $hour $minute;
playSilence 250;
if {$report_ctcss > 0} {
playMsg "Core" "pl_is";
playFrequency $report_ctcss
playSilence 300;
}
if {$active_module != ""} {
playMsg "Core" "active_module";
playMsg $active_module "name";
playSilence 250;
set func "::";
append func $active_module "::status_report";
if {"[info procs $func]" ne ""} {
$func;
}
} else {
foreach module [split $loaded_modules " "] {
set func "::";
append func $module "::status_report";
if {"[info procs $func]" ne ""} {
$func;
}
}
}
#playMsg "Default" "press_0_for_help"
#playSilence 250;
}
#
# Executed when a short identification should be sent
# hour - The hour on which this identification occur
# minute - The minute on which this identification occur
#
proc send_short_ident {{hour -1} {minute -1}} {
global mycall;
variable CFG_TYPE;
variable short_announce_file
variable short_announce_enable
variable short_voice_id_enable
variable short_cw_id_enable
# Play voice id if enabled
if {$short_voice_id_enable} {
puts "Playing short voice ID"
spellWord $mycall;
if {$CFG_TYPE == "Repeater"} {
playMsg "Core" "repeater";
}
playSilence 500;
}
# Play announcement file if enabled
if {$short_announce_enable} {
puts "Playing short announce"
if [file exist "$short_announce_file"] {
playFile "$short_announce_file"
playSilence 500
}
}
# Play CW id if enabled
if {$short_cw_id_enable} {
puts "Playing short CW ID"
if {$CFG_TYPE == "Repeater"} {
set call "$mycall/R"
CW::play $call
} else {
CW::play $mycall
}
playSilence 500;
}
}
#
# Executed when a long identification (e.g. hourly) should be sent
# hour - The hour on which this identification occur
# minute - The minute on which this identification occur
#
proc send_long_ident {hour minute} {
global mycall;
global loaded_modules;
global active_module;
variable CFG_TYPE;
variable long_announce_file
variable long_announce_enable
variable long_voice_id_enable
variable long_cw_id_enable
# Play the voice ID if enabled
if {$long_voice_id_enable} {
puts "Playing Long voice ID"
spellWord $mycall;
if {$CFG_TYPE == "Repeater"} {
playMsg "Core" "repeater";
}
playSilence 500;
playMsg "Core" "the_time_is";
playSilence 100;
playTime $hour $minute;
playSilence 500;
# Call the "status_report" function in all modules if no module is active
if {$active_module == ""} {
foreach module [split $loaded_modules " "] {
set func "::";
append func $module "::status_report";
if {"[info procs $func]" ne ""} {
$func;
}
}
}
playSilence 500;
}
# Play announcement file if enabled
if {$long_announce_enable} {
puts "Playing long announce"
if [file exist "$long_announce_file"] {
playFile "$long_announce_file"
playSilence 500
}
}
# Play CW id if enabled
if {$long_cw_id_enable} {
puts "Playing long CW ID"
if {$CFG_TYPE == "Repeater"} {
set call "$mycall/R"
CW::play $call
} else {
CW::play $mycall
}
playSilence 100
}
}
#
# Executed when the squelch have just closed and the RGR_SOUND_DELAY timer has
# expired.
#
proc send_rgr_sound {} {
variable sql_rx_id
if {$sql_rx_id != "?"} {
# 150 CPM, 1000 Hz, -4 dBFS
CW::play $sql_rx_id 150 1000 -4
set sql_rx_id "?"
} else {
playTone 440 500 100
}
playSilence 100
}
#
# Executed when an empty macro command (i.e. D#) has been entered.
#
proc macro_empty {} {
playMsg "Core" "operation_failed";
}
#
# Executed when an entered macro command could not be found
#
proc macro_not_found {} {
playMsg "Core" "operation_failed";
}
#
# Executed when a macro syntax error occurs (configuration error).
#
proc macro_syntax_error {} {
playMsg "Core" "operation_failed";
}
#
# Executed when the specified module in a macro command is not found
# (configuration error).
#
proc macro_module_not_found {} {
playMsg "Core" "operation_failed";
}
#
# Executed when the activation of the module specified in the macro command
# failed.
#
proc macro_module_activation_failed {} {
playMsg "Core" "operation_failed";
}
#
# Executed when a macro command is executed that requires a module to
# be activated but another module is already active.
#
proc macro_another_active_module {} {
global active_module;
playMsg "Core" "operation_failed";
playMsg "Core" "active_module";
playMsg $active_module "name";
}
#
# Executed when an unknown DTMF command is entered
# cmd - The command string
#
proc unknown_command {cmd} {
spellWord $cmd;
playMsg "Core" "unknown_command";
}
#
# Executed when an entered DTMF command failed
# cmd - The command string
#
proc command_failed {cmd} {
spellWord $cmd;
playMsg "Core" "operation_failed";
}
#
# Executed when a link to another logic core is activated.
# name - The name of the link
#
proc activating_link {name} {
if {[string length $name] > 0} {
playMsg "Core" "activating_link_to";
spellWord $name;
}
}
#
# Executed when a link to another logic core is deactivated.
# name - The name of the link
#
proc deactivating_link {name} {
if {[string length $name] > 0} {
playMsg "Core" "deactivating_link_to";
spellWord $name;
}
}
#
# Executed when trying to deactivate a link to another logic core but the
# link is not currently active.
# name - The name of the link
#
proc link_not_active {name} {
if {[string length $name] > 0} {
playMsg "Core" "link_not_active_to";
spellWord $name;
}
}
#
# Executed when trying to activate a link to another logic core but the
# link is already active.
# name - The name of the link
#
proc link_already_active {name} {
if {[string length $name] > 0} {
playMsg "Core" "link_already_active_to";
spellWord $name;
}
}
#
# Executed each time the transmitter is turned on or off
# is_on - Set to 1 if the transmitter is on or 0 if it's off
#
proc transmit {is_on} {
#puts "Turning the transmitter $is_on";
variable prev_ident;
variable need_ident;
if {$is_on && ([clock seconds] - $prev_ident > 5)} {
set need_ident 1;
}
}
#
# Executed each time the squelch is opened or closed
# rx_id - The ID of the RX that the squelch opened/closed on
# is_open - Set to 1 if the squelch is open or 0 if it's closed
#
proc squelch_open {rx_id is_open} {
variable sql_rx_id;
#puts "The squelch is $is_open on RX $rx_id";
set sql_rx_id $rx_id;
}
#
# Executed when a DTMF digit has been received
# digit - The detected DTMF digit
# duration - The duration, in milliseconds, of the digit
#
# Return 1 to hide the digit from further processing in SvxLink or
# return 0 to make SvxLink continue processing as normal.
#
proc dtmf_digit_received {digit duration} {
#puts "DTMF digit \"$digit\" detected with duration $duration ms";
return 0;
}
#
# Executed when a DTMF command has been received
# cmd - The command
#
# Return 1 to hide the command from further processing is SvxLink or
# return 0 to make SvxLink continue processing as normal.
#
# This function can be used to implement your own custom commands or to disable
# DTMF commands that you do not want users to execute.
proc dtmf_cmd_received {cmd} {
#global active_module
# Example: Ignore all commands starting with 3 in the EchoLink module.
# Allow commands that have four or more digits.
#if {$active_module == "EchoLink"} {
# if {[string length $cmd] < 4 && [string index $cmd 0] == "3"} {
# puts "Ignoring random connect command for module EchoLink: $cmd"
# return 1
# }
#}
# Handle the "force core command" mode where a command is forced to be
# executed by the core command processor instead of by an active module.
# The "force core command" mode is entered by prefixing a command by a star.
#if {$active_module != "" && [string index $cmd 0] != "*"} {
# return 0
#}
#if {[string index $cmd 0] == "*"} {
# set cmd [string range $cmd 1 end]
#}
# Example: Custom command executed when DTMF 99 is received
#if {$cmd == "99"} {
# puts "Executing external command"
# playMsg "Core" "online"
# exec ls &
# return 1
#}
return 0
}
#
# Executed once every whole minute. Don't put any code here directly
# Create a new function and add it to the timer tick subscriber list
# by using the function addMinuteTickSubscriber.
#
proc every_minute {} {
variable minute_tick_subscribers;
#puts [clock format [clock seconds] -format "%Y-%m-%d %H:%M:%S"];
foreach subscriber $minute_tick_subscribers {
$subscriber;
}
}
#
# Executed once every whole minute. Don't put any code here directly
# Create a new function and add it to the timer tick subscriber list
# by using the function addSecondTickSubscriber.
#
proc every_second {} {
variable second_tick_subscribers;
#puts [clock format [clock seconds] -format "%Y-%m-%d %H:%M:%S"];
foreach subscriber $second_tick_subscribers {
$subscriber;
}
}
#
# Deprecated: Use the addMinuteTickSubscriber function instead
#
proc addTimerTickSubscriber {func} {
puts "*** WARNING: Calling deprecated TCL event handler addTimerTickSubcriber."
puts " Use addMinuteTickSubscriber instead"
addMinuteTickSubscriber $func;
}
#
# Use this function to add a function to the list of functions that
# should be executed once every whole minute. This is not an event
# function but rather a management function.
#
proc addMinuteTickSubscriber {func} {
variable minute_tick_subscribers;
lappend minute_tick_subscribers $func;
}
#
# Use this function to add a function to the list of functions that
# should be executed once every second. This is not an event
# function but rather a management function.
#
proc addSecondTickSubscriber {func} {
variable second_tick_subscribers;
lappend second_tick_subscribers $func;
}
#
# Should be executed once every whole minute to check if it is time to
# identify. Not exactly an event function. This function handle the
# identification logic and call the send_short_ident or send_long_ident
# functions when it is time to identify.
#
proc checkPeriodicIdentify {} {
variable prev_ident;
variable short_ident_interval;
variable long_ident_interval;
variable min_time_between_ident;
variable ident_only_after_tx;
variable need_ident;
global logic_name;
if {$short_ident_interval == 0} {
return;
}
set now [clock seconds];
set hour [clock format $now -format "%k"];
regexp {([1-5]?\d)$} [clock format $now -format "%M"] -> minute;
set short_ident_now \
[expr {($hour * 60 + $minute) % $short_ident_interval == 0}];
set long_ident_now 0;
if {$long_ident_interval != 0} {
set long_ident_now \
[expr {($hour * 60 + $minute) % $long_ident_interval == 0}];
}
if {$long_ident_now} {
puts "$logic_name: Sending long identification...";
send_long_ident $hour $minute;
set prev_ident $now;
set need_ident 0;
} else {
if {$now - $prev_ident < $min_time_between_ident} {
return;
}
if {$ident_only_after_tx && !$need_ident} {
return;
}
if {$short_ident_now} {
puts "$logic_name: Sending short identification...";
send_short_ident $hour $minute;
set prev_ident $now;
set need_ident 0;
}
}
}
#
# Executed when the QSO recorder is being activated
#
proc activating_qso_recorder {} {
playMsg "Core" "activating";
playMsg "Core" "qso_recorder";
}
#
# Executed when the QSO recorder is being deactivated
#
proc deactivating_qso_recorder {} {
playMsg "Core" "deactivating";
playMsg "Core" "qso_recorder";
}
#
# Executed when trying to deactivate the QSO recorder even though it's
# not active
#
proc qso_recorder_not_active {} {
playMsg "Core" "qso_recorder";
playMsg "Core" "not_active";
}
#
# Executed when trying to activate the QSO recorder even though it's
# already active
#
proc qso_recorder_already_active {} {
playMsg "Core" "qso_recorder";
playMsg "Core" "already_active";
}
#
# Executed when the timeout kicks in to activate the QSO recorder
#
proc qso_recorder_timeout_activate {} {
playMsg "Core" "timeout"
playMsg "Core" "activating";
playMsg "Core" "qso_recorder";
}
#
# Executed when the timeout kicks in to deactivate the QSO recorder
#
proc qso_recorder_timeout_deactivate {} {
playMsg "Core" "timeout"
playMsg "Core" "deactivating";
playMsg "Core" "qso_recorder";
}
#
# Executed when the user is requesting a language change
#
proc set_language {lang_code} {
global logic_name;
puts "$logic_name: Setting language $lang_code (NOT IMPLEMENTED)";
}
#
# Executed when the user requests a list of available languages
#
proc list_languages {} {
global logic_name;
puts "$logic_name: Available languages: (NOT IMPLEMENTED)";
}
#
# Executed when the node is being brought online or offline
#
proc logic_online {online} {
global mycall
variable CFG_TYPE
if {$online} {
playMsg "Core" "online";
spellWord $mycall;
if {$CFG_TYPE == "Repeater"} {
playMsg "Core" "repeater";
}
}
}
#
# Executed when a configuration variable is updated at runtime in the logic
# core
#
proc config_updated {tag value} {
#puts "Configuration variable updated: $tag=$value"
}
#
# Executed when a DTMF command is received from another linked logic core
#
# logic -- The name of the logic core
# cmd -- The received command
#
proc remote_cmd_received {logic cmd} {
#puts "Remote command received from logic $logic: $cmd"
#playDtmf "$cmd" "500" "50"
}
#
# Executed when a talkgroup is received from another linked logic core
#
# logic -- The name of the logic core
# tg -- The received talkgroup
#
proc remote_received_tg_updated {logic tg} {
#puts "Remote TG received from logic $logic: $tg"
#if {$tg > 0} {
# playDtmf "1$tg" "500" "50"
#}
}
##############################################################################
#
# Main program
#
##############################################################################
if [info exists CFG_SHORT_IDENT_INTERVAL] {
if {$CFG_SHORT_IDENT_INTERVAL > 0} {
set short_ident_interval $CFG_SHORT_IDENT_INTERVAL;
}
}
if [info exists CFG_LONG_IDENT_INTERVAL] {
if {$CFG_LONG_IDENT_INTERVAL > 0} {
set long_ident_interval $CFG_LONG_IDENT_INTERVAL;
if {$short_ident_interval == 0} {
set short_ident_interval $long_ident_interval;
}
}
}
if [info exists CFG_IDENT_ONLY_AFTER_TX] {
if {$CFG_IDENT_ONLY_AFTER_TX > 0} {
set ident_only_after_tx $CFG_IDENT_ONLY_AFTER_TX;
}
}
if [info exists CFG_SHORT_ANNOUNCE_ENABLE] {
set short_announce_enable $CFG_SHORT_ANNOUNCE_ENABLE
}
if [info exists CFG_SHORT_ANNOUNCE_FILE] {
set short_announce_file $CFG_SHORT_ANNOUNCE_FILE
}
if [info exists CFG_SHORT_VOICE_ID_ENABLE] {
set short_voice_id_enable $CFG_SHORT_VOICE_ID_ENABLE
}
if [info exists CFG_SHORT_CW_ID_ENABLE] {
set short_cw_id_enable $CFG_SHORT_CW_ID_ENABLE
}
if [info exists CFG_LONG_ANNOUNCE_ENABLE] {
set long_announce_enable $CFG_LONG_ANNOUNCE_ENABLE
}
if [info exists CFG_LONG_ANNOUNCE_FILE] {
set long_announce_file $CFG_LONG_ANNOUNCE_FILE
}
if [info exists CFG_LONG_VOICE_ID_ENABLE] {
set long_voice_id_enable $CFG_LONG_VOICE_ID_ENABLE
}
if [info exists CFG_LONG_CW_ID_ENABLE] {
set long_cw_id_enable $CFG_LONG_CW_ID_ENABLE
}
# end of namespace
}
#
# This file has not been truncated
#
++++
++++ EchoLink.tcl |
###############################################################################
#
# EchoLink module event handlers
#
###############################################################################
#
# This is the namespace in which all functions and variables below will exist.
# The name must match the configuration variable "NAME" in the
# [ModuleEchoLink] section in the configuration file. The name may be changed
# but it must be changed in both places.
#
namespace eval EchoLink {
#
# Check if this module is loaded in the current logic core
#
if {![info exists CFG_ID]} {
return;
}
#
# Extract the module name from the current namespace
#
set module_name [namespace tail [namespace current]];
#
# An "overloaded" playMsg that eliminates the need to write the module name
# as the first argument.
#
proc playMsg {msg} {
variable module_name;
::playMsg $module_name $msg;
}
#
# A convenience function for printing out information prefixed by the
# module name
#
proc printInfo {msg} {
variable module_name;
puts "$module_name: $msg";
}
#
# This variable is updated by the EchoLink module when a station connects or
# disconnects. It contains the number of currently connected stations.
#
variable num_connected_stations 0;
#
# Executed when this module is being activated
#
proc activating_module {} {
variable module_name;
Module::activating_module $module_name;
}
#
# Executed when this module is being deactivated.
#
proc deactivating_module {} {
variable module_name;
Module::deactivating_module $module_name;
}
#
# Executed when the inactivity timeout for this module has expired.
#
proc timeout {} {
variable module_name;
Module::timeout $module_name;
}
#
# Executed when playing of the help message for this module has been requested.
#
proc play_help {} {
variable module_name;
Module::play_help $module_name;
}
#
# Spell an EchoLink callsign
#
proc spellEchoLinkCallsign {call} {
global langdir
if [regexp {^(\w+)-L$} $call ignored callsign] {
spellWord $callsign
playSilence 50
playMsg "link"
} elseif [regexp {^(\w+)-R$} $call ignored callsign] {
spellWord $callsign
playSilence 50
playMsg "repeater"
} elseif [regexp {^\*(.+)\*$} $call ignored name] {
playMsg "conference"
playSilence 50
set lc_name [string tolower $name]
if [file exists "$langdir/EchoLink/conf-$lc_name.wav"] {
playFile "$langdir/EchoLink/conf-$lc_name.wav"
} else {
spellEchoLinkCallsign $name
}
} else {
spellWord $call
}
}
#
# Executed when a request to list all connected stations is received.
# That is, someone press DTMF "1#" when the EchoLink module is active.
#
proc list_connected_stations {connected_stations} {
playNumber [llength $connected_stations];
playSilence 50;
playMsg "connected_stations";
foreach {call} "$connected_stations" {
spellEchoLinkCallsign $call;
playSilence 250;
}
}
#
# Executed when someone tries to setup an outgoing EchoLink connection but
# the directory server is offline due to communications failure.
#
proc directory_server_offline {} {
playMsg "directory_server_offline";
}
#
# Executed when the limit for maximum number of QSOs has been reached and
# an outgoing connection request is received.
#
proc no_more_connections_allowed {} {
# FIXME: Change the message to something that makes more sense...
playMsg "link_busy";
}
#
# Executed when a status report is requested. This usually happens at
# manual identification when the user press DTMF "*".
#
proc status_report {} {
variable num_connected_stations;
variable module_name;
global active_module;
if {$active_module == $module_name} {
playNumber $num_connected_stations;
playMsg "connected_stations";
}
}
#
# Executed when an EchoLink id cannot be found in an outgoing connect request.
#
proc station_id_not_found {station_id} {
playNumber $station_id;
playMsg "not_found";
}
#
# Executed when the lookup of an EchoLink callsign fail in an outgoing connect
# request.
#
proc lookup_failed {station_id} {
playMsg "operation_failed";
}
#
# Executed when a local user tries to connect to the local node.
#
proc self_connect {} {
playMsg "operation_failed";
}
#
# Executed when a local user tries to connect to a node that is already
# connected.
#
proc already_connected_to {call} {
playMsg "already_connected_to";
playSilence 50;
spellEchoLinkCallsign $call;
}
#
# Executed when an internal error occurs.
#
proc internal_error {} {
playMsg "operation_failed";
}
#
# Executed when an outgoing connection has been requested.
#
proc connecting_to {call} {
playMsg "connecting_to";
spellEchoLinkCallsign $call;
playSilence 500;
}
#
# Executed when an EchoLink connection has been terminated
#
proc disconnected {call} {
spellEchoLinkCallsign $call;
playMsg "disconnected";
playSilence 500;
}
#
# Executed when an incoming EchoLink connection has been accepted.
#
proc remote_connected {call} {
playMsg "connected";
spellEchoLinkCallsign $call;
playSilence 500;
}
#
# Executed when an outgoing connection has been established.
# call - The callsign of the remote station
#
proc connected {call} {
#puts "Outgoing Echolink connection to $call established"
playMsg "connected";
playSilence 500;
}
#
# Executed when the list of connected remote EchoLink clients changes
# client_list - List of connected clients
#
proc client_list_changed {client_list} {
#foreach {call} $client_list {
# puts $call
#}
}
#
# Executed when the EchoLink connection has been idle for too long. The
# connection will be terminated.
#
proc link_inactivity_timeout {} {
playMsg "timeout";
}
#
# Executed when a too short connect by callsign command is received
#
proc cbc_too_short_cmd {cmd} {
spellWord $cmd;
playSilence 50;
playMsg "operation_failed";
}
#
# Executed when the connect by callsign function cannot find a match
#
proc cbc_no_match {code} {
playNumber $code;
playSilence 50;
playMsg "no_match";
}
#
# Executed when the connect by callsign list has been retrieved
#
proc cbc_list {call_list} {
playMsg "choose_station";
set idx 0;
foreach {call} $call_list {
incr idx;
playSilence 500;
playNumber $idx;
playSilence 200;
spellEchoLinkCallsign $call;
}
}
#
# Executed when the connect by callsign function is manually aborted
#
proc cbc_aborted {} {
playMsg "aborted";
}
#
# Executed when an out of range index is entered in the connect by callsign
# list
#
proc cbc_index_out_of_range {idx} {
playNumber $idx;
playSilence 50;
playMsg "idx_out_of_range";
}
#
# Executed when there are more than nine matches in the connect by
# callsign function
#
proc cbc_too_many_matches {} {
playMsg "too_many_matches";
}
#
# Executed when no station have been chosen in 60 seconds in the connect
# by callsign function
#
proc cbc_timeout {} {
playMsg "aborted";
}
#
# Executed when the disconnect by callsign list has been retrieved
#
proc dbc_list {call_list} {
playMsg "disconnect_by_callsign";
playSilence 200
playMsg "choose_station";
set idx 0;
foreach {call} $call_list {
incr idx;
playSilence 500;
playNumber $idx;
playSilence 200;
spellEchoLinkCallsign $call;
}
}
#
# Executed when the disconnect by callsign function is manually aborted
#
proc dbc_aborted {} {
playMsg "disconnect_by_callsign";
playMsg "aborted";
}
#
# Executed when an out of range index is entered in the disconnect by callsign
# list
#
proc dbc_index_out_of_range {idx} {
playNumber $idx;
playSilence 50;
playMsg "idx_out_of_range";
}
#
# Executed when no station have been chosen in 60 seconds in the disconnect
# by callsign function
#
proc dbc_timeout {} {
playMsg "disconnect_by_callsign";
playMsg "timeout";
}
#
# Executed when a local user enter the DTMF code for playing back the
# local node ID.
#
proc play_node_id {my_node_id} {
playMsg "node_id_is";
playSilence 200;
if { $my_node_id != 0} {
playNumber $my_node_id;
} else {
playMsg "unknown";
}
}
#
# Executed when an entered command failed or have bad syntax.
#
proc command_failed {cmd} {
spellWord $cmd;
playMsg "operation_failed";
}
#
# Executed when an unrecognized command has been received.
#
proc unknown_command {cmd} {
spellWord $cmd;
playMsg "unknown_command";
}
#
# Executed when the listen only feature is activated or deactivated
# status - The current status of the feature (0=deactivated, 1=activated)
# activate - The requested new status of the feature
# (0=deactivate, 1=activate)
#
proc listen_only {status activate} {
variable module_name;
if {$status == $activate} {
playMsg "listen_only";
playMsg [expr {$status ? "already_active" : "not_active"}];
} else {
puts "$module_name: [expr {$activate ? "Activating" : "Deactivating"}]\
listen only mode.";
playMsg [expr {$activate ? "activating" : "deactivating"}];
playMsg "listen_only";
}
}
#
# Executed when an outgoing connection is rejected. This can happen if
# REJECT_OUTGOING and/or ACCEPT_OUTGOING has been setup.
#
proc reject_outgoing_connection {call} {
spellEchoLinkCallsign $call;
playSilence 50;
playMsg "reject_connection";
}
#
# Executed when a transmission from an EchoLink station is starting
# or stopping
# rx - 1 if receiving or 0 if not
# call - The callsign of the remote station
#
#
proc is_receiving {rx call} {
if {$rx == 0} {
playTone 1000 100 100;
}
}
#
# Executed when a chat message is received from a remote station
#
# msg -- The message text
#
# WARNING: This is a slightly dangerous function since unexepected input
# may open up a security flaw. Make sure that the message string is handled
# as unknown data that can contain anything. Check it thoroughly before
# using it. Do not run SvxLink as user root.
proc chat_received {msg} {
#puts $msg
}
#
# Executed when an info message is received from a remote station
#
# call -- The callsign of the sending station
# msg -- The message text
#
# WARNING: This is a slightly dangerous function since unexepected input
# may open up a security flaw. Make sure that the message string is handled
# as unknown data that can contain anything. Check it thoroughly before
# using it. Do not run SvxLink as user root.
proc info_received {call msg} {
#puts "$call: $msg"
}
#
# Executed when a configuration variable is updated at runtime
#
proc config_updated {tag value} {
#puts "Configuration variable updated: $tag=$value"
}
#-----------------------------------------------------------------------------
# The events below are for remote EchoLink announcements. Sounds are not
# played over the local transmitter but are sent to the remote station.
#-----------------------------------------------------------------------------
#
# Executed when an incoming connection is accepted
#
proc remote_greeting {call} {
# playSilence 1000;
# playMsg "greeting";
}
#
# Executed when an incoming connection is rejected
#
proc reject_remote_connection {perm} {
playSilence 1000;
if {$perm} {
playMsg "reject_connection";
} else {
playMsg "reject_connection";
playMsg "please_try_again_later"
}
playSilence 1000;
}
#
# Executed when the inactivity timer times out
#
proc remote_timeout {} {
playMsg "timeout";
playSilence 1000;
}
#
# Executed when the squelch state changes
#
proc squelch_open {is_open} {
# The listen_only_active and CFG_REMOTE_RGR_SOUND global variables are set by
# the C++ code
variable listen_only_active
variable CFG_REMOTE_RGR_SOUND
if {$CFG_REMOTE_RGR_SOUND && !$is_open && !$listen_only_active} {
playSilence 200
playTone 1000 100 100
}
}
# end of namespace
}
#
# This file has not been truncated
#
++++
//[[gm4slv@gm4slv.plus.com|John Pumford-Green]] Tue May 3 20:58:10 2022//
Page Updated : ~~LASTMOD~~
{{tag>svxlink mb7aze radio}}