def test_heartbeat_response_packet(self): pp = Packet() packet = pp.build( dict(start=b"\x78\x78", fields=dict(value=dict( length=1 + 2 + 2, protocol=0x23, data=bytes(), serial=256)))) self.assertEqual(packet, b'\x78\x78\x05\x23\x01\x00\x67\x0E\x0D\x0A')
def send(self, packet: Packet, server=False): self.__client.connect((self.server_host, self.port)) for p in packet.build(encrypt=(packet.command != Command.REGISTER), server=server): self.__client.send(p) resp = self.recv(encrypt=(packet.command != Command.REGISTER), server=server) return resp
def test_alarm_response_packet(self): pp = Packet() packet = pp.build( dict(start=b"\x79\x79", fields=dict(value=dict( length=1 + 2 + 2, protocol=0x33, data=bytes(), serial=256)))) self.assertEqual(packet, b'\x79\x79\x00\x05\x33\x01\x00\xD1\x32\x0D\x0A')
def test_information_response_packet(self): pp = Packet() packet = pp.build( dict(start=b"\x79\x79", fields=dict(value=dict(length=1 + (1) + 2 + 2, protocol=0x98, data=bytes(1), serial=0)))) self.assertEqual(packet, b'\x79\x79\x00\x06\x98\x00\x00\x00\xC7\x00\x0D\x0A')
def test_command_packet(self): pp = Packet() data = Packet.command.build( dict(length=4 + 7, serverflag=0, content=b"UNLOCK#")) packet = pp.build( dict(start=b"\x78\x78", fields=dict(value=dict(length=1 + (1 + 4 + 7) + 2 + 2, protocol=0x80, data=data, serial=1)))) self.assertEqual( packet, b'\x78\x78\x11\x80\x0B\x00\x00\x00\x00\x55\x4E\x4C\x4F\x43\x4B\x23\x00\x01\x53\x54\x0D\x0A' )
def test_login_response_packet(self): pp = Packet() packet = pp.build( dict(start=b"\x78\x78", fields=dict(value=dict(length=1 + (6 + 1 + 0) + 2 + 2, protocol=0x01, data=Packet.login_response.build( dict(datetime=dict(year=17, month=3, day=20, hour=8, minute=56, second=57), reserved_length=0, reserved=0)), serial=0x39)))) self.assertEqual( packet, b'\x78\x78\x0C\x01\x11\x03\x14\x08\x38\x39\x00\x00\x39\x95\x70\x0D\x0A' )
class BL10(LineReceiver): device_id = None serial = 0 def __init__(self): self.packet = Packet(crc_secret=CRC_SECRET) def printPacket(self, direction, packet): dt = datetime.utcnow().replace( tzinfo=timezone.utc).astimezone().replace( microsecond=0).isoformat() if direction == '>': direction = '==>' else: direction = '<==' print("%s [%s] %s %s" % ( dt, self.device_id, direction, binascii.hexlify(packet), )) def lineReceived(self, line): self.printPacket("<", line) lbl = {'device_id': self.device_id, **promlabels} locktimegauge.labels(**lbl).set(int(time.time())) try: data = self.packet.parse(line + b'\r\n') print(data) proto = str(data.protocol) print(proto) self.serial = data.serial if proto == 'login': self.handleLogin(data) elif proto == 'heartbeat': self.handleHeartbeat(data) elif proto == 'location': self.handleLocation(data) elif proto == 'alarm': self.handleAlarm(data) elif proto == 'information': self.handleInformation(data) elif proto == 'response': self.handleResponse(data) else: self.handleUnknown(data) except Exception as e: print(e) pass def write(self, data): self.printPacket(">", data) self.transport.write(data) def handleLogin(self, data): print("login from %s (%s)" % (data.data.imei, data.data.model)) now = datetime.now(timezone.utc) year = int(now.strftime("%y")) dt = dict(year=year, month=now.month, day=now.day, hour=now.hour, minute=now.minute, second=now.second) respdata = Packet.login_response.build( dict(datetime=dt, reserved_length=0, reserved=0)) self.serial += 1 resp = self.packet.build( dict(start=b"\x78\x78", fields=dict(value=dict(length=1 + (6 + 1 + 0) + 2 + 2, protocol=0x01, data=respdata, serial=self.serial)))) self.write(resp) self.device_id = str(data.data.imei) devices[self.device_id] = self update = {'device_id': self.device_id} print(jsons.dumps(update)) resp = requests.post(ENDPOINT, headers=headers, data=jsons.dumps(update)) print(resp) print(resp.text) def handleHeartbeat(self, data): self.serial += 1 resp = self.packet.build( dict(start=b"\x78\x78", fields=dict(value=dict(length=1 + 2 + 2, protocol=0x23, data=bytes(), serial=self.serial)))) self.write(resp) lbl = {'device_id': self.device_id, **promlabels} trackervoltgauge.labels(**lbl).set(data.data.voltage) lockvoltgauge.labels(**lbl).set(data.data.voltage) update = { 'device_id': self.device_id, 'battery_voltage': data.data.voltage } print(jsons.dumps(update)) resp = requests.post(ENDPOINT, headers=headers, data=jsons.dumps(update)) print(resp) print(resp.text) def handleLocation(self, data): self.serial += 1 resp = self.packet.build( dict(start=b"\x79\x79", fields=dict(value=dict(length=1 + 2 + 2, protocol=0x32, data=bytes(), serial=self.serial)))) self.write(resp) self.submitLocation(data) def submitLocation(self, data): lbl = {'device_id': self.device_id, **promlabels} trackertimegauge.labels(**lbl).set(int(time.time())) update = {'device_id': self.device_id} if data.data.gps: # FIXME: something something with the data.data.gps.cs.latitude, data.data.gps.cs.longitude flags update['lat'] = data.data.gps.latitude update['lng'] = data.data.gps.longitude print(jsons.dumps(update)) resp = requests.post(ENDPOINT, headers=headers, data=jsons.dumps(update)) print(resp) print(resp.text) def handleAlarm(self, data): self.serial += 1 resp = self.packet.build( dict(start=b"\x79\x79", fields=dict(value=dict(length=1 + 2 + 2, protocol=0x33, data=bytes(), serial=self.serial)))) self.write(resp) self.submitLocation(data) def handleInformation(self, data): self.serial += 1 resp = self.packet.build( dict(start=b"\x79\x79", fields=dict(value=dict(length=1 + (1) + 2 + 2, protocol=0x98, data=bytes(1), serial=self.serial)))) self.write(resp) def handleResponse(self, data): self.serial += 1 print("Got response: %s" % (data.data.content, )) def handleUnknown(self, data): self.serial += 1 print("Got unkown packet, protocol is %d" % (data.protocol, )) def sendCommand(self, command): length = len(command) self.serial += 1 data = Packet.command.build( dict(length=4 + length, serverflag=0, content=command)) resp = self.packet.build( dict(start=b"\x79\x79", fields=dict(value=dict(length=1 + (1 + 4 + length) + 2 + 2, protocol=0x80, data=data, serial=self.serial)))) self.write(resp) def sendUnlock(self): self.sendCommand(b"UNLOCK#") def ring(self): self.sendCommand(b"SDFIND,ON,3,15,1#") def locate(self): self.sendCommand(b"LJDW#")
def _send(self, sock, packet: Packet): for p in packet.build(server=True): sock.send(p)