#!/usr/bin/python # Hotplug script for gpsd by Eric S. Raymond, March 2005 # This script is part of the gpsd distribution: see http://gpsd.berlios.de # Can be called like "gpsd.hotplug [add|remove] /dev/ttyUSB0" for test # purposes. import sys, os, syslog, glob, socket, stat CONTROL_SOCKET = "/var/run/gpsd.sock" def gpsd_control_connect(): "Acquire a connection to the GPSD control socket." try: sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM, 0) sock.connect(CONTROL_SOCKET) sockfile = sock.makefile() except socket.error, msg: if sock: sock.close() sock = None sockfile = None if not sock: syslog.syslog("gpsd is not running or %s is unreachable" % CONTROL_SOCKET) return None else: return sockfile def gpsd_control(action, argument): "Pass a command to gpsd; start the daemon if not already running." connect = gpsd_control_connect() if connect: syslog.syslog("reached a running gpsd") elif action == 'add': syslog.syslog("attempting to launch gpsd") os.system("gpsd -F " + CONTROL_SOCKET) connect = gpsd_control_connect() if not connect: return None # We've got a live connection to the gpsd control socket. No # need to parse the response, because gpsd will lock on to the # device if it's really a GPS and ignore it if it's not. if action == 'add': # Force the group-read & group-write bits on, so gpsd will still be # able to use this device after dropping root privileges. os.chmod(argument, stat.S_IMODE(os.stat(argument)[stat.ST_MODE])|0660) connect.write("+%s\r\n" % argument) elif action == 'remove': connect.write("-%s\r\n" % argument) connect.close() return action def hotplug(action, devpath): syslog.openlog('gpsd.hotplug', 0, syslog.LOG_DAEMON) syslog.syslog("gpsd.hotplug begins with action: %s" % action) if not devpath: syslog.syslog("No device") else: subnodes = glob.glob("/sys" + devpath + "/*") subnodes = map(os.path.basename, subnodes) subnodes = filter(lambda s: s.startswith("ttyUSB"), subnodes) if len(subnodes) == 0: syslog.syslog("no ttyUSB device under " + devpath) return elif len(subnodes) > 1: syslog.syslog("too many ttyUSB devices under " + devpath) return else: tty = "/dev/" + subnodes[0] syslog.syslog(tty + " has gone active") gpsd_control(action, tty) return syslog.syslog("gpsd.hotplug ends") syslog.closelog() if __name__ == '__main__': try: if len(sys.argv) == 1: # Called as hotplug script hotplug(os.getenv("ACTION"), os.getenv("DEVPATH")) else: # Called by hand for testing gpsd_control(sys.argv[1], sys.argv[2]) except: (exc_type, exc_value, exc_traceback) = sys.exc_info() syslog.syslog("gpsd.hotplug: exception %s yields %s" % (exc_type, exc_value)) raise exc_type, exc_value, exc_traceback