from . import common
from .gps303proto import parse_message, proto_by_name, WIFI_POSITIONING
from .opencellid import qry_cell
-from .zmsg import Bcast, LocEvt, Resp
+from .zmsg import Bcast, Resp
log = getLogger("gps303/lookaside")
def runserver(conf):
zctx = zmq.Context()
- zpub = zctx.socket(zmq.PUB)
- oldmask = umask(0o117)
- zpub.bind(conf.get("lookaside", "publishurl"))
- umask(oldmask)
zsub = zctx.socket(zmq.SUB)
zsub.connect(conf.get("collector", "publishurl"))
- for protoname in (
- "GPS_POSITIONING",
- "WIFI_POSITIONING",
- ):
- topic = pack("B", proto_by_name(protoname))
- zsub.setsockopt(zmq.SUBSCRIBE, topic)
+ topic = pack("B", proto_by_name("WIFI_POSITIONING"))
+ zsub.setsockopt(zmq.SUBSCRIBE, topic)
zpush = zctx.socket(zmq.PUSH)
zpush.connect(conf.get("collector", "listenurl"))
datetime.fromtimestamp(zmsg.when).astimezone(tz=timezone.utc),
msg,
)
- if isinstance(msg, WIFI_POSITIONING):
- is_gps = False
- lat, lon = qry_cell(
- conf["opencellid"]["dbfn"], msg.mcc, msg.gsm_cells
+ if not isinstance(msg, WIFI_POSITIONING):
+ log.error(
+ "IMEI %s from %s at %s: %s",
+ zmsg.imei,
+ zmsg.peeraddr,
+ datetime.fromtimestamp(zmsg.when).astimezone(
+ tz=timezone.utc
+ ),
+ msg,
)
- resp = Resp(
- imei=zmsg.imei, packet=msg.Out(lat=lat, lon=lon).packed
- )
- log.debug("Response for lat=%s, lon=%s: %s", lat, lon, resp)
- zpush.send(resp.packed)
- else:
- is_gps = True
- lat = msg.latitude
- lon = msg.longitude
- zpub.send(
- LocEvt(
- imei=zmsg.imei,
- devtime=msg.devtime,
- is_gps=is_gps,
- lat=lat,
- lon=lon,
- ).packed
+ continue
+ lat, lon = qry_cell(
+ conf["opencellid"]["dbfn"], msg.mcc, msg.gsm_cells
)
+ resp = Resp(imei=zmsg.imei, packet=msg.Out(lat=lat, lon=lon).packed)
+ log.debug("Response for lat=%s, lon=%s: %s", lat, lon, resp)
+ zpush.send(resp.packed)
except KeyboardInterrupt:
pass
+++ /dev/null
-""" Generate and publish locevt from the text input """
-
-import atexit
-from datetime import datetime, timezone
-from logging import getLogger
-from os import path, umask
-from readline import read_history_file, set_history_length, write_history_file
-from sys import argv
-import zmq
-
-from . import common
-from .zmsg import LocEvt
-
-log = getLogger("gps303/watch")
-
-RL_HISTORY = path.join(path.expanduser("~"), ".gps303_history")
-
-def main(conf):
- zctx = zmq.Context()
- zpub = zctx.socket(zmq.PUB)
- oldmask = umask(0o117)
- zpub.bind(conf.get("lookaside", "publishurl"))
- umask(oldmask)
- try:
- read_history_file(RL_HISTORY)
- except FileNotFoundError:
- pass
- set_history_length(1000)
- atexit.register(write_history_file, RL_HISTORY)
-
- while True:
- try:
- line = input("> ")
- except EOFError:
- break
- line = line.rstrip("\r\n")
- args = line.split(" ")
- imei = args[0]
- kwargs = dict([arg.split("=") for arg in args[1:]])
- msg = LocEvt(imei=imei, **kwargs)
- print("Publishing:", msg)
- zpub.send(msg.packed)
-
-
-if __name__.endswith("__main__"):
- main(common.init(log))
import zmq
from . import common
-from .zmsg import LocEvt
+from .zmsg import Bcast
log = getLogger("gps303/watch")
def runserver(conf):
zctx = zmq.Context()
zsub = zctx.socket(zmq.SUB)
- zsub.connect(conf.get("lookaside", "publishurl"))
+ zsub.connect(conf.get("collector", "publishurl"))
zsub.setsockopt(zmq.SUBSCRIBE, b"")
try:
while True:
- zmsg = LocEvt(zsub.recv())
- print(zmsg)
+ zmsg = Bcast(zsub.recv())
+ msg = parse_message(zmsg.packet)
+ print(zmsg.imei, msg)
except KeyboardInterrupt:
pass
""" Zeromq messages """
-from datetime import datetime, timezone
-from json import dumps, loads
import ipaddress as ip
from struct import pack, unpack
-__all__ = "Bcast", "LocEvt", "Resp"
+__all__ = "Bcast", "Resp"
def pack_peer(peeraddr):
def decode(self, buffer):
self.imei = buffer[:16].decode()
self.packet = buffer[16:]
-
-
-class LocEvt(_Zmsg):
- """Zmq message with original or approximated location from lookaside"""
-
- KWARGS = (
- ("imei", "0000000000000000"),
- ("devtime", datetime(1970, 1, 1, tzinfo=timezone.utc)),
- ("lat", 0.0),
- ("lon", 0.0),
- ("is_gps", True),
- )
-
- # This message is for external consumption, so use json encoding,
- # except imei that forms 16 byte prefix that can be used as the
- # topic to subscribe.
- @property
- def packed(self):
- return (
- ("0000000000000000" + self.imei)[-16:].encode()
- + dumps(
- {
- "devtime": str(self.devtime),
- "latitude": self.lat,
- "longitude": self.lon,
- "is-gps": self.is_gps,
- }
- ).encode()
- )
-
- # And this is full json that can be sent over websocket etc.
- @property
- def json(self):
- return dumps(
- {
- "imei": self.imei,
- "devtime": str(self.devtime),
- "latitude": self.lat,
- "longitude": self.lon,
- "is-gps": self.is_gps,
- }
- )
-
- def decode(self, buffer):
- self.imei = buffer[:16].decode()
- json_data = loads(buffer[16:])
- self.devtime = datetime.fromisoformat(json_data["devtime"])
- self.lat = json_data["latitude"]
- self.lon = json_data["longitude"]
- self.is_gps = json_data["is-gps"]