#!/bin/bash

#this script will send messages over RF using ax25 & a TNC.
#depends = ax25-tools, ax25-apps, direwolf, yad
#Create menu item by running "./ax25-messages menu"
#02FEB2022 KM4ACK

VERSION=3
LOG=/run/user/$UID/axlisten.log
LOGBKUP=/run/user/$UID/axlisten.log.bkup
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
LOGO=/usr/share/icons/Adwaita/scalable/actions/send-to-symbolic.svg
touch $LOG
source $DIR/.ax25-messages.config > /dev/null 2>&1

#####################################
#change log
#version 2 29MARCH2022 KM4ACK
#added mobilind TNC support
#version 3 22FEB2023 KM4ACK
#add sudo password input to support x86 
#####################################

########################
#get sudo pw
########################
if [ ! -f /run/user/$UID/.ax25 ]; then
PW=$(yad --title="sudo password" --width=400 --height=100 \
--image $LOGO --window-icon=$LOGO --image-on-top --text-align=center \
--center --form --text="Please enter your sudo password" \
--field="Password":H \
--button=gtk-ok)
PASS=$(echo $PW | awk -F "|" '{print $1}')
echo $PASS | base64 > /run/user/$UID/.ax25
echo '#!/bin/bash' > /run/user/$UID/.axpw
echo 'PASS=$(base64 -d /run/user/$UID/.ax25)' >> /run/user/$UID/.axpw
echo 'echo $PASS' >> /run/user/$UID/.axpw
chmod +x /run/user/$UID/.axpw
export SUDO_ASKPASS=/run/user/$UID/.axpw
#reset sudo timer to prevent false positive
sudo -k
echo "Checking SUDO credentials....standby"
sudo -A touch /run/user/$UID/sutest 2>&1 </dev/null

    if [ $? = 1 ]; then
    echo "Wrong sudo password entered. Can't continue! Exiting"
    yad --title="Wrong Password" --width=400 --height=100 \
    --image $LOGO --window-icon=$LOGO --image-on-top --text-align=center \
    --center --form --text="Wrong Password. Can't continue'" \
    --button="Exit"
    rm /run/user/$UID/.ax25 /run/user/$UID/.axpw
    exit
    else 
    echo "Credentials check out....continuing"
    fi
    
else
export SUDO_ASKPASS=/run/user/$UID/.axpw
fi
############################

###########################
#Depends Check
###########################
AXT=`dpkg -l | grep ax25-tools`
if [ -z "$AXT" ]; then
echo "ax25-tools not installed but required"
exit
fi 

AXA=`dpkg -l | grep ax25-apps`
if [ -z "$AXA" ]; then
echo "ax25-apps not installed but required"
exit
fi 

if ! hash direwolf 2>/dev/null; then
echo "Direwolf not installed but required"
fi

YD=`dpkg -l | grep yad`
if [ -z "YD" ]; then
echo "Yad not installed"
fi

###########################
#MAIN MENU
###########################
MAINMENU(){
SYSTEM_CHECK
MENU=$(yad --form --width=400 --image ${LOGO} --window-icon={LOGO} \
--image-on-top --text="<b>ax25-messages v$VERSION</b> by KM4ACK\rMy Call - $CALL\r\rDirewolf - $DW\rKissattach - $KA\rAxlisten - $AL\r Mobilinkd - $ML\r\r<b>$STATUS\r</b>" \
--text-align=center --center --title="ax25-messages" \
--button="Start Listening":1 \
--button="Stop Listening":2 \
--button="Send Message":3 \
--button="Settings":4 )
BUT=$?

case ${BUT} in
	1)
	STARTUP
	sleep 1
	MSGCHECK &
	KILLTHIS=$!
	MAINMENU
	;;
	2)
	echo "Stop Listening...."
	rm $LOG $LOGBKUP /run/user/$UID/message.sh > /dev/null 2>&1
	sudo -A killall axlisten direwolf kissattach rigctld > /dev/null 2>&1
	sudo -A rfcomm release /dev/rfcomm8 > /dev/null 2>&1
	kill $KILLTHIS > /dev/null 2>&1
	MAINMENU
	;;
	3)
	if [ ! -f /run/user/$UID/message.sh ]; then
	yad --form --width=400 --text-align=center --center --title="ax25 messages" --text-align=center \
	--image ${LOGO} --window-icon=${LOGO} --image-on-top \
	--text="<b>Not Listening</b>\rWe must be listening\rbefore we can send messages." \
	--button=gtk-ok
	else
	/run/user/$UID/message.sh &
	fi
	MAINMENU
	;;
	4)
	MYCONFIG
	;;
	252)
	exit
	;;
esac
}

cleanup()
{
	echo "Shutting down...."
	rm $LOG $LOGBKUP /run/user/$UID/message.sh > /dev/null 2>&1
	sudo -A killall axlisten direwolf kissattach rigctld > /dev/null 2>&1
	sudo -A rfcomm release /dev/rfcomm8 > /dev/null 2>&1
	kill $KILLTHIS > /dev/null 2>&1 #this kills the loop looking for messages
}

trap cleanup EXIT

###########################
#create config if not found
###########################
TEMPFILE=$DIR/temp-config
CONFIG=$DIR/.ax25-messages.config
if [ ! -f $CONFIG ]; then

echo "#Config file for ax25-messages" > $TEMPFILE
echo "#06FEB2022 KM4ACK" >> $TEMPFILE
echo "" >> $TEMPFILE
echo "" >> $TEMPFILE
echo "CALL=N0CALL" >> $TEMPFILE
echo "USERIGCTL=no" >> $TEMPFILE
echo "RIGCTL=\"/usr/local/bin/rigctld -m 4\"" >> $TEMPFILE
echo "TNC=direwolf" >> $TEMPFILE
echo "MAC=" >> $TEMPFILE

cp $TEMPFILE $CONFIG
rm $TEMPFILE
fi

###########################
#create the reply script
###########################
CREATE_REPLY(){
cat <<"EOF" > /run/user/$UID/message.sh
#!/bin/bash

TMPCS=/run/user/$UID/tocall.txt
touch $TMPCS
NEWMSG(){
source $TMPCS
MSG=$(yad --center --on-top --width=400 --height=200 --window-icon= --form \
--image-on-top --text="<b>ax25-messages</b> by KM4ACK" --text-align=center --title="Send Message" \
--field="TO" "$TO" \
--field="Message")
BUT=$?
#give user an exit path
if [ $BUT = 252 ] || [ $BUT = 1 ]; then
rm $TMPCS
exit
fi
#process data
TO=$(echo $MSG | awk -F "|" '{print $1}')
MSG=$(echo $MSG | awk -F "|" '{print $2}')

echo "TO=$TO" > $TMPCS

#send beacon with message. wl2k is the port defined in the /etc/ax25/axports file.
source
/usr/sbin/beacon -s -c $CALL -d "$TO" wl2k "$MSG"
NEWMSG
}
NEWMSG
EOF

#make reply executable
chmod +x /run/user/$UID/message.sh
#update script with correct source path
sed -i "s|source|source $DIR/.ax25-messages.config|" /run/user/$UID/message.sh
}

###########################
#Startup function
###########################
STARTUP(){
source $DIR/.ax25-messages.config > /dev/null 2>&1
CREATE_REPLY

#Check & warn if FLRIG not started
if [ "$USERIGCTL" = 'yes' ]; then

	if [ -z `pidof flrig` ]; then
	yad --form --width=400 --text-align=center --center --title="ax25 messages" --text-align=center \
	--image ${LOGO} --window-icon=${LOGO} --image-on-top \
	--text="<b>FLRIG NOT RUNNING</b>\rFLRIG is usually used for rig control\rYou can start FLRIG and continue or\rjust continue if using other rig control." \
	--button="Continue":1 \
	--button="Exit":2
	BUT=$?
		if [ $BUT = 2 ] || [ $BUT = 252 ]; then
		exit
		fi
	fi
fi

#check if user is using rig control for PTT
if [ "$USERIGCTL" = 'yes' ]; then #defined in config file.
$RIGCTL & #defined in the config file
sleep 1
fi

if [ "$TNC" = 'direwolf' ]; then
/usr/local/bin/direwolf -p &
sleep 1
LINK=$(ls -l /tmp/kisstnc | awk '{print $NF}')
sudo -A /usr/sbin/kissattach $LINK wl2k
sudo -A kissparms -c 1 -p wl2k
elif [ "$TNC" = 'mobilinkd' ]; then
	if [ "$TNCV" = 2 ]; then
	sudo -A rfcomm bind /dev/rfcomm8 $MAC
	elif [ "$TNCV" = 3 ]; then
	sudo -A rfcomm bind /dev/rfcomm8 $MAC 6
	fi
sleep 1
sudo -A /usr/sbin/kissattach /dev/rfcomm8 wl2k
sudo -A kissparms -c 1 -p wl2k
fi

sudo -A axlisten -a | tee $LOG &

yad --form --width=200 --text-align=center --center --title="ax25 messages" --text-align=center \
--image ${LOGO} --window-icon=${LOGO} --image-on-top \
--text="<b>Modem Started</b>" \
--button=gtk-ok

}

###########################
#Message Processing
###########################
MSGPROCESS(){
source $DIR/.ax25-messages.config > /dev/null 2>&1
mv $LOG $LOGBKUP
touch $LOG
#kill axlisten so we can move the log file.
sudo -A killall axlisten
FROM=$(tail -2 $LOGBKUP | grep -i $CALL | awk '{print $3}')
MSG=$(tail -1 $LOGBKUP | sed 's/0000  //')
REPLYTO=$(tail -2 $LOGBKUP | grep -i $CALL | awk '{print $3}')

#this if statement is critical to keep from looping
if [ "$MSG" != 'ack' ] && [ "$FROM" != "$CALL" ]; then
#send ack
/usr/sbin/beacon -s -c "$CALL" -d "$REPLYTO" wl2k "ack"
fi

#verify message isn't our own before giving user notice.
#This prevents echoing our sent messages back to the user.
if [ "$FROM" != "$CALL" ]; then
#popup window for new incoming messages
yad --center --width=600 --wrap --window-icon= --title="New Message" \
--image-on-top --text="<b>ax25-messages v$VERSION</b> by KM4ACK" --text-align=center --center --title="New Message" \
--form --separator="|" --item-separator="," --field="From":RO "$FROM" \
--field="Message":RO "$MSG" \
--button=gtk-ok:1 &
fi

sleep .5
sudo -A axlisten -a | tee $LOG &
MSGCHECK
}

###########################
#Listen for messages
###########################
MSGCHECK(){
#Check for messages
MSG=$(grep -i $CALL $LOG | tail -2 | head -1 | sed "s/.*$CALL//;s/.*://")
while [ -z "$MSG" ]; do
sleep 1
MSG=$(grep -i $CALL $LOG | tail -2 | head -1 | sed "s/.*$CALL//;s/.*://")
done
MSGPROCESS
}

###########################
#SETTINGS
###########################
#Update config file function
MYCONFIG(){
TEMPFILE=$DIR/temp-config
CONFIG=$DIR/.ax25-messages.config
source $CONFIG
touch $TEMPFILE

if [ "$USERIGCTL" = 'yes' ]; then
USERIGCTL="yes|no"
else
USERIGCTL="no|yes"
fi

if [ "$TNC" = 'direwolf' ]; then
TNC="direwolf|mobilinkd"
else
TNC="mobilinkd|direwolf"
fi

if [ -z $MAC ]; then
MAC="not used for direwolf"
fi

if [ "$TNCV" = 2 ]; then
TNCV="2|3"
else
TNCV="3|2"
fi

SETTING=$(yad --center --width=500 --wrap --window-icon={LOGO} \
--image-on-top --text="<b>ax25-messages v$VERSION</b> by KM4ACK" --text-align=center --center --title="ax25-messages" \
 --title="ax25-messages settings" --text="ax25-messages settings\r" \
--form --separator="|" --item-separator="|" \
--field="Current Callsign" "$CALL" \
--field="Rig Control":CB "$USERIGCTL" \
--field="Rigctl Command" "$RIGCTL" \
--field="TNC":CB "$TNC" \
--field="Mobilinkd TNC MAC addr" "$MAC" \
--field="Mobilinkd TNC Version":CB "$TNCV"

)
BUT=$?

if [ $BUT = 1 ] || [ $BUT = 252 ]; then
MAINMENU
fi

if [ -z "$SETTING" ]; then
exit
fi

CALL=$(echo $SETTING | awk -F "|" '{print$1}')
CALL=${CALL^^}
USERIGCTL=$(echo $SETTING | awk -F "|" '{print$2}')
RIGCTL=$(echo $SETTING | awk -F "|" '{print$3}')
TNC=$(echo $SETTING | awk -F "|" '{print$4}')
MAC=$(echo $SETTING | awk -F "|" '{print$5}')
TNCV=$(echo $SETTING | awk -F "|" '{print$6}')

echo "#Config file for ax25-messages" > $TEMPFILE
echo "#06FEB2022 KM4ACK" >> $TEMPFILE
echo "" >> $TEMPFILE
echo "" >> $TEMPFILE
echo "CALL=$CALL" >> $TEMPFILE
echo "USERIGCTL=$USERIGCTL" >> $TEMPFILE
echo "RIGCTL=\"$RIGCTL\"" >> $TEMPFILE
echo "TNC=$TNC" >> $TEMPFILE
echo "MAC=\"$MAC\"" >> $TEMPFILE
echo "TNCV=$TNCV" >> $TEMPFILE

cp $TEMPFILE $CONFIG
rm $TEMPFILE
MAINMENU
}
###########################
#System Status Check
###########################
#This function is used in the GUI to tell the user what
#is running.
SYSTEM_CHECK(){
DW=`pidof direwolf`
KA=`pidof kissattach`
AL=`pidof axlisten`
ML=`ls /dev | grep rfcomm8`
#Set variables of apps 
if [ -z $DW ]; then
DW="Not Running"
else
DW="Running"
fi
if [ -z $KA ]; then
KA="Not Running"
else
KA="Running"
fi
if [ -z $AL ]; then
AL="Not Running"
else
AL="Running"
fi
if [ -z $ML ]; then
ML="Not connected"
else
ML="Connected"
fi
if [ ! -z $KA ] && [ ! -z $AL ]; then
STATUS="Listening for Messages"
else
STATUS="Not Listening"
fi
if [ -z "$CALL" ]; then
CALL=N0CALL
fi
}

#create menu item
if [ $1 = 'menu' ]; then
cat <<EOF > /run/user/$UID/ax25message.desktop
[Desktop Entry]
Name=AX25 Messages
GenericName=AX25 Messages
Comment=Messaging app that uses ax25
Exec=$HOME/bin/ax25-messages
Icon=/usr/share/icons/Adwaita/scalable/actions/send-to-symbolic.svg
Terminal=false
Type=Application
Categories=HamRadio
EOF
echo "menu item created"
echo "start ax25-messages using the Pi menu."
sudo -A mv /run/user/$UID/ax25message.desktop /usr/local/share/applications/ax25message.desktop
exit
fi

MAINMENU

















