344 lines
11 KiB
Bash
Executable File
344 lines
11 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# This script tries to figure out the baud rate of $DEVICE_NAME connected to $TTY_INTERFACE.
|
|
# If the script successfully determines the baud rate of the receiver,
|
|
# it changes both the baud rate of the tty inerface and the receiver to the
|
|
# value stored in DESIRED_BAUD_RATE
|
|
|
|
# exit codes:
|
|
# 0 success
|
|
# 1 unable to detect baud rate of receiver
|
|
# 2 config file missing
|
|
# 3 reciever baud rate not set to $DESIRED_BAUD_RATE or verifiying baud rate failed
|
|
# 4 saving to flash failed
|
|
# 5 baud rate specified in $CONFIG_FILE not supported by $DEVICE_NAME
|
|
# 6 set tty baud rate was not successful
|
|
# 7 failed to restart gpsd
|
|
|
|
# static variables
|
|
DEVICE_NAME="NEO-M8L"
|
|
TTY_INTERFACE="/dev/gnss0"
|
|
CONFIG_FILE="/etc/gnss/gnss0.conf"
|
|
SAVE_FILE="/var/gnss-receiver-save-state"
|
|
|
|
# first baud rate in PRESELECTION_BAUD_RATES should be the one which is most likely the current baud rate of the GNSS receiver,
|
|
# the last one should be the one least likely used by the reciever.
|
|
# This can reduce the runtime of this script
|
|
# Note that this array can be expanded to test more baud rates if needed
|
|
PRESELECTION_BAUD_RATES=(9600 115200 4800)
|
|
|
|
# this array contains the baud rates that can be specified to be used by $DEVICE_NAME
|
|
# There is no guarantee that those baud rates work in combination with your device
|
|
# Note: 921600 is supported by M8L but not ubxtool
|
|
#SUPPORTED_BAUD_RATES=(460800 230400 115200 57600 38400 19200 9600 4800)
|
|
SUPPORTED_BAUD_RATES=(4800 9600 19200 38400 57600 115200 230400 460800)
|
|
|
|
ACK_MESSAGE="UBX-ACK-ACK:"
|
|
MAX_ALLOWED_RETRIES=4
|
|
|
|
# non static variables
|
|
# this is ugly, nobody likes non static global variables :(
|
|
DETECTED_BAUD_RATE=0
|
|
DESIRED_BAUD_RATE=0
|
|
|
|
# pass baudrate of $TTY_INTERFACE as parameter $1
|
|
# echo'es back the polled baud rate
|
|
# if no baud rate is returned by the receiver this function echo'es back "0"
|
|
poll_baud_rate_receiver () {
|
|
local _br_ttys3
|
|
_br_ttys3=$1
|
|
read -r _br_receiver <<< "$(ubxtool -f "$TTY_INTERFACE" -p CFG-PRT -s "$_br_ttys3" | awk '/mode .* baudRate .*/{print $4}')"
|
|
if test -z "$_br_receiver"; then
|
|
# reading baud rate of receiver failed
|
|
echo "0"
|
|
else
|
|
echo "$_br_receiver"
|
|
fi
|
|
}
|
|
|
|
# pass baud rate of $TTY_INTERFACE as paramater $1 and baud rate to set on receiver as $2
|
|
set_baud_rate_receiver () {
|
|
local _br_ttys3
|
|
_br_ttys3="$1"
|
|
local _br_receiver
|
|
_br_receiver="$2"
|
|
# note: there is no ack when setting new baud rate
|
|
# -> there is no way to confirm config change without sending an additional message
|
|
ubxtool -f "$TTY_INTERFACE" -s "$1" -S "$2" > /dev/null
|
|
return 0
|
|
}
|
|
|
|
# args[0]: allowed retries
|
|
# args[1:n]: baud rates to test
|
|
detect_baud_rate () {
|
|
local _args
|
|
_args=("$@")
|
|
local _allowed_retries
|
|
_allowed_retries="${_args[0]}"
|
|
local _baud_rates
|
|
for i in "${_args[@]:1}"
|
|
do
|
|
_baud_rates+=("$i")
|
|
done
|
|
local _polled_baud_rate
|
|
for br in "${_baud_rates[@]}";
|
|
do
|
|
printf "testing %s baud\\n" "$br"
|
|
for i in $(eval "echo {1..$_allowed_retries}")
|
|
do
|
|
_polled_baud_rate="$(poll_baud_rate_receiver "$br")"
|
|
if [ "$_polled_baud_rate" == "0" ];then
|
|
# increasing timeout for each try
|
|
t=$(echo "$i" "0.1"| awk '{printf "%4.3f\n",$1*$2}')
|
|
sleep "$t"
|
|
else
|
|
DETECTED_BAUD_RATE=$_polled_baud_rate
|
|
return 0
|
|
fi
|
|
done
|
|
printf "no luck so far\\n"
|
|
done
|
|
# failed to detect baud rate
|
|
printf "failed to detect baud rate\\n"
|
|
return 1
|
|
}
|
|
|
|
save_receiver_config () {
|
|
local _ack
|
|
read -r _ack <<< "$(ubxtool -f "$TTY_INTERFACE" -p SAVE -s $DESIRED_BAUD_RATE | grep $ACK_MESSAGE)"
|
|
if [ "$_ack" == "$ACK_MESSAGE" ]; then
|
|
# saved successfully
|
|
# log succe save
|
|
echo 1 > $SAVE_FILE
|
|
#touch
|
|
return 0
|
|
fi
|
|
return 1
|
|
}
|
|
|
|
set_baud_rate_tty () {
|
|
# set baud rate of $TTY_INTERFACE
|
|
stty -F "$TTY_INTERFACE" speed "$DESIRED_BAUD_RATE" > /dev/null
|
|
# verify baud rate
|
|
read -r TTYS3_BAUD_RATE <<< "$(stty -F "$TTY_INTERFACE" | awk '/speed .* baud;/{print $2}')"
|
|
if [ "$TTYS3_BAUD_RATE" == "$DESIRED_BAUD_RATE" ];then
|
|
return 0
|
|
else
|
|
# baud rate configured on $TTY_INTERFACE is not matching baud rate specified in $CONFIG_FILE
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
write_config_out(){
|
|
|
|
# get general info about the gnss receiver - currently hardcoded to gnss0
|
|
|
|
# ubxtool -f $TTY_INTERFACE -s $DESIRED_BAUD_RATE -p MON-VER
|
|
# read -r DESIRED_BAUD_RATE <<< "$(cat $CONFIG_FILE | grep -o "^b\(aud\)\? \?r\(ate\)\? \?= \?\([[:digit:]]*\)" | grep -o [[:digit:]]*)"
|
|
TMP_GNSS_FOLDER="/tmp/gnss"
|
|
TMP_GNSS_FILE="$TMP_GNSS_FOLDER/mon_ver"
|
|
mkdir -p $TMP_GNSS_FOLDER
|
|
ubxtool -f $TTY_INTERFACE -s $DESIRED_BAUD_RATE -p MON-VER | grep "MON-VER" -A 10 > $TMP_GNSS_FILE
|
|
|
|
read -r swVersion <<< "$(grep -oP "(?<=swVersion EXT CORE )([\d.]* \(\w{6}\))" $TMP_GNSS_FILE)"
|
|
read -r hwVersion <<< "$(grep -oP "(?<=hwVersion )(\d{8})" $TMP_GNSS_FILE)"
|
|
read -r rom_base <<< "$(grep -oP "(?<=extension ROM BASE )([\d.]* \(\w{6}\))" $TMP_GNSS_FILE)"
|
|
read -r fwVer <<< "$(grep -oP "(?<=extension FWVER=)([\w]* [\d.]*)" $TMP_GNSS_FILE)"
|
|
read -r protVer <<< "$(grep -oP "(?<=extension PROTVER=)([\d.]*)" $TMP_GNSS_FILE)"
|
|
read -r mod <<< "$(grep -oP "(?<=extension MOD=)(.*)" $TMP_GNSS_FILE)"
|
|
read -r fis <<< "$(grep -oP "(?<=extension FIS=)(.* \(\w{6}\))" $TMP_GNSS_FILE)"
|
|
read -r gnss_tech <<< "$(grep -oP "(?<=extension )([\w]{3};)+[\w]{3}" $TMP_GNSS_FILE)"
|
|
read -r augment_service <<< "$(grep -oP "(?<=extension )([\w]{4};)+[\w]{4}" $TMP_GNSS_FILE)"
|
|
|
|
# write config
|
|
|
|
CONFIG_OUT_FOLDER="/run/gnss"
|
|
CONFIG_OUT_FILE="$CONFIG_OUT_FOLDER/gnss0.config"
|
|
mkdir -p $CONFIG_OUT_FOLDER
|
|
touch $CONFIG_OUT_FILE
|
|
|
|
echo "Vendor: ublox" > $CONFIG_OUT_FILE
|
|
echo "Model: $mod" >> $CONFIG_OUT_FILE
|
|
echo "Firmware: $fwVer" >> $CONFIG_OUT_FILE
|
|
echo "ubx-Protocol: $protVer" >> $CONFIG_OUT_FILE
|
|
echo "Supported Satellite Systems: $gnss_tech" >> $CONFIG_OUT_FILE
|
|
echo "Supported Augmentation Services: $augment_service" >> $CONFIG_OUT_FILE
|
|
}
|
|
|
|
restart_gpsd(){
|
|
if [ "$RESTART_GPSD" -eq "1" ]; then
|
|
systemctl start gpsd
|
|
if [ "$?" -ne "0" ]; then
|
|
exit 7 # failed to restart gpsd
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# start of main
|
|
|
|
# check if script was launched by systemd
|
|
if test -z "$INVOCATION_ID"; then
|
|
# launched by user
|
|
# TODO: get state of gpsd and decide accordingly
|
|
systemctl stop gpsd.socket && systemctl stop gpsd
|
|
RESTART_GPSD=1
|
|
else
|
|
RESTART_GPSD=0
|
|
fi
|
|
|
|
# TODO: remove this hack in favour of a proper python environment
|
|
# hack to get pyserial working
|
|
PYTHONPATH=/usr/lib/python3.7/site-packages/ && export PYTHONPATH
|
|
|
|
# TODO: parse input args to display help which would explain usage of $CONFIG_FILE
|
|
|
|
# check if CONFIG_FILE exists
|
|
if ! test -f "$CONFIG_FILE"; then
|
|
# CONFIG_FILE doesn't exist
|
|
printf "config file missing\\n"
|
|
exit 2
|
|
fi
|
|
|
|
# check if SAVE_FILE exists
|
|
if ! test -f "$SAVE_FILE"; then
|
|
# SAVE_FILE doesn't exist
|
|
printf "save file missing\\n"
|
|
touch $SAVE_FILE
|
|
echo 0 > $SAVE_FILE
|
|
printf "created save file %s\\n" "$SAVE_FILE"
|
|
fi
|
|
|
|
# read $DESIRED_BAUD_RATE specified in $CONFIG_FILE
|
|
read -r DESIRED_BAUD_RATE <<< "$(cat $CONFIG_FILE | grep -o "^b\(aud\)\? \?r\(ate\)\? \?= \?\([[:digit:]]*\)" | grep -o "[[:digit:]]*")"
|
|
|
|
|
|
|
|
# check if $DESIRED_BAUD_RATE is supported by $DEVICE_NAME
|
|
baud_rate_supported_flag=0
|
|
for i in "${SUPPORTED_BAUD_RATES[@]}"
|
|
do
|
|
if [ "$i" == "$DESIRED_BAUD_RATE" ];then
|
|
baud_rate_supported_flag=1
|
|
break
|
|
fi
|
|
done
|
|
if [ "$baud_rate_supported_flag" == "0" ];then
|
|
printf "baud rate specified in %s is not supported by receiver %s\\n" "$CONFIG_FILE" "$DEVICE_NAME"
|
|
printf "supported baud rates are:\\n"
|
|
for j in "${SUPPORTED_BAUD_RATES[@]}"
|
|
do
|
|
printf "%s " "$j"
|
|
done
|
|
printf "\\n"
|
|
exit 5 # baud rate specified in $CONFIG_FILE not supported by $DEVICE_NAME
|
|
fi
|
|
|
|
# check if baud rate of $DEVICE_NAME matches $DESIRED_BAUD_RATE
|
|
if br_receiver="$(poll_baud_rate_receiver "$DESIRED_BAUD_RATE")";then
|
|
# read worked
|
|
if [ "$br_receiver" == "$DESIRED_BAUD_RATE" ];then
|
|
# baud rate of receiver is matching baud rate specified in CONFIG_FILE
|
|
if [ "$(cat "$SAVE_FILE")" == "1" ];then
|
|
printf "baud rate of %s is already at %s baud\\n" "$DEVICE_NAME" "$DESIRED_BAUD_RATE"
|
|
printf "configuration is saved in flash of %s\\n" "$DEVICE_NAME"
|
|
|
|
if set_baud_rate_tty;then
|
|
printf "set baud rate of %s to %s baud\\n" "$TTY_INTERFACE" "$DESIRED_BAUD_RATE"
|
|
else
|
|
printf "failed to set baud rate of %s to %s\\n" "$TTY_INTERFACE" "$DESIRED_BAUD_RATE"
|
|
exit 6
|
|
fi
|
|
write_config_out
|
|
restart_gpsd
|
|
# script can exit
|
|
exit 0 # baud rate of receiver is already matching $DESIRED_BAUD_RATE
|
|
else
|
|
# TODO: this could be way faster by telling the detector which baud rate to use since we already know it
|
|
printf "baud rate of %s is already at %s baud\\n" "$DEVICE_NAME" "$DESIRED_BAUD_RATE"
|
|
printf "configuration is not saved in flash of %s\\n" "$DEVICE_NAME"
|
|
# hint for the detector
|
|
PRESELECTION_BAUD_RATES=("$br_receiver")
|
|
fi
|
|
else
|
|
printf "baud rates are not matching\\n"
|
|
fi
|
|
else
|
|
printf "read failed\\n"
|
|
fi
|
|
|
|
# determine current baud rate of receiver
|
|
args=("2" "${PRESELECTION_BAUD_RATES[@]}")
|
|
detect_baud_rate "${args[@]}"
|
|
if [ "$?" == "1" ];then
|
|
# retry with more baud rates and more tries per baud rate
|
|
printf "retrying\\n"
|
|
# maybe a time out increase would also work when dealing with lower baud rates?
|
|
args=("$MAX_ALLOWED_RETRIES" "${SUPPORTED_BAUD_RATES[@]}")
|
|
detect_baud_rate "${args[@]}"
|
|
if [ "$?" == "1" ];then
|
|
printf "baud rate not detected, even after retry\\n"
|
|
exit 1 # unable to detect baud rate
|
|
fi
|
|
fi
|
|
printf "detected baud rate of %s is %s baud\\n" "$DEVICE_NAME" "$DETECTED_BAUD_RATE"
|
|
|
|
# upgrade to $DESIRED_BAUD_RATE baud
|
|
new_baud_rate_set_flag=0
|
|
for i in $(eval "echo {0..$MAX_ALLOWED_RETRIES}")
|
|
do
|
|
set_baud_rate_receiver "$DETECTED_BAUD_RATE" "$DESIRED_BAUD_RATE"
|
|
|
|
if br_receiver="$(poll_baud_rate_receiver "$DESIRED_BAUD_RATE")";then
|
|
# poll of baud rate worked
|
|
if [ "$br_receiver" == "$DESIRED_BAUD_RATE" ];then
|
|
# baud rate of receiver is matching $DESIRED_BAUD_RATE
|
|
new_baud_rate_set_flag=1
|
|
# reset save log
|
|
echo 0 > $SAVE_FILE
|
|
break
|
|
fi
|
|
fi
|
|
# increasing timeout for each try
|
|
t=$(echo "$i" "0.1"| awk '{printf "%4.3f\n",$1*$2}')
|
|
sleep "$t"
|
|
done
|
|
|
|
if [ "$new_baud_rate_set_flag" == "0" ];then
|
|
printf "baud rate of %s is not set to %s baud or unable to verify, retried %s times\\n" "$DEVICE_NAME" "$DESIRED_BAUD_RATE" "$i"
|
|
exit 3 # baud rate not set to $DESIRED_BAUD_RATE or verifiying baud rate failed
|
|
else
|
|
printf "baud rate of %s is set to desired %s baud, it took %s retries\\n" "$DEVICE_NAME" "$DESIRED_BAUD_RATE" "$i"
|
|
fi
|
|
|
|
# save config to flash
|
|
config_saved_flag=0
|
|
for i in $(eval "echo {0..$MAX_ALLOWED_RETRIES}")
|
|
do
|
|
if save_receiver_config;then
|
|
config_saved_flag=1
|
|
break # success
|
|
fi
|
|
# increasing timeout for each try
|
|
t=$(echo "$i" "0.1"| awk '{printf "%4.3f\n",$1*$2}')
|
|
sleep "$t"
|
|
done
|
|
|
|
if [ "$config_saved_flag" == "0" ];then
|
|
printf "saving to flash was not successful, retried %s times\\n" "$i"
|
|
exit 4 # saving to flash failed
|
|
else
|
|
printf "saving to flash was successful, it took %s retries\\n" "$i"
|
|
fi
|
|
|
|
if set_baud_rate_tty;then
|
|
printf "set baud rate of %s to %s baud\\n" "$TTY_INTERFACE" "$DESIRED_BAUD_RATE"
|
|
else
|
|
printf "failed to set baud rate of %s to %s\\n" "$TTY_INTERFACE" "$DESIRED_BAUD_RATE"
|
|
exit 6
|
|
fi
|
|
|
|
write_config_out
|
|
restart_gpsd
|
|
|
|
exit 0 # successfully changed baud rate to $DESIRED_BAUD_RATE specified in $CONFIG_FILE
|