OpenHome/MAXPacketHandler.py

78 lines
3.3 KiB
Python
Raw Normal View History

2021-08-26 18:49:18 +02:00
from MAXCube import MAXCube
from MAXPacket import MAXPacket, MAXPacketFactory, MAXPairPingPacket, MAXPairPongPacket, MAXAckPacket, \
MAXResetPacket, MAXWakeUpPacket, MAXSetGroupIdPacket
from time import sleep
from enum import Enum
class HandshakeState(Enum):
PING_RECEIVED = 1
PONG_SENT = 2
PONG_ACK = 3
GROUP_ID_SENT = 4
GROUP_ID_ACK = 5
class Handshake:
def __init__(self, partner_addr, dev_type):
self.partner_addr = partner_addr
self.dev_type = dev_type
self.state: HandshakeState = HandshakeState.PING_RECEIVED
class MAXPacketHandler:
def __init__(self, cube: MAXCube):
self.cube = cube
self.quit_flag = False
self.handshakes = []
def handle_msg(self, pkt: MAXPacket):
print(pkt.to_string())
if pkt.dest_address == self.cube.addr or pkt.dest_address == "000000":
if isinstance(pkt, MAXPairPingPacket):
handshake = Handshake(pkt.sender_address, pkt.device_type)
self.handshakes.append(handshake)
pong = MAXPairPongPacket(message_counter="00", message_flag="00", sender_address=self.cube.addr,
dest_address=pkt.sender_address, group_id="00")
pong_str = pong.serialize()
print(pong.to_string())
self.cube.request(pong_str)
handshake.state = HandshakeState.PONG_SENT
elif isinstance(pkt, MAXAckPacket):
cur_handshake: Handshake = None
for handshake in self.handshakes:
if handshake.partner_addr == pkt.sender_address:
cur_handshake = handshake
break
if cur_handshake is not None:
if cur_handshake.state == HandshakeState.PONG_SENT:
cur_handshake.state = HandshakeState.PONG_ACK
print(pkt.to_string())
if cur_handshake.dev_type == "05":
# Handshake is finished
print("Paired device with addr={} and type={}".format(cur_handshake.partner_addr,
cur_handshake.dev_type))
self.handshakes.remove(cur_handshake)
else:
set_group_id = MAXSetGroupIdPacket(message_counter="00", message_flag="00", sender_address=self.cube.addr,
dest_address=pkt.sender_address, group_id="00")
set_group_id_str = set_group_id.serialize()
print(set_group_id_str)
self.cube.request(set_group_id_str)
cur_handshake.state = HandshakeState.GROUP_ID_SENT
if cur_handshake.state == HandshakeState.GROUP_ID_SENT:
cur_handshake.state = HandshakeState.GROUP_ID_ACK
else:
print("Paket is not ours!")
def receive_loop(self):
while not self.quit_flag and self.cube.is_connected():
resp = self.cube.response()
if resp is not None and resp[0:1] == "Z":
pkt = MAXPacketFactory.create_packet(resp)
self.handle_msg(pkt)
sleep(0.1)