From 9ad343844ce25dae94470f9e22bfc37c6a9e5eda Mon Sep 17 00:00:00 2001 From: Steven B <51370195+sdb9696@users.noreply.github.com> Date: Mon, 28 Oct 2024 16:39:41 +0000 Subject: [PATCH 1/5] Fix H200 discovery --- kasa/discover.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/kasa/discover.py b/kasa/discover.py index ade6a54a6..d96248f1e 100755 --- a/kasa/discover.py +++ b/kasa/discover.py @@ -86,7 +86,6 @@ import binascii import ipaddress import logging -import secrets import socket import struct from collections.abc import Awaitable @@ -146,7 +145,6 @@ class _AesDiscoveryQuery: def generate_query(cls): if not cls.keypair: cls.keypair = KeyPair.create_key_pair(key_size=2048) - secret = secrets.token_bytes(4) key_payload = {"params": {"rsa_key": cls.keypair.get_public_pem().decode()}} @@ -158,7 +156,7 @@ def generate_query(cls): msg_size = len(key_payload_bytes) flags = 17 padding_byte = 0 # blank byte - device_serial = int.from_bytes(secret, "big") + device_serial = 1337 initial_crc = 0x5A6B7C8D disco_header = struct.pack( From b13d916f86fba536853d6f673db4304b55cbe0a8 Mon Sep 17 00:00:00 2001 From: Steven B <51370195+sdb9696@users.noreply.github.com> Date: Tue, 29 Oct 2024 10:10:55 +0000 Subject: [PATCH 2/5] Revert "Fix H200 discovery" This reverts commit 9ad343844ce25dae94470f9e22bfc37c6a9e5eda. --- kasa/discover.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/kasa/discover.py b/kasa/discover.py index d96248f1e..ade6a54a6 100755 --- a/kasa/discover.py +++ b/kasa/discover.py @@ -86,6 +86,7 @@ import binascii import ipaddress import logging +import secrets import socket import struct from collections.abc import Awaitable @@ -145,6 +146,7 @@ class _AesDiscoveryQuery: def generate_query(cls): if not cls.keypair: cls.keypair = KeyPair.create_key_pair(key_size=2048) + secret = secrets.token_bytes(4) key_payload = {"params": {"rsa_key": cls.keypair.get_public_pem().decode()}} @@ -156,7 +158,7 @@ def generate_query(cls): msg_size = len(key_payload_bytes) flags = 17 padding_byte = 0 # blank byte - device_serial = 1337 + device_serial = int.from_bytes(secret, "big") initial_crc = 0x5A6B7C8D disco_header = struct.pack( From 3f366db664fd3e5de0046daf2ff8cb1b36111e36 Mon Sep 17 00:00:00 2001 From: Steven B <51370195+sdb9696@users.noreply.github.com> Date: Tue, 29 Oct 2024 10:54:56 +0000 Subject: [PATCH 3/5] Use broadcast target for aes discovery request --- kasa/discover.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/kasa/discover.py b/kasa/discover.py index ade6a54a6..d50e66eba 100755 --- a/kasa/discover.py +++ b/kasa/discover.py @@ -212,6 +212,9 @@ def __init__( self.target = target self.target_1 = (target, self.discovery_port) self.target_2 = (target, Discover.DISCOVERY_PORT_2) + broadcast_target = ".".join(target.split(".")[:3]) + ".255" + self.single_host = broadcast_target != target + self.target_3 = (broadcast_target, Discover.DISCOVERY_PORT_2) self.discovered_devices = {} self.unsupported_device_exceptions: dict = {} @@ -277,7 +280,7 @@ async def do_discover(self) -> None: break self.transport.sendto(encrypted_req[4:], self.target_1) # type: ignore self.transport.sendto(Discover.DISCOVERY_QUERY_2, self.target_2) # type: ignore - self.transport.sendto(aes_discovery_query, self.target_2) # type: ignore + self.transport.sendto(aes_discovery_query, self.target_3) # type: ignore await asyncio.sleep(sleep_between_packets) def datagram_received(self, data, addr) -> None: @@ -287,7 +290,7 @@ def datagram_received(self, data, addr) -> None: ip, port = addr # Prevent multiple entries due multiple broadcasts - if ip in self.seen_hosts: + if ip in self.seen_hosts or (self.single_host and ip != self.target): return self.seen_hosts.add(ip) From d8fb6fec8201d6dc47be2061538d3ea79c37326f Mon Sep 17 00:00:00 2001 From: Steven B <51370195+sdb9696@users.noreply.github.com> Date: Tue, 29 Oct 2024 10:55:15 +0000 Subject: [PATCH 4/5] Revert "Use broadcast target for aes discovery request" This reverts commit 3f366db664fd3e5de0046daf2ff8cb1b36111e36. --- kasa/discover.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/kasa/discover.py b/kasa/discover.py index d50e66eba..ade6a54a6 100755 --- a/kasa/discover.py +++ b/kasa/discover.py @@ -212,9 +212,6 @@ def __init__( self.target = target self.target_1 = (target, self.discovery_port) self.target_2 = (target, Discover.DISCOVERY_PORT_2) - broadcast_target = ".".join(target.split(".")[:3]) + ".255" - self.single_host = broadcast_target != target - self.target_3 = (broadcast_target, Discover.DISCOVERY_PORT_2) self.discovered_devices = {} self.unsupported_device_exceptions: dict = {} @@ -280,7 +277,7 @@ async def do_discover(self) -> None: break self.transport.sendto(encrypted_req[4:], self.target_1) # type: ignore self.transport.sendto(Discover.DISCOVERY_QUERY_2, self.target_2) # type: ignore - self.transport.sendto(aes_discovery_query, self.target_3) # type: ignore + self.transport.sendto(aes_discovery_query, self.target_2) # type: ignore await asyncio.sleep(sleep_between_packets) def datagram_received(self, data, addr) -> None: @@ -290,7 +287,7 @@ def datagram_received(self, data, addr) -> None: ip, port = addr # Prevent multiple entries due multiple broadcasts - if ip in self.seen_hosts or (self.single_host and ip != self.target): + if ip in self.seen_hosts: return self.seen_hosts.add(ip) From 0e077b4a2c0b570182b7278e99ab3b360ef2bc89 Mon Sep 17 00:00:00 2001 From: Steven B <51370195+sdb9696@users.noreply.github.com> Date: Tue, 29 Oct 2024 11:03:04 +0000 Subject: [PATCH 5/5] Do not send older 20002 discovery query --- kasa/discover.py | 1 - kasa/tests/test_discovery.py | 7 +++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/kasa/discover.py b/kasa/discover.py index ade6a54a6..3b8f7c448 100755 --- a/kasa/discover.py +++ b/kasa/discover.py @@ -276,7 +276,6 @@ async def do_discover(self) -> None: if self.target in self.seen_hosts: # Stop sending for discover_single break self.transport.sendto(encrypted_req[4:], self.target_1) # type: ignore - self.transport.sendto(Discover.DISCOVERY_QUERY_2, self.target_2) # type: ignore self.transport.sendto(aes_discovery_query, self.target_2) # type: ignore await asyncio.sleep(sleep_between_packets) diff --git a/kasa/tests/test_discovery.py b/kasa/tests/test_discovery.py index a31ef8363..0dc4e0d7c 100644 --- a/kasa/tests/test_discovery.py +++ b/kasa/tests/test_discovery.py @@ -294,7 +294,7 @@ async def test_discover_send(mocker): assert proto.target_1 == ("255.255.255.255", 9999) transport = mocker.patch.object(proto, "transport") await proto.do_discover() - assert transport.sendto.call_count == proto.discovery_packets * 3 + assert transport.sendto.call_count == proto.discovery_packets * 2 async def test_discover_datagram_received(mocker, discovery_data): @@ -501,14 +501,13 @@ async def test_do_discover_drop_packets(mocker, port, do_not_reply_count): discovery_timeout=discovery_timeout, discovery_packets=5, ) - expected_send = 1 if port == 9999 else 2 - ft = FakeDatagramTransport(dp, port, do_not_reply_count * expected_send) + ft = FakeDatagramTransport(dp, port, do_not_reply_count) dp.connection_made(ft) await dp.wait_for_discovery_to_complete() await asyncio.sleep(0) - assert ft.send_count == do_not_reply_count * expected_send + expected_send + assert ft.send_count == do_not_reply_count + 1 assert dp.discover_task.done() assert dp.discover_task.cancelled()