2023-03-21 19:56:02 +00:00
|
|
|
#!/usr/bin/with-contenv bash
|
2023-04-08 21:07:11 +00:00
|
|
|
# shellcheck shell=bash disable=SC1091,SC2015,SC2016
|
2023-03-21 19:56:02 +00:00
|
|
|
|
|
|
|
#---------------------------------------------------------------------------------------------
|
|
|
|
# Copyright (C) 2023, Ramon F. Kolb (kx1t)
|
|
|
|
#
|
|
|
|
# This program is free software: you can redistribute it and/or modify it
|
|
|
|
# under the terms of the GNU General Public License as published by the
|
|
|
|
# Free Software Foundation, either version 3 of the License, or (at your option)
|
|
|
|
# any later version.
|
|
|
|
#
|
|
|
|
# This program is distributed in the hope that it will be useful, but
|
|
|
|
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
|
|
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU General Public License along with this program.
|
|
|
|
# If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
#---------------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
APPNAME="mlat-client"
|
2023-05-03 19:58:08 +00:00
|
|
|
s6wrap --prepend="${APPNAME}" --timestamps --args echo "Started as an s6 service"
|
2023-03-21 19:56:02 +00:00
|
|
|
|
2023-04-19 00:36:45 +00:00
|
|
|
source /scripts/common
|
|
|
|
source /scripts/interpret_ultrafeeder_config
|
|
|
|
|
2023-03-21 19:56:02 +00:00
|
|
|
MLAT_CMD="/usr/bin/mlat-client"
|
|
|
|
|
|
|
|
RESTARTTIMER=15
|
|
|
|
declare -A pid_array
|
|
|
|
|
|
|
|
if [[ -z "${MLAT_CONFIG}" ]]
|
|
|
|
then
|
2023-05-03 19:58:08 +00:00
|
|
|
s6wrap --prepend="${APPNAME}" --timestamps --args echo "Warning: MLAT_CONFIG not defined - MLAT will be disabled."
|
2023-03-21 19:56:02 +00:00
|
|
|
sleep infinity
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [[ -z "${MLAT_USER}" ]] && [[ -z "${UUID}" ]]
|
|
|
|
then
|
2023-05-03 19:58:08 +00:00
|
|
|
s6wrap --prepend="${APPNAME}" --timestamps --args echo "ERROR: either UUID or MLAT_USER must be defined - MLAT will be disabled."
|
2023-03-21 19:56:02 +00:00
|
|
|
sleep infinity
|
|
|
|
fi
|
|
|
|
|
2023-04-08 21:07:11 +00:00
|
|
|
if [[ -z "$LAT$READSB_LAT" ]]; then
|
2023-05-03 19:58:08 +00:00
|
|
|
s6wrap --prepend="${APPNAME}" --timestamps --args echo "ERROR: READSB_LAT or LAT must be defined - MLAT will be disabled."
|
2023-04-08 21:07:11 +00:00
|
|
|
sleep infinity
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [[ -z "$LONG$READSB_LON" ]]; then
|
2023-05-03 19:58:08 +00:00
|
|
|
s6wrap --prepend="${APPNAME}" --timestamps --args echo "ERROR: READSB_LON or LONG must be defined - MLAT will be disabled."
|
2023-04-08 21:07:11 +00:00
|
|
|
sleep infinity
|
|
|
|
fi
|
|
|
|
if [[ -z "$ALT$READSB_ALT" ]]; then
|
2023-05-03 19:58:08 +00:00
|
|
|
s6wrap --prepend="${APPNAME}" --timestamps --args echo "ERROR: READSB_ALT or ALT must be defined - MLAT will be disabled."
|
2023-04-08 21:07:11 +00:00
|
|
|
sleep infinity
|
|
|
|
fi
|
|
|
|
|
2023-03-21 19:56:02 +00:00
|
|
|
# MLAT_CONFIG has the following format:
|
2023-04-14 12:21:17 +00:00
|
|
|
# MLAT_CONFIG=mlatserver_1,mlatserver_port_1,x1,y1,z1;mlatserver_2,mlatserver_port_2,x2,y2,z2 etc
|
|
|
|
# where x1,y1,z1; x22,y2,z2; etc are optional and are interpreted as follows:
|
|
|
|
# if it's a number, we'll assume it's a port number for return messages
|
|
|
|
# if it starts with 'uuid=', it's a UUID number for that instance
|
|
|
|
# anything else will be appended as extra parameter(s) to the mlat-client command line
|
2023-03-21 19:56:02 +00:00
|
|
|
|
|
|
|
# parse MLAT_CONFIG string into mlat_configs array
|
2023-04-19 00:36:45 +00:00
|
|
|
# Strip any extraneous spaces:
|
|
|
|
MLAT_CONFIG="${MLAT_CONFIG#"${MLAT_CONFIG%%[![:space:]]*}"}" # strip leading space
|
|
|
|
MLAT_CONFIG="${MLAT_CONFIG//; /;}"
|
|
|
|
readarray -td ";" mlat_configs < <(printf '%s' "${MLAT_CONFIG}")
|
2023-03-21 19:56:02 +00:00
|
|
|
|
|
|
|
# Now loop through the MLAT_CONFIG items and start up an Mlat_client for each of them:
|
|
|
|
for instance in "${mlat_configs[@]}"
|
|
|
|
do
|
|
|
|
[[ -z "${instance}" ]] && continue || true
|
|
|
|
# put individual params into the $params array:
|
|
|
|
readarray -td "," params < <(printf '%s' "${instance}")
|
|
|
|
|
|
|
|
# Check if the params array has values for the mandatory elements:
|
|
|
|
if [[ -z "${params[0]}" ]] || [[ -z "${params[1]}" ]]
|
|
|
|
then
|
2023-05-03 19:58:08 +00:00
|
|
|
s6wrap --prepend="${APPNAME}" --timestamps --args echo "ERROR -- MLAT_CONFIG is malformed: \"${instance}\". Stopping MLAT execution."
|
2023-03-21 19:56:02 +00:00
|
|
|
# shellcheck disable=SC2046
|
|
|
|
kill $(ps -s $$ -o pid=)
|
|
|
|
sleep infinity
|
|
|
|
fi
|
|
|
|
|
2023-05-04 16:14:48 +00:00
|
|
|
# Now process the the arguments
|
|
|
|
# The order doesn't matter, we'll do pattern matching:
|
|
|
|
# If the argument is a number, then it must be the beast_results port
|
|
|
|
# If the argument starts with "uuid=", then it must be a UUID, etc.
|
|
|
|
# If the argument isn't any of the above, then it's an "extra argument"
|
|
|
|
|
|
|
|
unset uuid_arg lat_arg lon_arg alt_arg input_connect_arg extra_args
|
|
|
|
|
|
|
|
for ((i=2; i<${#params[*]}; i++))
|
|
|
|
do
|
|
|
|
if [[ -n "${params[i]}" ]] && [[ "${params[i]}" =~ ^[0-9]+$ ]]; then
|
|
|
|
# It's a number so it must be the return port
|
|
|
|
MLAT_PARAM+=("--results beast,listen,${params[i]}")
|
|
|
|
elif header="${params[i]:0:5}" && [[ "${header,,}" == "uuid=" ]]; then
|
|
|
|
# It's a UUID
|
|
|
|
uuid_arg="${params[i]#*=}"
|
|
|
|
elif header="${params[i]:0:4}" && [[ "${header,,}" == "lat=" ]]; then
|
|
|
|
# It's a latitude
|
|
|
|
lat_arg="${params[i]#*=}"
|
|
|
|
elif header="${params[i]:0:4}" && [[ "${header,,}" == "lon=" ]]; then
|
|
|
|
# It's a longitude
|
|
|
|
lon_arg="${params[i]#*=}"
|
|
|
|
elif header="${params[i]:0:4}" && [[ "${header,,}" == "alt=" ]]; then
|
|
|
|
# It's a latitude
|
|
|
|
alt_arg="${params[i]#*=}"
|
|
|
|
elif header="${params[i]:0:14}" && [[ "${header,,}" == "input_connect=" ]]; then
|
|
|
|
#It's the input_connect parameter value
|
|
|
|
input_connect_arg="${params[i]#*=}"
|
|
|
|
else
|
|
|
|
# It's an Extra Args string
|
|
|
|
extra_args="$extra_args ${params[i]}"
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
|
2023-04-14 12:21:17 +00:00
|
|
|
# ------------------------------------------------
|
2023-03-21 19:56:02 +00:00
|
|
|
# Build the MLAT parameter string:
|
2023-05-04 16:14:48 +00:00
|
|
|
MLAT_PARAM=(--input-type "${MLAT_INPUT_TYPE:-auto}")
|
2023-03-21 19:56:02 +00:00
|
|
|
MLAT_PARAM+=(--server "${params[0]}:${params[1]}")
|
2023-03-22 17:46:24 +00:00
|
|
|
|
2023-05-04 16:14:48 +00:00
|
|
|
# add input-connect to the param array:
|
|
|
|
MLAT_PARAM+=(--input-connect "${input_connect_arg:-localhost:30005}")
|
|
|
|
|
|
|
|
if [ -n "${MLAT_USER}" ]; then
|
|
|
|
MLAT_PARAM+=(--user "${MLAT_USER}")
|
|
|
|
else
|
|
|
|
rnd="${RANDOM}"
|
|
|
|
s6wrap --prepend="${APPNAME}" --timestamps --args echo "WARNING: MLAT_USER is not set - using random number \"${rnd}\" as MLAT_USER"
|
|
|
|
MLAT_PARAM+=(--user "${rnd}")
|
|
|
|
fi
|
|
|
|
|
|
|
|
# add LAT/LON/ALT to instance:
|
|
|
|
if [ -n "${lat_arg}" ]; then
|
|
|
|
MLAT_PARAM+=(--lat "${lat_arg}")
|
|
|
|
elif [ -n "${LAT}" ]; then
|
2023-03-22 17:46:24 +00:00
|
|
|
MLAT_PARAM+=(--lat "${LAT}")
|
|
|
|
elif [ -n "${READSB_LAT}" ]; then
|
|
|
|
MLAT_PARAM+=(--lat "${READSB_LAT}")
|
|
|
|
fi
|
|
|
|
|
2023-05-04 16:14:48 +00:00
|
|
|
if [ -n "${lon_arg}" ]; then
|
|
|
|
MLAT_PARAM+=(--lat "${lon_arg}")
|
|
|
|
elif [ -n "${LONG}" ]; then
|
2023-03-22 17:46:24 +00:00
|
|
|
MLAT_PARAM+=(--lon "${LONG}")
|
|
|
|
elif [ -n "${READSB_LON}" ]; then
|
|
|
|
MLAT_PARAM+=(--lon "${READSB_LON}")
|
|
|
|
fi
|
|
|
|
|
2023-05-04 16:14:48 +00:00
|
|
|
if [ -n "${alt_arg}" ]; then
|
|
|
|
MLAT_PARAM+=(--lat "${alt_arg}")
|
|
|
|
elif [ -n "${ALT}" ]; then
|
2023-03-22 17:46:24 +00:00
|
|
|
MLAT_PARAM+=(--alt "${ALT}")
|
|
|
|
elif [ -n "${READSB_ALT}" ]; then
|
|
|
|
MLAT_PARAM+=(--alt "${READSB_ALT}")
|
|
|
|
fi
|
|
|
|
|
2023-05-04 16:14:48 +00:00
|
|
|
# Add UUID to instance
|
|
|
|
if [ -n "$uuid_arg" ]; then
|
|
|
|
MLAT_PARAM+=("--uuid ${uuid_arg}")
|
|
|
|
elif [ -n "${UUID}" ]; then
|
|
|
|
MLAT_PARAM+=("--uuid ${UUID}")
|
|
|
|
else
|
|
|
|
# generate a random UUID
|
|
|
|
UUID="$(cat /proc/sys/kernel/random/uuid)"
|
|
|
|
[[ -z "${UUID}" ]] && UUID="$(printf '00000000-ffff-aaaa-%04x-%012x\n' "$RANDOM" "$(date +%s)")"
|
|
|
|
s6wrap --prepend="${APPNAME}" --timestamps --args echo "WARNING: UUID is not defined - using randomized uuid \"${UUID}\""
|
2023-04-14 12:21:17 +00:00
|
|
|
MLAT_PARAM+=("--uuid ${UUID}")
|
|
|
|
fi
|
2023-05-04 16:14:48 +00:00
|
|
|
|
2023-04-14 12:21:17 +00:00
|
|
|
# Now add the extra_args, if any:
|
|
|
|
[[ -n "${extra_args}" ]] && MLAT_PARAM+=("${extra_args}") || true
|
|
|
|
|
|
|
|
# ------------------------------------------------
|
|
|
|
# Create the command exec string:
|
|
|
|
# shellcheck disable=SC2048,SC2086
|
|
|
|
execstring="$(echo ${MLAT_CMD} ${MLAT_PARAM[*]} | xargs)"
|
|
|
|
|
|
|
|
# ------------------------------------------------
|
|
|
|
# Ready to launch, but wait until readsb is established...
|
|
|
|
if ! pgrep readsb >/dev/null; then
|
2023-05-03 19:58:08 +00:00
|
|
|
s6wrap --prepend="${APPNAME}" --timestamps --args echo "Delaying start of MLAT client(s) until container is established..."
|
2023-04-14 12:21:17 +00:00
|
|
|
while ! pgrep readsb >/dev/null
|
|
|
|
do
|
|
|
|
sleep 2
|
|
|
|
done
|
|
|
|
fi
|
|
|
|
sleep 10 # sleep a bit so everything is well established - starting readsb may take a bit
|
2023-04-08 13:21:46 +00:00
|
|
|
|
2023-03-21 19:56:02 +00:00
|
|
|
# run this Mlat_client instance in the background:
|
2023-05-03 19:58:08 +00:00
|
|
|
s6wrap --prepend="${APPNAME}" --timestamps --args echo "starting: ${MLAT_CMD} ${MLAT_PARAM[*]}"
|
2023-03-27 15:39:27 +00:00
|
|
|
|
2023-05-03 19:58:08 +00:00
|
|
|
#shellcheck disable=SC2069,SC2086
|
2023-03-27 15:39:27 +00:00
|
|
|
if [[ -z "${LOGLEVEL}" ]] || [[ "${LOGLEVEL,,}" == "verbose" ]]; then
|
2023-05-03 19:58:08 +00:00
|
|
|
{ exec s6wrap --prepend="${APPNAME}" --timestamps --args ${execstring}; } &
|
2023-03-27 15:39:27 +00:00
|
|
|
elif [[ "${LOGLEVEL,,}" == "error" ]]; then
|
2023-05-03 19:58:08 +00:00
|
|
|
{ exec s6wrap --prepend="${APPNAME}" --timestamps --args ${execstring} 2>&1 >/dev/null; } &
|
2023-03-27 15:39:27 +00:00
|
|
|
elif [[ "${LOGLEVEL,,}" == "none" ]]; then
|
|
|
|
{ exec ${execstring} >/dev/null 2>/dev/null; } &
|
|
|
|
fi
|
|
|
|
|
2023-04-14 12:21:17 +00:00
|
|
|
# pid_array is indexed by the PID of each mlat_client and contains the MLAT_PARAMs for that instance
|
|
|
|
# This is done so we can monitor them and restart them if needed
|
2023-03-21 19:56:02 +00:00
|
|
|
pid_array[$!]="${MLAT_PARAM[*]}"
|
|
|
|
sleep 5
|
|
|
|
done
|
|
|
|
|
2023-04-14 12:21:17 +00:00
|
|
|
# All MLAT Clients are up, so set the flag. This flag is read by MLATHUB as a sign that it's
|
|
|
|
# safe to start up
|
2023-04-09 14:41:07 +00:00
|
|
|
touch /run/mlathub_up
|
|
|
|
|
2023-03-21 19:56:02 +00:00
|
|
|
# Now iterate over all MLAT-client instances and check if they are still running:
|
|
|
|
while true
|
|
|
|
do
|
|
|
|
for mlat_pid in "${!pid_array[@]}"
|
|
|
|
do
|
|
|
|
if ! kill -0 "${mlat_pid}" >/dev/null 2>&1
|
|
|
|
then
|
|
|
|
# it exited - let's restart:
|
|
|
|
sleep "${RESTARTTIMER}"
|
2023-05-03 19:58:08 +00:00
|
|
|
[[ "${LOGLEVEL,,}" != "none" ]] && s6wrap --prepend="${APPNAME}" --timestamps --args echo "MLAT_Client $(awk '{print $6}' <<< "${pid_array[$mlat_pid]}") exited. Attempting to restart." || true
|
2023-03-21 19:56:02 +00:00
|
|
|
# shellcheck disable=SC2086
|
|
|
|
execstring="$(echo ${MLAT_CMD} ${pid_array[$mlat_pid]} | xargs)"
|
2023-03-27 15:39:27 +00:00
|
|
|
|
2023-05-03 19:58:08 +00:00
|
|
|
#shellcheck disable=SC2069,SC2086
|
2023-03-27 15:39:27 +00:00
|
|
|
if [[ -z "${LOGLEVEL}" ]] || [[ "${LOGLEVEL,,}" == "verbose" ]]; then
|
2023-05-04 17:43:26 +00:00
|
|
|
{ exec s6wrap --prepend="${APPNAME}][${params[0]}" --timestamps --args ${execstring} 2>&1; } &
|
2023-03-27 15:39:27 +00:00
|
|
|
elif [[ "${LOGLEVEL,,}" == "error" ]]; then
|
2023-05-04 17:43:26 +00:00
|
|
|
{ exec s6wrap --prepend="${APPNAME}][${params[0]}" --timestamps --args ${execstring} 2>&1 >/dev/null; } &
|
2023-03-27 15:39:27 +00:00
|
|
|
elif [[ "${LOGLEVEL,,}" == "none" ]]; then
|
|
|
|
{ exec ${execstring} >/dev/null 2>/dev/null; } &
|
|
|
|
fi
|
|
|
|
|
2023-03-21 19:56:02 +00:00
|
|
|
pid_array[$!]="${pid_array[${mlat_pid}]}"
|
|
|
|
unset "pid_array[${mlat_pid}]"
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
sleep 10
|
|
|
|
done
|