diff --git a/ardop_pat_gui.sh b/ardop_pat_gui.sh new file mode 100755 index 0000000..f459d93 --- /dev/null +++ b/ardop_pat_gui.sh @@ -0,0 +1,571 @@ +#!/bin/bash +#================================================================ +# HEADER +#================================================================ +#% SYNOPSIS +#+ ${SCRIPT_NAME} [-hv] +#% +#% DESCRIPTION +#% This script provides a GUI to configure and start/stop +#% ARDOP (piardopc) and pat. It is designed to work on the +#% Nexus DR-X image. +#% +#% OPTIONS +#% -h, --help Print this help +#% -v, --version Print script information +#% +#================================================================ +#- IMPLEMENTATION +#- version ${SCRIPT_NAME} 1.0.0 +#- author Steve Magnuson, AG7GN +#- license CC-BY-SA Creative Commons License +#- script_id 0 +#- +#================================================================ +# HISTORY +# 20200718 : Steve Magnuson : Script creation. +# +#================================================================ +# 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 +Optnum=$# + +#============================ +# FUNCTIONS +#============================ + +function TrapCleanup() { + [[ -d "${TMPDIR}" ]] && rm -rf "${TMPDIR}/" + kill $timeStamp_PID >/dev/null 2>&1 + kill $ardop_PID >/dev/null 2>&1 + kill $pat_PID >/dev/null 2>&1 + kill $RIG_PID >/dev/null 2>&1 + for P in ${YAD_PIDs[@]} + do + kill $P >/dev/null 2>&1 + done + sudo pkill kissattach >/dev/null 2>&1 + rm -f /tmp/kisstnc + rm -f $PIPE +} + +function SafeExit() { + trap - INT TERM EXIT SIGINT + TrapCleanup + exit 0 +} + +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" \ + -e "s/\${SPEED}/${SPEED}/g" \ + -e "s/\${DEFAULT_PORTSTRING}/${DEFAULT_PORTSTRING}/g" +} + +function Usage() { + printf "Usage: " + ScriptInfo usage + exit +} + +function Die () { + echo "${*}" + SafeExit +} + +function loadpatDefaults () { + for I in $(seq 7 10) + do # I is the field number. D[$I] is the default value + echo "${I}:${D[$I]}" + done +} + +function setARDOPpatDefaults () { + declare -gA D + D[1]="null" # Audio capture interface (ADEVICE) + D[2]="null" # Audio playback interface (ADEVICE) + D[3]="GPIO 23" # GPIO PTT (BCM pin) + D[4]="8515" # ARDOP Port +# D[5]="FALSE" # Forced ARQ bandwidth +# D[6]="500" # Max ARQ bandwidth +# D[7]="0" # Beacon Interval +# D[8]="TRUE" # CW ID Enabled +# D[9]="FALSE" # Enable pat HTTP server +} + +function loadSettings () { + + PTTs="GPIO 12!GPIO 23!RIG 2 localhost:4532" + ARDOP_CONFIG="$TMPDIR/ardop.conf" + + if [ -s "$CONFIG_FILE" ] + then # There is a config file + echo "$CONFIG_FILE found." >&8 + source "$CONFIG_FILE" + else # Set some default values in a new config file + echo -e "Config file $CONFIG_FILE not found.\nCreating a new one with default values." >&8 + setARDOPpatDefaults + echo "declare -gA F" > "$CONFIG_FILE" + echo "F[_ADEVICE_CAPTURE_]='${D[1]}'" >> "$CONFIG_FILE" + echo "F[_ADEVICE_PLAY_]='${D[2]}'" >> "$CONFIG_FILE" + echo "F[_PTT_]='${D[3]}'" >> "$CONFIG_FILE" + echo "F[_ARDOPPORT_]='${D[4]}'" >> "$CONFIG_FILE" + echo "F[_PAT_HTTP_]='${D[5]}'" >> "$CONFIG_FILE" + source "$CONFIG_FILE" + fi + if pgrep pulseaudio >/dev/null 2>&1 + then # There may be pulseaudio ALSA devices. Look for them. + CAPTURE_IGNORE="$(pacmd list-sinks 2>/dev/null | grep name: | tr -d '\t' | cut -d' ' -f2 | sed 's/^$//' | tr '\n' '\|' | sed 's/|/\\|/g')" + ADEVICE_CAPTUREs="$(arecord -L | grep -v "$CAPTURE_IGNORE^ .*\|^dsnoop\|^sys\|^default\|^dmix\|^hw\|^usbstream\|^jack\|^pulse" | tr '\n' '!' | sed 's/!$//')" + PLAYBACK_IGNORE="$(pacmd list-sources 2>/dev/null | grep name: | tr -d '\t' | cut -d' ' -f2 | sed 's/^$//' | tr '\n' '\|' | sed 's/|/\\|/g')" + ADEVICE_PLAYBACKs="$(aplay -L | grep -v "$PLAYBACK_IGNORE^ .*\|^dsnoop\|^sys\|^default\|^dmix\|^hw\|^usbstream\|^jack\|^pulse" | tr '\n' '!' | sed 's/!$//')" + else # pulseaudio isn't running. Check only for null and plughw devices + ADEVICE_CAPTUREs="$(arecord -L | grep "^null\|^plughw" | tr '\n' '!' | sed 's/!$//')" + ADEVICE_PLAYBACKs="$(aplay -L | grep "^null\|^plughw" | tr '\n' '!' | sed 's/!$//')" + fi + [[ $ADEVICE_CAPTUREs =~ ${F[_ADEVICE_CAPTURE_]} ]] && ADEVICE_CAPTUREs="$(echo "$ADEVICE_CAPTUREs" | sed "s/${F[_ADEVICE_CAPTURE_]}/\^${F[_ADEVICE_CAPTURE_]}/")" + [[ $ADEVICE_CAPTUREs == "" ]] && ADEVICE_CAPTUREs="null" + [[ $ADEVICE_PLAYBACKs =~ ${F[_ADEVICE_PLAY_]} ]] && ADEVICE_PLAYBACKs="$(echo "$ADEVICE_PLAYBACKs" | sed "s/${F[_ADEVICE_PLAY_]}/\^${F[_ADEVICE_PLAY_]}/")" + [[ $ADEVICE_PLAYBACKs == "" ]] && ADEVICE_PLAYBACKs="null" + + if [[ $PTTs =~ ${F[_PTT_]} ]] + then + PTTs="$(echo "$PTTs" | sed "s/${F[_PTT_]}/\^${F[_PTT_]}/")" + else + PTTs+="!^${F[_PTT_]}" + fi + + ARDOPPORT="${F[_ARDOPPORT_]}" + + PAT_START_HTTP="${F[_PAT_HTTP_]}" + PAT_CALL="$(jq -r ".mycall" $PAT_CONFIG)" + PAT_PASSWORD="$(jq -r ".secure_login_password" $PAT_CONFIG)" + PAT_HTTP_PORT="$(jq -r ".http_addr" $PAT_CONFIG | cut -d: -f2)" + PAT_TELNET_PORT="$(jq -r ".telnet.listen_addr" $PAT_CONFIG | cut -d: -f2)" + PAT_LOCATOR="$(jq -r ".locator" $PAT_CONFIG)" + PAT_ARDOPPORT="$(jq -r ".ardop.addr" $PAT_CONFIG | cut -d: -f2)" + PAT_ARQ_BW_FORCED="$(jq -r ".ardop.arq_bandwidth.Forced" $PAT_CONFIG)" + PAT_ARQ_BW_MAX="$(jq -r ".ardop.arq_bandwidth.Max" $PAT_CONFIG)" + PAT_BEACON_INTERVAL="$(jq -r ".ardop.beacon_interval" $PAT_CONFIG)" + PAT_CW_ID="$(jq -r ".ardop.cwid_enabled" $PAT_CONFIG)" +} + +function timeStamp () { + while sleep 60 + do + echo -e "\nTIMESTAMP: $(date)" + done >$PIPEDATA +} + +function killARDOP () { + # $1 is the ardop PID + if pgrep ^piardopc | grep -q $1 2>/dev/null + then + kill $1 >/dev/null 2>&1 + echo -e "\n\npiardopc stopped. Click \"Save Settings...\" button below to restart." >$PIPEDATA + else + echo -e "\n\npiardopc was already stopped. Click \"Save Settings...\" button below to restart." >$PIPEDATA + fi +} + +#============================ +# FILES AND VARIABLES +#============================ + +# Set Temp Directory +# ----------------------------------- +# Create temp directory with three random numbers and the process ID +# in the name. This directory is removed automatically at exit. +# ----------------------------------- +TMPDIR="/tmp/${SCRIPT_NAME}.$RANDOM.$RANDOM.$RANDOM.$$" +(umask 077 && mkdir "${TMPDIR}") || { + Die "Could not create temporary directory! Exiting." +} + + #== 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:) +VERSION="$(ScriptInfo version | grep version | tr -s ' ' | cut -d' ' -f 4)" + +TITLE="ARDOP Monitor and Configuration $VERSION" +CONFIG_FILE="$HOME/ardop.conf" +MESSAGE="ARDOP Configuration" + +ID="${RANDOM}" + +PAT_CONFIG="$HOME/.wl2k/config.json" + +RETURN_CODE=0 +ARDOP="$(command -v piardopc)" +#PAT="$(command -v pat) --log /dev/stdout -l ax25,telnet http" +PAT="$(command -v pat) -l ardop,telnet http" + +PIPE=$TMPDIR/pipe +mkfifo $PIPE +exec 8<> $PIPE + +#============================ +# PARSE OPTIONS WITH GETOPTS +#============================ + +#== set short options ==# +SCRIPT_OPTS=':hv-:' + +#== set long options associated with short one ==# +typeset -A ARRAY_OPTS +ARRAY_OPTS=( + [help]=h + [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 + ;; + 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 + +# Ensure only one instance of this script is running. +pidof -o %PPID -x $(basename "$0") >/dev/null && exit 1 + +# Check for required apps. +for A in yad pat jq sponge rigctld piardopc +do + command -v $A >/dev/null 2>&1 || Die "$A is required but not installed." +done + +# If this is the first time running this script, don't attempt to start Direwolf +# or pat until user configures both. +if [[ -s $PAT_CONFIG && -s $CONFIG_FILE ]] +then # ARDOP and pat configuration files exist + if [[ $(jq -r ".mycall" $PAT_CONFIG) == "" || ${F[_ADEVICE_CAPTURE_]} == "null" ]] + then # Config files present, but not configured + FIRST_RUN=true + else # Config files present and configured + FIRST_RUN=false + fi +else # No configuration files exist + FIRST_RUN=true +fi + +# Check for pat's config.json. Create it if necessary +if ! [[ -s $PAT_CONFIG ]] +then + cd $HOME + export EDITOR=ed + echo -n "" | pat configure >/dev/null 2>&1 +fi + +export -f setARDOPpatDefaults loadpatDefaults +export load_pat_defaults_cmd='@bash -c "setARDOPpatDefaults; loadpatDefaults"' +export PIPEDATA=$PIPE + +#============================ +# MAIN SCRIPT +#============================ + +# Trap bad exits with cleanup function +trap SafeExit EXIT INT TERM + +# 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 + + +# Set up rig for rigctl in pat +#RIG="$(jq -r '.hamlib_rigs | keys[] as $k | "\($k)"' $PAT_CONFIG)" +RIG="$(jq -r .hamlib_rigs $PAT_CONFIG)" +if [[ $RIG == "{}" ]] +then # No rigs configured. Make a network Hamlib rig + cat $PAT_CONFIG | jq \ + '.hamlib_rigs += {"network": {"address": "localhost:4532", "network": "tcp"}}' | sponge $PAT_CONFIG + # Add the network Hamlib rig to the ax25, winmor, ardop, pactor sections + cat $PAT_CONFIG | jq \ + --arg R "network" \ + '.ax25.rig = $R | .winmor.rig = $R | .ardop.rig = $R | .pactor.rig = $R' | sponge $PAT_CONFIG +fi + +timeStamp & +timeStamp_PID=$! + +ardop_PID="" +pat_PID="" +YAD_PIDs=() + +while true +do + # Kill any running processes and load latest settings + killARDOP $ardop_PID + [[ $pat_PID == "" ]] || kill $pat_PID >/dev/null 2>&1 + for P in ${YAD_PIDs[@]} + do + ps x | egrep -q "^$P" && kill $P + done + loadSettings + YAD_PIDs=() + + # Start the tail window tab + TEXT="ARDOP Port: ${F[_ARDOPPORT_]}" + [[ $PAT_START_HTTP == TRUE ]] && TEXT+=" pat Telnet Port: $PAT_TELNET_PORT pat Web Server: http://$HOSTNAME.local:$PAT_HTTP_PORT" + yad --plug="$ID" --tabnum=1 \ + --back=black --fore=yellow --selectable-labels \ + --text-info --text-align=center --text="$TEXT" \ + --editable --tail --center <&8 & + YAD_PIDs+=( $! ) + + # Start rigctld. + if pgrep rigctld >/dev/null + then + echo "rigctld already running." >&8 + else # Start rigctl as a dummy rig because we have no idea what rig is used. + echo "Starting rigctld using dummy rig..." >&8 + $(command -v rigctld) -m 1 >&8 2>&8 & + RIG_PID=$! + echo "Done." >&8 + fi + + if [[ $FIRST_RUN == true ]] + then + echo -e "Configure ARDOP and pat in the \"Configure ARDOP\" and \"Configure pat\" tabs,\nthen click \"Save Settings...\" button below." >&8 + else # Not a first run. pat and ARDOP configured so start 'em + # Start piardopc + echo "Launching $ARDOP ${F[_ARDOPPORT_]} ${F[_ADEVICE_CAPTURE_]} ${F[_ADEVICE_PLAY_]} -p "$(echo "${F[_PTT_]}" | tr ' ' '=')"" >&8 + $ARDOP ${F[_ARDOPPORT_]} ${F[_ADEVICE_CAPTURE_]} ${F[_ADEVICE_PLAY_]} -p "$(echo "${F[_PTT_]}" | tr ' ' '=')" >&8 2>&8 & + ardop_PID=$! + echo -e "\n\nARDOP has started. PID=$ardop_PID" >&8 + + # Start pat + if [[ $PAT_START_HTTP == TRUE ]] + then + $PAT >&8 2>&8 & + pat_PID=$! + else + pat_PID="" + fi + fi + + # Set up tab for configuring piardopc. + yad --plug="$ID" --tabnum=2 \ + --text="ARDOP Configuration\n\n \ +Typical Sound Card and PTT Settings for Nexus DR-X\n \ +LEFT Radio: Use ADEVICEs \ +fepi-capture-left and fepi-playback-left and PTT GPIO 12.\n \ +RIGHT Radio: Use ADEVICEs \ +fepi-capture-right and fepi-playback-right and PTT GPIO 23.\n\n \ +Click the Save Settings... button below after you make your changes.\n\n" \ + --item-separator="!" \ + --separator="|" \ + --text-align=center \ + --align=right \ + --borders=20 \ + --form \ + --columns=2 \ + --field="ARDOP Capture ADEVICE":CB "$ADEVICE_CAPTUREs" \ + --field="ARDOP Playback ADEVICE":CB "$ADEVICE_PLAYBACKs" \ + --field="ARDOP PTT":CBE "$PTTs" \ + --field="ARDOP Port":NUM "${F[_ARDOPPORT_]}!8510..8519!1!" \ + --focus-field 1 > $TMPDIR/CONFIGURE_ARDOP.txt & + YAD_PIDs+=( $! ) + + # Set up tab for pat configuration + yad --plug="$ID" --tabnum=3 \ + --text="pat Configuration\n\n \ +Click the Save Settings... button below after you make your changes.\n\n" \ + --item-separator="!" \ + --separator="|" \ + --text-align=center \ + --align=right \ + --borders=20 \ + --form \ + --columns=2 \ + --field="Call Sign" "$PAT_CALL" \ + --field="Winlink Password":H "$PAT_PASSWORD" \ + --field="Locator Code" "$PAT_LOCATOR" \ + --field="Web Service Port":NUM "$PAT_HTTP_PORT!8040..8049!1!" \ + --field="Telnet Service Port":NUM "$PAT_TELNET_PORT!8770..8779!1!" \ + --field="Forced ARQ Bandwidth":CHK "$PAT_ARQ_BW_FORCED" \ + --field="Max ARQ Bandwidth":NUM "$PAT_ARQ_BW_MAX!50..1000!50!" \ + --field="Beacon Interval (minutes)":NUM "$PAT_BEACON_INTERVAL!0..120!1!" \ + --field="Enable CW ID":CHK "$PAT_CW_ID" \ + --field="Start pat web service when ARDOP starts":CHK "$PAT_START_HTTP" \ + --field="Edit pat Connection Aliases":FBTN "bash -c edit_pat_aliases.sh &" \ + --focus-field 1 > $TMPDIR/CONFIGURE_PAT.txt & + YAD_PIDs+=( $! ) + [[ $PAT_START_HTTP == TRUE ]] && AND_PAT=" + pat" || AND_PAT="" + + # Set up tab with form button to launch pat web interface + #yad --plug="$ID" --tabnum=4 --text-align="center" \ + # --text="Open pat Web Interface" --form \ + # --field="Open pat Web Interface":FBTN "bash -c xdg-open >/dev/null &" >/dev/null & + #YAD_PIDs+=( $! ) + + # Set up tab to present button to launch rigctld manager + RIGCTL_INFO=" \ +The rig control daemon (rigctld) is part of Hamlib. It provides a way to control \ +various rigs using CAT commands, usually over a serial port.\n\nIn order to set up \ +aliases (shortcuts) in the pat web interface for RMS Gateway stations ALONG WITH \ +their frequency, pat requires the use of rigctld. When started, the GUI you're \ +currently using will check to see if rigctld is already running. If it's not, it'll \ +start rigctld using a 'dummy' rig, which fools pat into thinking it's controlling a \ +radio when it's not (meaning you have to set your radio's frequency manually).\n\nIf \ +your rig is supported by Hamlib (or to check to see if it is supported), click the \ +'Manage Hamlib rigctld' button below to have the TNC and pat REALLY talk to your \ +radio (if supported) and have pat automatically QSY as needed." + yad --plug="$ID" --tabnum=4 --text-align=center --borders=20 --form --wrap \ + --text="Hamlib Rig Control (rigctld)" \ + --field="":TXT "$RIGCTL_INFO" \ + --field="Manage Hamlib rigctld":FBTN "bash -c rigctl_gui.sh >/dev/null &" >/dev/null & + YAD_PIDs+=( $! ) + + if [[ $pat_PID == "" ]] + then + cat > $TMPDIR/pat_web.sh <pat is not running.\nNo web interface to open." --button="Close":0 --buttons-layout=center +EOF + else + cat > $TMPDIR/pat_web.sh </dev/null 2>&1 +EOF + fi + chmod +x $TMPDIR/pat_web.sh + + # Set up a notebook with the tabs. + yad --title="ARDOP and pat $VERSION" --text="ARDOP$AND_PAT Configuration and Operation" \ + --text-align="center" --notebook --key="$ID" \ + --posx=10 --posy=50 \ + --buttons-layout=center \ + --tab="Monitor" \ + --tab="Configure ARDOP" \ + --tab="Configure pat" \ + --tab="Rig Control" \ + --width="800" --height="600" \ + --button="Stop ARDOP$AND_PAT & Exit":1 \ + --button="Save Settings & Restart ARDOP$AND_PAT":0 \ + --button="Open pat Web interface":"bash -c $TMPDIR/pat_web.sh" + RETURN_CODE=$? + + case $RETURN_CODE in + 0) # Read and handle the Configure TNC tab yad output + [[ -s $TMPDIR/CONFIGURE_ARDOP.txt ]] || Die "Unexpected input from dialog" + IFS='|' read -r -a TF < "$TMPDIR/CONFIGURE_ARDOP.txt" + F[_ADEVICE_CAPTURE_]="${TF[0]}" + F[_ADEVICE_PLAY_]="${TF[1]}" + F[_PTT_]="${TF[2]}" + F[_ARDOPPORT_]="${TF[3]}" + + + # Read and handle the Configure pat tab yad output + [[ -s $TMPDIR/CONFIGURE_PAT.txt ]] || Die "Unexpected input from dialog" + IFS='|' read -r -a TF < "$TMPDIR/CONFIGURE_PAT.txt" + PAT_CALL="${TF[0]^^}" + PAT_PASSWORD="${TF[1]}" + PAT_LOCATOR="${TF[2]^^}" + PAT_HTTP_PORT="${TF[3]}" + PAT_TELNET_PORT="${TF[4]}" + PAT_ARQ_BW_FORCED="${TF[5]}" + PAT_ARQ_BW_MAX="${TF[6]}" + PAT_BEACON_INTERVAL="${TF[7]}" + PAT_CW_ID="${TF[8]}" + F[_PAT_HTTP_]="${TF[9]}" + + # Update the pat config.json file with the new data. + cat $PAT_CONFIG | jq \ + --arg C "$PAT_CALL" \ + --arg P "$PAT_PASSWORD" \ + --arg H "0.0.0.0:$PAT_HTTP_PORT" \ + --arg T "0.0.0.0:$PAT_TELNET_PORT" \ + --arg L "$PAT_LOCATOR" \ + --arg R "127.0.0.1:${F[_ARDOPPORT_]}" \ + --argjson F ${PAT_ARQ_BW_FORCED,,} \ + --argjson B $PAT_ARQ_BW_MAX \ + --argjson I $PAT_BEACON_INTERVAL \ + --argjson D ${PAT_CW_ID,,} \ + '.mycall = $C | .secure_login_password = $P | .http_addr = $H | .telnet.listen_addr = $T | .locator = $L | .ardop.addr = $R | .ardop.arq_bandwidth.Max = $B | .ardop.beacon_interval = $I | .ardop.arq_bandwidth.Forced = $F | .ardop.cwid_enabled = $D' | sponge $PAT_CONFIG + + # Update the yad configuration file. + echo "declare -gA F" > "$CONFIG_FILE" + for J in "${!F[@]}" + do + echo "F[$J]='${F[$J]}'" >> "$CONFIG_FILE" + done + if [[ $(jq -r ".mycall" $PAT_CONFIG) == "" || ${F[_ADEVICE_CAPTURE_]} == "null" ]] + then + FIRST_RUN=true + else + FIRST_RUN=false + fi + ;; + *) # User click Exit button or closed window. + break + ;; + esac +done +SafeExit diff --git a/dw_pat_gui.sh b/dw_pat_gui.sh index cbf4e19..e0aba64 100755 --- a/dw_pat_gui.sh +++ b/dw_pat_gui.sh @@ -15,7 +15,7 @@ #% #================================================================ #- IMPLEMENTATION -#- version ${SCRIPT_NAME} 1.6.0 +#- version ${SCRIPT_NAME} 1.6.1 #- author Steve Magnuson, AG7GN #- license CC-BY-SA Creative Commons License #- script_id 0 @@ -24,6 +24,8 @@ # HISTORY # 20200428 : Steve Magnuson : Script creation. # 20200507 : Steve Magnuson : Bug fixes +# 20200719 : Steve Magnuson : Improved handling of pat rigctl +# settings # #================================================================ # DEBUG OPTION @@ -380,17 +382,17 @@ $SYNTAX && set -n # Run in debug mode, if set $DEBUG && set -x - -# Set up a dummy rig for rigctl in pat +# Set up rig for rigctl in pat +#RIG="$(jq -r '.hamlib_rigs | keys[] as $k | "\($k)"' $PAT_CONFIG)" RIG="$(jq -r .hamlib_rigs $PAT_CONFIG)" if [[ $RIG == "{}" ]] then # No rigs configured. Make a network Hamlib rig cat $PAT_CONFIG | jq \ '.hamlib_rigs += {"network": {"address": "localhost:4532", "network": "tcp"}}' | sponge $PAT_CONFIG - # Add the network Hamlib rig to the ax25 section + # Add the network Hamlib rig to the ax25, winmor, ardop, pactor sections cat $PAT_CONFIG | jq \ --arg R "network" \ - '.ax25.rig = $R' | sponge $PAT_CONFIG + '.ax25.rig = $R | .winmor.rig = $R | .ardop.rig = $R | .pactor.rig = $R' | sponge $PAT_CONFIG fi timeStamp & @@ -615,7 +617,7 @@ EOF IFS='|' read -r -a TF < "$TMPDIR/CONFIGURE_PAT.txt" PAT_CALL="${TF[0]^^}" PAT_PASSWORD="${TF[1]}" - PAT_LOCATOR="${TF[2]}" + PAT_LOCATOR="${TF[2]^^}" PAT_HTTP_PORT="${TF[3]}" PAT_TELNET_PORT="${TF[4]}" F[_PAT_HTTP_]="${TF[5]}" diff --git a/edit_pat_aliases.sh b/edit_pat_aliases.sh index 4e1e0fc..28bc57c 100755 --- a/edit_pat_aliases.sh +++ b/edit_pat_aliases.sh @@ -18,7 +18,7 @@ #% #================================================================ #- IMPLEMENTATION -#- version ${SCRIPT_NAME} 1.3.7 +#- version ${SCRIPT_NAME} 1.4.1 #- author Steve Magnuson, AG7GN #- license CC-BY-SA Creative Commons License #- script_id 0 @@ -26,6 +26,7 @@ #================================================================ # HISTORY # 20200507 : Steve Magnuson : Script creation. +# 20200718 : Steve Magnuson : Allow pactor, winmor, ardop aliases # #================================================================ # DEBUG OPTION @@ -84,35 +85,35 @@ function Die () { } function runFind () { - echo "5:@disable@" + echo "5:@disabled@" PAT="pat rmslist" - [[ $2 == "Any" ]] || PAT+=" -b $2" - [[ $3 == "Any" ]] || PAT+=" -m $3" - [[ $4 == TRUE ]] && PAT+=" -s" + [[ $2 == "Any" ]] || PAT+=" -b $2" # Band filter + [[ $3 == "Any" ]] || PAT+=" -m $3" # Mode filter + [[ $4 == TRUE ]] && PAT+=" -s" # Sort by distance echo -e '\f' >> "$fpipe" eval $PAT | grep -i "$1" | grep -v VARA | grep -v "^callsign" | grep -v "^$" | tr -s ' ' | \ - awk '{printf "%s\n%s\n%s\n%s\n%s\n%s %s\n%s\n",$1,$7,$2,$3,$4,$5,$6,$8}' >> "$fpipe" + awk '{printf "%s\n%s\n%s\n%s\n%s\n%s\n%s %s\n",$11,$1,$7,$2,$3,$4,$5,$6}' >> "$fpipe" echo "5:$find_cmd" } export -f runFind function processAlias () { - CALL="$(echo "$1" | sed 's/^ //' | cut -d' ' -f1)" - FREQ="$(echo "$1" | sed 's/^ //' | cut -d' ' -f2 | sed -e 's/\.00$//' -e 's/\.//1')" - if jq -r .connect_aliases $PAT_CONFIG | grep ":" | tr -d '", ' | grep -q ^$CALL.*$FREQ$ - then + local CALL="$(echo "$1" | sed 's/^ //' | cut -d' ' -f2)" + local URI="$(echo "$1" | sed 's/^ //' | sed -e 's/packet/ax25/' | cut -d' ' -f1)" + if jq -r '.connect_aliases | keys[] as $k | "\(.[$k])"' $PAT_CONFIG | grep -q "$URI" + then # Alias already present yad --info --center --text-align=center --buttons-layout=center \ - --text="$CALL @ $FREQ was already in aliases" --borders=20 --button="gtk-ok":0 - else - cat $PAT_CONFIG | jq --arg K "$CALL" --arg V "ax25:///$CALL?freq=$FREQ" \ - '.connect_aliases += {($K): $V}' | sponge $PAT_CONFIG + --text="$URI was already in aliases" --borders=20 --button="gtk-ok":0 + else # Alias not in list. Add it. + cat $PAT_CONFIG | jq --arg K "$CALL" --arg U "$URI" \ + '.connect_aliases += {($K): $U}' | sponge $PAT_CONFIG if [[ $? == 0 ]] then yad --info --center --text-align=center --buttons-layout=center \ - --text="$CALL @ $FREQ was added to aliases" --borders=20 --button="gtk-ok":0 + --text="$URI was added to aliases" --borders=20 --button="gtk-ok":0 else yad --info --center --text-align=center --buttons-layout=center \ - --text="ERROR: $CALL @ $FREQ was NOT added to aliases" --borders=20 --button="gtk-ok":0 + --text="ERROR: $URI was NOT added to aliases" --borders=20 --button="gtk-ok":0 fi fi } @@ -277,9 +278,9 @@ YAD_PIDs+=( $! ) yad --plug="$fkey" --tabnum=2 --list --grid-lines=hor --dclick-action="bash -c \"processAlias '%s'\"" \ --text "Search results. Double-click a Call to add it to your pat aliases." \ - --column="Call" --column="Frequency" --column="Location" --column="Distance" --column="Azimuth" \ - --column="Mode" --column="Units" \ - --search-column=1 --expand-column=1 <&4 >/dev/null & + --column="URI" --column="Call" --column="Frequency (MHz)" --column="Location" --column="Distance" --column="Azimuth" \ + --column="Mode" \ + --search-column=2 --expand-column=7 --hide-column=1 <&4 >/dev/null & YAD_PIDs+=( $! ) yad --paned --key="$fkey" --buttons-layout=center --button="gtk-close":0 --width=700 --height=700 \ diff --git a/rigctl_gui.sh b/rigctl_gui.sh index e9baf4d..cc77a92 100755 --- a/rigctl_gui.sh +++ b/rigctl_gui.sh @@ -14,7 +14,7 @@ #% #================================================================ #- IMPLEMENTATION -#- version ${SCRIPT_NAME} 1.0.2 +#- version ${SCRIPT_NAME} 1.0.3 #- author Steve Magnuson, AG7GN #- license CC-BY-SA Creative Commons License #- script_id 0 @@ -22,6 +22,7 @@ #================================================================ # HISTORY # 20200609 : Steve Magnuson : Script creation. +# 20200718 : Steve Magnuson : Delete unused function. # #================================================================ # DEBUG OPTION @@ -92,28 +93,6 @@ function runFind () { } export -f runFind -function processAlias () { - CALL="$(echo "$1" | sed 's/^ //' | cut -d' ' -f1)" - FREQ="$(echo "$1" | sed 's/^ //' | cut -d' ' -f2 | sed -e 's/\.00$//' -e 's/\.//1')" - if jq -r .connect_aliases $PAT_CONFIG | grep ":" | tr -d '", ' | grep -q ^$CALL.*$FREQ$ - then - yad --info --center --text-align=center --buttons-layout=center \ - --text="$CALL @ $FREQ was already in aliases" --borders=20 --button="gtk-ok":0 - else - cat $PAT_CONFIG | jq --arg K "$CALL" --arg V "ax25:///$CALL?freq=$FREQ" \ - '.connect_aliases += {($K): $V}' | sponge $PAT_CONFIG - if [[ $? == 0 ]] - then - yad --info --center --text-align=center --buttons-layout=center \ - --text="$CALL @ $FREQ was added to aliases" --borders=20 --button="gtk-ok":0 - else - yad --info --center --text-align=center --buttons-layout=center \ - --text="ERROR: $CALL @ $FREQ was NOT added to aliases" --borders=20 --button="gtk-ok":0 - fi - fi -} -export -f processAlias - function viewDeleteAliases () { # Load existing aliases while true