summaryrefslogtreecommitdiff
path: root/recipes-navigation/gpsd/gpsd/gpsd_ubx_fixed.sh
blob: c975942e7caa51dffc75767934896432f9c8fa3e (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
#!/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.
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
}

# Most exits are errors, so remove the GPS fix file.
trap rm_gps_file EXIT

if ! [[ -x /usr/bin/gpsmon ]] ; then
  logger -p user.err "gpsd_ubx_3dfix.sh:  Please install gpsmon"
  exit 0
fi

ppid=$$
# echo gpsd_ubx_fixed parent $$ >>/tmp/gpsdlog.${ppid}
# Restrict future kill to our process group.  During boot,
# this is the entire rc complex, but not any daemons.
pgid=$(ps -o pgrp -p $ppid --no-heading)
# Terminate gpsmon after 10 seconds if it is our child
(
  sleep 10
  # echo in child pgid $pgid  >>"/tmp/gpsdlog.${ppid}"
  # ps -o  pid,pgid,args -e >>"/tmp/log1.${ppid}"
  # Kill a gpsmon -a in our process group.  Hopefully this is our
  # parents gpsmon -a.
  gpsmonpid=$(ps -o pid,pgid,args -e | egrep "[[:space:]]${pgid}[[:space:]]+gpsmon[[:space:]]-a$" | sed -r 's/^[[:space:]]*([0-9]*)[[:space:]]+.*/\1/')
  # echo sleeper TERM found pid $gpsmonpid >>"/tmp/gpsdlog.${ppid}"
  if ((${#gpsmonpid})) ; then
    logger -p user.info "terminating gpsmon(${gpsmonpid}) with SIGTERM"
    # echo "terminating gpsmon(${gpsmonpid}) with SIGTERM"
    kill ${gpsmonpid}
  else
    exit 0
  fi
  sleep 2
  # echo "SIGKILL next" >>"/tmp/gpsdlog.${ppid}"
  # ps -o  pid,pgid,comm -e >>"/tmp/log2.${ppid}"
  gpsmonpid=$(ps -o pid,pgid,args -e | egrep "[[:space:]]${pgid}[[:space:]]+gpsmon[[:space:]]-a$" | sed -r 's/^[[:space:]]*([0-9]*)[[:space:]]+.*/\1/')
  # echo sleeper KILL found pid $gpsmonpid  >>"/tmp/gpsdlog.${ppid}"
  # Kill with SIGKILL, in case SIGTERM fails.
  if ((${#gpsmonpid})) ; then
    logger -p user.info "terminating gpsmon(${gpsmonpid}) with SIGKILL"
    kill -9 ${gpsmonpid}
  fi
) &
  
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
})"

# echo Past GPSMON in gpsd_ubx_fixed pid $$
if ((${#stuff} == 0)) ; then
  logger -p user.err No data from GPS
  exit 1
fi

if [[ -t 1 ]] ; then
  stty echo icanon
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))
    ;;
  *)
    logger -p user.err "Is GPSD running?"
    logger -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
  logger -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
    logger user.info "GPS has fix $fix found in list GPSFIX: $GPSFIX"
    echo $x >"${GPS_FIXFILE}"
    GPS_FIXFILE=""
    exit 0
  fi
done

logger -p user.info "GPS fix is bad: $fix and should be one of: $GPSFIX"
# Start later
exit 1