-
-
Notifications
You must be signed in to change notification settings - Fork 24
fix(discovery): resolve Windows broadcast discovery failure with ProactorEventLoop #62
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -6,6 +6,8 @@ | |||||||||||||||||||
| import logging | ||||||||||||||||||||
| from typing import Any, List, Union | ||||||||||||||||||||
|
|
||||||||||||||||||||
| import netifaces | ||||||||||||||||||||
|
|
||||||||||||||||||||
| from .bridge import Bridge | ||||||||||||||||||||
| from .protobuf import zehnder_pb2 | ||||||||||||||||||||
|
|
||||||||||||||||||||
|
|
@@ -15,7 +17,7 @@ | |||||||||||||||||||
| class BridgeDiscoveryProtocol(asyncio.DatagramProtocol): | ||||||||||||||||||||
| """UDP Protocol for the ComfoConnect LAN C bridge discovery.""" | ||||||||||||||||||||
|
|
||||||||||||||||||||
| def __init__(self, target: str = None, timeout: int = 5): | ||||||||||||||||||||
| def __init__(self, target: str | None = None, timeout: int = 5): | ||||||||||||||||||||
| loop = asyncio.get_running_loop() | ||||||||||||||||||||
|
|
||||||||||||||||||||
| self._bridges: List[Bridge] = [] | ||||||||||||||||||||
|
|
@@ -33,8 +35,17 @@ def connection_made(self, transport: asyncio.transports.DatagramTransport): | |||||||||||||||||||
| _LOGGER.debug("Sending discovery request to %s:%d", self._target, Bridge.PORT) | ||||||||||||||||||||
| self.transport.sendto(b"\x0a\x00", (self._target, Bridge.PORT)) | ||||||||||||||||||||
| else: | ||||||||||||||||||||
| _LOGGER.debug("Sending discovery request to broadcast:%d", Bridge.PORT) | ||||||||||||||||||||
| self.transport.sendto(b"\x0a\x00", ("<broadcast>", Bridge.PORT)) | ||||||||||||||||||||
| # Determine broadcast address programmatically | ||||||||||||||||||||
| try: | ||||||||||||||||||||
| gws = netifaces.gateways() | ||||||||||||||||||||
| default_iface = gws['default'][netifaces.AF_INET][1] | ||||||||||||||||||||
| addrs = netifaces.ifaddresses(default_iface) | ||||||||||||||||||||
| broadcast_addr = addrs[netifaces.AF_INET][0].get('broadcast', '255.255.255.255') | ||||||||||||||||||||
| except Exception as e: | ||||||||||||||||||||
| _LOGGER.warning("Could not determine broadcast address, using 255.255.255.255: %s", e) | ||||||||||||||||||||
| broadcast_addr = '255.255.255.255' | ||||||||||||||||||||
|
Comment on lines
+43
to
+46
|
||||||||||||||||||||
| broadcast_addr = addrs[netifaces.AF_INET][0].get('broadcast', '255.255.255.255') | |
| except Exception as e: | |
| _LOGGER.warning("Could not determine broadcast address, using 255.255.255.255: %s", e) | |
| broadcast_addr = '255.255.255.255' | |
| inet_addrs = addrs.get(netifaces.AF_INET, []) | |
| if inet_addrs and 'broadcast' in inet_addrs[0]: | |
| broadcast_addr = inet_addrs[0]['broadcast'] | |
| else: | |
| broadcast_addr = '255.255.255.255' |
Copilot
AI
Oct 31, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The 'Raises' section is vague and unhelpful. It should document specific exceptions that callers might need to handle. Based on the code, this function doesn't raise exceptions from the protocol (they're caught internally), but could raise exceptions from loop.create_datagram_endpoint(). Consider either removing this section or documenting specific exceptions like OSError for network issues.
| Any exceptions raised by the underlying asyncio transport or protocol. | |
| OSError: If a network error occurs while creating the datagram endpoint. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code assumes the presence of keys in nested dictionaries without checking their existence, which can cause KeyError exceptions not caught by the generic Exception handler. Specifically,
gws['default'],gws['default'][netifaces.AF_INET], andaddrs[netifaces.AF_INET]could raise KeyError if the network doesn't have a default IPv4 gateway or IPv4 addresses configured. While the broad exception handler will catch this, it would be more explicit and maintainable to use.get()methods or check for key existence.