#!/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 -f %s %s" % (os.getpid(),slave,doptions) spawncmd = spawncmd.strip() if not spawn: raw_input("gpsfake: launch '%s' and press enter..." % spawncmd) elif os.system(spawncmd + " &"): sys.stderr.write("gpsfake: '%s' failed.\n" % spawncmd) sys.exit(1) else: sys.stderr.write("gpsfake: '%s' launch OK.\n" % spawncmd) 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)]) if spawn: 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)