#!/bin/bash # Fix file creation for U-Blox GPS. # If GPS reaches expected # fix level, file GSP_FIXFILE is created. # This is to know when to set the system # and hardware clock, and when # it is safe to start ntp. # DEBUG=1 to set debug NAME=gpsd_ubx_fixed shopt -s expand_aliases alias LG=logger\ -t\ ${NAME} if [[ -r /etc/default/gpsd ]] ; then . /etc/default/gpsd else echo "Must configure GPSD requirements" exit 1 fi UBXNAVSOL='b56201063400' UBXNAVSOLLEN=60 function rm_gps_file { if [[ -n "${GPS_FIXFILE}" ]] && [[ -f ${GPS_FIXFILE} ]] ; then rm -f "${GPS_FIXFILE}" fi } function kill_it { cmd=$1 pid=$2 sig=$3 ((DEBUG)) && LG -p user.info "terminating $cmd(${pid}) with SIG${sig}" kill -SIG${sig} ${pid} >/dev/null 2>&1 result=$? ((DEBUG)) && LG -p user.info "kill -SIG${sig} ${pid} result is $result" } # Most exits are errors, so remove the GPS fix file. trap rm_gps_file EXIT if ! [[ -x /usr/bin/gpsmon ]] ; then LG -p user.err "Please install gpsmon" exit 0 fi # Terminate gpsmon after 10 seconds if it is our child # gpsmon has issues with terminals and stalling on terminal # read of the console. ( sleep 10 # We use BASHPID because our parent, $$, may have already exited, and # then ps will not work. BASHPID is the current subshell. ppid=$BASHPID pgid=$(ps --no-heading -o pgid -p $ppid) if ((${#pgid} == 0)) ; then LG -p user.err "Could not find a pgid for $ppid" ps -fjp $ppid | LG -p user.error fi gpsmonpid=$(pgrep -lg $pgid | egrep '[[:space:]]gpsmon$' | sed 's/[[:space:]].*//') ((DEBUG)) && LG -p user.info "$pgid is pgid $gpsmonpid is gpsmonpid" # Find the gpsmonpid that is our grandchild ((didkill=0)) # for loop is in case gpsmonpid has children. for p in ${gpsmonpid} ; do if ((${#p})) ; then kill_it gpsmon $p TERM ((didkill=p)) break fi done if ((didkill == 0)) ; then exit 0 fi # Do a sigkill to be sure. sleep 2 kill_it gpsmon $didkill KILL ) & fix="" status="" # egrep in busybox has a horrible buffering issue. # echo My shell pid is $$ # echo Place data fix, status stuff="$(gpsmon -a 2>&1 | { OIFS=${IFS} IFS=$'\n' while read ln ; do if [[ $ln =~ ^[[:space:]]*\(${UBXNAVSOLLEN}\)[[:space:]]*${UBXNAVSOL}....................(..)(.) ]] ; then IFS=${OIFS} fix="${BASH_REMATCH[1]}" if ((${#fix} == 0)) ; then fix="unknown" fi status=$(echo "${BASH_REMATCH[2]}") if ((${#status} == 0)) ; then status="unknown" fi break; fi oldln="${ln}" done if ((${#fix})) && ((${#status})) ; then echo "$fix,$status" else echo "${oldln}" fi })" if ((${#stuff} == 0)) ; then LG -p user.err "No data from GPS" exit 1 fi if [[ -t 1 ]] ; then stty echo icanon 2>/dev/null fi OIFS=${IFS} IFS=, set $stuff fix="$1" status="$2" IFS=${OIFS} # fixOK is the least significant bit of a hex single digit case $status in [13579bBdDfF]) ((fixOK=1)) ;; [02468aAcCeE]) ((fixOK=0)) ;; *) LG -p user.err "Is GPSD running?" LG -p user.err "FIX OK field should be single hex digit: gpsmon data: $stuff" exit 1 break ;; esac # echo "status is $status. fixOK is $fixOK" if ((fixOK == 0)) ; then LG -p user.err "Problem with the GPS fix. The fix is an even value, \"$status\", and should be an odd value. fixOK=${fixOK}" exit 1 # Retry later. How? fi # echo "fix is $fix. Is it in $GPSFIX?" # Test the GPS fixOK for x in $GPSFIX ; do # echo test $x with $fix if [[ $x == $fix ]] ; then LG -p user.info "GPS has fix $fix found in list GPSFIX: $GPSFIX" echo $x >"${GPS_FIXFILE}" GPS_FIXFILE="" exit 0 fi done LG -p user.info "GPS fix is bad: $fix and should be one of: $GPSFIX" # Start later exit 1