X-Git-Url: http://average.org/gitweb/?a=blobdiff_plain;f=gps303%2Fzmsg.py;h=1fe18123c441739a9891b1433ec8bc276b5c876a;hb=c09b5175b9cebb804cd23e5468dd8da87442a08a;hp=80cf0003cbb97eee3baf55684a9085cb010d2c3f;hpb=80e795c08def3466884223357798cd1aff265212;p=loctrkd.git diff --git a/gps303/zmsg.py b/gps303/zmsg.py index 80cf000..1fe1812 100644 --- a/gps303/zmsg.py +++ b/gps303/zmsg.py @@ -1,15 +1,18 @@ """ Zeromq messages """ -from datetime import datetime, timezone import ipaddress as ip from struct import pack, unpack -__all__ = "Bcast", "LocEvt", "Resp" +__all__ = "Bcast", "Resp", "topic" def pack_peer(peeraddr): try: - saddr, port, _x, _y = peeraddr + if peeraddr is None: + saddr = "::" + port = 0 + else: + saddr, port, _x, _y = peeraddr addr = ip.ip_address(saddr) except ValueError: saddr, port = peeraddr @@ -59,22 +62,34 @@ class _Zmsg: ), ) + def __eq__(self, other): + return all( + [getattr(self, k) == getattr(other, k) for k, _ in self.KWARGS] + ) + def decode(self, buffer): - raise RuntimeError( - self.__class__.__name__ + "must implement `encode()` method" + raise NotImplementedError( + self.__class__.__name__ + "must implement `decode()` method" ) @property def packed(self): - raise RuntimeError( - self.__class__.__name__ + "must implement `encode()` method" + raise NotImplementedError( + self.__class__.__name__ + "must implement `packed()` property" ) +def topic(proto, is_incoming=True, imei=None): + return pack("BB", is_incoming, proto) + ( + b"" if imei is None else pack("16s", imei.encode()) + ) + + class Bcast(_Zmsg): """Zmq message to broadcast what was received from the terminal""" KWARGS = ( + ("is_incoming", True), ("proto", 256), ("imei", None), ("when", None), @@ -85,8 +100,14 @@ class Bcast(_Zmsg): @property def packed(self): return ( - pack("B", self.proto) - + ("0000000000000000" if self.imei is None else self.imei).encode() + pack( + "BB16s", + int(self.is_incoming), + self.proto, + "0000000000000000" + if self.imei is None + else self.imei.encode(), + ) + ( b"\0\0\0\0\0\0\0\0" if self.when is None @@ -97,54 +118,39 @@ class Bcast(_Zmsg): ) def decode(self, buffer): - self.proto = buffer[0] - self.imei = buffer[1:17].decode() + self.is_incoming = bool(buffer[0]) + self.proto = buffer[1] + self.imei = buffer[2:18].decode() if self.imei == "0000000000000000": self.imei = None - self.when = unpack("!d", buffer[17:25])[0] - self.peeraddr = unpack_peer(buffer[25:43]) - self.packet = buffer[43:] + self.when = unpack("!d", buffer[18:26])[0] + self.peeraddr = unpack_peer(buffer[26:44]) + self.packet = buffer[44:] class Resp(_Zmsg): """Zmq message received from a third party to send to the terminal""" - KWARGS = (("imei", None), ("packet", b"")) + KWARGS = (("imei", None), ("when", None), ("packet", b"")) @property def packed(self): return ( - "0000000000000000" if self.imei is None else self.imei.encode() - ) + self.packet - - 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), - ) - - @property - def packed(self): - return self.imei.encode() + pack( - "!dddB", - self.devtime.replace(tzinfo=timezone.utc).timestamp(), - self.lat, - self.lon, - int(self.is_gps), + pack( + "16s", + "0000000000000000" + if self.imei is None + else self.imei.encode(), + ) + + ( + b"\0\0\0\0\0\0\0\0" + if self.when is None + else pack("!d", self.when) + ) + + self.packet ) def decode(self, buffer): self.imei = buffer[:16].decode() - when, self.lat, self.lon, is_gps = unpack("!dddB", buffer[16:]) - self.devtime = datetime.fromtimestamp(when).astimezone(tz=timezone.utc) - self.is_gps = bool(is_gps) + self.when = unpack("!d", buffer[16:24])[0] + self.packet = buffer[24:]