]> www.average.org Git - loctrkd.git/blob - gps303/__main__.py
use correct config entry
[loctrkd.git] / gps303 / __main__.py
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
6 import sys
7 from time import time
8
9 from .config import readconfig
10 from .GT06mod import handle_packet, make_response, LOGIN
11 from .evstore import initdb, stow
12
13 CONF = "/etc/gps303.conf"
14
15 log = getLogger("gps303")
16
17 if __name__.endswith("__main__"):
18     opts, _ = getopt(sys.argv[1:], "c:p:")
19     opts = dict(opts)
20     conf = readconfig(opts["c"] if "c" in opts else CONF)
21
22     if sys.stdout.isatty():
23         log.addHandler(StreamHandler(sys.stderr))
24         log.setLevel(DEBUG)
25     else:
26         log.addHandler(SysLogHandler(address="/dev/log"))
27         log.setLevel(INFO)
28
29     initdb(conf.get("daemon", "dbfn"))
30
31     ctlsock = socket(AF_INET, SOCK_STREAM)
32     ctlsock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
33     ctlsock.bind(("", conf.getint("daemon", "port")))
34     ctlsock.listen(5)
35     ctlfd = ctlsock.fileno()
36     pollset = poll()
37     pollset.register(ctlfd, POLLIN | POLLERR | POLLHUP | POLLPRI)
38     clnt_dict = {}
39     while True:
40         try:
41             events = pollset.poll(1000)
42         except KeyboardInterrupt:
43             log.info("Exiting")
44             sys.exit(0)
45         for fd, ev in events:
46             if fd == ctlfd:
47                 if ev & POLLIN:
48                     clntsock, clntaddr = ctlsock.accept()
49                     clntfd = clntsock.fileno()
50                     clnt_dict[clntfd] = (clntsock, clntaddr, None)
51                     pollset.register(
52                         clntfd, POLLIN | POLLERR | POLLHUP | POLLPRI
53                     )
54                     log.debug(
55                         "accepted connection from %s as fd %d",
56                         clntaddr,
57                         clntfd,
58                     )
59                 if ev & ~POLLIN:
60                     log.debug("unexpected event on ctlfd: %s", ev)
61             else:
62                 try:
63                     clntsock, clntaddr, imei = clnt_dict[fd]
64                 except KeyError:  # this socket closed already
65                     continue
66                 if ev & POLLIN:
67                     packet = clntsock.recv(4096)
68                     when = time()
69                     if packet:
70                         msg = handle_packet(packet, clntaddr, when)
71                         log.debug("%s from %s fd %d'", msg, clntaddr, fd)
72                         if isinstance(msg, LOGIN):
73                             imei = msg.imei
74                             clnt_dict[fd] = (clntsock, clntaddr, imei)
75                         stow(clntaddr, when, imei, msg.proto, msg.payload)
76                         response = make_response(msg)
77                         if response:
78                             try:
79                                 # Ignore possibility of blocking
80                                 clntsock.send(make_response(msg))
81                             except OSError as e:
82                                 log.debug("sending to fd %d error %s", fd, e)
83                     else:
84                         log.info("disconnect fd %d imei %s", fd, imei)
85                         pollset.unregister(fd)
86                         clntsock.close()
87                         del clnt_dict[fd]
88                 if ev & ~POLLIN:
89                     log.warning("unexpected event", ev, "on fd", fd)