X-Git-Url: http://average.org/gitweb/?a=blobdiff_plain;f=gps303%2F__main__.py;h=fcd07a6380ff43ec3c8d1060ebcfba57da443a99;hb=bf48ccad4b4b91e7d7e09d1087f5953bc2db97d7;hp=c8c5a28c4a265096bc12f3aee7056355c5299a05;hpb=5d6f5033cfe12dff6bfd26110d1b67efcb249f53;p=loctrkd.git diff --git a/gps303/__main__.py b/gps303/__main__.py old mode 100755 new mode 100644 index c8c5a28..fcd07a6 --- a/gps303/__main__.py +++ b/gps303/__main__.py @@ -1,89 +1,48 @@ +""" Command line tool for sending requests to the terminal """ + +from configparser import ConfigParser +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 +from typing import List, Tuple +import zmq -from .config import readconfig -from .GT06mod import handle_packet, make_response, LOGIN -from .evstore import initdb, stow - -CONF = "/etc/gps303.conf" +from . import common +from .zx303proto import * +from .zmsg import Bcast, Resp log = getLogger("gps303") -if __name__.endswith("__main__"): - opts, _ = getopt(sys.argv[1:], "c:p:") - opts = dict(opts) - conf = readconfig(opts["c"] if "c" in opts else CONF) - if sys.stdout.isatty(): - log.addHandler(StreamHandler(sys.stderr)) - log.setLevel(DEBUG) - else: - log.addHandler(SysLogHandler(address="/dev/log")) - log.setLevel(INFO) +def main( + conf: ConfigParser, opts: List[Tuple[str, str]], args: List[str] +) -> None: + # Is this https://github.com/zeromq/pyzmq/issues/1627 still not fixed?! + zctx = zmq.Context() # type: ignore + zpush = zctx.socket(zmq.PUSH) # type: ignore + zpush.connect(conf.get("collector", "listenurl")) - initdb(conf.get("daemon", "dbfn")) + 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.proto, msg.payload) - response = make_response(msg) - 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: - 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)