mirror of
https://github.com/AG7GN/nexus-utilities.git
synced 2025-05-15 14:10:09 -07:00
773 lines
24 KiB
Bash
Executable File
773 lines
24 KiB
Bash
Executable File
#!/bin/bash
|
|
#================================================================
|
|
# HEADER
|
|
#================================================================
|
|
#% SYNOPSIS
|
|
#+ ${SCRIPT_NAME} [-hv]
|
|
#+ ${SCRIPT_NAME} [-c FILE] start COMMAND [COMMAND ...]
|
|
#+ ${SCRIPT_NAME} stop
|
|
#%
|
|
#% DESCRIPTION
|
|
#% This script will start direwolf in one of 3 APRS modes: igate, digipeater,
|
|
#% or igate + digipeater, OR in AX.25 mode as a TNC for Winlink or other apps.
|
|
#% Use the companion script watchdog-tnc.sh in crontab to launch this script
|
|
#% and keep it running.
|
|
#%
|
|
#% OPTIONS
|
|
#% -c FILE, --config=FILE
|
|
#% Override using the default configuration file.
|
|
#% Default configuration file is $HOME/tnc.conf
|
|
#%
|
|
#% -h, --help Print this help
|
|
#% -v, --version Print script information
|
|
#%
|
|
#% COMMANDS
|
|
#% ${SCRIPT_NAME} [-c FILE] start ax25|ax25+pat [1200|9600 [2]]
|
|
#% Starts the ax25 TNC or the ax25 TNC and pat email
|
|
#% client."
|
|
#% Note that pat requires configuration in
|
|
#% $HOME/.wl2k/config.json.
|
|
#%
|
|
#% Direwolf baud set to 1200 bps (for V/UHF) on a single
|
|
#% audio channel by default.
|
|
#% You can optionally specify baud (1200 or 9600) and
|
|
#% number of audio channels. 9600 might work on V/UHF
|
|
#% with another 9600 station depending on conditions and
|
|
#% the capabilities of your soundcard. 9600 will likely
|
|
#% not work with a Signalink.
|
|
#% If you specify the baud, you can optionally also
|
|
#% specify '2' to tell Direwolf to use both channels.
|
|
#% '2' assumes" you have a stereo audio card *and* direwolf
|
|
#% is configured to use both channels of the stereo sound
|
|
#% card.
|
|
#% Winlink clients can access Direwolf's second channel by
|
|
#% selecting Packet TNC Type 'KISS Port 2' in Winlink.
|
|
#% Default is a single channel.
|
|
#% 1200 baud uses Direwolf's AFSK 1200 & 2200 Hz modem.
|
|
#% 9600 baud uses Direwolf's K9NG/G3RUH modem.
|
|
#%
|
|
#% ${SCRIPT_NAME} [-c FILE] start pat
|
|
#% Starts pat email client in telnet mode only (niether
|
|
#% ax25 nor ARDOP TNC is started).
|
|
#% Note that pat requires configuration in
|
|
#% $HOME/.wl2k/config.json.
|
|
#%
|
|
#% ${SCRIPT_NAME} [-c FILE] start ardop|ardop+pat
|
|
#% Starts the ARDOP TNC (piardop2) or the ARDOP TNC and
|
|
#% pat. Note that pat requires configuration in
|
|
#% $HOME/.wl2k/config.json.
|
|
#%
|
|
#% ${SCRIPT_NAME} [-c FILE] start digiigate [both]
|
|
#% Starts the Direwolf APRS digipeater and iGate.
|
|
#% If you specify 'both', Direwolf will decode audio on
|
|
#% channel 1 (stereo left) and channel 2 (stereo right)
|
|
#% on stereo sound cards only.
|
|
#%
|
|
#% ${SCRIPT_NAME} [-c FILE] start digi [both]
|
|
#% Starts the Direwolf APRS digipeater (only).
|
|
#% If you specify 'both', Direwolf will decode audio on
|
|
#% channel 1 (stereo left) and channel 2 (stereo right)
|
|
#% on stereo sound cards only.
|
|
#%
|
|
#% ${SCRIPT_NAME} [-c FILE] start igate [both]
|
|
#% Starts the Direwolf APRS iGate (only).
|
|
#% If you specify 'both', Direwolf will decode audio on
|
|
#% channel 1 (stereo left) and channel 2 (stereo right)
|
|
#% on stereo sound cards only.
|
|
#%
|
|
#% ${SCRIPT_NAME} stop
|
|
#% Stops all the apps. Same as pressing Ctrl-C.
|
|
#%
|
|
#% EXAMPLES
|
|
#%
|
|
#% Locate serial port file name containing ${DEFAULT_PORTSTRING} (default search string),
|
|
#% then set APO to 30 minutes:
|
|
#%
|
|
#% ${SCRIPT_NAME} set apo 30
|
|
#%
|
|
#% Override the default search string ${DEFAULT_PORTSTRING} to locate serial port
|
|
#% connected to radio, then get radio information:
|
|
#%
|
|
#% ${SCRIPT_NAME} -s Prolific_Technology get info
|
|
#%
|
|
#% Specify the serial port used to connect to your radio then set radio TX timeout
|
|
#% to 3 minutes:
|
|
#%
|
|
#% ${SCRIPT_NAME} -p /dev/ttyUSB0 set timeout 3
|
|
#%
|
|
#================================================================
|
|
#- IMPLEMENTATION
|
|
#- version ${SCRIPT_NAME} 3.3.9
|
|
#- author Steve Magnuson, AG7GN
|
|
#- license CC-BY-SA Creative Commons License
|
|
#- script_id 0
|
|
#-
|
|
#================================================================
|
|
# HISTORY
|
|
# 20180125 : Steve Magnuson : Script creation
|
|
# 20200203 : Steve Magnuson : New script template
|
|
#
|
|
#================================================================
|
|
# DEBUG OPTION
|
|
# set -n # Uncomment to check your syntax, without execution.
|
|
# set -x # Uncomment to debug this shell script
|
|
#
|
|
#================================================================
|
|
# END_OF_HEADER
|
|
#================================================================
|
|
|
|
SYNTAX=false
|
|
DEBUG=false
|
|
|
|
#============================
|
|
# FUNCTIONS
|
|
#============================
|
|
|
|
function TrapCleanup () {
|
|
${SCRIPT_NAME} stop
|
|
exit 0
|
|
}
|
|
|
|
function SafeExit () {
|
|
rm -f /tmp/tnc*
|
|
rm -f $CONFFILE
|
|
exit
|
|
}
|
|
|
|
function ScriptInfo () {
|
|
HEAD_FILTER="^#-"
|
|
[[ "$1" = "usage" ]] && HEAD_FILTER="^#+"
|
|
[[ "$1" = "full" ]] && HEAD_FILTER="^#[%+]"
|
|
[[ "$1" = "version" ]] && HEAD_FILTER="^#-"
|
|
head -${SCRIPT_HEADSIZE:-99} ${0} | grep -e "${HEAD_FILTER}" | \
|
|
sed -e "s/${HEAD_FILTER}//g" \
|
|
-e "s/\${SCRIPT_NAME}/${SCRIPT_NAME}/g"
|
|
}
|
|
|
|
function Usage () {
|
|
printf "Usage:\n"
|
|
ScriptInfo usage
|
|
exit 0
|
|
}
|
|
|
|
function Die () {
|
|
echo "${*}"
|
|
exit 1
|
|
}
|
|
|
|
#---------------------------------------
|
|
|
|
function checkApp () {
|
|
APP="$(command -v $1 2>/dev/null)"
|
|
if [[ $APP == "" ]]
|
|
then
|
|
Die "Error: $1 is required but not installed."
|
|
fi
|
|
echo "$APP"
|
|
}
|
|
|
|
function aprsPasscode () {
|
|
# Generates the APRS website passcode from the supplied callsign
|
|
CALL="$(echo ${1^^} | cut -d'-' -f1)"
|
|
H="0x73e2"
|
|
declare -i LEN=${#CALL}
|
|
declare -i I=0
|
|
while [ $I -lt $LEN ]
|
|
do
|
|
H=$(( $H ^ $(($(printf '%d' "'${CALL:$I:2}") << 8)) ))
|
|
H=$(( $H ^ $(printf '%d' "'${CALL:$(( I+1 )):2}") ))
|
|
(( I+=2 ))
|
|
done
|
|
echo -n $(( $H & 0x7fff ))
|
|
}
|
|
|
|
function checkSoundCard () {
|
|
# Checks for the presence of the requested sound card
|
|
if [[ $AUDIO_DEV != "" ]]
|
|
then
|
|
CAP_DEV="$AUDIO_DEV"
|
|
elif [[ $AUDIO_DEV_SEARCH_STRING == "" ]]
|
|
then
|
|
Die "Error: You must set either the AUDIO_DEV or AUDIO_DEV_SEARCH_STRING variables in this script to select the sound card."
|
|
else
|
|
CAP_DEV="$($ARECORD -l | grep -i "$AUDIO_DEV_SEARCH_STRING" | grep "card [0-9]\|device [0-9]" | sed 's/:.*,/,/;s/:.*$//;s/, /,/;s/ /=/g;s/ice//' | tr -s [:lower:] [:upper:])"
|
|
if [[ $CAP_DEV == "" ]]
|
|
then
|
|
Die "Error: Unable to find audio interface using string $AUDIO_DEV_SEARCH_STRING."
|
|
fi
|
|
CAP_DEV="plughw:$CAP_DEV"
|
|
fi
|
|
}
|
|
|
|
function makeConfig() {
|
|
# direwolf.conf parameters
|
|
ADEVICE="$CAP_DEV"
|
|
CONFFILE="$(mktemp)"
|
|
case "$1" in
|
|
digi*|igate)
|
|
PASSCODE="$(aprsPasscode $MYCALL)"
|
|
case "$SPEED" in
|
|
both) # Decode stereo right (channel 1) and stereo left (channel 0)
|
|
FROM_CHANNEL="1"
|
|
TO_CHANNEL="0"
|
|
cat >> $CONFFILE << EOF
|
|
ADEVICE $ADEVICE
|
|
ACHANNELS 2
|
|
CHANNEL 0
|
|
$PTT0
|
|
MYCALL $MYCALL
|
|
MODEM 1200
|
|
CHANNEL 1
|
|
$PTT1
|
|
MYCALL $MYCALL
|
|
MODEM 1200
|
|
EOF
|
|
;;
|
|
*) # Decode stereo left only
|
|
FROM_CHANNEL="0"
|
|
TO_CHANNEL="0"
|
|
cat >> $CONFFILE << EOF
|
|
ADEVICE $ADEVICE
|
|
ACHANNELS 1
|
|
CHANNEL 0
|
|
$PTT0
|
|
MYCALL $MYCALL
|
|
MODEM 1200
|
|
EOF
|
|
;;
|
|
esac
|
|
case "$1" in
|
|
digi*) # digipeater+igate or digipeater
|
|
if [[ $1 == "digi" ]] # digipeat ONLY
|
|
then
|
|
IGLOGIN=""
|
|
PBEACONIG=""
|
|
IGTXVIA=""
|
|
COMMENT="$COMMENTCALL Digipeater | $LOC"
|
|
else # Digipeater + iGate
|
|
# IGTXVIA is set at the top of the script
|
|
COMMENT="$COMMENTCALL Digipeater+iGate | $LOC"
|
|
PBEACONIG="PBEACON sendto=IG delay=$IGDELAY every=$IGEVERY symbol=\"igate\" overlay=T lat=$LAT long=$LONG COMMENT=\"$COMMENT\""
|
|
IGLOGIN="IGLOGIN $MYCALL $PASSCODE"
|
|
fi
|
|
DIGIPEAT="DIGIPEAT $FROM_CHANNEL $TO_CHANNEL ^WIDE[3-7]-[1-7]$|^TEST$ ^WIDE[12]-[12]$ TRACE"
|
|
PBEACON="PBEACON delay=$DIGIPEATDELAY every=$DIGIPEATEVERY symbol=\"digi\" overlay=S lat=$LAT long=$LONG POWER=$POWER HEIGHT=$HEIGHT GAIN=$GAIN COMMENT=\"$COMMENT\" via=$HOPS"
|
|
;;
|
|
*) # iGate
|
|
PBEACON=""
|
|
DIGIPEAT=""
|
|
IGTXVIA=""
|
|
COMMENT="$COMMENTCALL iGate | $LOC"
|
|
PBEACONIG="PBEACON sendto=IG delay=$IGDELAY every=$IGEVERY symbol=\"igate\" overlay=R lat=$LAT long=$LONG COMMENT=\"$COMMENT\""
|
|
IGLOGIN="IGLOGIN $MYCALL $PASSCODE"
|
|
;;
|
|
esac
|
|
cat >> $CONFFILE << EOF
|
|
$AGWPORT
|
|
$KISSPORT
|
|
$PBEACONIG
|
|
$PBEACON
|
|
$DIGIPEAT
|
|
$IGTXVIA
|
|
$IGLOGIN
|
|
$FILTER
|
|
$IGSERVER
|
|
$IGTXLIMIT
|
|
$IGFILTER
|
|
EOF
|
|
;;
|
|
ax25)
|
|
case "$SPEED" in
|
|
1200|9600)
|
|
case "$AUDIO_CHANNELS" in
|
|
2) # Assumes stereo input - use both channels
|
|
if [[ $PTT0 =~ "GPIO" ]]
|
|
then # Allow only one radio at a time to transmit
|
|
TXINH0="TXINH $(echo $PTT1 | sed 's/PTT //')"
|
|
TXINH1="TXINH $(echo $PTT0 | sed 's/PTT //')"
|
|
else
|
|
TXINH0=""
|
|
TXINH1=""
|
|
fi
|
|
cat > $CONFFILE << EOF
|
|
ADEVICE $ADEVICE
|
|
ACHANNELS 2
|
|
CHANNEL 0
|
|
MODEM $SPEED
|
|
$PTT0
|
|
$TXINH0
|
|
MYCALL $MYCALL
|
|
CHANNEL 1
|
|
MODEM $SPEED
|
|
$PTT1
|
|
$TXINH1
|
|
MYCALL $MYCALL
|
|
$AGWPORT
|
|
$KISSPORT
|
|
EOF
|
|
;;
|
|
*) # Use only left channel
|
|
cat > $CONFFILE << EOF
|
|
ADEVICE $ADEVICE
|
|
ACHANNELS 1
|
|
CHANNEL 0
|
|
MODEM $SPEED
|
|
$PTT0
|
|
MYCALL $MYCALL
|
|
$AGWPORT
|
|
$KISSPORT
|
|
EOF
|
|
;;
|
|
esac
|
|
;;
|
|
*)
|
|
Die "Error: Valid baud settings are 1200 or 9600."
|
|
;;
|
|
esac
|
|
;;
|
|
ardop)
|
|
CONFFILE=""
|
|
;;
|
|
*)
|
|
;;
|
|
esac
|
|
echo "$CONFFILE"
|
|
}
|
|
|
|
|
|
function checkSerial () {
|
|
if [[ $DEVSTRING == "" ]]
|
|
then # No rig defined. Don't use rigctld or ARDOP CAT commands to key radio
|
|
CMDS[rigctld]=""
|
|
else
|
|
SERIAL_PORT="$(find -P /dev/serial/by-id -maxdepth 1 -type l -exec echo -n "{} -> " \; -exec readlink {} \; | \
|
|
grep "$DEVSTRING" | cut -d' ' -f3 | tr -d './')"
|
|
if [[ $SERIAL_PORT == "" ]]
|
|
then # rigctl or ardop CAT control requested, but could not find serial port
|
|
Die "Error: Could not locate serial device with name containing \"$DEVSTRING\"."
|
|
fi
|
|
DEVICE="/dev/$SERIAL_PORT"
|
|
if [[ $RIGCTL_RADIO != "" ]]
|
|
then
|
|
CMDS[rigctld]="$(command -v rigctld) -m $RIGCTL_RADIO -r $DEVICE -s $RIGCTL_SPEED"
|
|
else
|
|
CMDS[rigctld]=""
|
|
fi
|
|
fi
|
|
}
|
|
|
|
#============================
|
|
# FILES AND VARIABLES
|
|
#============================
|
|
|
|
#== general variables ==#
|
|
SCRIPT_NAME="$(basename ${0})" # scriptname without path
|
|
SCRIPT_DIR="$( cd $(dirname "$0") && pwd )" # script directory
|
|
SCRIPT_FULLPATH="${SCRIPT_DIR}/${SCRIPT_NAME}"
|
|
SCRIPT_ID="$(ScriptInfo | grep script_id | tr -s ' ' | cut -d' ' -f3)"
|
|
SCRIPT_HEADSIZE=$(grep -sn "^# END_OF_HEADER" ${0} | head -1 | cut -f1 -d:)
|
|
|
|
TNC_CONFIG_FILE=""
|
|
LOGFILE="/tmp/tnc.log"
|
|
SCREENCONFIG="/tmp/tnc.sh.screenrc"
|
|
cat > $SCREENCONFIG << EOF
|
|
logfile $LOGFILE
|
|
logfile flush 1
|
|
logtstamp on
|
|
logtstamp after 60
|
|
log on
|
|
logtstamp string "[ %n:%t ] ---- TIMESTAMP ---- %Y-%m-%d %c:%s ---- Press Ctrl-C to Quit\012"
|
|
EOF
|
|
VERSION="$(ScriptInfo version | grep version | tr -s ' ' | cut -d' ' -f 4)"
|
|
|
|
#============================
|
|
# PARSE OPTIONS WITH GETOPTS
|
|
#============================
|
|
Optnum=$#
|
|
|
|
#== set short options ==#
|
|
SCRIPT_OPTS=':hc:v-:'
|
|
|
|
#== set long options associated with short one ==#
|
|
typeset -A ARRAY_OPTS
|
|
ARRAY_OPTS=(
|
|
[help]=h
|
|
[config]=c
|
|
[version]=v
|
|
)
|
|
|
|
LONG_OPTS="^($(echo "${!ARRAY_OPTS[@]}" | tr ' ' '|'))="
|
|
|
|
# Parse options
|
|
while getopts ${SCRIPT_OPTS} OPTION
|
|
do
|
|
# Translate long options to short
|
|
if [[ "x$OPTION" == "x-" ]]
|
|
then
|
|
LONG_OPTION=$OPTARG
|
|
LONG_OPTARG=$(echo $LONG_OPTION | egrep "$LONG_OPTS" | cut -d'=' -f2-)
|
|
LONG_OPTIND=-1
|
|
[[ "x$LONG_OPTARG" = "x" ]] && LONG_OPTIND=$OPTIND || LONG_OPTION=$(echo $OPTARG | cut -d'=' -f1)
|
|
[[ $LONG_OPTIND -ne -1 ]] && eval LONG_OPTARG="\$$LONG_OPTIND"
|
|
OPTION=${ARRAY_OPTS[$LONG_OPTION]}
|
|
[[ "x$OPTION" = "x" ]] && OPTION="?" OPTARG="-$LONG_OPTION"
|
|
|
|
if [[ $( echo "${SCRIPT_OPTS}" | grep -c "${OPTION}:" ) -eq 1 ]]
|
|
then
|
|
if [[ "x${LONG_OPTARG}" = "x" ]] || [[ "${LONG_OPTARG}" = -* ]]
|
|
then
|
|
OPTION=":" OPTARG="-$LONG_OPTION"
|
|
else
|
|
OPTARG="$LONG_OPTARG";
|
|
if [[ $LONG_OPTIND -ne -1 ]]
|
|
then
|
|
[[ $OPTIND -le $Optnum ]] && OPTIND=$(( $OPTIND+1 ))
|
|
shift $OPTIND
|
|
OPTIND=1
|
|
fi
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
# Options followed by another option instead of argument
|
|
if [[ "x${OPTION}" != "x:" ]] && [[ "x${OPTION}" != "x?" ]] && [[ "${OPTARG}" = -* ]]
|
|
then
|
|
OPTARG="$OPTION" OPTION=":"
|
|
fi
|
|
|
|
# Finally, manage options
|
|
case "$OPTION" in
|
|
h)
|
|
ScriptInfo full
|
|
exit 0
|
|
;;
|
|
c)
|
|
TNC_CONFIG_FILE="$OPTARG"
|
|
[[ -s "$TNC_CONFIG_FILE" ]] || Die "Configuration file $TNC_CONFIG_FILE is missing or empty."
|
|
;;
|
|
v)
|
|
ScriptInfo version
|
|
exit 0
|
|
;;
|
|
:)
|
|
Die "${SCRIPT_NAME}: -$OPTARG: option requires an argument"
|
|
;;
|
|
?)
|
|
Die "${SCRIPT_NAME}: -$OPTARG: unknown option"
|
|
;;
|
|
esac
|
|
done
|
|
shift $((${OPTIND} - 1)) ## shift options
|
|
|
|
#============================
|
|
# MAIN SCRIPT
|
|
#============================
|
|
|
|
# Trap bad exits with cleanup function
|
|
trap TrapCleanup INT
|
|
trap SafeExit TERM EXIT
|
|
|
|
# Exit on error. Append '||true' when you run the script if you expect an error.
|
|
set -o errexit
|
|
|
|
# Check Syntax if set
|
|
$SYNTAX && set -n
|
|
# Run in debug mode, if set
|
|
$DEBUG && set -x
|
|
|
|
# No configuration file supplied, so use the default
|
|
[[ $TNC_CONFIG_FILE == "" ]] && TNC_CONFIG_FILE="$HOME/tnc.conf"
|
|
|
|
source $TNC_CONFIG_FILE
|
|
[[ $MYCALL =~ N0CALL || $MYCALL =~ N0ONE || $MYCALL == "" ]] && Die "You must set the MYCALL variable in $TNC_CONFIG_FILE."
|
|
|
|
ACTION="${1,,}" # start|stop
|
|
DMODE="${2,,}" # direwolf mode: digi,igate,digi+igate,ax25,ax25+pat
|
|
SPEED="${3,,}" # speed. No value implies 1200. Otherwise, allowed values are 300 or 9600.
|
|
AUDIO_CHANNELS="${4}"
|
|
|
|
[[ $SPEED == "" ]] && SPEED="1200"
|
|
[[ $AUDIO_CHANNELS == "" ]] && AUDIO_CHANNELS="1"
|
|
|
|
declare -a ORDERS
|
|
declare -A CMDS
|
|
CMDS[direwolf]="$(command -v direwolf) -a $AUDIOSTATS -t $COLORS -r $ARATE"
|
|
|
|
SCREEN="$(checkApp screen)"
|
|
ARECORD="$(checkApp arecord)"
|
|
WGET="$(checkApp wget)"
|
|
case "$ACTION" in
|
|
start)
|
|
[[ $DMODE == "" ]] && Usage
|
|
checkSoundCard
|
|
echo "" > $LOGFILE
|
|
echo
|
|
echo "Version $VERSION"
|
|
echo
|
|
echo "Running $0 $ACTION $DMODE $SPEED $AUDIO_CHANNELS"
|
|
echo "Using configuration file $TNC_CONFIG_FILE"
|
|
echo "Mode: $DMODE Speed: $SPEED Audio Device: $CAP_DEV Audio Channels: $AUDIO_CHANNELS"
|
|
echo
|
|
case "$DMODE" in
|
|
pat)
|
|
checkSerial
|
|
if [[ ${CMDS[rigctld]} == "" ]]
|
|
then
|
|
echo "rigctld will not be used."
|
|
ORDERS=( pat )
|
|
else
|
|
echo "rigctld will use radio found on $DEVICE."
|
|
ORDERS=( rigctld pat )
|
|
fi
|
|
echo "NOTE: If you haven't already done so, you must run 'pat configure' or manually"
|
|
echo " configure $HOME/.wl2k/config.json to use pat."
|
|
echo
|
|
CMDS[pat]="$(command -v pat) -l telnet http"
|
|
for i in ${!ORDERS[@]}
|
|
do
|
|
$SCREEN -c $SCREENCONFIG -L -d -m -S ${ORDERS[$i]} ${CMDS[${ORDERS[$i]}]}
|
|
echo "============================"
|
|
done
|
|
screen -list
|
|
echo
|
|
sleep 2
|
|
rm -f $CONFFILE
|
|
if [[ $GRID != "" ]]
|
|
then
|
|
if $WGET -q --tries=2 --timeout=5 --spider http://google.com
|
|
then # There is an internet connection, so get local RMS list
|
|
GRID="${GRID:0:4}"
|
|
GRID="${GRID^^}"
|
|
echo
|
|
echo "RMS Stations in grid square $GRID:"
|
|
$(command -v pat) rmslist | grep "${GRID}\|callsign" | sort -k 3,3 -n
|
|
fi
|
|
fi
|
|
echo
|
|
echo "Tailing $LOGFILE. All apps log to this file. Press Ctrl-C to quit all apps."
|
|
echo
|
|
tail -n 150 -F $LOGFILE
|
|
;;
|
|
*ax25*)
|
|
checkSerial
|
|
if [[ ${CMDS[rigctld]} == "" ]]
|
|
then
|
|
echo "rigctld will not be used."
|
|
case "$DMODE" in
|
|
*pat*)
|
|
ORDERS=( direwolf pat )
|
|
;;
|
|
*)
|
|
ORDERS=( direwolf )
|
|
;;
|
|
esac
|
|
else
|
|
case "$DMODE" in
|
|
*pat*)
|
|
ORDERS=( rigctld direwolf pat )
|
|
;;
|
|
*)
|
|
ORDERS=( rigctld direwolf )
|
|
;;
|
|
esac
|
|
echo "rigctld will use radio found on $DEVICE."
|
|
fi
|
|
if [[ $DMODE =~ "pat" ]]
|
|
then
|
|
echo "NOTE: If you haven't already done so, you must run 'pat configure' or manually"
|
|
echo " configure $HOME/.wl2k/config.json to use pat."
|
|
echo
|
|
CMDS[pat]="$(command -v pat) -l ax25,telnet http"
|
|
fi
|
|
# Check that the app is installed.
|
|
for i in ${!ORDERS[@]}
|
|
do
|
|
command -v ${ORDERS[$i]} >/dev/null
|
|
[ $? -eq 0 ] && echo "${ORDERS[$i]} found." || Die "${ORDERS[$i]} required but not found. Aborting."
|
|
# Kill existing session if it exists
|
|
SCR="$($SCREEN -list | grep ${ORDERS[$i]} | tr -d ' \t' | cut -d'(' -f1 | tr -d '\n')"
|
|
[[ "$SCR" != "" ]] && { pkill piardop2; $SCREEN -S $SCR -X quit; }
|
|
done
|
|
## Kill existing session if it exists
|
|
pgrep kissattach >/dev/null && sudo kill $(pgrep kissattach)
|
|
## Are the apps installed?
|
|
for i in kissattach kissparms
|
|
do
|
|
command -v $i >/dev/null
|
|
[ $? -eq 0 ] && echo "$i found." || Die "Error: $i required but not found. Aborting."
|
|
done
|
|
CONFFILE="$(makeConfig ax25)"
|
|
CMDS[direwolf]+=" -p -d u -c $CONFFILE"
|
|
for i in ${!ORDERS[@]}
|
|
do
|
|
echo
|
|
echo "Starting ${CMDS[${ORDERS[$i]}]}"
|
|
case "${ORDERS[$i]}" in
|
|
direwolf)
|
|
if ! grep -q "^$AX25PORT[[:space:]]" $AX25PORTFILE 2>/dev/null
|
|
then
|
|
echo -n "File $AX25PORTFILE empty or does not contain $AX25PORT. Adding..."
|
|
echo "$AX25PORT $MYCALL 0 255 7 Winlink" | sudo tee --append $AX25PORTFILE
|
|
echo "done."
|
|
fi
|
|
rm -f /tmp/kisstnc
|
|
$SCREEN -c $SCREENCONFIG -L -d -m -S ${ORDERS[$i]} ${CMDS[${ORDERS[$i]}]}
|
|
COUNTER=0
|
|
MAXWAIT=8
|
|
while [ $COUNTER -lt $MAXWAIT ]
|
|
do
|
|
# Allocate a PTY to ax25
|
|
[ -L /tmp/kisstnc ] && break
|
|
sleep 1
|
|
let COUNTER=COUNTER+1
|
|
done
|
|
if [ $COUNTER -ge $MAXWAIT ]
|
|
then
|
|
Die "Direwolf failed to allocate a PTY! Aborting. Is ADEVICE set to your sound card?"
|
|
fi
|
|
echo "Direwolf started."
|
|
sudo $(command -v kissattach) $(readlink -f /tmp/kisstnc) $AX25PORT
|
|
[ $? -eq 0 ] || Die "kissattach failed. Aborting."
|
|
KISSPARMS="-c 1 -p $AX25PORT -t $TXDelay -l $TXTail -s $Slottime -r $Persist -f n"
|
|
echo "Setting $(command -v kissparms) $KISSPARMS"
|
|
sleep 2
|
|
sudo $(command -v kissparms) $KISSPARMS
|
|
[ $? -eq 0 ] || Die "kissparms settings failed. Aborting."
|
|
;;
|
|
*)
|
|
$SCREEN -c $SCREENCONFIG -L -d -m -S ${ORDERS[$i]} ${CMDS[${ORDERS[$i]}]}
|
|
;;
|
|
esac
|
|
echo "============================"
|
|
done
|
|
screen -list
|
|
echo
|
|
echo "------ ax25 Direwolf configuration file ------"
|
|
cat $CONFFILE | grep -v "^$"
|
|
echo "----------------------------------------------"
|
|
sleep 2
|
|
rm -f $CONFFILE
|
|
if [[ $DMODE == "pat" && $GRID != "" ]]
|
|
then
|
|
if $WGET -q --tries=2 --timeout=5 --spider http://google.com
|
|
then # There is an internet connection, so get local RMS list
|
|
GRID="${GRID:0:4}"
|
|
GRID="${GRID^^}"
|
|
echo
|
|
echo "RMS Stations in grid square $GRID:"
|
|
$(command -v pat) rmslist | grep "${GRID}\|callsign" | sort -k 3,3 -n
|
|
fi
|
|
fi
|
|
echo
|
|
echo "Tailing $LOGFILE. All apps log to this file. Press Ctrl-C to quit all apps."
|
|
echo
|
|
tail -n 150 -F $LOGFILE
|
|
;;
|
|
digi*|igate)
|
|
[[ $PTT0 == "" || $PTT0 =~ "GPIO" ]] && ORDERS=( direwolf ) || { checkSerial; ORDERS=( rigctld direwolf ); }
|
|
# Check that the app is installed.
|
|
for i in ${!ORDERS[@]}
|
|
do
|
|
command -v ${ORDERS[$i]} >/dev/null
|
|
[ $? -eq 0 ] && echo "${ORDERS[$i]} found." || Die "${ORDERS[$i]} required but not found. Aborting."
|
|
# Kill existing session if it exists
|
|
SCR="$($SCREEN -list | grep ${ORDERS[$i]} | tr -d ' \t' | cut -d'(' -f1 | tr -d '\n')"
|
|
[[ "$SCR" != "" ]] && { pkill piardop2; $SCREEN -S $SCR -X quit; }
|
|
#[[ "$SCR" != "" ]] && $SCREEN -S $SCR -X quit
|
|
done
|
|
CONFFILE="$(makeConfig $DMODE)"
|
|
CMDS[direwolf]+=" -d t -c $CONFFILE"
|
|
for i in ${!ORDERS[@]}
|
|
do
|
|
echo
|
|
echo "Starting ${CMDS[${ORDERS[$i]}]}"
|
|
$SCREEN -c $SCREENCONFIG -L -d -m -S ${ORDERS[$i]} ${CMDS[${ORDERS[$i]}]}
|
|
done
|
|
screen -list
|
|
echo
|
|
echo "------ APRS $DMODE Direwolf configuration file ------"
|
|
cat $CONFFILE | grep -v "^$"
|
|
echo "-----------------------------------------------------"
|
|
echo
|
|
sleep 2
|
|
rm -f $CONFFILE
|
|
echo "Tailing $LOGFILE. All apps log to this file. Press Ctrl-C to quit all apps."
|
|
echo
|
|
tail -n 150 -F $LOGFILE
|
|
;;
|
|
*ardop*)
|
|
case "$DMODE" in
|
|
*pat*)
|
|
ORDERS=( piardop2 pat )
|
|
echo "NOTE: If you haven't already done so, you must run 'pat configure' or manually"
|
|
echo " configure $HOME/.wl2k/config.json to use pat."
|
|
echo
|
|
CMDS[pat]="$(command -v pat) -l ardop,telnet http"
|
|
;;
|
|
*)
|
|
ORDERS=( piardop2 )
|
|
;;
|
|
esac
|
|
# Check that the app is installed, and kill it if it is already running.
|
|
for i in ${!ORDERS[@]}
|
|
do
|
|
command -v ${ORDERS[$i]} >/dev/null
|
|
[ $? -eq 0 ] && echo "${ORDERS[$i]} found." || Die "${ORDERS[$i]} required but not found. Aborting."
|
|
# Kill existing session if it exists
|
|
SCR="$($SCREEN -list | grep ${ORDERS[$i]} | tr -d ' \t' | cut -d'(' -f1 | tr -d '\n')"
|
|
[[ "$SCR" != "" ]] && $SCREEN -S $SCR -X quit
|
|
done
|
|
CMDS[piardop2]="$(command -v piardop2) $ARDOP_PORT $ARDOP_DEV"
|
|
if [[ $ARDOP_PTT == "" ]]
|
|
then
|
|
Die "Error: Please set PTT type (variable ARDOP_PTT) for ARDOP in this script."
|
|
else
|
|
CMDS[piardop2]+=" $ARDOP_PTT"
|
|
fi
|
|
for i in ${!ORDERS[@]}
|
|
do
|
|
echo
|
|
echo "Starting ${CMDS[${ORDERS[$i]}]}"
|
|
$SCREEN -c $SCREENCONFIG -L -d -m -S ${ORDERS[$i]} ${CMDS[${ORDERS[$i]}]}
|
|
done
|
|
echo "Tailing $LOGFILE. All apps log to this file. Press Ctrl-C to quit all apps."
|
|
echo
|
|
tail -n 150 -F $LOGFILE
|
|
;;
|
|
*)
|
|
Die "Invalid mode requested. Run ${SCRIPT_NAME} -h for instructions."
|
|
;;
|
|
esac
|
|
;;
|
|
stop)
|
|
ORDERS=( rigctld piardop2 direwolf pat )
|
|
#ORDERS=( rigctld direwolf )
|
|
echo
|
|
for i in ${!ORDERS[@]}
|
|
do
|
|
SCR="$($SCREEN -list | grep ${ORDERS[$i]} | tr -d ' \t' | cut -d'(' -f1 | tr -d '\n')"
|
|
if [[ "$SCR" != "" ]]
|
|
then
|
|
echo -n "Stopping $SCR..."
|
|
$SCREEN -S $SCR -X quit
|
|
echo "done."
|
|
else
|
|
echo "Stopping ${ORDERS[$i]}: ${ORDERS[$i]} not running"
|
|
fi
|
|
done
|
|
pgrep piardop2 >/dev/null && kill -9 $(pgrep piardop2)
|
|
KISSATTACHPID="$(pgrep kissattach)"
|
|
if [[ $KISSATTACHPID != "" ]]
|
|
then
|
|
echo -n "Stopping kissattach..."
|
|
sudo killall kissattach
|
|
rm -f /tmp/kisstnc
|
|
echo "done."
|
|
fi
|
|
;;
|
|
*)
|
|
Usage
|
|
;;
|
|
esac
|
|
|