summaryrefslogtreecommitdiff
path: root/gpsfake
blob: 4f79910ada0160de8eae28e9f69b7de7a0fb2a6e (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
#!/usr/bin/env python
#
# gpsfake -- test harness for gpsd
#
# Simulates a GPS, playing back an NMEA logfile

import sys, os, time, signal, pty, getopt, tempfile, termios

(options, arguments) = getopt.getopt(sys.argv[1:], "c:hlno:s:")
cycle = 1
speed = 4800
spawn = True
linedump = False
doptions = ""
for (switch, val) in options:
    if (switch == '-c'):
        cycle = float(val)
    elif (switch == '-l'):
        linedump = True
    elif (switch == '-n'):
        spawn = False
    elif (switch == '-o'):
        doptions = val
    elif (switch == '-s'):
        speed = int(val)
    elif (switch == '-h'):
        sys.stderr.write("usage: gpsfake [-h] [-l] [-n] [-o options] [-s speed] [-c cycle] logfile\n")
        sys.exit(0)
logfile = arguments[0]

try:
    (master_fd, slave_fd) = pty.openpty()
except:
    sys.stderr.write("gpsfake: can't open pty.\n")
    sys.exit(1)
slave = os.ttyname(slave_fd)

spawncmd = "gpsd -N -P /tmp/gpsfake%d -p %s %s" % (os.getpid(),slave,doptions)
print spawncmd

if not spawn:
    sys.stderr.write("gpsfake: slave tty is %s\n" % slave)
elif os.system(spawncmd + " &"):
    sys.stderr.write("gpsfake: gpsd launch failed.\n")
    sys.exit(1)
else:
    sys.stderr.write("gpsfake: gpsd launch OK.\n")

    fp = open("/tmp/gpsfake%s" % os.getpid())
    pid = int(fp.read())
    fp.close()
    os.remove("/tmp/gpsfake%s" % os.getpid())

try:
    logfp = open(logfile, "r")
    logdata = logfp.read()
    logfp.close()
    while logdata[0] == "#":
        logdata = logdata[logdata.find('\n')+1:]
    if logdata[0] == '$':
        print "gpsfake: interpreting as NMEA"
        leader = '$';
        legend = "gpsfake: line %d "
        textual = 1
    elif logdata[0] == 0xa0:
        print "gpsfake: interpreting as SiRF-II binary packets"
        leader = 0xa0
        legend = "gpsfake: packet %d"
        textual = 0
    else:
        print "gpsfake: unknown log type, can't handle it!"
        logdata = None

    if logdata:
        lines = map(lambda x: leader+x, logdata.split(leader)[1:])

        ttyfp = open(slave, "rw")
        raw = termios.tcgetattr(ttyfp.fileno())
        raw[0] = 0					# iflag
        raw[1] = termios.ONLCR				# oflag
        raw[2] &= ~(termios.PARENB | termios.CRTSCTS)	# cflag
        raw[2] |= (termios.CSIZE & termios.CS8)		# cflag
        raw[2] |= termios.CREAD | termios.CLOCAL	# cflag
        raw[3] = 0					# lflag
        raw[4] = raw[5] = eval("termios.B" + `speed`)
        termios.tcsetattr(ttyfp.fileno(), termios.TCSANOW, raw)

        try:
            i = 0;
            while True:
                if i % len(lines) == 0:
                    print "gpsfake: log cycle begins."
                time.sleep(cycle)
                if linedump:
                    if textual:
                        ml = lines[i % len(lines)].strip()
                    else:
                        ml = ""
                    print legend % (i % len(lines) + 1) + ml
                os.write(master_fd, lines[i % len(lines)])
                try:
                    st = os.kill(pid, 0)
                except OSError:
                    pid = 0
                    print "gpsfake: gpsd is gone."
                    break
                i += 1
        except KeyboardInterrupt:
            pass
finally:
    if spawn and (pid == 0 or os.kill(pid, 0) == 0):
        os.kill(pid, signal.SIGTERM)