Skip to content

Commit b35eec8

Browse files
committed
Update pc host's python script and shell script
1 parent c175ff0 commit b35eec8

3 files changed

Lines changed: 150 additions & 61 deletions

File tree

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
@echo off
2-
:: Check for admin rights
2+
:: Check for admin rights (Required for installing global packages and for netsh commands later)
33
net session >nul 2>&1
44
if %errorLevel% == 0 (
55
echo Running as Administrator...
@@ -10,7 +10,12 @@ if %errorLevel% == 0 (
1010
)
1111

1212
cd /d "%~dp0"
13+
echo Installing Python Dependencies...
1314
python -m pip install --upgrade pip
14-
python -m pip install pyserial cobs websocket-client
15+
:: 'flask' is optional but included for the HTTP Streaming server example
16+
python -m pip install pyserial cobs websocket-client flask
1517

16-
pause
18+
echo.
19+
echo Dependencies installed successfully.
20+
echo You can now run 'run.bat' to start the bridge.
21+
pause

examples/Features/PC_USB_Host/install_libs.sh

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,47 @@
22

33
# Check if running as root
44
if [ "$EUID" -ne 0 ]; then
5-
echo "Re-running with sudo..."
6-
exec sudo "$0" "$@"
5+
echo "Requesting sudo privileges to install dependencies..."
6+
sudo "$0" "$@"
7+
exit
78
fi
89

910
cd "$(dirname "$0")"
11+
12+
echo "Installing Python Dependencies..."
13+
# Ensure pip is installed (common issue on some Linux distros)
14+
if ! command -v pip3 &> /dev/null; then
15+
echo "pip3 not found. Attempting to install python3-pip..."
16+
if [ -x "$(command -v apt-get)" ]; then
17+
apt-get update && apt-get install -y python3-pip
18+
fi
19+
fi
20+
1021
python3 -m pip install --upgrade pip
11-
python3 -m pip install pyserial cobs websocket-client
22+
# 'flask' is optional but included for the HTTP Streaming server example
23+
python3 -m pip install pyserial cobs websocket-client flask
24+
25+
echo ""
26+
echo "Dependencies installed."
27+
28+
# OS-Specific Checks
29+
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
30+
echo "Checking for network managers..."
31+
if command -v nmcli &> /dev/null; then
32+
echo " [OK] NetworkManager (nmcli) found."
33+
elif command -v wpa_cli &> /dev/null; then
34+
echo " [OK] wpa_supplicant (wpa_cli) found."
35+
else
36+
echo " [WARNING] Neither nmcli nor wpa_cli found. WiFi management may not work."
37+
fi
38+
elif [[ "$OSTYPE" == "darwin"* ]]; then
39+
echo "Checking for network setup tools..."
40+
if command -v networksetup &> /dev/null; then
41+
echo " [OK] networksetup found."
42+
else
43+
echo " [WARNING] networksetup command not found. WiFi management may not work."
44+
fi
45+
fi
46+
47+
echo ""
48+
echo "Setup complete. You can now run './run.sh'."

examples/Features/PC_USB_Host/serial_bridge.py

Lines changed: 102 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
# ==========================================
1616
# CONFIGURATION
1717
# ==========================================
18-
SERIAL_PORT = 'COM16' # Update this to match your port
18+
SERIAL_PORT = 'COM3' # Update this to match your port
1919
BAUD_RATE = 115200
2020

2121
# ==========================================
@@ -200,9 +200,7 @@ def wrap_socket_ssl(self, sock, hostname, ca_cert=None):
200200
def udp_rx_thread(self, slot_id, sock):
201201
while self.udp_sockets[slot_id] == sock and self.running:
202202
try:
203-
data = sock.recv(64)
204-
if not data: break
205-
203+
data, addr = sock.recvfrom(512)
206204
self.udp_rx_queues[slot_id].put((data, addr[0], addr[1]))
207205
except socket.timeout: continue
208206
except: break
@@ -250,7 +248,7 @@ def on_open(ws):
250248
wst.start()
251249

252250
# --------------------------------------------------------------------------
253-
# System Command Utilities
251+
# System Command Utilities (Integrated from wifi_management.py)
254252
# --------------------------------------------------------------------------
255253
def check_internet(self):
256254
try:
@@ -259,47 +257,64 @@ def check_internet(self):
259257
except OSError:
260258
return False
261259

260+
def is_raspberry_pi(self):
261+
"""Detect if running on Raspberry Pi hardware."""
262+
if platform.system() == "Linux":
263+
try:
264+
with open("/proc/cpuinfo", "r") as f:
265+
cpuinfo = f.read().lower()
266+
if "raspberry pi" in cpuinfo or "bcm" in cpuinfo:
267+
return True
268+
except Exception:
269+
pass
270+
return False
271+
272+
def get_wifi_interface_linux(self):
273+
"""Auto-detect WiFi interface on Linux using nmcli, fallback to wlan0."""
274+
try:
275+
result = subprocess.check_output("nmcli device status", shell=True).decode()
276+
for line in result.splitlines():
277+
if "wifi" in line.lower():
278+
return line.split()[0] # first column is interface name
279+
except Exception:
280+
pass
281+
return "wlan0"
282+
283+
def get_wifi_interface_mac(self):
284+
"""Auto-detect WiFi interface on macOS using networksetup, fallback to en0."""
285+
try:
286+
result = subprocess.check_output("networksetup -listallhardwareports", shell=True).decode()
287+
for block in result.split("\n\n"):
288+
if "Wi-Fi" in block:
289+
for line in block.splitlines():
290+
if line.startswith("Device:"):
291+
return line.split(":")[1].strip()
292+
except Exception:
293+
pass
294+
return "en0"
295+
262296
def system_set_wifi(self, ssid, password):
263297
sys_platform = platform.system()
264298
print(f"[SYSTEM] Configuring WiFi for {sys_platform}...")
265299

266300
if sys_platform == "Windows":
267-
# Correct XML format for Windows netsh
268301
xml_template = f"""<?xml version="1.0"?>
269302
<WLANProfile xmlns="http://www.microsoft.com/networking/WLAN/profile/v1">
270303
<name>{ssid}</name>
271-
<SSIDConfig>
272-
<SSID>
273-
<name>{ssid}</name>
274-
</SSID>
275-
</SSIDConfig>
304+
<SSIDConfig><SSID><name>{ssid}</name></SSID></SSIDConfig>
276305
<connectionType>ESS</connectionType>
277306
<connectionMode>auto</connectionMode>
278-
<MSM>
279-
<security>
280-
<authEncryption>
281-
<authentication>WPA2PSK</authentication>
282-
<encryption>AES</encryption>
283-
<useOneX>false</useOneX>
284-
</authEncryption>
285-
<sharedKey>
286-
<keyType>passPhrase</keyType>
287-
<protected>false</protected>
288-
<keyMaterial>{password}</keyMaterial>
289-
</sharedKey>
290-
</security>
291-
</MSM>
307+
<MSM><security>
308+
<authEncryption><authentication>WPA2PSK</authentication><encryption>AES</encryption><useOneX>false</useOneX></authEncryption>
309+
<sharedKey><keyType>passPhrase</keyType><protected>false</protected><keyMaterial>{password}</keyMaterial></sharedKey>
310+
</security></MSM>
292311
</WLANProfile>"""
293312
try:
294-
# Write temporary XML profile
295313
with open("wifi.xml", "w") as f:
296314
f.write(xml_template)
297-
298-
# Execute commands
315+
os.system("netsh wlan disconnect")
299316
os.system('netsh wlan add profile filename="wifi.xml"')
300317
os.system(f'netsh wlan connect name="{ssid}"')
301-
302-
# Cleanup
303318
if os.path.exists("wifi.xml"):
304319
os.remove("wifi.xml")
305320
return True
@@ -308,34 +323,63 @@ def system_set_wifi(self, ssid, password):
308323
return False
309324

310325
elif sys_platform == "Linux":
311-
# Using nmcli (Network Manager CLI)
312-
try:
313-
# Disconnect current first to ensure clean switch
314-
os.system("nmcli dev disconnect wlan0")
315-
if password:
316-
ret = os.system(f"nmcli dev wifi connect '{ssid}' password '{password}'")
317-
else:
318-
ret = os.system(f"nmcli dev wifi connect '{ssid}'")
319-
return ret == 0
320-
except:
321-
return False
326+
iface = self.get_wifi_interface_linux()
327+
print(f"[SYSTEM] Using Interface: {iface}")
328+
329+
# Check if Raspberry Pi (might need wpa_cli instead of nmcli)
330+
if self.is_raspberry_pi():
331+
try:
332+
# Prefer nmcli first
333+
os.system(f"nmcli device disconnect {iface}")
334+
if password:
335+
ret = os.system(f"nmcli device wifi connect '{ssid}' password '{password}'")
336+
else:
337+
ret = os.system(f"nmcli device wifi connect '{ssid}'")
338+
if ret == 0: return True
339+
except:
340+
pass # Fallback to wpa_cli below
341+
342+
# Fallback for RPi Lite (wpa_cli)
343+
try:
344+
print("[SYSTEM] nmcli failed, trying wpa_cli...")
345+
os.system(f"wpa_cli -i {iface} disconnect")
346+
os.system(f"wpa_cli -i {iface} add_network")
347+
os.system(f"wpa_cli -i {iface} set_network 0 ssid '\"{ssid}\"'")
348+
if password:
349+
os.system(f"wpa_cli -i {iface} set_network 0 psk '\"{password}\"'")
350+
os.system(f"wpa_cli -i {iface} enable_network 0")
351+
return True
352+
except Exception as e:
353+
print(f"[ERROR] RPi WiFi Config Failed: {e}")
354+
return False
355+
else:
356+
# Standard Linux (Ubuntu/Fedora etc)
357+
try:
358+
os.system(f"nmcli device disconnect {iface}")
359+
if password:
360+
ret = os.system(f"nmcli device wifi connect '{ssid}' password '{password}'")
361+
else:
362+
ret = os.system(f"nmcli device wifi connect '{ssid}'")
363+
return ret == 0
364+
except:
365+
return False
322366

323367
elif sys_platform == "Darwin": # macOS
368+
iface = self.get_wifi_interface_mac()
369+
print(f"[SYSTEM] Using Interface: {iface}")
324370
try:
325-
os.system("networksetup -setairportpower en0 off")
371+
os.system(f"networksetup -setairportpower {iface} off")
326372
time.sleep(1)
327-
os.system("networksetup -setairportpower en0 on")
373+
os.system(f"networksetup -setairportpower {iface} on")
328374
if password:
329-
ret = os.system(f"networksetup -setairportnetwork en0 '{ssid}' '{password}'")
375+
ret = os.system(f"networksetup -setairportnetwork {iface} '{ssid}' '{password}'")
330376
else:
331-
ret = os.system(f"networksetup -setairportnetwork en0 '{ssid}'")
377+
ret = os.system(f"networksetup -setairportnetwork {iface} '{ssid}'")
332378
return ret == 0
333379
except:
334380
return False
335381

336-
else:
337-
print(f"[SYSTEM] Unsupported OS: {sys_platform}")
338-
return False
382+
return False
339383

340384
def system_disconnect_wifi(self):
341385
sys_platform = platform.system()
@@ -344,11 +388,17 @@ def system_disconnect_wifi(self):
344388
if sys_platform == "Windows":
345389
os.system("netsh wlan disconnect")
346390
elif sys_platform == "Linux":
347-
os.system("nmcli dev disconnect wlan0")
391+
iface = self.get_wifi_interface_linux()
392+
if self.is_raspberry_pi():
393+
try:
394+
os.system(f"nmcli device disconnect {iface}")
395+
except:
396+
os.system(f"wpa_cli -i {iface} disconnect")
397+
else:
398+
os.system(f"nmcli device disconnect {iface}")
348399
elif sys_platform == "Darwin": # macOS
349-
os.system("networksetup -setairportpower en0 off")
350-
else:
351-
print("Unsupported OS")
400+
iface = self.get_wifi_interface_mac()
401+
os.system(f"networksetup -setairportpower {iface} off")
352402
return True
353403

354404
def system_reboot(self):
@@ -402,7 +452,6 @@ def perform_reboot():
402452

403453
print(f"[GLOBAL] Set WiFi Request: {ssid}")
404454

405-
# Store for connection
406455
self.wifi_ssid = ssid
407456
self.wifi_pass = password
408457

@@ -416,8 +465,6 @@ def perform_reboot():
416465
elif cmd == CMD_C_CONNECT_NET:
417466
print(f"[GLOBAL] Connecting to WiFi: {self.wifi_ssid}...")
418467
if self.wifi_ssid:
419-
# Trigger the actual system connection in a thread
420-
# This avoids blocking the serial read loop
421468
threading.Thread(target=self.system_set_wifi, args=(self.wifi_ssid, self.wifi_pass), daemon=True).start()
422469
success = True
423470
else:

0 commit comments

Comments
 (0)