1 from getopt import getopt
2 from logging import getLogger, StreamHandler, DEBUG, INFO
3 from logging.handlers import SysLogHandler
4 from select import poll, POLLIN, POLLERR, POLLHUP, POLLPRI
5 from socket import socket, AF_INET, SOCK_STREAM, SOL_SOCKET, SO_REUSEADDR
9 from .config import readconfig
10 from .gps303proto import handle_packet, make_response, LOGIN, set_config
11 from .evstore import initdb, stow
12 from .lookaside import prepare_response
14 CONF = "/etc/gps303.conf"
16 log = getLogger("gps303")
18 if __name__.endswith("__main__"):
19 opts, _ = getopt(sys.argv[1:], "c:d")
21 conf = readconfig(opts["-c"] if "-c" in opts else CONF)
23 if sys.stdout.isatty():
24 log.addHandler(StreamHandler(sys.stderr))
26 log.addHandler(SysLogHandler(address="/dev/log"))
27 log.setLevel(DEBUG if "-d" in opts else INFO)
28 log.info("starting with options: %s", opts)
30 initdb(conf.get("storage", "dbfn"))
33 ctlsock = socket(AF_INET, SOCK_STREAM)
34 ctlsock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
35 ctlsock.bind(("", conf.getint("collector", "port")))
37 ctlfd = ctlsock.fileno()
39 pollset.register(ctlfd, POLLIN | POLLERR | POLLHUP | POLLPRI)
43 events = pollset.poll(1000)
44 except KeyboardInterrupt:
50 clntsock, clntaddr = ctlsock.accept()
51 clntfd = clntsock.fileno()
52 clnt_dict[clntfd] = (clntsock, clntaddr, None)
54 clntfd, POLLIN | POLLERR | POLLHUP | POLLPRI
57 "accepted connection from %s as fd %d",
62 log.debug("unexpected event on ctlfd: %s", ev)
65 clntsock, clntaddr, imei = clnt_dict[fd]
66 except KeyError: # this socket closed already
69 packet = clntsock.recv(4096)
72 msg = handle_packet(packet)
73 log.debug("%s from %s fd %d", msg, clntaddr, fd)
74 if isinstance(msg, LOGIN):
76 clnt_dict[fd] = (clntsock, clntaddr, imei)
85 kwargs = prepare_response(conf, msg)
86 response = make_response(msg, **kwargs)
89 # Ignore possibility of blocking
90 clntsock.send(make_response(msg))
92 log.debug("sending to fd %d error %s", fd, e)
94 # TODO: Also disconnect on HIBERNATION
95 log.info("disconnect fd %d imei %s", fd, imei)
96 pollset.unregister(fd)
100 log.warning("unexpected event", ev, "on fd", fd)