def datagram_received(sp, data, addr): if not self.online: return log.debug( hp.lc("RECV", bts=binascii.hexlify(data).decode(), protocol="udp", serial=self.serial)) pkt = Messages.unpack(data, self.protocol_register, unknown_ok=True) if pkt.serial not in ("000000000000", self.serial): return ack = self.ack_for(pkt, "udp") if ack: ack.sequence = pkt.sequence ack.source = pkt.source ack.target = self.serial self.udp_transport.sendto(ack.tobytes(serial=self.serial), addr) for res in self.response_for(pkt, "udp"): res.sequence = pkt.sequence res.source = pkt.source res.target = self.serial self.udp_transport.sendto(res.tobytes(serial=self.serial), addr)
async def write(self, source, received_data, bts): if not self.attrs.online: return addr = None for service in self.services: a = service.address(source) if a: addr = a break if addr is None: log.warning( hp.lc( "Tried to write a packet to the fake device, but no appropriate service found", source=source, serial=self.serial, )) return log.debug( hp.lc("RECV", bts=binascii.hexlify(bts).decode(), source=source, serial=self.serial)) pkt = Messages.unpack(bts, self.protocol_register, unknown_ok=True) if pkt.serial not in ("000000000000", self.serial): return async for msg in self.got_message(pkt, source): await received_data(msg.tobytes(serial=self.serial), addr)
async def received_data(self, data, addr, allow_zero=False): """What to do when we get some data""" if type(data) is bytes: log.debug( hp.lc("Received bytes", bts=binascii.hexlify(data).decode())) try: protocol_register = self.transport_target.protocol_register protocol, pkt_type, Packet, PacketKls, data = Messages.get_packet_type( data, protocol_register) if protocol == 1024 and pkt_type == 45: if isinstance(data, bytes): source = struct.unpack("<I", data[4:8])[0] target = data[8:16] sequence = data[23] else: source = data.source target = data.target sequence = data.sequence serial = binascii.hexlify(target[:6]).decode() pkt = FakeAck(source, sequence, target, serial, addr) else: if PacketKls is None: PacketKls = Packet if isinstance(data, PacketKls): pkt = data.clone() else: pkt = PacketKls.create(data) except Exception as error: log.exception(error) else: await self.receiver.recv(pkt, addr, allow_zero=allow_zero)
async def execute_task(self, **kwargs): extra = self.photons_app.extra_as_json if "extra_payload_kwargs" in kwargs: extra.update(kwargs["extra_payload_kwargs"]) packd = Messages.pack(extra, protocol_register, unknown_ok=True) print(binascii.hexlify(packd.tobytes()).decode())
async def unpack_base64(collector, **kwargs): """ Unpack base64 string found after the ``--`` into a json dictionary ``unpack_base64 -- MQAAFIIF7TPQc9USYeIAAAAAAAAAAAMBAAAAAAAAAABmAAAAAPRpAAD//6wNAAAAAA==`` """ bts = base64.b64decode(collector.configuration["photons_app"].extra) pkt = Messages.unpack(bts, collector.configuration["protocol_register"], unknown_ok=True) print(repr(pkt))
async def unpack(collector, **kwargs): """ Unpack hexlified string found after the ``--`` into a json dictionary ``unpack -- 310000148205ed33d073d51261e20000000000000000030100000000000000006600000000f4690000ffffac0d00000000`` """ bts = binascii.unhexlify(collector.configuration["photons_app"].extra) pkt = Messages.unpack(bts, collector.configuration["protocol_register"], unknown_ok=True) print(repr(pkt))
async def execute_task(self, **kwargs): extra = self.photons_app.extra_as_json message_register = protocol_register.message_register(1024) if "extra_payload_kwargs" in kwargs: extra.update(kwargs["extra_payload_kwargs"]) packd = Messages.pack_payload(self.reference, extra, message_register) print(binascii.hexlify(packd.tobytes()).decode())
async def write(s, transport, bts, original_message): called.append("write") pkt = Messages.unpack(bts, protocol_register=protocol_register) res = DeviceMessages.EchoResponse( source=pkt.source, sequence=pkt.sequence, target=pkt.target, echoing=b"pong" ) loop = asyncio.get_event_loop() bts = res.pack().tobytes() addr = ("fake://device", 56700) loop.call_soon(s.session.sync_received_data, bts, addr)
async def pack(collector, **kwargs): """ Pack json found after the ``--`` into hexlified string ``pack -- '{"frame_address": {"ack_required": true, "res_required": true, "reserved2": "000000000000", "reserved3": "00", "sequence": 1, "target": "0000000000000000"}, "frame_header": {"addressable": true, "protocol": 1024, "reserved1": "00", "size": 68, "source": 591976603, "tagged": false}, "payload": {}, "protocol_header": {"pkt_type": 45, "reserved4": "0000000000000000", "reserved5": "0000"}}'`` """ extra = collector.configuration["photons_app"].extra_as_json protocol_register = collector.configuration["protocol_register"] if "extra_payload_kwargs" in kwargs: extra.update(kwargs["extra_payload_kwargs"]) packd = Messages.pack(extra, protocol_register, unknown_ok=True) print(binascii.hexlify(packd.tobytes()).decode())
async def process_incoming(self, bts, give_reply, addr): if not self.device.has_power: return pkt = Messages.create(bts, protocol_register=self.device.protocol_register) event = await self.device.event_with_options( Events.INCOMING, execute=False, args=(self, ), kwargs=dict(pkt=pkt, addr=addr), ) processed = await self.packet_filter.process_request(event) if processed is None: event = await self.device.event(Events.LOST, self, pkt=pkt, addr=addr) return await self.device.execute_event(event, lambda e: e.handled) await self.process_instruction(SendAck(event), give_reply) if processed is False: await self.device.event(Events.IGNORED, self, pkt=event.pkt, bts=event.bts, addr=event.addr) return if event.ignored: await self.device.event(Events.IGNORED, self, pkt=event.pkt, bts=event.bts, addr=event.addr) elif not event.handled and not event.replies: await self.device.event(Events.UNHANDLED, self, pkt=event.pkt, bts=event.bts, addr=event.addr) await self.process_instruction(SendUnhandled(event), give_reply) else: await self.process_instruction(SendReplies(event), give_reply)
async def pack_payload(collector, reference, **kwargs): """ Pack json found after the ``--`` into hexlified string ``pack_payload 117 -- '{"level": 65535, "duration": 10}'`` """ extra = collector.configuration["photons_app"].extra_as_json protocol_register = collector.configuration["protocol_register"] message_register = protocol_register.message_register(1024) if "extra_payload_kwargs" in kwargs: extra.update(kwargs["extra_payload_kwargs"]) packd = Messages.pack_payload(reference, extra, message_register) print(binascii.hexlify(packd.tobytes()).decode())
@pytest.fixture() def protocol_register(self, TestMessages): protocol_register = ProtocolRegister() protocol_register.add(1024, LIFXPacket) protocol_register.message_register(1024).add(TestMessages) return protocol_register describe "get_packet_type": it "can get us information about our data", protocol_register, TestMessages: data = mock.Mock(name="data") packet_type = mock.Mock(name="packet_type", return_value=(1024, 78)) with mock.patch.object(PacketTypeExtractor, "packet_type", packet_type): info = Messages.get_packet_type(data, protocol_register) assert info == (1024, 78, LIFXPacket, TestMessages.One, data) packet_type.assert_called_once_with(data) data = mock.Mock(name="data") packet_type = mock.Mock(name="packet_type", return_value=(1024, 99)) with mock.patch.object(PacketTypeExtractor, "packet_type", packet_type): info = Messages.get_packet_type(data, protocol_register) assert info == (1024, 99, LIFXPacket, TestMessages.Two, data) packet_type.assert_called_once_with(data) it "can get us information about unknown pkt types (known protocol)", protocol_register: data = mock.Mock(name="data")
def make_message(bts): return Messages.create(bts, protocol_register=protocol_register)
async def execute_task(self, **kwargs): bts = base64.b64decode(self.photons_app.extra) pkt = Messages.create(bts, protocol_register, unknown_ok=True) print(repr(pkt))
async def execute_task(self, **kwargs): bts = binascii.unhexlify(self.photons_app.extra) pkt = Messages.create(bts, protocol_register, unknown_ok=True) print(repr(pkt))
) assert msg.instanceid > 0 keys = pktkeys([msg]) assert keys == [(1024, 508, mock.ANY)] dct = json.loads(keys[0][-1]) assert dct["instanceid"] == 0 assert msg.instanceid > 0 it "knows to zero reserved fields": from photons_protocol.messages import T, Messages from photons_messages.frame import msg class Messages(Messages): SetExample = msg(9001, ("one", T.Reserved(6)), ("two", T.String(10))) msg = Messages.SetExample(source=1, sequence=2, target="d073d512", two="stuff") assert msg.actual("one") == sb.NotSpecified keys = pktkeys([msg]) assert keys == [(1024, 9001, '{"one": "00", "two": "stuff"}')] assert msg.actual("one") == sb.NotSpecified assert ( repr(msg.payload) == """{"one": "<class 'delfick_project.norms.spec_base.NotSpecified'>", "two": "stuff"}""" )
self.assertEqual(msg.payload.actual("skew_ratio"), 3276) self.assertEqual(msg.payload.actual("waveform"), 1) self.assertEqual(msg.payload.actual("set_hue"), 1) self.assertEqual(msg.payload.actual("set_saturation"), 0) self.assertEqual(msg.payload.actual("set_brightness"), 1) self.assertEqual(msg.payload.actual("set_kelvin"), 1) it "SetWaveformOptional does not require all hsbk values": msg = LightMessages.SetWaveformOptional(hue=100, source=1, sequence=0, target=None) self.assertIs(msg.actual("brightness"), sb.NotSpecified) self.assertEqual(msg.set_hue, 1) self.assertEqual(msg.set_saturation, 0) self.assertEqual(msg.set_brightness, 0) self.assertEqual(msg.set_kelvin, 0) unpackd = Messages.unpack(msg.pack(), protocol_register=protocol_register) self.assertAlmostEqual(unpackd.hue, 100, places=2) self.assertEqual(unpackd.set_hue, 1) self.assertEqual(unpackd.set_saturation, 0) self.assertEqual(unpackd.saturation, 0) self.assertEqual(unpackd.set_brightness, 0) self.assertEqual(unpackd.brightness, 0) self.assertEqual(unpackd.set_kelvin, 0) self.assertEqual(unpackd.kelvin, 0) msg = LightMessages.SetWaveformOptional.empty_normalise(hue=100, source=1, sequence=0, target=None) self.assertIs(msg.actual("brightness"), Optional) self.assertEqual(msg.set_hue, 1) self.assertEqual(msg.set_saturation, 0)