summaryrefslogtreecommitdiff
path: root/recipes-navigation/gpsd/gpsd/gpsd_ubx_fixed.sh
blob: 6c9c12643a391342c7d4aed7578a7d77ade61145 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#!/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