X-Git-Url: http://www.average.org/gitweb/?a=blobdiff_plain;f=gps303%2F__main__.py;h=15832804c130e0ffebe249d7926ab3d84a9a500e;hb=2cc29ee67b6432e1cd74a21b3c9181b8b5b557f9;hp=e3fd84a2460271a69fb65acfee1485e406e06a89;hpb=45e5cd8ce6f931b3bfb291394336cf8d94d895c3;p=loctrkd.git diff --git a/gps303/__main__.py b/gps303/__main__.py old mode 100755 new mode 100644 index e3fd84a..1583280 --- a/gps303/__main__.py +++ b/gps303/__main__.py @@ -1,100 +1,43 @@ +""" Command line tool for sending requests to the terminal """ + +from datetime import datetime, timezone from getopt import getopt -from logging import getLogger, StreamHandler, DEBUG, INFO -from logging.handlers import SysLogHandler -from select import poll, POLLIN, POLLERR, POLLHUP, POLLPRI -from socket import socket, AF_INET, SOCK_STREAM, SOL_SOCKET, SO_REUSEADDR -import sys +from logging import getLogger +from sys import argv from time import time +import zmq -from .config import readconfig -from .GT06mod import handle_packet, make_response, LOGIN, set_config -from .evstore import initdb, stow -from .lookaside import prepare_response - -CONF = "/etc/gps303.conf" +from . import common +from .gps303proto import * +from .zmsg import Bcast, Resp log = getLogger("gps303") -if __name__.endswith("__main__"): - opts, _ = getopt(sys.argv[1:], "c:d") - opts = dict(opts) - conf = readconfig(opts["-c"] if "-c" in opts else CONF) - if sys.stdout.isatty(): - log.addHandler(StreamHandler(sys.stderr)) - else: - log.addHandler(SysLogHandler(address="/dev/log")) - log.setLevel(DEBUG if "-d" in opts else INFO) - log.info("starting with options: %s", opts) +def main(conf, opts, args): + zctx = zmq.Context() + zpush = zctx.socket(zmq.PUSH) + zpush.connect(conf.get("collector", "listenurl")) - initdb(conf.get("daemon", "dbfn")) - set_config(conf) + if len(args) < 2: + raise ValueError( + "Too few args, need IMEI and command min: " + str(args) + ) + imei = args[0] + cmd = args[1] + args = args[2:] + cls = class_by_prefix(cmd) + if isinstance(cls, list): + raise ValueError("Prefix does not select a single class: " + str(cls)) + kwargs = dict([arg.split("=") for arg in args]) + for arg in args: + k, v = arg.split("=") + kwargs[k] = v + resp = Resp(imei=imei, when=time(), packet=cls.Out(**kwargs).packed) + log.debug("Response: %s", resp) + zpush.send(resp.packed) - ctlsock = socket(AF_INET, SOCK_STREAM) - ctlsock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) - ctlsock.bind(("", conf.getint("daemon", "port"))) - ctlsock.listen(5) - ctlfd = ctlsock.fileno() - pollset = poll() - pollset.register(ctlfd, POLLIN | POLLERR | POLLHUP | POLLPRI) - clnt_dict = {} - while True: - try: - events = pollset.poll(1000) - except KeyboardInterrupt: - log.info("Exiting") - sys.exit(0) - for fd, ev in events: - if fd == ctlfd: - if ev & POLLIN: - clntsock, clntaddr = ctlsock.accept() - clntfd = clntsock.fileno() - clnt_dict[clntfd] = (clntsock, clntaddr, None) - pollset.register( - clntfd, POLLIN | POLLERR | POLLHUP | POLLPRI - ) - log.debug( - "accepted connection from %s as fd %d", - clntaddr, - clntfd, - ) - if ev & ~POLLIN: - log.debug("unexpected event on ctlfd: %s", ev) - else: - try: - clntsock, clntaddr, imei = clnt_dict[fd] - except KeyError: # this socket closed already - continue - if ev & POLLIN: - packet = clntsock.recv(4096) - when = time() - if packet: - msg = handle_packet(packet, clntaddr, when) - log.debug("%s from %s fd %d", msg, clntaddr, fd) - if isinstance(msg, LOGIN): - imei = msg.imei - clnt_dict[fd] = (clntsock, clntaddr, imei) - stow( - clntaddr, - when, - imei, - msg.length, - msg.proto, - msg.payload, - ) - kwargs = prepare_response(conf, msg) - response = make_response(msg, **kwargs) - if response: - try: - # Ignore possibility of blocking - clntsock.send(make_response(msg)) - except OSError as e: - log.debug("sending to fd %d error %s", fd, e) - else: - # TODO: Also disconnect on HIBERNATION - log.info("disconnect fd %d imei %s", fd, imei) - pollset.unregister(fd) - clntsock.close() - del clnt_dict[fd] - if ev & ~POLLIN: - log.warning("unexpected event", ev, "on fd", fd) + +if __name__.endswith("__main__"): + opts, args = getopt(argv[1:], "c:d") + main(common.init(log, opts=opts), opts, args)