Pi-Star_Binaries_sbin/pistar-dapnetapi
2019-02-21 19:51:50 +01:00

230 lines
8.3 KiB
Bash
Executable file

#!/bin/bash
#
##############################################################################
# #
# Pi-Star DAPNET API Tool #
# #
# Version 2.1, Code, Design and Development by Andy Taylor (MW0MWZ). #
# Helpfull input from Florian Wolters (DF2FET) - Thank you Flo. #
# #
##############################################################################
#
if [ "$(id -u)" != "0" ]; then
echo -e "You need to be root to run this command...\n"
exit 1
fi
# Get the stored DAPNET API Config
DAPNETAPIFile=/etc/dapnetapi.key
if [ -f ${DAPNETAPIFile} ]; then
source <(grep = <(grep -A5 '\[DAPNETAPI\]' $DAPNETAPIFile | tr -d ' ' | tr -d '\r'))
else
echo "Unable to find your DAPNET API Info, no API commands available."
exit 1
fi
# Check command line arguments
if [ $# -lt 2 ]; then
echo ""
echo "To use this script, call the script with some arguments;"
echo ""
echo "Example:"
echo " pistar-dapnetapi M1ABC[,callsign...] \"Test Message\" [options]"
echo ""
echo "The above command will send a page containing \"Text Message\" to M1ABC"
echo "More than one call can be specified for multiple recipients, separated"
echo "by a comma, without any space in betweeen."
echo ""
echo "For additional feedback add the \"debug\" option:"
echo "pistar-dapnetapi M1ABC \"Test Message\" debug"
echo ""
echo "Suppress the hostname with the \"nohost\" option:"
echo "pistar-dapnetapi M1ABC \"Test Message\" nohost"
echo ""
exit 0
fi
# Check some options
if [ "${3^^}" = "DEBUG" ] || [ "${4^^}" = "DEBUG" ]; then
DEBUG="1"
else
DEBUG="0"
fi
if [ "${3^^}" = "NOHOST" ] || [ "${4^^}" = "NOHOST" ]; then
HOST=${USER^^}
else
HOST=$(hostname)
fi
# Setup some variables
APIURL="https://hampager.de/api"
RECIPIENT=$(echo "$1" | sed -r 's/\,/"\,"/g')
MESSAGE=${2}
SIZEHOST=${#HOST}
SIZEMESSAGE=$(expr 78 - ${SIZEHOST})
SIZETEXT=${#MESSAGE}
NUMMESSAGES=$(expr ${SIZETEXT} / ${SIZEMESSAGE})
# Curl error codes
curlErrorCodes[1]="Unsupported protocol. This build of curl has no support for this protocol."
curlErrorCodes[2]="Failed to initialize."
curlErrorCodes[3]="URL malformed. The syntax was not correct."
curlErrorCodes[4]="A feature or option that was needed to perform the desired request was not enabled or was explicitly disabled at build-time. To make curl able to do this, you probably need another build of libcurl!"
curlErrorCodes[5]="Couldn't resolve proxy. The given proxy host could not be resolved."
curlErrorCodes[6]="Couldn't resolve host. The given remote host was not resolved."
curlErrorCodes[7]="Failed to connect to host."
curlErrorCodes[22]="HTTP page not retrieved. The requested url was not found or returned another error with the HTTP error code being 400 or above. This return code only appears if -f, --fail is used."
curlErrorCodes[23]="Write error. Curl couldn't write data to a local filesystem or similar."
curlErrorCodes[26]="Read error. Various reading problems."
curlErrorCodes[27]="Out of memory. A memory allocation request failed."
curlErrorCodes[28]="Operation timeout. The specified time-out period was reached according to the conditions."
curlErrorCodes[33]="HTTP range error. The range \"command\" didn't work."
curlErrorCodes[34]="HTTP post error. Internal post-request generation error."
curlErrorCodes[35]="SSL connect error. The SSL handshaking failed."
curlErrorCodes[37]="FILE couldn't read file. Failed to open the file. Permissions?"
curlErrorCodes[42]="Aborted by callback. An application told curl to abort the operation."
curlErrorCodes[43]="Internal error. A function was called with a bad parameter."
curlErrorCodes[45]="Interface error. A specified outgoing interface could not be used."
curlErrorCodes[47]="Too many redirects. When following redirects, curl hit the maximum amount."
curlErrorCodes[48]="Unknown option specified to libcurl. This indicates that you passed a weird option to curl that was passed on to libcurl and rejected. Read up in the manual!"
curlErrorCodes[51]="The peer's SSL certificate or SSH MD5 fingerprint was not OK."
curlErrorCodes[52]="The server didn't reply anything, which here is considered an error."
curlErrorCodes[53]="SSL crypto engine not found."
curlErrorCodes[54]="Cannot set SSL crypto engine as default."
curlErrorCodes[55]="Failed sending network data."
curlErrorCodes[56]="Failure in receiving network data."
curlErrorCodes[58]="Problem with the local certificate."
curlErrorCodes[59]="Couldn't use specified SSL cipher."
curlErrorCodes[60]="Peer certificate cannot be authenticated with known CA certificates."
curlErrorCodes[61]="Unrecognized transfer encoding."
curlErrorCodes[63]="Maximum file size exceeded."
curlErrorCodes[65]="Sending the data requires a rewind that failed."
curlErrorCodes[66]="Failed to initialise SSL Engine."
curlErrorCodes[67]="The user name, password, or similar was not accepted and curl failed to log in."
curlErrorCodes[75]="Character conversion failed."
curlErrorCodes[76]="Character conversion functions required."
curlErrorCodes[77]="Problem with reading the SSL CA cert (path? access rights?)."
curlErrorCodes[78]="The resource referenced in the URL does not exist."
curlErrorCodes[79]="An unspecified error occurred during the SSH session."
curlErrorCodes[80]="Failed to shut down the SSL connection."
curlErrorCodes[82]="Could not load CRL file, missing or wrong format (added in 7.19.0)."
curlErrorCodes[83]="Issuer check failed (added in 7.19.0)."
curlErrorCodes[85]="RTSP: mismatch of CSeq numbers"
curlErrorCodes[86]="RTSP: mismatch of Session Identifiers"
curlErrorCodes[89]="No connection available, the session will be queued"
# Function that parse returned JSON for error code
function python_ParseJSON() {
DAPNET_RESULT_ARG="$1" python - <<EOF
import os
import json
import sys
jdata = os.environ['DAPNET_RESULT_ARG']
data = json.loads(jdata)
if 'code' in data:
print("%s [error:%d]" % (str(data["message"]), data["code"]))
sys.exit(1)
else:
sys.exit(0)
EOF
}
# Function that send a page
# returns 0 on success, otherwise 1
function send_page () {
# Set the variables for the function
TEXT="$(echo ${1})"
# Debug option
if [ "${DEBUG}" -gt "0" ]; then
echo " Request to DAPNET API: {"
echo " \"text\": \"${HOST^^}: ${TEXT}\","
echo " \"callSignNames\": ["
echo " \"${RECIPIENT}\""
echo " ],"
echo " \"transmitterGroupNames\": ["
echo " \"${TRXAREA}\""
echo " ],"
echo " \"emergency\": false"
echo "}"
echo ""
echo ""
fi
# Speak to DAPNET
RESULT=$(curl -f -S -s -H "Content-Type: application/json" -X POST -u ${USER}:${PASS} -d \
"{ \"text\": \"${HOST^^}: ${TEXT}\", \"callSignNames\": [\"${RECIPIENT}\"], \"transmitterGroupNames\": [\"${TRXAREA}\"], \"emergency\": false }" \
${APIURL}/calls 2>&1)
ret=$?
# Check curl return code
if [ "$ret" != "0" ]; then
echo "ERROR: ($ret) ${curlErrorCodes[ret]}"
return $ret
fi
# Debug option
if [ "${DEBUG}" -gt "0" ]; then
echo "Answer from DAPNET API: '${RESULT}'"
echo ""
echo ""
fi
# Parse returned JSON code, to catch possible error
error=$(python_ParseJSON "${RESULT}")
ret=$?
if [ "$ret" != "0" ]; then
echo "$error"
fi
return $ret
}
if [ "${NUMMESSAGES}" -gt "0" ]; then
# OK now I know I need to split the message, now I need to know now many I need.
SIZEMESSAGESPLIT=$(expr 73 - ${SIZEHOST})
NUMMESSAGESSPLIT=$(expr ${SIZETEXT} / ${SIZEMESSAGESPLIT} + 1)
# Limit output to 5 concurrent messages
if [ "${NUMMESSAGESSPLIT}" -ge "6" ]; then
NUMMESSAGESSPLIT=5
fi
# Now I need to split the message into ${NUMMESSAGESSPLIT} chunks
COUNTER=1
while [ ${COUNTER} -le ${NUMMESSAGESSPLIT} ]; do
TXTSTART=$(expr ${SIZEMESSAGESPLIT} \* ${COUNTER} - ${SIZEMESSAGESPLIT})
TXTPRE="${COUNTER}/${NUMMESSAGESSPLIT}"
TXTCHUNK=${MESSAGE:$TXTSTART:$SIZEMESSAGESPLIT}
TXTMESSAGE=${TXTPRE}" "${TXTCHUNK}
send_page "${TXTMESSAGE}"
ret=$?
if [ "$ret" != "0" ]; then
exit $ret
fi
let COUNTER=COUNTER+1
done
else
# Messge does not need to be split
send_page "${MESSAGE}"
ret=$?
if [ "$ret" != "0" ]; then
exit $ret
fi
fi
echo "Page to \"$RECIPIENT\" successfully sent."
# Exit Clean
exit 0