Skip to content

Commit d15f168

Browse files
committed
Add fix for Linux
Linux cannot receive broadcasts if IP is bound to the host IP
1 parent d44a6c6 commit d15f168

2 files changed

Lines changed: 32 additions & 18 deletions

File tree

PyStageLinQ/PyStageLinQ.py

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import platform
1212
import psutil
1313
import ipaddress
14+
import os
1415
from typing import Callable
1516

1617
from . import Device
@@ -39,9 +40,6 @@ def __init__(self, ip=None, discovery_port=51337):
3940
self.target_interfaces = []
4041
self.discovery_port = discovery_port
4142
self.get_interface_from_ip(ip)
42-
logger.info(f"Found {len(self.target_interfaces)} network interfaces:")
43-
for iface in self.target_interfaces:
44-
logger.info(f" - {iface.name}: {iface.addr_str}")
4543

4644
def get_interface_from_ip(self, ip):
4745
if ip is None:
@@ -55,24 +53,32 @@ def get_interface_from_ip(self, ip):
5553
ip_list = ip
5654
else:
5755
raise TypeError
56+
logger.info(f"Found {len(psutil.net_if_stats().items())} total network interfaces, listing IPv4 interfaces:")
5857

5958
for interface in psutil.net_if_stats().items():
6059
for interface_info in psutil.net_if_addrs()[interface[0]]:
6160
# Only look for IPV4 binds
62-
if socket.AF_INET == interface_info.family and (
63-
interface_info.address in ip_list or ip_list[0] == "any"
64-
):
65-
self.target_interfaces.append(
66-
PyStageLinQ_interface_info(
67-
interface[0],
68-
len(self.target_interfaces),
69-
int(ipaddress.IPv4Address(interface_info.address)),
70-
interface_info.address,
71-
int(ipaddress.IPv4Address(interface_info.netmask)),
72-
interface[1],
73-
0,
61+
if socket.AF_INET == interface_info.family:
62+
logger.info(f" - {interface[0]}: {interface_info.address}")
63+
if interface_info.address in ip_list or ip_list[0] == "any":
64+
self.target_interfaces.append(
65+
PyStageLinQ_interface_info(
66+
interface[0],
67+
len(self.target_interfaces),
68+
int(ipaddress.IPv4Address(interface_info.address)),
69+
interface_info.address,
70+
int(ipaddress.IPv4Address(interface_info.netmask)),
71+
interface[1],
72+
0,
73+
)
7474
)
75-
)
75+
76+
logger.info(f"{len(self.target_interfaces)} interfaces matched with requested interfaces and will be used by PyStageLinQ:")
77+
for iface in self.target_interfaces:
78+
logger.info(f" - {iface.name}: {iface.addr_str}")
79+
80+
81+
7682

7783
def send_discovery_frame(self, discovery_frame):
7884
for interface in self.target_interfaces:
@@ -214,9 +220,11 @@ async def _discover_stagelinq_device(self, host_ip, timeout=10):
214220
# Create socket
215221
discover_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
216222

223+
bind_ip = "" if os.name == "posix" else host_ip
224+
217225
try:
218226
discover_socket.bind(
219-
(host_ip, self.StageLinQ_discovery_port)
227+
(bind_ip, self.StageLinQ_discovery_port)
220228
) # bind socket to broadcast
221229
except Exception as e:
222230
# Cannot bind to socket, check if IP is correct and link is up

tests/Main.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def state_map_data_print(data):
5353
def main():
5454
logging.basicConfig(level=logging.INFO)
5555
global PrimeGo
56-
ip_choice = 1
56+
ip_choice = 2
5757
match ip_choice:
5858
case 0:
5959
PrimeGo = PyStageLinQ.PyStageLinQ(
@@ -69,6 +69,12 @@ def main():
6969
name="Jaxcie StageLinQ",
7070
ip=["169.254.13.37", "127.0.0.1"],
7171
)
72+
case 3:
73+
# should fail
74+
PrimeGo = PyStageLinQ.PyStageLinQ(
75+
new_device_found_callback, name="Jaxcie StageLinQ", ip="127.0.0.1"
76+
)
77+
7278
PrimeGo.start_standalone()
7379

7480

0 commit comments

Comments
 (0)